diff --git a/package.json b/package.json index 974a724..2b7e9a8 100644 --- a/package.json +++ b/package.json @@ -2,12 +2,16 @@ "name": "@musistudio/claude-code-router", "version": "1.0.73", "description": "Use Claude Code without an Anthropics account and route it to another LLM provider", - "bin": { - "ccr": "dist/cli.js" - }, + "private": true, "scripts": { "build": "node scripts/build.js", - "release": "npm run build && npm publish" + "build:cli": "pnpm --filter @musistudio/claude-code-router-cli build", + "build:server": "pnpm --filter @musistudio/claude-code-router-server build", + "build:ui": "pnpm --filter @musistudio/claude-code-router-ui build", + "release": "pnpm build && pnpm publish -r", + "dev:cli": "pnpm --filter @musistudio/claude-code-router-cli dev", + "dev:server": "pnpm --filter @musistudio/claude-code-router-server dev", + "dev:ui": "pnpm --filter @musistudio/claude-code-router-ui dev" }, "keywords": [ "claude", @@ -18,33 +22,14 @@ ], "author": "musistudio", "license": "MIT", - "dependencies": { - "@fastify/static": "^8.2.0", - "@musistudio/llms": "^1.0.51", - "@inquirer/prompts": "^5.0.0", - "dotenv": "^16.4.7", - "find-process": "^2.0.0", - "json5": "^2.2.3", - "lru-cache": "^11.2.2", - "minimist": "^1.2.8", - "openurl": "^1.1.1", - "rotating-file-stream": "^3.2.7", - "shell-quote": "^1.8.3", - "tiktoken": "^1.0.21", - "uuid": "^11.1.0" - }, "devDependencies": { "@types/node": "^24.0.15", "esbuild": "^0.25.1", - "fastify": "^5.4.0", "shx": "^0.4.0", "typescript": "^5.8.2" }, - "publishConfig": { - "ignore": [ - "!build/", - "src/", - "screenshots/" - ] + "engines": { + "node": ">=18.0.0", + "pnpm": ">=8.0.0" } } diff --git a/packages/cli/package.json b/packages/cli/package.json new file mode 100644 index 0000000..e71b914 --- /dev/null +++ b/packages/cli/package.json @@ -0,0 +1,34 @@ +{ + "name": "@musistudio/claude-code-router-cli", + "version": "1.0.73", + "description": "CLI for Claude Code Router", + "bin": { + "ccr": "dist/cli.js" + }, + "scripts": { + "build": "node ../../scripts/build-cli.js", + "dev": "ts-node src/cli.ts" + }, + "keywords": [ + "claude", + "code", + "router", + "cli" + ], + "author": "musistudio", + "license": "MIT", + "dependencies": { + "@musistudio/claude-code-router-shared": "workspace:*", + "@inquirer/prompts": "^5.0.0", + "@musistudio/claude-code-router-server": "workspace:*", + "find-process": "^2.0.0", + "minimist": "^1.2.8", + "openurl": "^1.1.1" + }, + "devDependencies": { + "@types/node": "^24.0.15", + "esbuild": "^0.25.1", + "ts-node": "^10.9.2", + "typescript": "^5.8.2" + } +} diff --git a/src/cli.ts b/packages/cli/src/cli.ts similarity index 96% rename from src/cli.ts rename to packages/cli/src/cli.ts index 2588330..f83650f 100644 --- a/src/cli.ts +++ b/packages/cli/src/cli.ts @@ -1,8 +1,10 @@ #!/usr/bin/env node -import { run } from "./index"; +// @ts-ignore - server package is built separately +import { run } from "@musistudio/claude-code-router-server"; +// @ts-ignore - server package is built separately +import { parseStatusLineData, type StatusLineInput } from "@musistudio/claude-code-router-server"; import { showStatus } from "./utils/status"; import { executeCodeCommand } from "./utils/codeCommand"; -import { parseStatusLineData, type StatusLineInput } from "./utils/statusline"; import { cleanupPidFile, isServiceRunning, @@ -12,7 +14,7 @@ import { runModelSelector } from "./utils/modelSelector"; // ADD THIS LINE import { activateCommand } from "./utils/activateCommand"; import { version } from "../package.json"; import { spawn, exec } from "child_process"; -import { PID_FILE, REFERENCE_COUNT_FILE } from "./constants"; +import { PID_FILE, REFERENCE_COUNT_FILE } from "@musistudio/claude-code-router-shared"; import fs, { existsSync, readFileSync } from "fs"; import { join } from "path"; diff --git a/packages/cli/src/types.d.ts b/packages/cli/src/types.d.ts new file mode 100644 index 0000000..9f3fab7 --- /dev/null +++ b/packages/cli/src/types.d.ts @@ -0,0 +1,82 @@ +declare module 'shell-quote' { + export function quote(args: string[]): string; + export function parse(cmd: string): string[]; +} + +declare module 'minimist' { + interface Options { + string?: string[]; + boolean?: string | string[]; + alias?: Record; + default?: Record; + stopEarly?: boolean; + '--'?: boolean; + unknown?: (arg: string) => boolean; + } + + interface ParsedArgs { + _: string[]; + [key: string]: any; + } + + function minimist(args?: string[], opts?: Options): ParsedArgs; + export = minimist; +} + +declare module '@inquirer/prompts' { + export function select(config: { + message: string; + choices: Array<{ name: string; value: T; description?: string }>; + pageSize?: number; + }): Promise; + export function input(config: { + message: string; + default?: string; + validate?: (value: string) => boolean | string | Promise; + }): Promise; + export function confirm(config: { + message: string; + default?: boolean; + }): Promise; +} + +declare module 'find-process' { + export default function find( + type: 'pid' | 'name' | 'port', + value: string | number + ): Promise>; +} + +declare module 'json5' { + export function parse(text: string): any; + export function stringify(value: any, replacer?: any, space?: string | number): string; +} + +declare namespace NodeJS { + interface ProcessEnv { + CI?: string; + FORCE_COLOR?: string; + NODE_NO_READLINE?: string; + TERM?: string; + ANTHROPIC_SMALL_FAST_MODEL?: string; + } +} + +interface ClaudeSettingsFlag { + env: { + ANTHROPIC_AUTH_TOKEN?: any; + ANTHROPIC_API_KEY: string; + ANTHROPIC_BASE_URL: string; + NO_PROXY: string; + DISABLE_TELEMETRY: string; + DISABLE_COST_WARNINGS: string; + API_TIMEOUT_MS: string; + CLAUDE_CODE_USE_BEDROCK?: undefined; + [key: string]: any; + }; + statusLine?: { + type: string; + command: string; + padding: number; + }; +} diff --git a/src/utils/activateCommand.ts b/packages/cli/src/utils/activateCommand.ts similarity index 100% rename from src/utils/activateCommand.ts rename to packages/cli/src/utils/activateCommand.ts diff --git a/src/utils/codeCommand.ts b/packages/cli/src/utils/codeCommand.ts similarity index 92% rename from src/utils/codeCommand.ts rename to packages/cli/src/utils/codeCommand.ts index c31c0b5..aa551db 100644 --- a/src/utils/codeCommand.ts +++ b/packages/cli/src/utils/codeCommand.ts @@ -1,6 +1,7 @@ import { spawn, type StdioOptions } from "child_process"; import { readConfigFile } from "."; -import { closeService } from "./close"; +// @ts-ignore - server package is built separately +import { closeService } from "@musistudio/claude-code-router-server"; import { decrementReferenceCount, incrementReferenceCount, @@ -14,8 +15,8 @@ export async function executeCodeCommand(args: string[] = []) { // Set environment variables using shared function const config = await readConfigFile(); const env = await createEnvVariables(); - const settingsFlag = { - env + const settingsFlag: ClaudeSettingsFlag = { + env: env as ClaudeSettingsFlag['env'] }; if (config?.StatusLine?.enabled) { settingsFlag.statusLine = { diff --git a/src/utils/createEnvVariables.ts b/packages/cli/src/utils/createEnvVariables.ts similarity index 88% rename from src/utils/createEnvVariables.ts rename to packages/cli/src/utils/createEnvVariables.ts index 9473ff0..437c0aa 100644 --- a/src/utils/createEnvVariables.ts +++ b/packages/cli/src/utils/createEnvVariables.ts @@ -4,7 +4,7 @@ import { readConfigFile } from "."; * Get environment variables for Agent SDK/Claude Code integration * This function is shared between `ccr env` and `ccr code` commands */ -export const createEnvVariables = async () => { +export const createEnvVariables = async (): Promise> => { const config = await readConfigFile(); const port = config.PORT || 3456; const apiKey = config.APIKEY || "test"; diff --git a/src/utils/index.ts b/packages/cli/src/utils/index.ts similarity index 96% rename from src/utils/index.ts rename to packages/cli/src/utils/index.ts index 5e47e84..d031e61 100644 --- a/src/utils/index.ts +++ b/packages/cli/src/utils/index.ts @@ -7,8 +7,9 @@ import { DEFAULT_CONFIG, HOME_DIR, PLUGINS_DIR, -} from "../constants"; -import { cleanupLogFiles } from "./logCleanup"; +} from "@musistudio/claude-code-router-shared"; +// @ts-ignore - server package is built separately +import { cleanupLogFiles } from "@musistudio/claude-code-router-server"; // Function to interpolate environment variables in config values const interpolateEnvVars = (obj: any): any => { diff --git a/src/utils/modelSelector.ts b/packages/cli/src/utils/modelSelector.ts similarity index 100% rename from src/utils/modelSelector.ts rename to packages/cli/src/utils/modelSelector.ts diff --git a/src/utils/processCheck.ts b/packages/cli/src/utils/processCheck.ts similarity index 97% rename from src/utils/processCheck.ts rename to packages/cli/src/utils/processCheck.ts index 9e106ae..bcd45e1 100644 --- a/src/utils/processCheck.ts +++ b/packages/cli/src/utils/processCheck.ts @@ -1,5 +1,5 @@ import { existsSync, readFileSync, writeFileSync } from 'fs'; -import { PID_FILE, REFERENCE_COUNT_FILE } from '../constants'; +import { PID_FILE, REFERENCE_COUNT_FILE } from '@musistudio/claude-code-router-shared'; import { readConfigFile } from '.'; import find from 'find-process'; import { execSync } from 'child_process'; // 引入 execSync 来执行命令行 diff --git a/src/utils/status.ts b/packages/cli/src/utils/status.ts similarity index 100% rename from src/utils/status.ts rename to packages/cli/src/utils/status.ts diff --git a/packages/cli/src/utils/statusline.ts b/packages/cli/src/utils/statusline.ts new file mode 100644 index 0000000..78a3724 --- /dev/null +++ b/packages/cli/src/utils/statusline.ts @@ -0,0 +1,813 @@ +import fs from "node:fs/promises"; +import path from "node:path"; +import { execSync } from "child_process"; +import { CONFIG_FILE } from "@musistudio/claude-code-router-shared"; +import JSON5 from "json5"; + +export interface StatusLineModuleConfig { + type: string; + icon?: string; + text: string; + color?: string; + background?: string; + scriptPath?: string; // 用于script类型的模块,指定要执行的Node.js脚本文件路径 +} + +export interface StatusLineThemeConfig { + modules: StatusLineModuleConfig[]; +} + +export interface StatusLineInput { + hook_event_name: string; + session_id: string; + transcript_path: string; + cwd: string; + model: { + id: string; + display_name: string; + }; + workspace: { + current_dir: string; + project_dir: string; + }; +} + +export interface AssistantMessage { + type: "assistant"; + message: { + model: string; + usage: { + input_tokens: number; + output_tokens: number; + }; + }; +} + +// ANSIColor代码 +const COLORS: Record = { + reset: "\x1b[0m", + bold: "\x1b[1m", + dim: "\x1b[2m", + // 标准颜色 + black: "\x1b[30m", + red: "\x1b[31m", + green: "\x1b[32m", + yellow: "\x1b[33m", + blue: "\x1b[34m", + magenta: "\x1b[35m", + cyan: "\x1b[36m", + white: "\x1b[37m", + // 亮色 + bright_black: "\x1b[90m", + bright_red: "\x1b[91m", + bright_green: "\x1b[92m", + bright_yellow: "\x1b[93m", + bright_blue: "\x1b[94m", + bright_magenta: "\x1b[95m", + bright_cyan: "\x1b[96m", + bright_white: "\x1b[97m", + // 背景颜色 + bg_black: "\x1b[40m", + bg_red: "\x1b[41m", + bg_green: "\x1b[42m", + bg_yellow: "\x1b[43m", + bg_blue: "\x1b[44m", + bg_magenta: "\x1b[45m", + bg_cyan: "\x1b[46m", + bg_white: "\x1b[47m", + // 亮背景色 + bg_bright_black: "\x1b[100m", + bg_bright_red: "\x1b[101m", + bg_bright_green: "\x1b[102m", + bg_bright_yellow: "\x1b[103m", + bg_bright_blue: "\x1b[104m", + bg_bright_magenta: "\x1b[105m", + bg_bright_cyan: "\x1b[106m", + bg_bright_white: "\x1b[107m", +}; + +// 使用TrueColor(24位色)支持十六进制颜色 +const TRUE_COLOR_PREFIX = "\x1b[38;2;"; +const TRUE_COLOR_BG_PREFIX = "\x1b[48;2;"; + +// 将十六进制颜色转为RGB格式 +function hexToRgb(hex: string): { r: number; g: number; b: number } | null { + // 移除#和空格 + hex = hex.replace(/^#/, '').trim(); + + // 处理简写形式 (#RGB -> #RRGGBB) + if (hex.length === 3) { + hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; + } + + if (hex.length !== 6) { + return null; + } + + const r = parseInt(hex.substring(0, 2), 16); + const g = parseInt(hex.substring(2, 4), 16); + const b = parseInt(hex.substring(4, 6), 16); + + // 验证RGB值是否有效 + if (isNaN(r) || isNaN(g) || isNaN(b) || r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) { + return null; + } + + return { r, g, b }; +} + +// 获取颜色代码 +function getColorCode(colorName: string): string { + // 检查是否是十六进制颜色 + if (colorName.startsWith('#') || /^[0-9a-fA-F]{6}$/.test(colorName) || /^[0-9a-fA-F]{3}$/.test(colorName)) { + const rgb = hexToRgb(colorName); + if (rgb) { + return `${TRUE_COLOR_PREFIX}${rgb.r};${rgb.g};${rgb.b}m`; + } + } + + // 默认返回空字符串 + return ""; +} + + +// 变量替换函数,支持{{var}}格式的变量替换 +function replaceVariables(text: string, variables: Record): string { + return text.replace(/\{\{(\w+)\}\}/g, (_match, varName) => { + return variables[varName] || ""; + }); +} + +// 执行脚本并获取输出 +async function executeScript(scriptPath: string, variables: Record): Promise { + try { + // 检查文件是否存在 + await fs.access(scriptPath); + + // 使用require动态加载脚本模块 + const scriptModule = require(scriptPath); + + // 如果导出的是函数,则调用它并传入变量 + if (typeof scriptModule === 'function') { + const result = scriptModule(variables); + // 如果返回的是Promise,则等待它完成 + if (result instanceof Promise) { + return await result; + } + return result; + } + + // 如果导出的是default函数,则调用它 + if (scriptModule.default && typeof scriptModule.default === 'function') { + const result = scriptModule.default(variables); + // 如果返回的是Promise,则等待它完成 + if (result instanceof Promise) { + return await result; + } + return result; + } + + // 如果导出的是字符串,则直接返回 + if (typeof scriptModule === 'string') { + return scriptModule; + } + + // 如果导出的是default字符串,则返回它 + if (scriptModule.default && typeof scriptModule.default === 'string') { + return scriptModule.default; + } + + // 默认情况下返回空字符串 + return ""; + } catch (error) { + console.error(`执行脚本 ${scriptPath} 时出错:`, error); + return ""; + } +} + +// 默认主题配置 - 使用Nerd Fonts图标和美观配色 +const DEFAULT_THEME: StatusLineThemeConfig = { + modules: [ + { + type: "workDir", + icon: "󰉋", // nf-md-folder_outline + text: "{{workDirName}}", + color: "bright_blue" + }, + { + type: "gitBranch", + icon: "", // nf-dev-git_branch + text: "{{gitBranch}}", + color: "bright_magenta" + }, + { + type: "model", + icon: "󰚩", // nf-md-robot_outline + text: "{{model}}", + color: "bright_cyan" + }, + { + type: "usage", + icon: "↑", // 上箭头 + text: "{{inputTokens}}", + color: "bright_green" + }, + { + type: "usage", + icon: "↓", // 下箭头 + text: "{{outputTokens}}", + color: "bright_yellow" + } + ] +}; + +// Powerline风格主题配置 +const POWERLINE_THEME: StatusLineThemeConfig = { + modules: [ + { + type: "workDir", + icon: "󰉋", // nf-md-folder_outline + text: "{{workDirName}}", + color: "white", + background: "bg_bright_blue" + }, + { + type: "gitBranch", + icon: "", // nf-dev-git_branch + text: "{{gitBranch}}", + color: "white", + background: "bg_bright_magenta" + }, + { + type: "model", + icon: "󰚩", // nf-md-robot_outline + text: "{{model}}", + color: "white", + background: "bg_bright_cyan" + }, + { + type: "usage", + icon: "↑", // 上箭头 + text: "{{inputTokens}}", + color: "white", + background: "bg_bright_green" + }, + { + type: "usage", + icon: "↓", // 下箭头 + text: "{{outputTokens}}", + color: "white", + background: "bg_bright_yellow" + } + ] +}; + +// 简单文本主题配置 - 用于图标无法显示时的fallback +const SIMPLE_THEME: StatusLineThemeConfig = { + modules: [ + { + type: "workDir", + icon: "", + text: "{{workDirName}}", + color: "bright_blue" + }, + { + type: "gitBranch", + icon: "", + text: "{{gitBranch}}", + color: "bright_magenta" + }, + { + type: "model", + icon: "", + text: "{{model}}", + color: "bright_cyan" + }, + { + type: "usage", + icon: "↑", + text: "{{inputTokens}}", + color: "bright_green" + }, + { + type: "usage", + icon: "↓", + text: "{{outputTokens}}", + color: "bright_yellow" + } + ] +}; + +// 格式化usage信息,如果大于1000则使用k单位 +function formatUsage(input_tokens: number, output_tokens: number): string { + if (input_tokens > 1000 || output_tokens > 1000) { + const inputFormatted = input_tokens > 1000 ? `${(input_tokens / 1000).toFixed(1)}k` : `${input_tokens}`; + const outputFormatted = output_tokens > 1000 ? `${(output_tokens / 1000).toFixed(1)}k` : `${output_tokens}`; + return `${inputFormatted} ${outputFormatted}`; + } + return `${input_tokens} ${output_tokens}`; +} + +// 读取用户主目录的主题配置 +async function getProjectThemeConfig(): Promise<{ theme: StatusLineThemeConfig | null, style: string }> { + try { + // 只使用主目录的固定配置文件 + const configPath = CONFIG_FILE; + + // 检查配置文件是否存在 + try { + await fs.access(configPath); + } catch { + return { theme: null, style: 'default' }; + } + + const configContent = await fs.readFile(configPath, "utf-8"); + const config = JSON5.parse(configContent); + + // 检查是否有StatusLine配置 + if (config.StatusLine) { + // 获取当前使用的风格,默认为default + const currentStyle = config.StatusLine.currentStyle || 'default'; + + // 检查是否有对应风格的配置 + if (config.StatusLine[currentStyle] && config.StatusLine[currentStyle].modules) { + return { theme: config.StatusLine[currentStyle], style: currentStyle }; + } + } + } catch (error) { + // 如果读取失败,返回null + // console.error("Failed to read theme config:", error); + } + + return { theme: null, style: 'default' }; +} + +// 检查是否应该使用简单主题(fallback方案) +// 当环境变量 USE_SIMPLE_ICONS 被设置时,或者当检测到可能不支持Nerd Fonts的终端时 +function shouldUseSimpleTheme(): boolean { + // 检查环境变量 + if (process.env.USE_SIMPLE_ICONS === 'true') { + return true; + } + + // 检查终端类型(一些常见的不支持复杂图标的终端) + const term = process.env.TERM || ''; + const unsupportedTerms = ['dumb', 'unknown']; + if (unsupportedTerms.includes(term)) { + return true; + } + + // 默认情况下,假设终端支持Nerd Fonts + return false; +} + +// 检查Nerd Fonts图标是否能正确显示 +// 通过检查终端字体信息或使用试探性方法 +function canDisplayNerdFonts(): boolean { + // 如果环境变量明确指定使用简单图标,则不能显示Nerd Fonts + if (process.env.USE_SIMPLE_ICONS === 'true') { + return false; + } + + // 检查一些常见的支持Nerd Fonts的终端环境变量 + const fontEnvVars = ['NERD_FONT', 'NERDFONT', 'FONT']; + for (const envVar of fontEnvVars) { + const value = process.env[envVar]; + if (value && (value.includes('Nerd') || value.includes('nerd'))) { + return true; + } + } + + // 检查终端类型 + const termProgram = process.env.TERM_PROGRAM || ''; + const supportedTerminals = ['iTerm.app', 'vscode', 'Hyper', 'kitty', 'alacritty']; + if (supportedTerminals.includes(termProgram)) { + return true; + } + + // 检查COLORTERM环境变量 + const colorTerm = process.env.COLORTERM || ''; + if (colorTerm.includes('truecolor') || colorTerm.includes('24bit')) { + return true; + } + + // 默认情况下,假设可以显示Nerd Fonts(但允许用户通过环境变量覆盖) + return process.env.USE_SIMPLE_ICONS !== 'true'; +} + +// 检查特定Unicode字符是否能正确显示 +// 这是一个简单的试探性检查 +function canDisplayUnicodeCharacter(char: string): boolean { + // 对于Nerd Fonts图标,我们假设支持UTF-8的终端可以显示 + // 但实际上很难准确检测,所以我们依赖环境变量和终端类型检测 + try { + // 检查终端是否支持UTF-8 + const lang = process.env.LANG || process.env.LC_ALL || process.env.LC_CTYPE || ''; + if (lang.includes('UTF-8') || lang.includes('utf8') || lang.includes('UTF8')) { + return true; + } + + // 检查LC_*环境变量 + const lcVars = ['LC_ALL', 'LC_CTYPE', 'LANG']; + for (const lcVar of lcVars) { + const value = process.env[lcVar]; + if (value && (value.includes('UTF-8') || value.includes('utf8'))) { + return true; + } + } + } catch (e) { + // 如果检查失败,默认返回true + return true; + } + + // 默认情况下,假设可以显示 + return true; +} + +export async function parseStatusLineData(input: StatusLineInput): Promise { + try { + // 检查是否应该使用简单主题 + const useSimpleTheme = shouldUseSimpleTheme(); + + // 检查是否可以显示Nerd Fonts图标 + const canDisplayNerd = canDisplayNerdFonts(); + + // 确定使用的主题:如果用户强制使用简单主题或无法显示Nerd Fonts,则使用简单主题 + const effectiveTheme = useSimpleTheme || !canDisplayNerd ? SIMPLE_THEME : DEFAULT_THEME; + + // 获取主目录的主题配置,如果没有则使用确定的默认配置 + const { theme: projectTheme, style: currentStyle } = await getProjectThemeConfig(); + const theme = projectTheme || effectiveTheme; + + // 获取当前工作目录和Git分支 + const workDir = input.workspace.current_dir; + let gitBranch = ""; + + try { + // 尝试获取Git分支名 + gitBranch = execSync("git branch --show-current", { + cwd: workDir, + stdio: ["pipe", "pipe", "ignore"], + }) + .toString() + .trim(); + } catch (error) { + // 如果不是Git仓库或获取失败,则忽略错误 + } + + // 从transcript_path文件中读取最后一条assistant消息 + const transcriptContent = await fs.readFile(input.transcript_path, "utf-8"); + const lines = transcriptContent.trim().split("\n"); + + // 反向遍历寻找最后一条assistant消息 + let model = ""; + let inputTokens = 0; + let outputTokens = 0; + + for (let i = lines.length - 1; i >= 0; i--) { + try { + const message: AssistantMessage = JSON.parse(lines[i]); + if (message.type === "assistant" && message.message.model) { + model = message.message.model; + + if (message.message.usage) { + inputTokens = message.message.usage.input_tokens; + outputTokens = message.message.usage.output_tokens; + } + break; + } + } catch (parseError) { + // 忽略解析错误,继续查找 + continue; + } + } + + // 如果没有从transcript中获取到模型名称,则尝试从配置文件中获取 + if (!model) { + try { + // 获取项目配置文件路径 + const projectConfigPath = path.join(workDir, ".claude-code-router", "config.json"); + let configPath = projectConfigPath; + + // 检查项目配置文件是否存在,如果不存在则使用用户主目录的配置文件 + try { + await fs.access(projectConfigPath); + } catch { + configPath = CONFIG_FILE; + } + + // 读取配置文件 + const configContent = await fs.readFile(configPath, "utf-8"); + const config = JSON5.parse(configContent); + + // 从Router字段的default内容中获取模型名称 + if (config.Router && config.Router.default) { + const [, defaultModel] = config.Router.default.split(","); + if (defaultModel) { + model = defaultModel.trim(); + } + } + } catch (configError) { + // 如果配置文件读取失败,则忽略错误 + } + } + + // 如果仍然没有获取到模型名称,则使用传入的JSON数据中的model字段的display_name + if (!model) { + model = input.model.display_name; + } + + // 获取工作目录名 + const workDirName = workDir.split("/").pop() || ""; + + // 格式化usage信息 + const usage = formatUsage(inputTokens, outputTokens); + const [formattedInputTokens, formattedOutputTokens] = usage.split(" "); + + // 定义变量替换映射 + const variables = { + workDirName, + gitBranch, + model, + inputTokens: formattedInputTokens, + outputTokens: formattedOutputTokens + }; + + // 确定使用的风格 + const isPowerline = currentStyle === 'powerline'; + + // 根据风格渲染状态行 + if (isPowerline) { + return await renderPowerlineStyle(theme, variables); + } else { + return await renderDefaultStyle(theme, variables); + } + } catch (error) { + // 发生错误时返回空字符串 + return ""; + } +} + +// 读取用户主目录的主题配置(指定风格) +async function getProjectThemeConfigForStyle(style: string): Promise { + try { + // 只使用主目录的固定配置文件 + const configPath = CONFIG_FILE; + + // 检查配置文件是否存在 + try { + await fs.access(configPath); + } catch { + return null; + } + + const configContent = await fs.readFile(configPath, "utf-8"); + const config = JSON5.parse(configContent); + + // 检查是否有StatusLine配置 + if (config.StatusLine && config.StatusLine[style] && config.StatusLine[style].modules) { + return config.StatusLine[style]; + } + } catch (error) { + // 如果读取失败,返回null + // console.error("Failed to read theme config:", error); + } + + return null; +} + +// 渲染默认风格的状态行 +async function renderDefaultStyle( + theme: StatusLineThemeConfig, + variables: Record +): Promise { + const modules = theme.modules || DEFAULT_THEME.modules; + const parts: string[] = []; + + // 遍历模块数组,渲染每个模块 + for (let i = 0; i < Math.min(modules.length, 5); i++) { + const module = modules[i]; + const color = module.color ? getColorCode(module.color) : ""; + const background = module.background ? getColorCode(module.background) : ""; + const icon = module.icon || ""; + + // 如果是script类型,执行脚本获取文本 + let text = ""; + if (module.type === "script" && module.scriptPath) { + text = await executeScript(module.scriptPath, variables); + } else { + text = replaceVariables(module.text, variables); + } + + // 构建显示文本 + let displayText = ""; + if (icon) { + displayText += `${icon} `; + } + displayText += text; + + // 如果displayText为空,或者只有图标没有实际文本,则跳过该模块 + if (!displayText || !text) { + continue; + } + + // 构建模块字符串 + let part = `${background}${color}`; + part += `${displayText}${COLORS.reset}`; + + parts.push(part); + } + + // 使用空格连接所有部分 + return parts.join(" "); +} + +// Powerline符号 +const SEP_RIGHT = "\uE0B0"; //  + +// 颜色编号(256色表) +const COLOR_MAP: Record = { + // 基础颜色映射到256色 + black: 0, + red: 1, + green: 2, + yellow: 3, + blue: 4, + magenta: 5, + cyan: 6, + white: 7, + bright_black: 8, + bright_red: 9, + bright_green: 10, + bright_yellow: 11, + bright_blue: 12, + bright_magenta: 13, + bright_cyan: 14, + bright_white: 15, + // 亮背景色映射 + bg_black: 0, + bg_red: 1, + bg_green: 2, + bg_yellow: 3, + bg_blue: 4, + bg_magenta: 5, + bg_cyan: 6, + bg_white: 7, + bg_bright_black: 8, + bg_bright_red: 9, + bg_bright_green: 10, + bg_bright_yellow: 11, + bg_bright_blue: 12, + bg_bright_magenta: 13, + bg_bright_cyan: 14, + bg_bright_white: 15, + // 自定义颜色映射 + bg_bright_orange: 202, + bg_bright_purple: 129, +}; + +// 获取TrueColor的RGB值 +function getTrueColorRgb(colorName: string): { r: number; g: number; b: number } | null { + // 如果是预定义颜色,返回对应RGB + if (COLOR_MAP[colorName] !== undefined) { + const color256 = COLOR_MAP[colorName]; + return color256ToRgb(color256); + } + + // 处理十六进制颜色 + if (colorName.startsWith('#') || /^[0-9a-fA-F]{6}$/.test(colorName) || /^[0-9a-fA-F]{3}$/.test(colorName)) { + return hexToRgb(colorName); + } + + // 处理背景色十六进制 + if (colorName.startsWith('bg_#')) { + return hexToRgb(colorName.substring(3)); + } + + return null; +} + +// 将256色表索引转换为RGB值 +function color256ToRgb(index: number): { r: number; g: number; b: number } | null { + if (index < 0 || index > 255) return null; + + // ANSI 256色表转换 + if (index < 16) { + // 基本颜色 + const basicColors = [ + [0, 0, 0], [128, 0, 0], [0, 128, 0], [128, 128, 0], + [0, 0, 128], [128, 0, 128], [0, 128, 128], [192, 192, 192], + [128, 128, 128], [255, 0, 0], [0, 255, 0], [255, 255, 0], + [0, 0, 255], [255, 0, 255], [0, 255, 255], [255, 255, 255] + ]; + return { r: basicColors[index][0], g: basicColors[index][1], b: basicColors[index][2] }; + } else if (index < 232) { + // 216色:6×6×6的颜色立方体 + const i = index - 16; + const r = Math.floor(i / 36); + const g = Math.floor((i % 36) / 6); + const b = i % 6; + const rgb = [0, 95, 135, 175, 215, 255]; + return { r: rgb[r], g: rgb[g], b: rgb[b] }; + } else { + // 灰度色 + const gray = 8 + (index - 232) * 10; + return { r: gray, g: gray, b: gray }; + } +} + +// 生成一个无缝拼接的段:文本在 bgN 上显示,分隔符从 bgN 过渡到 nextBgN +function segment(text: string, textFg: string, bgColor: string, nextBgColor: string | null): string { + const bgRgb = getTrueColorRgb(bgColor); + if (!bgRgb) { + // 如果无法获取RGB,使用默认蓝色背景 + const defaultBlueRgb = { r: 33, g: 150, b: 243 }; + const curBg = `\x1b[48;2;${defaultBlueRgb.r};${defaultBlueRgb.g};${defaultBlueRgb.b}m`; + const fgColor = `\x1b[38;2;255;255;255m`; + const body = `${curBg}${fgColor} ${text} \x1b[0m`; + return body; + } + + const curBg = `\x1b[48;2;${bgRgb.r};${bgRgb.g};${bgRgb.b}m`; + + // 获取前景色RGB + let fgRgb = { r: 255, g: 255, b: 255 }; // 默认前景色为白色 + const textFgRgb = getTrueColorRgb(textFg); + if (textFgRgb) { + fgRgb = textFgRgb; + } + + const fgColor = `\x1b[38;2;${fgRgb.r};${fgRgb.g};${fgRgb.b}m`; + const body = `${curBg}${fgColor} ${text} \x1b[0m`; + + if (nextBgColor != null) { + const nextBgRgb = getTrueColorRgb(nextBgColor); + if (nextBgRgb) { + // 分隔符:前景色是当前段的背景色,背景色是下一段的背景色 + const sepCurFg = `\x1b[38;2;${bgRgb.r};${bgRgb.g};${bgRgb.b}m`; + const sepNextBg = `\x1b[48;2;${nextBgRgb.r};${nextBgRgb.g};${nextBgRgb.b}m`; + const sep = `${sepCurFg}${sepNextBg}${SEP_RIGHT}\x1b[0m`; + return body + sep; + } + // 如果没有下一个背景色,假设终端背景为黑色并渲染黑色箭头 + const sepCurFg = `\x1b[38;2;${bgRgb.r};${bgRgb.g};${bgRgb.b}m`; + const sepNextBg = `\x1b[48;2;0;0;0m`; // 黑色背景 + const sep = `${sepCurFg}${sepNextBg}${SEP_RIGHT}\x1b[0m`; + return body + sep; + } + + return body; +} + +// 渲染Powerline风格的状态行 +async function renderPowerlineStyle( + theme: StatusLineThemeConfig, + variables: Record +): Promise { + const modules = theme.modules || POWERLINE_THEME.modules; + const segments: string[] = []; + + // 遍历模块数组,渲染每个模块 + for (let i = 0; i < Math.min(modules.length, 5); i++) { + const module = modules[i]; + const color = module.color || "white"; + const backgroundName = module.background || ""; + const icon = module.icon || ""; + + // 如果是script类型,执行脚本获取文本 + let text = ""; + if (module.type === "script" && module.scriptPath) { + text = await executeScript(module.scriptPath, variables); + } else { + text = replaceVariables(module.text, variables); + } + + // 构建显示文本 + let displayText = ""; + if (icon) { + displayText += `${icon} `; + } + displayText += text; + + // 如果displayText为空,或者只有图标没有实际文本,则跳过该模块 + if (!displayText || !text) { + continue; + } + + // 获取下一个模块的背景色(用于分隔符) + let nextBackground: string | null = null; + if (i < modules.length - 1) { + const nextModule = modules[i + 1]; + nextBackground = nextModule.background || null; + } + + // 使用模块定义的背景色,或者为Powerline风格提供默认背景色 + const actualBackground = backgroundName || "bg_bright_blue"; + + // 生成段,支持十六进制颜色 + const segmentStr = segment(displayText, color, actualBackground, nextBackground); + segments.push(segmentStr); + } + + return segments.join(""); +} diff --git a/src/utils/update.ts b/packages/cli/src/utils/update.ts similarity index 100% rename from src/utils/update.ts rename to packages/cli/src/utils/update.ts diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json new file mode 100644 index 0000000..866b298 --- /dev/null +++ b/packages/cli/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src", + "baseUrl": "./src" + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/server/.dockerignore b/packages/server/.dockerignore new file mode 100644 index 0000000..706857f --- /dev/null +++ b/packages/server/.dockerignore @@ -0,0 +1,12 @@ +node_modules +dist +.git +.gitignore +*.md +.vscode +.idea +*.log +.env +.DS_Store +coverage +.nyc_output diff --git a/packages/server/Dockerfile b/packages/server/Dockerfile new file mode 100644 index 0000000..1010588 --- /dev/null +++ b/packages/server/Dockerfile @@ -0,0 +1,69 @@ +# =========================== +# 构建阶段 +# =========================== +FROM node:20-alpine AS builder + +WORKDIR /app + +# 安装 pnpm +RUN npm install -g pnpm@latest && \ + rm -rf /root/.npm + +# 复制工作区配置文件 +COPY pnpm-workspace.yaml pnpm-lock.yaml package.json tsconfig.base.json ./ +COPY scripts ./scripts +COPY packages/shared/package.json ./packages/shared/ +COPY packages/server/package.json ./packages/server/ + +# 安装所有依赖(包括开发依赖)并清理 +RUN pnpm install --frozen-lockfile && \ + pnpm store prune + +# 复制源代码并构建 +COPY packages/shared ./packages/shared +COPY packages/server ./packages/server + +# 构建所有包 +WORKDIR /app/packages/shared +RUN pnpm build + +WORKDIR /app/packages/server +RUN pnpm build && \ + rm -rf node_modules/.cache + +# =========================== +# 生产阶段(极简版 - 无 node_modules) +# =========================== +FROM node:20-alpine AS production + +# 只安装 PM2、curl 和 pm2-logrotate,并删除不需要的 npm 和 corepack +RUN apk add --no-cache curl && \ + npm install -g pm2 pm2-logrotate --no-scripts && \ + pm2 install pm2-logrotate && \ + pm2 set pm2-logrotate:max_size 100M && \ + pm2 set pm2-logrotate:retain 5 && \ + pm2 set pm2-logrotate:compress true && \ + pm2 set pm2-logrotate:rotateInterval '0 0 * * *' + +WORKDIR /app + +# 从构建阶段复制 server bundle(shared 已被打包进 index.js,无需单独复制) +COPY --from=builder /app/packages/server/dist ./packages/server/dist +# 复制本地预先构建的 UI 产物到同一目录 +COPY packages/ui/dist/. ./packages/server/dist/ + +# 复制 PM2 配置文件 +COPY packages/server/ecosystem.config.cjs /app/ + +# 创建日志目录 +RUN mkdir -p /root/.claude-code-router/logs + +# 暴露端口 +EXPOSE 3456 + +# 健康检查 +HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ + CMD curl -f http://127.0.0.1:3456/health || exit 1 + +# 直接启动应用 +CMD ["pm2-runtime", "start", "/app/ecosystem.config.cjs"] diff --git a/packages/server/ecosystem.config.cjs b/packages/server/ecosystem.config.cjs new file mode 100644 index 0000000..4bf49aa --- /dev/null +++ b/packages/server/ecosystem.config.cjs @@ -0,0 +1,23 @@ +module.exports = { + apps: [ + { + name: 'claude-code-router-server', + script: '/app/packages/server/dist/index.js', + cwd: '/app/packages/server', + instances: 1, + autorestart: true, + watch: false, + max_memory_restart: '1G', + env: { + NODE_ENV: 'production', + }, + // 日志配置 + error_file: '/root/.claude-code-router/logs/error.log', + out_file: '/root/.claude-code-router/logs/out.log', + log_date_format: 'YYYY-MM-DD HH:mm:ss Z', + merge_logs: true, + // 启用日志时间戳 + time: true, + }, + ], +}; diff --git a/packages/server/package.json b/packages/server/package.json new file mode 100644 index 0000000..1970083 --- /dev/null +++ b/packages/server/package.json @@ -0,0 +1,37 @@ +{ + "name": "@musistudio/claude-code-router-server", + "version": "1.0.73", + "description": "Server for Claude Code Router", + "main": "dist/index.js", + "scripts": { + "build": "node ../../scripts/build-server.js", + "dev": "ts-node src/index.ts" + }, + "keywords": [ + "claude", + "code", + "router", + "server" + ], + "author": "musistudio", + "license": "MIT", + "dependencies": { + "@musistudio/claude-code-router-shared": "workspace:*", + "@fastify/static": "^8.2.0", + "@musistudio/llms": "^1.0.51", + "dotenv": "^16.4.7", + "json5": "^2.2.3", + "lru-cache": "^11.2.2", + "rotating-file-stream": "^3.2.7", + "shell-quote": "^1.8.3", + "tiktoken": "^1.0.21", + "uuid": "^11.1.0" + }, + "devDependencies": { + "@types/node": "^24.0.15", + "esbuild": "^0.25.1", + "fastify": "^5.4.0", + "ts-node": "^10.9.2", + "typescript": "^5.8.2" + } +} diff --git a/src/agents/image.agent.ts b/packages/server/src/agents/image.agent.ts similarity index 98% rename from src/agents/image.agent.ts rename to packages/server/src/agents/image.agent.ts index 0ef273b..f9ef0f1 100644 --- a/src/agents/image.agent.ts +++ b/packages/server/src/agents/image.agent.ts @@ -71,7 +71,7 @@ export class ImageAgent implements IAgent { ) ) { req.body.model = config.Router.image; - const images = []; + const images: any[] = []; lastMessage.content .filter((item: any) => item.type === "tool_result") .forEach((item: any) => { @@ -183,7 +183,7 @@ export class ImageAgent implements IAgent { context.req.body.messages[context.req.body.messages.length - 1]; if (userMessage.role === "user" && Array.isArray(userMessage.content)) { const msgs = userMessage.content.filter( - (item) => + (item: any) => item.type === "text" && !item.text.includes( "This is an image, if you need to view or analyze it, you need to extract the imageId" @@ -286,7 +286,7 @@ Your response should consistently follow this rule whenever image-related analys } else if (msg.type === "tool_result") { if ( Array.isArray(msg.content) && - msg.content.some((ele) => ele.type === "image") + msg.content.some((ele: any) => ele.type === "image") ) { imageCache.storeImage( `${req.id}_Image#${imgId}`, diff --git a/src/agents/index.ts b/packages/server/src/agents/index.ts similarity index 100% rename from src/agents/index.ts rename to packages/server/src/agents/index.ts diff --git a/src/agents/type.ts b/packages/server/src/agents/type.ts similarity index 100% rename from src/agents/type.ts rename to packages/server/src/agents/type.ts diff --git a/src/index.ts b/packages/server/src/index.ts similarity index 76% rename from src/index.ts rename to packages/server/src/index.ts index efb38f4..b6c53a2 100644 --- a/src/index.ts +++ b/packages/server/src/index.ts @@ -1,19 +1,13 @@ -import { existsSync } from "fs"; +import { existsSync, writeFileSync, unlinkSync } from "fs"; import { writeFile } from "fs/promises"; import { homedir } from "os"; -import path, { join } from "path"; -import { initConfig, initDir, cleanupLogFiles } from "./utils"; +import { join } from "path"; +import { initConfig, initDir } from "./utils"; import { createServer } from "./server"; import { router } from "./utils/router"; import { apiKeyAuth } from "./middleware/auth"; -import { - cleanupPidFile, - isServiceRunning, - savePid, -} from "./utils/processCheck"; -import { CONFIG_FILE } from "./constants"; +import { PID_FILE, CONFIG_FILE, HOME_DIR } from "@musistudio/claude-code-router-shared"; import { createStream } from 'rotating-file-stream'; -import { HOME_DIR } from "./constants"; import { sessionUsageCache } from "./utils/cache"; import {SSEParserTransform} from "./utils/SSEParser.transform"; import {SSESerializerTransform} from "./utils/SSESerializer.transform"; @@ -47,11 +41,12 @@ async function initializeClaudeConfig() { interface RunOptions { port?: number; + logger?: any; } async function run(options: RunOptions = {}) { // Check if service is already running - const isRunning = await isServiceRunning() + const isRunning = existsSync(PID_FILE); if (isRunning) { console.log("✅ Service is already running in the background."); return; @@ -59,33 +54,56 @@ async function run(options: RunOptions = {}) { await initializeClaudeConfig(); await initDir(); - // Clean up old log files, keeping only the 10 most recent ones - await cleanupLogFiles(); const config = await initConfig(); + // Check if Providers is configured + const providers = config.Providers || config.providers || []; + const hasProviders = providers && providers.length > 0; let HOST = config.HOST || "127.0.0.1"; - if (config.HOST && !config.APIKEY) { - HOST = "127.0.0.1"; - console.warn("⚠️ API key is not set. HOST is forced to 127.0.0.1."); + if (hasProviders) { + // When providers are configured, require both HOST and APIKEY + if (!config.HOST || !config.APIKEY) { + console.error("❌ Both HOST and APIKEY must be configured when Providers are set."); + console.error(" Please add HOST and APIKEY to your config file."); + process.exit(1); + } + HOST = config.HOST; + } else { + // When no providers are configured, listen on 0.0.0.0 without authentication + HOST = "0.0.0.0"; + console.log("ℹ️ No providers configured. Listening on 0.0.0.0 without authentication."); } const port = config.PORT || 3456; // Save the PID of the background process - savePid(process.pid); + writeFileSync(PID_FILE, process.pid.toString()); // Handle SIGINT (Ctrl+C) to clean up PID file process.on("SIGINT", () => { console.log("Received SIGINT, cleaning up..."); - cleanupPidFile(); + if (existsSync(PID_FILE)) { + try { + unlinkSync(PID_FILE); + } catch (e) { + // Ignore cleanup errors + } + } process.exit(0); }); // Handle SIGTERM to clean up PID file process.on("SIGTERM", () => { - cleanupPidFile(); + if (existsSync(PID_FILE)) { + try { + const fs = require('fs'); + fs.unlinkSync(PID_FILE); + } catch (e) { + // Ignore cleanup errors + } + } process.exit(0); }); @@ -94,33 +112,52 @@ async function run(options: RunOptions = {}) { ? parseInt(process.env.SERVICE_PORT) : port; - // Configure logger based on config settings - const pad = num => (num > 9 ? "" : "0") + num; - const generator = (time, index) => { + // Configure logger based on config settings or external options + const pad = (num: number) => (num > 9 ? "" : "0") + num; + const generator = (time: number | Date | undefined, index: number | undefined) => { + let date: Date; if (!time) { - time = new Date() + date = new Date(); + } else if (typeof time === 'number') { + date = new Date(time); + } else { + date = time; } - var month = time.getFullYear() + "" + pad(time.getMonth() + 1); - var day = pad(time.getDate()); - var hour = pad(time.getHours()); - var minute = pad(time.getMinutes()); + const month = date.getFullYear() + "" + pad(date.getMonth() + 1); + const day = pad(date.getDate()); + const hour = pad(date.getHours()); + const minute = pad(date.getMinutes()); - return `./logs/ccr-${month}${day}${hour}${minute}${pad(time.getSeconds())}${index ? `_${index}` : ''}.log`; + return `./logs/ccr-${month}${day}${hour}${minute}${pad(date.getSeconds())}${index ? `_${index}` : ''}.log`; }; - const loggerConfig = - config.LOG !== false - ? { - level: config.LOG_LEVEL || "debug", - stream: createStream(generator, { - path: HOME_DIR, - maxFiles: 3, - interval: "1d", - compress: false, - maxSize: "50M" - }), - } - : false; + + let loggerConfig: any; + + // 如果外部传入了 logger 配置,使用外部的 + if (options.logger !== undefined) { + loggerConfig = options.logger; + } else { + // 如果没有传入,并且 config.LOG !== false,则启用 logger + if (config.LOG !== false) { + // 将 config.LOG 设为 true(如果它还未设置) + if (config.LOG === undefined) { + config.LOG = true; + } + loggerConfig = { + level: config.LOG_LEVEL || "debug", + stream: createStream(generator, { + path: HOME_DIR, + maxFiles: 3, + interval: "1d", + compress: false, + maxSize: "50M" + }), + }; + } else { + loggerConfig = false; + } + } const server = createServer({ jsonPath: CONFIG_FILE, @@ -147,8 +184,8 @@ async function run(options: RunOptions = {}) { server.logger.error("Unhandled rejection at:", promise, "reason:", reason); }); // Add async preHandler hook for authentication - server.addHook("preHandler", async (req, reply) => { - return new Promise((resolve, reject) => { + server.addHook("preHandler", async (req: any, reply: any) => { + return new Promise((resolve, reject) => { const done = (err?: Error) => { if (err) reject(err); else resolve(); @@ -157,7 +194,7 @@ async function run(options: RunOptions = {}) { apiKeyAuth(config)(req, reply, done).catch(reject); }); }); - server.addHook("preHandler", async (req, reply) => { + server.addHook("preHandler", async (req: any, reply: any) => { if (req.url.startsWith("/v1/messages") && !req.url.startsWith("/v1/messages/count_tokens")) { const useAgents = [] @@ -194,10 +231,10 @@ async function run(options: RunOptions = {}) { }); } }); - server.addHook("onError", async (request, reply, error) => { + server.addHook("onError", async (request: any, reply: any, error: any) => { event.emit('onError', request, reply, error); }) - server.addHook("onSend", (req, reply, payload, done) => { + server.addHook("onSend", (req: any, reply: any, payload: any, done: any) => { if (req.sessionId && req.url.startsWith("/v1/messages") && !req.url.startsWith("/v1/messages/count_tokens")) { if (payload instanceof ReadableStream) { if (req.agents) { @@ -281,7 +318,7 @@ async function run(options: RunOptions = {}) { if (!response.ok) { return undefined; } - const stream = response.body!.pipeThrough(new SSEParserTransform()) + const stream = response.body!.pipeThrough(new SSEParserTransform() as any) const reader = stream.getReader() while (true) { try { @@ -289,7 +326,8 @@ async function run(options: RunOptions = {}) { if (done) { break; } - if (['message_start', 'message_stop'].includes(value.event)) { + const eventData = value as any; + if (['message_start', 'message_stop'].includes(eventData.event)) { continue } @@ -298,7 +336,7 @@ async function run(options: RunOptions = {}) { break; } - controller.enqueue(value) + controller.enqueue(eventData) }catch (readError: any) { if (readError.name === 'AbortError' || readError.code === 'ERR_STREAM_PREMATURE_CLOSE') { abortController.abort(); // 中止所有相关操作 @@ -371,7 +409,7 @@ async function run(options: RunOptions = {}) { } done(null, payload) }); - server.addHook("onSend", async (req, reply, payload) => { + server.addHook("onSend", async (req: any, reply: any, payload: any) => { event.emit('onSend', req, reply, payload); return payload; }) @@ -381,4 +419,11 @@ async function run(options: RunOptions = {}) { } export { run }; -// run(); + +// 如果是直接运行此文件,则启动服务 +if (require.main === module) { + run().catch((error) => { + console.error('Failed to start server:', error); + process.exit(1); + }); +} diff --git a/src/middleware/auth.ts b/packages/server/src/middleware/auth.ts similarity index 86% rename from src/middleware/auth.ts rename to packages/server/src/middleware/auth.ts index ec1816b..2ee3b65 100644 --- a/src/middleware/auth.ts +++ b/packages/server/src/middleware/auth.ts @@ -8,6 +8,13 @@ export const apiKeyAuth = return done(); } + // Check if Providers is empty or not configured + const providers = config.Providers || config.providers || []; + if (!providers || providers.length === 0) { + // No providers configured, skip authentication + return done(); + } + const apiKey = config.APIKEY; if (!apiKey) { // If no API key is set, enable CORS for local diff --git a/src/server.ts b/packages/server/src/server.ts similarity index 70% rename from src/server.ts rename to packages/server/src/server.ts index 6ca3e4d..a9f005e 100644 --- a/src/server.ts +++ b/packages/server/src/server.ts @@ -1,29 +1,28 @@ import Server from "@musistudio/llms"; import { readConfigFile, writeConfigFile, backupConfigFile } from "./utils"; -import { checkForUpdates, performUpdate } from "./utils"; import { join } from "path"; import fastifyStatic from "@fastify/static"; import { readdirSync, statSync, readFileSync, writeFileSync, existsSync } from "fs"; import { homedir } from "os"; import {calculateTokenCount} from "./utils/router"; -export const createServer = (config: any): Server => { +export const createServer = (config: any): any => { const server = new Server(config); - server.app.post("/v1/messages/count_tokens", async (req, reply) => { + server.app.post("/v1/messages/count_tokens", async (req: any, reply: any) => { const {messages, tools, system} = req.body; const tokenCount = calculateTokenCount(messages, system, tools); return { "input_tokens": tokenCount } }); // Add endpoint to read config.json with access control - server.app.get("/api/config", async (req, reply) => { + server.app.get("/api/config", async (req: any, reply: any) => { return await readConfigFile(); }); - server.app.get("/api/transformers", async () => { + server.app.get("/api/transformers", async (req: any, reply: any) => { const transformers = - server.app._server!.transformerService.getAllTransformers(); + (server.app as any)._server!.transformerService.getAllTransformers(); const transformerList = Array.from(transformers.entries()).map( ([name, transformer]: any) => ({ name, @@ -34,7 +33,7 @@ export const createServer = (config: any): Server => { }); // Add endpoint to save config.json with access control - server.app.post("/api/config", async (req, reply) => { + server.app.post("/api/config", async (req: any, reply: any) => { const newConfig = req.body; // Backup existing config file if it exists @@ -48,7 +47,7 @@ export const createServer = (config: any): Server => { }); // Add endpoint to restart the service with access control - server.app.post("/api/restart", async (req, reply) => { + server.app.post("/api/restart", async (req: any, reply: any) => { reply.send({ success: true, message: "Service restart initiated" }); // Restart the service after a short delay to allow response to be sent @@ -69,50 +68,12 @@ export const createServer = (config: any): Server => { }); // Redirect /ui to /ui/ for proper static file serving - server.app.get("/ui", async (_, reply) => { + server.app.get("/ui", async (_: any, reply: any) => { return reply.redirect("/ui/"); }); - // 版本检查端点 - server.app.get("/api/update/check", async (req, reply) => { - try { - // 获取当前版本 - const currentVersion = require("../package.json").version; - const { hasUpdate, latestVersion, changelog } = await checkForUpdates(currentVersion); - - return { - hasUpdate, - latestVersion: hasUpdate ? latestVersion : undefined, - changelog: hasUpdate ? changelog : undefined - }; - } catch (error) { - console.error("Failed to check for updates:", error); - reply.status(500).send({ error: "Failed to check for updates" }); - } - }); - - // 执行更新端点 - server.app.post("/api/update/perform", async (req, reply) => { - try { - // 只允许完全访问权限的用户执行更新 - const accessLevel = (req as any).accessLevel || "restricted"; - if (accessLevel !== "full") { - reply.status(403).send("Full access required to perform updates"); - return; - } - - // 执行更新逻辑 - const result = await performUpdate(); - - return result; - } catch (error) { - console.error("Failed to perform update:", error); - reply.status(500).send({ error: "Failed to perform update" }); - } - }); - // 获取日志文件列表端点 - server.app.get("/api/logs/files", async (req, reply) => { + server.app.get("/api/logs/files", async (req: any, reply: any) => { try { const logDir = join(homedir(), ".claude-code-router", "logs"); const logFiles: Array<{ name: string; path: string; size: number; lastModified: string }> = []; @@ -146,7 +107,7 @@ export const createServer = (config: any): Server => { }); // 获取日志内容端点 - server.app.get("/api/logs", async (req, reply) => { + server.app.get("/api/logs", async (req: any, reply: any) => { try { const filePath = (req.query as any).file as string; let logFilePath: string; @@ -174,7 +135,7 @@ export const createServer = (config: any): Server => { }); // 清除日志内容端点 - server.app.delete("/api/logs", async (req, reply) => { + server.app.delete("/api/logs", async (req: any, reply: any) => { try { const filePath = (req.query as any).file as string; let logFilePath: string; diff --git a/packages/server/src/types.d.ts b/packages/server/src/types.d.ts new file mode 100644 index 0000000..b37c84b --- /dev/null +++ b/packages/server/src/types.d.ts @@ -0,0 +1,21 @@ +declare module "@musistudio/llms" { + import { FastifyInstance } from "fastify"; + + export interface ServerConfig { + jsonPath?: string; + initialConfig?: any; + logger?: any; + } + + export interface Server { + app: FastifyInstance; + logger: any; + start(): Promise; + } + + const Server: { + new (config: ServerConfig): Server; + }; + + export default Server; +} diff --git a/src/utils/SSEParser.transform.ts b/packages/server/src/utils/SSEParser.transform.ts similarity index 94% rename from src/utils/SSEParser.transform.ts rename to packages/server/src/utils/SSEParser.transform.ts index 8e7fa32..fc25abc 100644 --- a/src/utils/SSEParser.transform.ts +++ b/packages/server/src/utils/SSEParser.transform.ts @@ -5,9 +5,7 @@ export class SSEParserTransform extends TransformStream { constructor() { super({ transform: (chunk: string, controller) => { - const decoder = new TextDecoder(); - const text = decoder.decode(chunk); - this.buffer += text; + this.buffer += chunk; const lines = this.buffer.split('\n'); // 保留最后一行(可能不完整) diff --git a/src/utils/SSESerializer.transform.ts b/packages/server/src/utils/SSESerializer.transform.ts similarity index 100% rename from src/utils/SSESerializer.transform.ts rename to packages/server/src/utils/SSESerializer.transform.ts diff --git a/src/utils/cache.ts b/packages/server/src/utils/cache.ts similarity index 100% rename from src/utils/cache.ts rename to packages/server/src/utils/cache.ts diff --git a/packages/server/src/utils/index.ts b/packages/server/src/utils/index.ts new file mode 100644 index 0000000..945aaa4 --- /dev/null +++ b/packages/server/src/utils/index.ts @@ -0,0 +1,173 @@ +import fs from "node:fs/promises"; +import readline from "node:readline"; +import JSON5 from "json5"; +import path from "node:path"; +import { + CONFIG_FILE, + DEFAULT_CONFIG, + HOME_DIR, + PLUGINS_DIR, +} from "@musistudio/claude-code-router-shared"; + +// Function to interpolate environment variables in config values +const interpolateEnvVars = (obj: any): any => { + if (typeof obj === "string") { + // Replace $VAR_NAME or ${VAR_NAME} with environment variable values + return obj.replace(/\$\{([^}]+)\}|\$([A-Z_][A-Z0-9_]*)/g, (match, braced, unbraced) => { + const varName = braced || unbraced; + return process.env[varName] || match; // Keep original if env var doesn't exist + }); + } else if (Array.isArray(obj)) { + return obj.map(interpolateEnvVars); + } else if (obj !== null && typeof obj === "object") { + const result: any = {}; + for (const [key, value] of Object.entries(obj)) { + result[key] = interpolateEnvVars(value); + } + return result; + } + return obj; +}; + +const ensureDir = async (dir_path: string) => { + try { + await fs.access(dir_path); + } catch { + await fs.mkdir(dir_path, { recursive: true }); + } +}; + +export const initDir = async () => { + await ensureDir(HOME_DIR); + await ensureDir(PLUGINS_DIR); + await ensureDir(path.join(HOME_DIR, "logs")); +}; + +const createReadline = () => { + return readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); +}; + +const question = (query: string): Promise => { + return new Promise((resolve) => { + const rl = createReadline(); + rl.question(query, (answer) => { + rl.close(); + resolve(answer); + }); + }); +}; + +const confirm = async (query: string): Promise => { + const answer = await question(query); + return answer.toLowerCase() !== "n"; +}; + +export const readConfigFile = async () => { + try { + const config = await fs.readFile(CONFIG_FILE, "utf-8"); + try { + // Try to parse with JSON5 first (which also supports standard JSON) + const parsedConfig = JSON5.parse(config); + // Interpolate environment variables in the parsed config + return interpolateEnvVars(parsedConfig); + } catch (parseError) { + console.error(`Failed to parse config file at ${CONFIG_FILE}`); + console.error("Error details:", (parseError as Error).message); + console.error("Please check your config file syntax."); + process.exit(1); + } + } catch (readError: any) { + if (readError.code === "ENOENT") { + // Config file doesn't exist, prompt user for initial setup + try { + // Initialize directories + await initDir(); + + // Backup existing config file if it exists + const backupPath = await backupConfigFile(); + if (backupPath) { + console.log( + `Backed up existing configuration file to ${backupPath}` + ); + } + const config = { + PORT: 3456, + Providers: [], + Router: {}, + } + // Create a minimal default config file + await writeConfigFile(config); + console.log( + "Created minimal default configuration file at ~/.claude-code-router/config.json" + ); + console.log( + "Please edit this file with your actual configuration." + ); + return config + } catch (error: any) { + console.error( + "Failed to create default configuration:", + error.message + ); + process.exit(1); + } + } else { + console.error(`Failed to read config file at ${CONFIG_FILE}`); + console.error("Error details:", readError.message); + process.exit(1); + } + } +}; + +export const backupConfigFile = async () => { + try { + if (await fs.access(CONFIG_FILE).then(() => true).catch(() => false)) { + const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); + const backupPath = `${CONFIG_FILE}.${timestamp}.bak`; + await fs.copyFile(CONFIG_FILE, backupPath); + + // Clean up old backups, keeping only the 3 most recent + try { + const configDir = path.dirname(CONFIG_FILE); + const configFileName = path.basename(CONFIG_FILE); + const files = await fs.readdir(configDir); + + // Find all backup files for this config + const backupFiles = files + .filter(file => file.startsWith(configFileName) && file.endsWith('.bak')) + .sort() + .reverse(); // Sort in descending order (newest first) + + // Delete all but the 3 most recent backups + if (backupFiles.length > 3) { + for (let i = 3; i < backupFiles.length; i++) { + const oldBackupPath = path.join(configDir, backupFiles[i]); + await fs.unlink(oldBackupPath); + } + } + } catch (cleanupError) { + console.warn("Failed to clean up old backups:", cleanupError); + } + + return backupPath; + } + } catch (error) { + console.error("Failed to backup config file:", error); + } + return null; +}; + +export const writeConfigFile = async (config: any) => { + await ensureDir(HOME_DIR); + const configWithComment = `${JSON.stringify(config, null, 2)}`; + await fs.writeFile(CONFIG_FILE, configWithComment); +}; + +export const initConfig = async () => { + const config = await readConfigFile(); + Object.assign(process.env, config); + return config; +}; diff --git a/src/utils/rewriteStream.ts b/packages/server/src/utils/rewriteStream.ts similarity index 100% rename from src/utils/rewriteStream.ts rename to packages/server/src/utils/rewriteStream.ts diff --git a/src/utils/router.ts b/packages/server/src/utils/router.ts similarity index 91% rename from src/utils/router.ts rename to packages/server/src/utils/router.ts index 8bd0e02..7e77d23 100644 --- a/src/utils/router.ts +++ b/packages/server/src/utils/router.ts @@ -1,16 +1,35 @@ -import { - MessageCreateParamsBase, - MessageParam, - Tool, -} from "@anthropic-ai/sdk/resources/messages"; import { get_encoding } from "tiktoken"; import { sessionUsageCache, Usage } from "./cache"; import { readFile, access } from "fs/promises"; import { opendir, stat } from "fs/promises"; import { join } from "path"; -import { CLAUDE_PROJECTS_DIR, HOME_DIR } from "../constants"; +import { CLAUDE_PROJECTS_DIR, HOME_DIR } from "@musistudio/claude-code-router-shared"; import { LRUCache } from "lru-cache"; +// Types from @anthropic-ai/sdk +interface Tool { + name: string; + description?: string; + input_schema: object; +} + +interface ContentBlockParam { + type: string; + [key: string]: any; +} + +interface MessageParam { + role: string; + content: string | ContentBlockParam[]; +} + +interface MessageCreateParamsBase { + messages?: MessageParam[]; + system?: string | any[]; + tools?: Tool[]; + [key: string]: any; +} + const enc = get_encoding("cl100k_base"); export const calculateTokenCount = ( @@ -232,7 +251,7 @@ export const router = async (req: any, _res: any, context: any) => { // 内存缓存,存储sessionId到项目名称的映射 // null值表示之前已查找过但未找到项目 // 使用LRU缓存,限制最大1000个条目 -const sessionProjectCache = new LRUCache({ +const sessionProjectCache = new LRUCache({ max: 1000, }); @@ -241,7 +260,11 @@ export const searchProjectBySession = async ( ): Promise => { // 首先检查缓存 if (sessionProjectCache.has(sessionId)) { - return sessionProjectCache.get(sessionId)!; + const result = sessionProjectCache.get(sessionId); + if (!result || result === '') { + return null; + } + return result; } try { @@ -283,12 +306,12 @@ export const searchProjectBySession = async ( } // 缓存未找到的结果(null值表示之前已查找过但未找到项目) - sessionProjectCache.set(sessionId, null); + sessionProjectCache.set(sessionId, ''); return null; // 没有找到匹配的项目 } catch (error) { console.error("Error searching for project by session:", error); // 出错时也缓存null结果,避免重复出错 - sessionProjectCache.set(sessionId, null); + sessionProjectCache.set(sessionId, ''); return null; } }; diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json new file mode 100644 index 0000000..866b298 --- /dev/null +++ b/packages/server/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src", + "baseUrl": "./src" + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/shared/package.json b/packages/shared/package.json new file mode 100644 index 0000000..9ae6171 --- /dev/null +++ b/packages/shared/package.json @@ -0,0 +1,23 @@ +{ + "name": "@musistudio/claude-code-router-shared", + "version": "1.0.73", + "description": "Shared utilities and constants for Claude Code Router", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "node ../../scripts/build-shared.js" + }, + "keywords": [ + "claude", + "code", + "router", + "shared" + ], + "author": "musistudio", + "license": "MIT", + "devDependencies": { + "@types/node": "^24.0.15", + "esbuild": "^0.25.1", + "typescript": "^5.8.2" + } +} diff --git a/src/constants.ts b/packages/shared/src/constants.ts similarity index 100% rename from src/constants.ts rename to packages/shared/src/constants.ts diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts new file mode 100644 index 0000000..b04bfcf --- /dev/null +++ b/packages/shared/src/index.ts @@ -0,0 +1 @@ +export * from "./constants"; diff --git a/packages/shared/tsconfig.json b/packages/shared/tsconfig.json new file mode 100644 index 0000000..b813d42 --- /dev/null +++ b/packages/shared/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/ui/PROJECT.md b/packages/ui/PROJECT.md similarity index 100% rename from ui/PROJECT.md rename to packages/ui/PROJECT.md diff --git a/ui/README.md b/packages/ui/README.md similarity index 100% rename from ui/README.md rename to packages/ui/README.md diff --git a/ui/components.json b/packages/ui/components.json similarity index 100% rename from ui/components.json rename to packages/ui/components.json diff --git a/ui/config.example.json b/packages/ui/config.example.json similarity index 100% rename from ui/config.example.json rename to packages/ui/config.example.json diff --git a/ui/eslint.config.js b/packages/ui/eslint.config.js similarity index 100% rename from ui/eslint.config.js rename to packages/ui/eslint.config.js diff --git a/ui/index.html b/packages/ui/index.html similarity index 100% rename from ui/index.html rename to packages/ui/index.html diff --git a/ui/package-lock.json b/packages/ui/package-lock.json similarity index 100% rename from ui/package-lock.json rename to packages/ui/package-lock.json diff --git a/ui/package.json b/packages/ui/package.json similarity index 95% rename from ui/package.json rename to packages/ui/package.json index e881843..abda17b 100644 --- a/ui/package.json +++ b/packages/ui/package.json @@ -1,7 +1,7 @@ { - "name": "temp-project", + "name": "@musistudio/claude-code-router-ui", "private": true, - "version": "0.0.0", + "version": "1.0.73", "type": "module", "scripts": { "dev": "vite", diff --git a/ui/pnpm-lock.yaml b/packages/ui/pnpm-lock.yaml similarity index 100% rename from ui/pnpm-lock.yaml rename to packages/ui/pnpm-lock.yaml diff --git a/ui/public/vite.svg b/packages/ui/public/vite.svg similarity index 100% rename from ui/public/vite.svg rename to packages/ui/public/vite.svg diff --git a/ui/src/App.tsx b/packages/ui/src/App.tsx similarity index 100% rename from ui/src/App.tsx rename to packages/ui/src/App.tsx diff --git a/ui/src/assets/react.svg b/packages/ui/src/assets/react.svg similarity index 100% rename from ui/src/assets/react.svg rename to packages/ui/src/assets/react.svg diff --git a/ui/src/components/ConfigProvider.tsx b/packages/ui/src/components/ConfigProvider.tsx similarity index 100% rename from ui/src/components/ConfigProvider.tsx rename to packages/ui/src/components/ConfigProvider.tsx diff --git a/ui/src/components/DebugPage.tsx b/packages/ui/src/components/DebugPage.tsx similarity index 100% rename from ui/src/components/DebugPage.tsx rename to packages/ui/src/components/DebugPage.tsx diff --git a/ui/src/components/JsonEditor.tsx b/packages/ui/src/components/JsonEditor.tsx similarity index 100% rename from ui/src/components/JsonEditor.tsx rename to packages/ui/src/components/JsonEditor.tsx diff --git a/ui/src/components/LogViewer.tsx b/packages/ui/src/components/LogViewer.tsx similarity index 100% rename from ui/src/components/LogViewer.tsx rename to packages/ui/src/components/LogViewer.tsx diff --git a/ui/src/components/Login.tsx b/packages/ui/src/components/Login.tsx similarity index 100% rename from ui/src/components/Login.tsx rename to packages/ui/src/components/Login.tsx diff --git a/ui/src/components/ProtectedRoute.tsx b/packages/ui/src/components/ProtectedRoute.tsx similarity index 100% rename from ui/src/components/ProtectedRoute.tsx rename to packages/ui/src/components/ProtectedRoute.tsx diff --git a/ui/src/components/ProviderList.tsx b/packages/ui/src/components/ProviderList.tsx similarity index 100% rename from ui/src/components/ProviderList.tsx rename to packages/ui/src/components/ProviderList.tsx diff --git a/ui/src/components/Providers.tsx b/packages/ui/src/components/Providers.tsx similarity index 100% rename from ui/src/components/Providers.tsx rename to packages/ui/src/components/Providers.tsx diff --git a/ui/src/components/PublicRoute.tsx b/packages/ui/src/components/PublicRoute.tsx similarity index 100% rename from ui/src/components/PublicRoute.tsx rename to packages/ui/src/components/PublicRoute.tsx diff --git a/ui/src/components/RequestHistoryDrawer.tsx b/packages/ui/src/components/RequestHistoryDrawer.tsx similarity index 100% rename from ui/src/components/RequestHistoryDrawer.tsx rename to packages/ui/src/components/RequestHistoryDrawer.tsx diff --git a/ui/src/components/Router.tsx b/packages/ui/src/components/Router.tsx similarity index 100% rename from ui/src/components/Router.tsx rename to packages/ui/src/components/Router.tsx diff --git a/ui/src/components/SettingsDialog.tsx b/packages/ui/src/components/SettingsDialog.tsx similarity index 100% rename from ui/src/components/SettingsDialog.tsx rename to packages/ui/src/components/SettingsDialog.tsx diff --git a/ui/src/components/StatusLineConfigDialog.tsx b/packages/ui/src/components/StatusLineConfigDialog.tsx similarity index 100% rename from ui/src/components/StatusLineConfigDialog.tsx rename to packages/ui/src/components/StatusLineConfigDialog.tsx diff --git a/ui/src/components/StatusLineImportExport.tsx b/packages/ui/src/components/StatusLineImportExport.tsx similarity index 100% rename from ui/src/components/StatusLineImportExport.tsx rename to packages/ui/src/components/StatusLineImportExport.tsx diff --git a/ui/src/components/TransformerList.tsx b/packages/ui/src/components/TransformerList.tsx similarity index 100% rename from ui/src/components/TransformerList.tsx rename to packages/ui/src/components/TransformerList.tsx diff --git a/ui/src/components/Transformers.tsx b/packages/ui/src/components/Transformers.tsx similarity index 100% rename from ui/src/components/Transformers.tsx rename to packages/ui/src/components/Transformers.tsx diff --git a/ui/src/components/ui/badge.tsx b/packages/ui/src/components/ui/badge.tsx similarity index 100% rename from ui/src/components/ui/badge.tsx rename to packages/ui/src/components/ui/badge.tsx diff --git a/ui/src/components/ui/button.tsx b/packages/ui/src/components/ui/button.tsx similarity index 100% rename from ui/src/components/ui/button.tsx rename to packages/ui/src/components/ui/button.tsx diff --git a/ui/src/components/ui/card.tsx b/packages/ui/src/components/ui/card.tsx similarity index 100% rename from ui/src/components/ui/card.tsx rename to packages/ui/src/components/ui/card.tsx diff --git a/ui/src/components/ui/color-picker.tsx b/packages/ui/src/components/ui/color-picker.tsx similarity index 100% rename from ui/src/components/ui/color-picker.tsx rename to packages/ui/src/components/ui/color-picker.tsx diff --git a/ui/src/components/ui/combo-input.tsx b/packages/ui/src/components/ui/combo-input.tsx similarity index 100% rename from ui/src/components/ui/combo-input.tsx rename to packages/ui/src/components/ui/combo-input.tsx diff --git a/ui/src/components/ui/combobox.tsx b/packages/ui/src/components/ui/combobox.tsx similarity index 100% rename from ui/src/components/ui/combobox.tsx rename to packages/ui/src/components/ui/combobox.tsx diff --git a/ui/src/components/ui/command.tsx b/packages/ui/src/components/ui/command.tsx similarity index 100% rename from ui/src/components/ui/command.tsx rename to packages/ui/src/components/ui/command.tsx diff --git a/ui/src/components/ui/dialog.tsx b/packages/ui/src/components/ui/dialog.tsx similarity index 100% rename from ui/src/components/ui/dialog.tsx rename to packages/ui/src/components/ui/dialog.tsx diff --git a/ui/src/components/ui/input.tsx b/packages/ui/src/components/ui/input.tsx similarity index 100% rename from ui/src/components/ui/input.tsx rename to packages/ui/src/components/ui/input.tsx diff --git a/ui/src/components/ui/label.tsx b/packages/ui/src/components/ui/label.tsx similarity index 100% rename from ui/src/components/ui/label.tsx rename to packages/ui/src/components/ui/label.tsx diff --git a/ui/src/components/ui/multi-combobox.tsx b/packages/ui/src/components/ui/multi-combobox.tsx similarity index 100% rename from ui/src/components/ui/multi-combobox.tsx rename to packages/ui/src/components/ui/multi-combobox.tsx diff --git a/ui/src/components/ui/popover.tsx b/packages/ui/src/components/ui/popover.tsx similarity index 100% rename from ui/src/components/ui/popover.tsx rename to packages/ui/src/components/ui/popover.tsx diff --git a/ui/src/components/ui/switch.tsx b/packages/ui/src/components/ui/switch.tsx similarity index 100% rename from ui/src/components/ui/switch.tsx rename to packages/ui/src/components/ui/switch.tsx diff --git a/ui/src/components/ui/tabs.tsx b/packages/ui/src/components/ui/tabs.tsx similarity index 100% rename from ui/src/components/ui/tabs.tsx rename to packages/ui/src/components/ui/tabs.tsx diff --git a/ui/src/components/ui/toast.tsx b/packages/ui/src/components/ui/toast.tsx similarity index 100% rename from ui/src/components/ui/toast.tsx rename to packages/ui/src/components/ui/toast.tsx diff --git a/ui/src/i18n.ts b/packages/ui/src/i18n.ts similarity index 100% rename from ui/src/i18n.ts rename to packages/ui/src/i18n.ts diff --git a/ui/src/index.css b/packages/ui/src/index.css similarity index 100% rename from ui/src/index.css rename to packages/ui/src/index.css diff --git a/ui/src/lib/api.ts b/packages/ui/src/lib/api.ts similarity index 100% rename from ui/src/lib/api.ts rename to packages/ui/src/lib/api.ts diff --git a/ui/src/lib/db.ts b/packages/ui/src/lib/db.ts similarity index 100% rename from ui/src/lib/db.ts rename to packages/ui/src/lib/db.ts diff --git a/ui/src/lib/utils.ts b/packages/ui/src/lib/utils.ts similarity index 100% rename from ui/src/lib/utils.ts rename to packages/ui/src/lib/utils.ts diff --git a/ui/src/locales/en.json b/packages/ui/src/locales/en.json similarity index 100% rename from ui/src/locales/en.json rename to packages/ui/src/locales/en.json diff --git a/ui/src/locales/zh.json b/packages/ui/src/locales/zh.json similarity index 100% rename from ui/src/locales/zh.json rename to packages/ui/src/locales/zh.json diff --git a/ui/src/main.tsx b/packages/ui/src/main.tsx similarity index 100% rename from ui/src/main.tsx rename to packages/ui/src/main.tsx diff --git a/ui/src/routes.tsx b/packages/ui/src/routes.tsx similarity index 100% rename from ui/src/routes.tsx rename to packages/ui/src/routes.tsx diff --git a/ui/src/styles/animations.css b/packages/ui/src/styles/animations.css similarity index 100% rename from ui/src/styles/animations.css rename to packages/ui/src/styles/animations.css diff --git a/ui/src/types.ts b/packages/ui/src/types.ts similarity index 100% rename from ui/src/types.ts rename to packages/ui/src/types.ts diff --git a/ui/src/utils/statusline.ts b/packages/ui/src/utils/statusline.ts similarity index 100% rename from ui/src/utils/statusline.ts rename to packages/ui/src/utils/statusline.ts diff --git a/ui/src/vite-env.d.ts b/packages/ui/src/vite-env.d.ts similarity index 100% rename from ui/src/vite-env.d.ts rename to packages/ui/src/vite-env.d.ts diff --git a/ui/tsconfig.app.json b/packages/ui/tsconfig.app.json similarity index 100% rename from ui/tsconfig.app.json rename to packages/ui/tsconfig.app.json diff --git a/ui/tsconfig.json b/packages/ui/tsconfig.json similarity index 100% rename from ui/tsconfig.json rename to packages/ui/tsconfig.json diff --git a/ui/vite.config.ts b/packages/ui/vite.config.ts similarity index 100% rename from ui/vite.config.ts rename to packages/ui/vite.config.ts diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8cf6f52..33fd769 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,34 +7,74 @@ settings: importers: .: + devDependencies: + '@types/node': + specifier: ^24.0.15 + version: 24.7.0 + esbuild: + specifier: ^0.25.1 + version: 0.25.10 + shx: + specifier: ^0.4.0 + version: 0.4.0 + typescript: + specifier: ^5.8.2 + version: 5.9.3 + + packages/cli: dependencies: - '@fastify/static': - specifier: ^8.2.0 - version: 8.2.0 '@inquirer/prompts': specifier: ^5.0.0 version: 5.5.0 - '@musistudio/llms': - specifier: ^1.0.51 - version: 1.0.51(ws@8.18.3) - dotenv: - specifier: ^16.4.7 - version: 16.6.1 + '@musistudio/claude-code-router-server': + specifier: workspace:* + version: link:../server + '@musistudio/claude-code-router-shared': + specifier: workspace:* + version: link:../shared find-process: specifier: ^2.0.0 version: 2.0.0 - json5: - specifier: ^2.2.3 - version: 2.2.3 - lru-cache: - specifier: ^11.2.2 - version: 11.2.2 minimist: specifier: ^1.2.8 version: 1.2.8 openurl: specifier: ^1.1.1 version: 1.1.1 + devDependencies: + '@types/node': + specifier: ^24.0.15 + version: 24.7.0 + esbuild: + specifier: ^0.25.1 + version: 0.25.10 + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@24.7.0)(typescript@5.8.3) + typescript: + specifier: ^5.8.2 + version: 5.8.3 + + packages/server: + dependencies: + '@fastify/static': + specifier: ^8.2.0 + version: 8.2.0 + '@musistudio/claude-code-router-shared': + specifier: workspace:* + version: link:../shared + '@musistudio/llms': + specifier: ^1.0.51 + version: 1.0.51(ws@8.18.3) + dotenv: + specifier: ^16.4.7 + version: 16.6.1 + json5: + specifier: ^2.2.3 + version: 2.2.3 + lru-cache: + specifier: ^11.2.2 + version: 11.2.2 rotating-file-stream: specifier: ^3.2.7 version: 3.2.7 @@ -57,175 +97,606 @@ importers: fastify: specifier: ^5.4.0 version: 5.6.1 - shx: - specifier: ^0.4.0 - version: 0.4.0 + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@24.7.0)(typescript@5.8.3) typescript: specifier: ^5.8.2 - version: 5.9.3 + version: 5.8.3 + + packages/shared: + devDependencies: + '@types/node': + specifier: ^24.0.15 + version: 24.7.0 + esbuild: + specifier: ^0.25.1 + version: 0.25.10 + typescript: + specifier: ^5.8.2 + version: 5.8.3 + + packages/ui: + dependencies: + '@monaco-editor/react': + specifier: ^4.7.0 + version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-dialog': + specifier: ^1.1.14 + version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-label': + specifier: ^2.1.7 + version: 2.1.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-popover': + specifier: ^1.1.14 + version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-slot': + specifier: ^1.2.3 + version: 1.2.4(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-switch': + specifier: ^1.2.5 + version: 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-tabs': + specifier: ^1.1.13 + version: 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-tooltip': + specifier: ^1.2.7 + version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tailwindcss/vite': + specifier: ^4.1.11 + version: 4.1.18(vite@7.3.0(@types/node@24.7.0)(jiti@2.6.1)(lightningcss@1.30.2)) + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + cmdk: + specifier: ^1.1.1 + version: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + i18next: + specifier: ^25.3.2 + version: 25.7.3(typescript@5.8.3) + i18next-browser-languagedetector: + specifier: ^8.2.0 + version: 8.2.0 + lucide-react: + specifier: ^0.525.0 + version: 0.525.0(react@19.2.3) + react: + specifier: ^19.1.0 + version: 19.2.3 + react-colorful: + specifier: ^5.6.1 + version: 5.6.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react-dnd: + specifier: ^16.0.1 + version: 16.0.1(@types/node@24.7.0)(@types/react@19.2.7)(react@19.2.3) + react-dnd-html5-backend: + specifier: ^16.0.1 + version: 16.0.1 + react-dom: + specifier: ^19.1.0 + version: 19.2.3(react@19.2.3) + react-i18next: + specifier: ^15.6.1 + version: 15.7.4(i18next@25.7.3(typescript@5.8.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.8.3) + react-router-dom: + specifier: ^7.7.0 + version: 7.11.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + tailwind-merge: + specifier: ^3.3.1 + version: 3.4.0 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@4.1.18) + devDependencies: + '@eslint/js': + specifier: ^9.30.1 + version: 9.39.2 + '@tailwindcss/postcss': + specifier: ^4.1.11 + version: 4.1.18 + '@types/node': + specifier: ^24.1.0 + version: 24.7.0 + '@types/react': + specifier: ^19.1.8 + version: 19.2.7 + '@types/react-dom': + specifier: ^19.1.6 + version: 19.2.3(@types/react@19.2.7) + '@vitejs/plugin-react': + specifier: ^4.6.0 + version: 4.7.0(vite@7.3.0(@types/node@24.7.0)(jiti@2.6.1)(lightningcss@1.30.2)) + autoprefixer: + specifier: ^10.4.21 + version: 10.4.23(postcss@8.5.6) + eslint: + specifier: ^9.30.1 + version: 9.39.2(jiti@2.6.1) + eslint-plugin-react-hooks: + specifier: ^5.2.0 + version: 5.2.0(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-react-refresh: + specifier: ^0.4.20 + version: 0.4.26(eslint@9.39.2(jiti@2.6.1)) + globals: + specifier: ^16.3.0 + version: 16.5.0 + postcss: + specifier: ^8.5.6 + version: 8.5.6 + tailwindcss: + specifier: ^4.1.11 + version: 4.1.18 + tw-animate-css: + specifier: ^1.3.5 + version: 1.4.0 + typescript: + specifier: ~5.8.3 + version: 5.8.3 + typescript-eslint: + specifier: ^8.35.1 + version: 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.8.3) + vite: + specifier: ^7.0.4 + version: 7.3.0(@types/node@24.7.0)(jiti@2.6.1)(lightningcss@1.30.2) + vite-plugin-singlefile: + specifier: ^2.3.0 + version: 2.3.0(rollup@4.54.0)(vite@7.3.0(@types/node@24.7.0)(jiti@2.6.1)(lightningcss@1.30.2)) packages: + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + '@anthropic-ai/sdk@0.54.0': resolution: {integrity: sha512-xyoCtHJnt/qg5GG6IgK+UJEndz8h8ljzt/caKXmq3LfBF81nC/BW6E4x2rOWCZcvsLyVW+e8U5mtIr6UCE/kJw==} hasBin: true + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.28.5': + resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.28.5': + resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + '@esbuild/aix-ppc64@0.25.10': resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.27.2': + resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.25.10': resolution: {integrity: sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.27.2': + resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.25.10': resolution: {integrity: sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.27.2': + resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.25.10': resolution: {integrity: sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.27.2': + resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.25.10': resolution: {integrity: sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.27.2': + resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.25.10': resolution: {integrity: sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.27.2': + resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.25.10': resolution: {integrity: sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.27.2': + resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.10': resolution: {integrity: sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.27.2': + resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.25.10': resolution: {integrity: sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.27.2': + resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.25.10': resolution: {integrity: sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.27.2': + resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.25.10': resolution: {integrity: sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.27.2': + resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.25.10': resolution: {integrity: sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.27.2': + resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.25.10': resolution: {integrity: sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.27.2': + resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.25.10': resolution: {integrity: sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.27.2': + resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.25.10': resolution: {integrity: sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.27.2': + resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.25.10': resolution: {integrity: sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.27.2': + resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.25.10': resolution: {integrity: sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.27.2': + resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.25.10': resolution: {integrity: sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.27.2': + resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.10': resolution: {integrity: sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.27.2': + resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.25.10': resolution: {integrity: sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.27.2': + resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.10': resolution: {integrity: sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.27.2': + resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.25.10': resolution: {integrity: sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.27.2': + resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.25.10': resolution: {integrity: sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.27.2': + resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.25.10': resolution: {integrity: sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.27.2': + resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.25.10': resolution: {integrity: sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.27.2': + resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.25.10': resolution: {integrity: sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==} engines: {node: '>=18'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.27.2': + resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.1': + resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.3': + resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.2': + resolution: {integrity: sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@fastify/accept-negotiator@2.0.1': resolution: {integrity: sha512-/c/TW2bO/v9JeEgoD/g1G5GxGeCF1Hafdf79WPmUlgYiBXummY0oX3VVq4yFkKKVBKDNlaDUYoab7g38RpPqCQ==} @@ -256,6 +727,21 @@ packages: '@fastify/static@8.2.0': resolution: {integrity: sha512-PejC/DtT7p1yo3p+W7LiUtLMsV8fEvxAK15sozHy9t8kwo5r0uLYmhV/inURmGz1SkHZFz/8CNtHLPyhKcx4SQ==} + '@floating-ui/core@1.7.3': + resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} + + '@floating-ui/dom@1.7.4': + resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} + + '@floating-ui/react-dom@2.1.6': + resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.10': + resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@google/genai@1.24.0': resolution: {integrity: sha512-e3jZF9Dx3dDaDCzygdMuYByHI2xJZ0PaD3r2fRgHZe2IOwBnmJ/Tu5Lt/nefTCxqr1ZnbcbQK9T13d8U/9UMWg==} engines: {node: '>=20.0.0'} @@ -265,6 +751,22 @@ packages: '@modelcontextprotocol/sdk': optional: true + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + '@inquirer/checkbox@2.5.0': resolution: {integrity: sha512-sMgdETOfi2dUHT8r7TT1BTKOwNvdDGFDXYWtQ2J69SvlYNntk9I/gJe7r5yvMwwsuKnYbuRs3pNhx4tgNck5aA==} engines: {node: '>=18'} @@ -337,10 +839,39 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@lukeed/ms@2.0.2': resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==} engines: {node: '>=8'} + '@monaco-editor/loader@1.7.0': + resolution: {integrity: sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA==} + + '@monaco-editor/react@4.7.0': + resolution: {integrity: sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==} + peerDependencies: + monaco-editor: '>= 0.25.0 < 1' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + '@musistudio/llms@1.0.51': resolution: {integrity: sha512-38T9NYrL9/Ombwx4YkGZSryYPtyaSMWJb3aGsepY8m9nbwCST60V+68xKVEaWyri6EfN8D3kenU0W8+okfVSmQ==} @@ -356,6 +887,613 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@radix-ui/primitive@1.1.3': + resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} + + '@radix-ui/react-arrow@1.1.7': + resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.1.15': + resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.11': + resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.3': + resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.7': + resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.1': + resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-label@2.1.8': + resolution: {integrity: sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popover@1.1.15': + resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popper@1.2.8': + resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-portal@1.1.9': + resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.5': + resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.4': + resolution: {integrity: sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.1.11': + resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-slot@1.2.4': + resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-switch@1.2.6': + resolution: {integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-tabs@1.1.13': + resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-tooltip@1.2.8': + resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.1': + resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.1': + resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-previous@1.1.1': + resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-rect@1.1.1': + resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.1': + resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-visually-hidden@1.2.3': + resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/rect@1.1.1': + resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + + '@react-dnd/asap@5.0.2': + resolution: {integrity: sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==} + + '@react-dnd/invariant@4.0.2': + resolution: {integrity: sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==} + + '@react-dnd/shallowequal@4.0.2': + resolution: {integrity: sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==} + + '@rolldown/pluginutils@1.0.0-beta.27': + resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} + + '@rollup/rollup-android-arm-eabi@4.54.0': + resolution: {integrity: sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.54.0': + resolution: {integrity: sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.54.0': + resolution: {integrity: sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.54.0': + resolution: {integrity: sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.54.0': + resolution: {integrity: sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.54.0': + resolution: {integrity: sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.54.0': + resolution: {integrity: sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.54.0': + resolution: {integrity: sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.54.0': + resolution: {integrity: sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.54.0': + resolution: {integrity: sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.54.0': + resolution: {integrity: sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.54.0': + resolution: {integrity: sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.54.0': + resolution: {integrity: sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.54.0': + resolution: {integrity: sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.54.0': + resolution: {integrity: sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.54.0': + resolution: {integrity: sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.54.0': + resolution: {integrity: sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.54.0': + resolution: {integrity: sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.54.0': + resolution: {integrity: sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.54.0': + resolution: {integrity: sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.54.0': + resolution: {integrity: sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.54.0': + resolution: {integrity: sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==} + cpu: [x64] + os: [win32] + + '@tailwindcss/node@4.1.18': + resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==} + + '@tailwindcss/oxide-android-arm64@4.1.18': + resolution: {integrity: sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.1.18': + resolution: {integrity: sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.1.18': + resolution: {integrity: sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.1.18': + resolution: {integrity: sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18': + resolution: {integrity: sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.18': + resolution: {integrity: sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.1.18': + resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.1.18': + resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.1.18': + resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.1.18': + resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.18': + resolution: {integrity: sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.1.18': + resolution: {integrity: sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.1.18': + resolution: {integrity: sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==} + engines: {node: '>= 10'} + + '@tailwindcss/postcss@4.1.18': + resolution: {integrity: sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==} + + '@tailwindcss/vite@4.1.18': + resolution: {integrity: sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 + + '@tsconfig/node10@1.0.12': + resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/mute-stream@0.0.4': resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} @@ -365,12 +1503,102 @@ packages: '@types/node@24.7.0': resolution: {integrity: sha512-IbKooQVqUBrlzWTi79E8Fw78l8k1RNtlDDNWsFZs7XonuQSJ8oNYfEeclhprUldXISRMLzBpILuKgPlIxm+/Yw==} + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.7': + resolution: {integrity: sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/wrap-ansi@3.0.0': resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==} + '@typescript-eslint/eslint-plugin@8.50.1': + resolution: {integrity: sha512-PKhLGDq3JAg0Jk/aK890knnqduuI/Qj+udH7wCf0217IGi4gt+acgCyPVe79qoT+qKUvHMDQkwJeKW9fwl8Cyw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.50.1 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.50.1': + resolution: {integrity: sha512-hM5faZwg7aVNa819m/5r7D0h0c9yC4DUlWAOvHAtISdFTc8xB86VmX5Xqabrama3wIPJ/q9RbGS1worb6JfnMg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.50.1': + resolution: {integrity: sha512-E1ur1MCVf+YiP89+o4Les/oBAVzmSbeRB0MQLfSlYtbWU17HPxZ6Bhs5iYmKZRALvEuBoXIZMOIRRc/P++Ortg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.50.1': + resolution: {integrity: sha512-mfRx06Myt3T4vuoHaKi8ZWNTPdzKPNBhiblze5N50//TSHOAQQevl/aolqA/BcqqbJ88GUnLqjjcBc8EWdBcVw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.50.1': + resolution: {integrity: sha512-ooHmotT/lCWLXi55G4mvaUF60aJa012QzvLK0Y+Mp4WdSt17QhMhWOaBWeGTFVkb2gDgBe19Cxy1elPXylslDw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.50.1': + resolution: {integrity: sha512-7J3bf022QZE42tYMO6SL+6lTPKFk/WphhRPe9Tw/el+cEwzLz1Jjz2PX3GtGQVxooLDKeMVmMt7fWpYRdG5Etg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.50.1': + resolution: {integrity: sha512-v5lFIS2feTkNyMhd7AucE/9j/4V9v5iIbpVRncjk/K0sQ6Sb+Np9fgYS/63n6nwqahHQvbmujeBL7mp07Q9mlA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.50.1': + resolution: {integrity: sha512-woHPdW+0gj53aM+cxchymJCrh0cyS7BTIdcDxWUNsclr9VDkOSbqC13juHzxOmQ22dDkMZEpZB+3X1WpUvzgVQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.50.1': + resolution: {integrity: sha512-lCLp8H1T9T7gPbEuJSnHwnSuO9mDf8mfK/Nion5mZmiEaQD9sWf9W4dfeFqRyqRjF06/kBuTmAqcs9sewM2NbQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.50.1': + resolution: {integrity: sha512-IrDKrw7pCRUR94zeuCSUWQ+w8JEf5ZX5jl/e6AHGSLi1/zIr0lgutfn/7JpfCey+urpgQEdrZVYzCaVVKiTwhQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@vitejs/plugin-react@4.7.0': + resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + abstract-logging@2.0.1: resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + agent-base@7.1.4: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} @@ -383,6 +1611,9 @@ packages: ajv: optional: true + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} @@ -406,26 +1637,68 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + atomic-sleep@1.0.0: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} + autoprefixer@10.4.23: + resolution: {integrity: sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + avvio@9.1.0: resolution: {integrity: sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==} + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.9.11: + resolution: {integrity: sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==} + hasBin: true + bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001761: + resolution: {integrity: sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -433,10 +1706,23 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + cli-width@4.1.0: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + cmdk@1.1.1: + resolution: {integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==} + peerDependencies: + react: ^18 || ^19 || ^19.0.0-rc + react-dom: ^18 || ^19 || ^19.0.0-rc + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -448,14 +1734,23 @@ packages: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie@1.0.2: resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} engines: {node: '>=18'} + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + cross-spawn@6.0.6: resolution: {integrity: sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==} engines: {node: '>=4.8'} @@ -464,6 +1759,9 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + data-uri-to-buffer@4.0.1: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} @@ -477,6 +1775,9 @@ packages: supports-color: optional: true + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -485,6 +1786,23 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + dnd-core@16.0.1: + resolution: {integrity: sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==} + + dompurify@3.2.7: + resolution: {integrity: sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==} + dotenv@16.6.1: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} @@ -495,6 +1813,9 @@ packages: ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + electron-to-chromium@1.5.267: + resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -504,14 +1825,84 @@ packages: end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + enhanced-resolve@5.18.4: + resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} + engines: {node: '>=10.13.0'} + esbuild@0.25.10: resolution: {integrity: sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==} engines: {node: '>=18'} hasBin: true + esbuild@0.27.2: + resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-plugin-react-hooks@5.2.0: + resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-refresh@0.4.26: + resolution: {integrity: sha512-1RETEylht2O6FM/MvgnyvT+8K21wLqDNg4qD51Zj3guhjt433XbnnkVttHMyaVyAFD03QSV4LPS5iE3VQmO7XQ==} + peerDependencies: + eslint: '>=8.40' + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.39.2: + resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + execa@1.0.0: resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==} engines: {node: '>=6'} @@ -533,9 +1924,15 @@ packages: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + fast-json-stringify@6.1.1: resolution: {integrity: sha512-DbgptncYEXZqDUOEl4krff4mUiVrTZZVI7BBrQR/T3BqMj/eM1flTC1Uk2uUoLcWCxjT95xKulV/Lc6hhOZsBQ==} + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-querystring@1.1.2: resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} @@ -551,10 +1948,23 @@ packages: fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + fetch-blob@3.2.0: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -567,6 +1977,17 @@ packages: resolution: {integrity: sha512-YUBQnteWGASJoEVVsOXy6XtKAY2O1FCsWnnvQ8y0YwgY1rZiKeVptnFvMu6RSELZAJOGklqseTnUGGs5D0bKmg==} hasBin: true + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + foreground-child@3.3.1: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} @@ -575,6 +1996,14 @@ packages: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} @@ -594,6 +2023,14 @@ packages: resolution: {integrity: sha512-UcO3kefx6dCcZkgcTGgVOTFb7b1LlQ02hY1omMjjrrBzkajRMCFgYOjs7J71WqnuG1k2b+9ppGL7FsOfhZMQKQ==} engines: {node: '>=18'} + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + get-stream@4.1.0: resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} engines: {node: '>=6'} @@ -602,11 +2039,23 @@ packages: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + glob@11.0.3: resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==} engines: {node: 20 || >=22} hasBin: true + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@16.5.0: + resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} + engines: {node: '>=18'} + google-auth-library@10.4.0: resolution: {integrity: sha512-CmIrSy1bqMQUsPmA9+hcSbAXL80cFhu40cGMUjCaLpNKVzzvi+0uAHq8GNZxkoGYIsTX4ZQ7e4aInAqWxgn4fg==} engines: {node: '>=18'} @@ -623,6 +2072,9 @@ packages: resolution: {integrity: sha512-rcX58I7nqpu4mbKztFeOAObbomBbHU2oIb/d3tJfF3dizGSApqtSwYJigGCooHdnMyQBIw8BrWyK96w3YXgr6A==} engines: {node: '>=14'} + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + gtoken@7.1.0: resolution: {integrity: sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==} engines: {node: '>=14.0.0'} @@ -639,6 +2091,12 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + html-parse-stringify@3.0.1: + resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} @@ -647,10 +2105,37 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} + i18next-browser-languagedetector@8.2.0: + resolution: {integrity: sha512-P+3zEKLnOF0qmiesW383vsLdtQVyKtCNA9cjSoKCppTKPQVfKd2W8hbVo5ZhNJKDqeM7BOcvNoKJOjpHh4Js9g==} + + i18next@25.7.3: + resolution: {integrity: sha512-2XaT+HpYGuc2uTExq9TVRhLsso+Dxym6PWaKpn36wfBmTI779OQ7iP/XaZHzrnGyzU4SHpFrTYLKfVyBfAhVNA==} + peerDependencies: + typescript: ^5 + peerDependenciesMeta: + typescript: + optional: true + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -697,15 +2182,40 @@ packages: resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} engines: {node: 20 || >=22} + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + json-bigint@1.0.0: resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-schema-ref-resolver@3.0.0: resolution: {integrity: sha512-hOrZIVL5jyYFjzk7+y7n5JDzGlU8rfWDuYyHwGa2WA8/pcmMHezp2xsVwxrebD/Q9t8Nc5DboieySDpCp4WG4A==} + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -721,9 +2231,93 @@ packages: jws@4.0.0: resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==} + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + light-my-request@6.6.0: resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==} + lightningcss-android-arm64@1.30.2: + resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.30.2: + resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.30.2: + resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.30.2: + resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.30.2: + resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.30.2: + resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.30.2: + resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.30.2: + resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.30.2: + resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.30.2: + resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.30.2: + resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.30.2: + resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} + engines: {node: '>= 12.0.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + loglevel@1.9.2: resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} engines: {node: '>= 0.6.0'} @@ -732,6 +2326,25 @@ packages: resolution: {integrity: sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==} engines: {node: 20 || >=22} + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lucide-react@0.525.0: + resolution: {integrity: sha512-Tm1txJ2OkymCGkvwoHt33Y2JpN5xucVq1slHcgE6Lk0WjDfjgKWor5CdVER8U6DvcfMwh4M8XxmpTiyzfmfDYQ==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + marked@14.0.0: + resolution: {integrity: sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==} + engines: {node: '>= 18'} + hasBin: true + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -749,6 +2362,13 @@ packages: resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} engines: {node: 20 || >=22} + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -756,6 +2376,9 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + monaco-editor@0.55.1: + resolution: {integrity: sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -763,6 +2386,14 @@ packages: resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + nice-try@1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} @@ -784,6 +2415,9 @@ packages: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + npm-run-path@2.0.2: resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} engines: {node: '>=4'} @@ -810,6 +2444,10 @@ packages: openurl@1.1.1: resolution: {integrity: sha512-d/gTkTb1i1GKz5k3XE3XFV/PxQ1k45zDqGP2OA7YhgsaLoqm6qRvARAZOFer1fcXritWlGBRCu/UgeS4HAnXAA==} + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -818,9 +2456,25 @@ packages: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + path-key@2.0.1: resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} engines: {node: '>=4'} @@ -836,10 +2490,17 @@ packages: resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} engines: {node: 20 || >=22} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + pino-abstract-transport@2.0.0: resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} @@ -850,6 +2511,17 @@ packages: resolution: {integrity: sha512-Szuj+ViDTjKPQYiKumGmEn3frdl+ZPSdosHyt9SnUevFosOkMY2b7ipxlEctNKPmMD/VibeBI+ZcZCJK+4DPuw==} hasBin: true + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + process-warning@4.0.1: resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==} @@ -859,12 +2531,119 @@ packages: pump@3.0.3: resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + react-colorful@5.6.1: + resolution: {integrity: sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + react-dnd-html5-backend@16.0.1: + resolution: {integrity: sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==} + + react-dnd@16.0.1: + resolution: {integrity: sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==} + peerDependencies: + '@types/hoist-non-react-statics': '>= 3.3.1' + '@types/node': '>= 12' + '@types/react': '>= 16' + react: '>= 16.14' + peerDependenciesMeta: + '@types/hoist-non-react-statics': + optional: true + '@types/node': + optional: true + '@types/react': + optional: true + + react-dom@19.2.3: + resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} + peerDependencies: + react: ^19.2.3 + + react-i18next@15.7.4: + resolution: {integrity: sha512-nyU8iKNrI5uDJch0z9+Y5XEr34b0wkyYj3Rp+tfbahxtlswxSCjcUL9H0nqXo9IR3/t5Y5PKIA3fx3MfUyR9Xw==} + peerDependencies: + i18next: '>= 23.4.0' + react: '>= 16.8.0' + react-dom: '*' + react-native: '*' + typescript: ^5 + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + typescript: + optional: true + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-refresh@0.17.0: + resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} + engines: {node: '>=0.10.0'} + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.2: + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-router-dom@7.11.0: + resolution: {integrity: sha512-e49Ir/kMGRzFOOrYQBdoitq3ULigw4lKbAyKusnvtDu2t4dBX4AGYPrzNvorXmVuOyeakai6FUPW5MmibvVG8g==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + + react-router@7.11.0: + resolution: {integrity: sha512-uI4JkMmjbWCZc01WVP2cH7ZfSzH91JAZUDd7/nIprDgWxBV1TkkmLToFh7EbMTcMak8URFRa2YoBL/W8GWnCTQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + react-dom: + optional: true + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react@19.2.3: + resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} + engines: {node: '>=0.10.0'} + real-require@0.2.0: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} engines: {node: '>= 12.13.0'} @@ -873,10 +2652,17 @@ packages: resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} engines: {node: '>= 0.10'} + redux@4.2.1: + resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} + require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + resolve@1.22.10: resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} engines: {node: '>= 0.4'} @@ -893,6 +2679,11 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + rollup@4.54.0: + resolution: {integrity: sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + rotating-file-stream@3.2.7: resolution: {integrity: sha512-SVquhBEVvRFY+nWLUc791Y0MIlyZrEClRZwZFLLRgJKldHyV1z4e2e/dp9LPqCS3AM//uq/c3PnOFgjqnm5P+A==} engines: {node: '>=14.0'} @@ -913,6 +2704,9 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + secure-json-parse@4.1.0: resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==} @@ -920,6 +2714,10 @@ packages: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + semver@7.7.2: resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} engines: {node: '>=10'} @@ -974,10 +2772,17 @@ packages: sonic-boom@4.2.0: resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} + state-local@1.0.7: + resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==} + statuses@2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} @@ -1002,6 +2807,10 @@ packages: resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} engines: {node: '>=0.10.0'} + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -1010,12 +2819,31 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + tailwind-merge@3.4.0: + resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==} + + tailwindcss-animate@1.0.7: + resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + + tailwindcss@4.1.18: + resolution: {integrity: sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==} + + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + thread-stream@3.1.0: resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} tiktoken@1.0.22: resolution: {integrity: sha512-PKvy1rVF1RibfF3JlXBSP0Jrcw2uq3yXdgcEXtKTYn3QJ/cBRBHDnrJ5jHky+MENZ6DIPwNUGWpkVx+7joCpNA==} + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -1035,10 +2863,52 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tw-animate-css@1.4.0: + resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + type-fest@0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} + typescript-eslint@8.50.1: + resolution: {integrity: sha512-ytTHO+SoYSbhAH9CrYnMhiLx8To6PSSvqnvXyPUgPETCvB6eBKmTI9w6XMPS3HsBRGkwTVBX+urA8dYQx6bHfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + engines: {node: '>=14.17'} + hasBin: true + typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} @@ -1054,6 +2924,35 @@ packages: resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==} engines: {node: '>=20.18.1'} + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + uuid@11.1.0: resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} hasBin: true @@ -1062,6 +2961,60 @@ packages: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + vite-plugin-singlefile@2.3.0: + resolution: {integrity: sha512-DAcHzYypM0CasNLSz/WG0VdKOCxGHErfrjOoyIPiNxTPTGmO6rRD/te93n1YL/s+miXq66ipF1brMBikf99c6A==} + engines: {node: '>18.0.0'} + peerDependencies: + rollup: ^4.44.1 + vite: ^5.4.11 || ^6.0.0 || ^7.0.0 + + vite@7.3.0: + resolution: {integrity: sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + web-streams-polyfill@3.3.3: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} @@ -1081,6 +3034,10 @@ packages: engines: {node: '>= 8'} hasBin: true + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -1108,92 +3065,347 @@ packages: utf-8-validate: optional: true + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + yoctocolors-cjs@2.1.3: resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} engines: {node: '>=18'} snapshots: + '@alloc/quick-lru@5.2.0': {} + '@anthropic-ai/sdk@0.54.0': {} + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.28.5': {} + + '@babel/core@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.28.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.28.5 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.28.4': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 + + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/runtime@7.28.4': {} + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@babel/traverse@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + '@esbuild/aix-ppc64@0.25.10': optional: true + '@esbuild/aix-ppc64@0.27.2': + optional: true + '@esbuild/android-arm64@0.25.10': optional: true + '@esbuild/android-arm64@0.27.2': + optional: true + '@esbuild/android-arm@0.25.10': optional: true + '@esbuild/android-arm@0.27.2': + optional: true + '@esbuild/android-x64@0.25.10': optional: true + '@esbuild/android-x64@0.27.2': + optional: true + '@esbuild/darwin-arm64@0.25.10': optional: true + '@esbuild/darwin-arm64@0.27.2': + optional: true + '@esbuild/darwin-x64@0.25.10': optional: true + '@esbuild/darwin-x64@0.27.2': + optional: true + '@esbuild/freebsd-arm64@0.25.10': optional: true + '@esbuild/freebsd-arm64@0.27.2': + optional: true + '@esbuild/freebsd-x64@0.25.10': optional: true + '@esbuild/freebsd-x64@0.27.2': + optional: true + '@esbuild/linux-arm64@0.25.10': optional: true + '@esbuild/linux-arm64@0.27.2': + optional: true + '@esbuild/linux-arm@0.25.10': optional: true + '@esbuild/linux-arm@0.27.2': + optional: true + '@esbuild/linux-ia32@0.25.10': optional: true + '@esbuild/linux-ia32@0.27.2': + optional: true + '@esbuild/linux-loong64@0.25.10': optional: true + '@esbuild/linux-loong64@0.27.2': + optional: true + '@esbuild/linux-mips64el@0.25.10': optional: true + '@esbuild/linux-mips64el@0.27.2': + optional: true + '@esbuild/linux-ppc64@0.25.10': optional: true + '@esbuild/linux-ppc64@0.27.2': + optional: true + '@esbuild/linux-riscv64@0.25.10': optional: true + '@esbuild/linux-riscv64@0.27.2': + optional: true + '@esbuild/linux-s390x@0.25.10': optional: true + '@esbuild/linux-s390x@0.27.2': + optional: true + '@esbuild/linux-x64@0.25.10': optional: true + '@esbuild/linux-x64@0.27.2': + optional: true + '@esbuild/netbsd-arm64@0.25.10': optional: true + '@esbuild/netbsd-arm64@0.27.2': + optional: true + '@esbuild/netbsd-x64@0.25.10': optional: true + '@esbuild/netbsd-x64@0.27.2': + optional: true + '@esbuild/openbsd-arm64@0.25.10': optional: true + '@esbuild/openbsd-arm64@0.27.2': + optional: true + '@esbuild/openbsd-x64@0.25.10': optional: true + '@esbuild/openbsd-x64@0.27.2': + optional: true + '@esbuild/openharmony-arm64@0.25.10': optional: true + '@esbuild/openharmony-arm64@0.27.2': + optional: true + '@esbuild/sunos-x64@0.25.10': optional: true + '@esbuild/sunos-x64@0.27.2': + optional: true + '@esbuild/win32-arm64@0.25.10': optional: true + '@esbuild/win32-arm64@0.27.2': + optional: true + '@esbuild/win32-ia32@0.25.10': optional: true + '@esbuild/win32-ia32@0.27.2': + optional: true + '@esbuild/win32-x64@0.25.10': optional: true + '@esbuild/win32-x64@0.27.2': + optional: true + + '@eslint-community/eslint-utils@4.9.0(eslint@9.39.2(jiti@2.6.1))': + dependencies: + eslint: 9.39.2(jiti@2.6.1) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.1': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.3': + dependencies: + ajv: 6.12.6 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.2': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + '@fastify/accept-negotiator@2.0.1': {} '@fastify/ajv-compiler@4.0.2': @@ -1241,6 +3453,23 @@ snapshots: fastq: 1.19.1 glob: 11.0.3 + '@floating-ui/core@1.7.3': + dependencies: + '@floating-ui/utils': 0.2.10 + + '@floating-ui/dom@1.7.4': + dependencies: + '@floating-ui/core': 1.7.3 + '@floating-ui/utils': 0.2.10 + + '@floating-ui/react-dom@2.1.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@floating-ui/dom': 1.7.4 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@floating-ui/utils@0.2.10': {} + '@google/genai@1.24.0': dependencies: google-auth-library: 9.15.1 @@ -1251,6 +3480,17 @@ snapshots: - supports-color - utf-8-validate + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + '@inquirer/checkbox@2.5.0': dependencies: '@inquirer/core': 9.2.1 @@ -1366,8 +3606,43 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + '@lukeed/ms@2.0.2': {} + '@monaco-editor/loader@1.7.0': + dependencies: + state-local: 1.0.7 + + '@monaco-editor/react@4.7.0(monaco-editor@0.55.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@monaco-editor/loader': 1.7.0 + monaco-editor: 0.55.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + '@musistudio/llms@1.0.51(ws@8.18.3)': dependencies: '@anthropic-ai/sdk': 0.54.0 @@ -1402,6 +3677,524 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 + '@radix-ui/primitive@1.1.3': {} + + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.7)(react@19.2.3)': + dependencies: + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.7 + + '@radix-ui/react-context@1.1.2(@types/react@19.2.7)(react@19.2.3)': + dependencies: + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.7 + + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3) + aria-hidden: 1.2.6 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + react-remove-scroll: 2.7.2(@types/react@19.2.7)(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/react-direction@1.1.1(@types/react@19.2.7)(react@19.2.3)': + dependencies: + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.7 + + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.7)(react@19.2.3)': + dependencies: + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.7 + + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/react-id@1.1.1(@types/react@19.2.7)(react@19.2.3)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.7 + + '@radix-ui/react-label@2.1.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3) + aria-hidden: 1.2.6 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + react-remove-scroll: 2.7.2(@types/react@19.2.7)(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@floating-ui/react-dom': 2.1.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/rect': 1.1.1 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/react-primitive@2.1.4(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/react-slot': 1.2.4(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/react-slot@1.2.3(@types/react@19.2.7)(react@19.2.3)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.7 + + '@radix-ui/react-slot@1.2.4(@types/react@19.2.7)(react@19.2.3)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.7 + + '@radix-ui/react-switch@1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.7)(react@19.2.3)': + dependencies: + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.7 + + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.7)(react@19.2.3)': + dependencies: + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.7 + + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.7)(react@19.2.3)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.7 + + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.7)(react@19.2.3)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.7 + + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.7)(react@19.2.3)': + dependencies: + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.7 + + '@radix-ui/react-use-previous@1.1.1(@types/react@19.2.7)(react@19.2.3)': + dependencies: + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.7 + + '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.7)(react@19.2.3)': + dependencies: + '@radix-ui/rect': 1.1.1 + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.7 + + '@radix-ui/react-use-size@1.1.1(@types/react@19.2.7)(react@19.2.3)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3) + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.7 + + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + + '@radix-ui/rect@1.1.1': {} + + '@react-dnd/asap@5.0.2': {} + + '@react-dnd/invariant@4.0.2': {} + + '@react-dnd/shallowequal@4.0.2': {} + + '@rolldown/pluginutils@1.0.0-beta.27': {} + + '@rollup/rollup-android-arm-eabi@4.54.0': + optional: true + + '@rollup/rollup-android-arm64@4.54.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.54.0': + optional: true + + '@rollup/rollup-darwin-x64@4.54.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.54.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.54.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.54.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.54.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.54.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.54.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.54.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.54.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.54.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.54.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.54.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.54.0': + optional: true + + '@tailwindcss/node@4.1.18': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.18.4 + jiti: 2.6.1 + lightningcss: 1.30.2 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.1.18 + + '@tailwindcss/oxide-android-arm64@4.1.18': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.1.18': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.1.18': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.1.18': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.1.18': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.18': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.1.18': + optional: true + + '@tailwindcss/oxide@4.1.18': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.1.18 + '@tailwindcss/oxide-darwin-arm64': 4.1.18 + '@tailwindcss/oxide-darwin-x64': 4.1.18 + '@tailwindcss/oxide-freebsd-x64': 4.1.18 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.18 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.18 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.18 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.18 + '@tailwindcss/oxide-linux-x64-musl': 4.1.18 + '@tailwindcss/oxide-wasm32-wasi': 4.1.18 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.18 + + '@tailwindcss/postcss@4.1.18': + dependencies: + '@alloc/quick-lru': 5.2.0 + '@tailwindcss/node': 4.1.18 + '@tailwindcss/oxide': 4.1.18 + postcss: 8.5.6 + tailwindcss: 4.1.18 + + '@tailwindcss/vite@4.1.18(vite@7.3.0(@types/node@24.7.0)(jiti@2.6.1)(lightningcss@1.30.2))': + dependencies: + '@tailwindcss/node': 4.1.18 + '@tailwindcss/oxide': 4.1.18 + tailwindcss: 4.1.18 + vite: 7.3.0(@types/node@24.7.0)(jiti@2.6.1)(lightningcss@1.30.2) + + '@tsconfig/node10@1.0.12': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.28.5 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.28.5 + + '@types/estree@1.0.8': {} + + '@types/json-schema@7.0.15': {} + '@types/mute-stream@0.0.4': dependencies: '@types/node': 24.7.0 @@ -1414,16 +4207,147 @@ snapshots: dependencies: undici-types: 7.14.0 + '@types/react-dom@19.2.3(@types/react@19.2.7)': + dependencies: + '@types/react': 19.2.7 + + '@types/react@19.2.7': + dependencies: + csstype: 3.2.3 + + '@types/trusted-types@2.0.7': + optional: true + '@types/wrap-ansi@3.0.0': {} + '@typescript-eslint/eslint-plugin@8.50.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.8.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.50.1 + '@typescript-eslint/type-utils': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.8.3) + '@typescript-eslint/utils': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.50.1 + eslint: 9.39.2(jiti@2.6.1) + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.50.1 + '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.50.1 + debug: 4.4.3 + eslint: 9.39.2(jiti@2.6.1) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.50.1(typescript@5.8.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.50.1(typescript@5.8.3) + '@typescript-eslint/types': 8.50.1 + debug: 4.4.3 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.50.1': + dependencies: + '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/visitor-keys': 8.50.1 + + '@typescript-eslint/tsconfig-utils@8.50.1(typescript@5.8.3)': + dependencies: + typescript: 5.8.3 + + '@typescript-eslint/type-utils@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.8.3) + '@typescript-eslint/utils': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.8.3) + debug: 4.4.3 + eslint: 9.39.2(jiti@2.6.1) + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.50.1': {} + + '@typescript-eslint/typescript-estree@8.50.1(typescript@5.8.3)': + dependencies: + '@typescript-eslint/project-service': 8.50.1(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.50.1(typescript@5.8.3) + '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/visitor-keys': 8.50.1 + debug: 4.4.3 + minimatch: 9.0.5 + semver: 7.7.2 + tinyglobby: 0.2.15 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.8.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.50.1 + '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.8.3) + eslint: 9.39.2(jiti@2.6.1) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.50.1': + dependencies: + '@typescript-eslint/types': 8.50.1 + eslint-visitor-keys: 4.2.1 + + '@vitejs/plugin-react@4.7.0(vite@7.3.0(@types/node@24.7.0)(jiti@2.6.1)(lightningcss@1.30.2))': + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5) + '@rolldown/pluginutils': 1.0.0-beta.27 + '@types/babel__core': 7.20.5 + react-refresh: 0.17.0 + vite: 7.3.0(@types/node@24.7.0)(jiti@2.6.1)(lightningcss@1.30.2) + transitivePeerDependencies: + - supports-color + abstract-logging@2.0.1: {} + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn-walk@8.3.4: + dependencies: + acorn: 8.15.0 + + acorn@8.15.0: {} + agent-base@7.1.4: {} ajv-formats@3.0.1(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 @@ -1445,23 +4369,65 @@ snapshots: ansi-styles@6.2.3: {} + arg@4.1.3: {} + + argparse@2.0.1: {} + + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + atomic-sleep@1.0.0: {} + autoprefixer@10.4.23(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + caniuse-lite: 1.0.30001761 + fraction.js: 5.3.4 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + avvio@9.1.0: dependencies: '@fastify/error': 4.2.0 fastq: 1.19.1 + balanced-match@1.0.2: {} + base64-js@1.5.1: {} + baseline-browser-mapping@2.9.11: {} + bignumber.js@9.3.1: {} + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + braces@3.0.3: dependencies: fill-range: 7.1.1 + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.9.11 + caniuse-lite: 1.0.30001761 + electron-to-chromium: 1.5.267 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + buffer-equal-constant-time@1.0.1: {} + callsites@3.1.0: {} + + caniuse-lite@1.0.30001761: {} + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -1469,8 +4435,26 @@ snapshots: chardet@0.7.0: {} + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + cli-width@4.1.0: {} + clsx@2.1.1: {} + + cmdk@1.1.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3) + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -1479,12 +4463,18 @@ snapshots: commander@12.1.0: {} + concat-map@0.0.1: {} + content-disposition@0.5.4: dependencies: safe-buffer: 5.2.1 + convert-source-map@2.0.0: {} + cookie@1.0.2: {} + create-require@1.1.1: {} + cross-spawn@6.0.6: dependencies: nice-try: 1.0.5 @@ -1499,16 +4489,36 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + csstype@3.2.3: {} + data-uri-to-buffer@4.0.1: {} debug@4.4.3: dependencies: ms: 2.1.3 + deep-is@0.1.4: {} + depd@2.0.0: {} dequal@2.0.3: {} + detect-libc@2.1.2: {} + + detect-node-es@1.1.0: {} + + diff@4.0.2: {} + + dnd-core@16.0.1: + dependencies: + '@react-dnd/asap': 5.0.2 + '@react-dnd/invariant': 4.0.2 + redux: 4.2.1 + + dompurify@3.2.7: + optionalDependencies: + '@types/trusted-types': 2.0.7 + dotenv@16.6.1: {} eastasianwidth@0.2.0: {} @@ -1517,6 +4527,8 @@ snapshots: dependencies: safe-buffer: 5.2.1 + electron-to-chromium@1.5.267: {} + emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -1525,6 +4537,11 @@ snapshots: dependencies: once: 1.4.0 + enhanced-resolve@5.18.4: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + esbuild@0.25.10: optionalDependencies: '@esbuild/aix-ppc64': 0.25.10 @@ -1554,8 +4571,117 @@ snapshots: '@esbuild/win32-ia32': 0.25.10 '@esbuild/win32-x64': 0.25.10 + esbuild@0.27.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.2 + '@esbuild/android-arm': 0.27.2 + '@esbuild/android-arm64': 0.27.2 + '@esbuild/android-x64': 0.27.2 + '@esbuild/darwin-arm64': 0.27.2 + '@esbuild/darwin-x64': 0.27.2 + '@esbuild/freebsd-arm64': 0.27.2 + '@esbuild/freebsd-x64': 0.27.2 + '@esbuild/linux-arm': 0.27.2 + '@esbuild/linux-arm64': 0.27.2 + '@esbuild/linux-ia32': 0.27.2 + '@esbuild/linux-loong64': 0.27.2 + '@esbuild/linux-mips64el': 0.27.2 + '@esbuild/linux-ppc64': 0.27.2 + '@esbuild/linux-riscv64': 0.27.2 + '@esbuild/linux-s390x': 0.27.2 + '@esbuild/linux-x64': 0.27.2 + '@esbuild/netbsd-arm64': 0.27.2 + '@esbuild/netbsd-x64': 0.27.2 + '@esbuild/openbsd-arm64': 0.27.2 + '@esbuild/openbsd-x64': 0.27.2 + '@esbuild/openharmony-arm64': 0.27.2 + '@esbuild/sunos-x64': 0.27.2 + '@esbuild/win32-arm64': 0.27.2 + '@esbuild/win32-ia32': 0.27.2 + '@esbuild/win32-x64': 0.27.2 + + escalade@3.2.0: {} + escape-html@1.0.3: {} + escape-string-regexp@4.0.0: {} + + eslint-plugin-react-hooks@5.2.0(eslint@9.39.2(jiti@2.6.1)): + dependencies: + eslint: 9.39.2(jiti@2.6.1) + + eslint-plugin-react-refresh@0.4.26(eslint@9.39.2(jiti@2.6.1)): + dependencies: + eslint: 9.39.2(jiti@2.6.1) + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint@9.39.2(jiti@2.6.1): + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@2.6.1)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.1 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.3 + '@eslint/js': 9.39.2 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.6.1 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + execa@1.0.0: dependencies: cross-spawn: 6.0.6 @@ -1586,6 +4712,8 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 + fast-json-stable-stringify@2.1.0: {} + fast-json-stringify@6.1.1: dependencies: '@fastify/merge-json-schemas': 0.2.1 @@ -1595,6 +4723,8 @@ snapshots: json-schema-ref-resolver: 3.0.0 rfdc: 1.4.1 + fast-levenshtein@2.0.6: {} + fast-querystring@1.1.2: dependencies: fast-decode-uri-component: 1.0.1 @@ -1625,11 +4755,19 @@ snapshots: dependencies: reusify: 1.1.0 + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + fetch-blob@3.2.0: dependencies: node-domexception: 1.0.0 web-streams-polyfill: 3.3.3 + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -1646,6 +4784,18 @@ snapshots: commander: 12.1.0 loglevel: 1.9.2 + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 @@ -1655,6 +4805,11 @@ snapshots: dependencies: fetch-blob: 3.2.0 + fraction.js@5.3.4: {} + + fsevents@2.3.3: + optional: true + function-bind@1.1.2: {} gaxios@6.7.1: @@ -1693,6 +4848,10 @@ snapshots: transitivePeerDependencies: - supports-color + gensync@1.0.0-beta.2: {} + + get-nonce@1.0.1: {} + get-stream@4.1.0: dependencies: pump: 3.0.3 @@ -1701,6 +4860,10 @@ snapshots: dependencies: is-glob: 4.0.3 + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + glob@11.0.3: dependencies: foreground-child: 3.3.1 @@ -1710,6 +4873,10 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 2.0.0 + globals@14.0.0: {} + + globals@16.5.0: {} + google-auth-library@10.4.0: dependencies: base64-js: 1.5.1 @@ -1738,6 +4905,8 @@ snapshots: google-logging-utils@1.1.1: {} + graceful-fs@4.2.11: {} + gtoken@7.1.0: dependencies: gaxios: 6.7.1 @@ -1759,6 +4928,14 @@ snapshots: dependencies: function-bind: 1.1.2 + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + + html-parse-stringify@3.0.1: + dependencies: + void-elements: 3.1.0 + http-errors@2.0.0: dependencies: depd: 2.0.0 @@ -1774,10 +4951,31 @@ snapshots: transitivePeerDependencies: - supports-color + i18next-browser-languagedetector@8.2.0: + dependencies: + '@babel/runtime': 7.28.4 + + i18next@25.7.3(typescript@5.8.3): + dependencies: + '@babel/runtime': 7.28.4 + optionalDependencies: + typescript: 5.8.3 + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + inherits@2.0.4: {} interpret@1.4.0: {} @@ -1808,16 +5006,32 @@ snapshots: dependencies: '@isaacs/cliui': 8.0.2 + jiti@2.6.1: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + json-bigint@1.0.0: dependencies: bignumber.js: 9.3.1 + json-buffer@3.0.1: {} + json-schema-ref-resolver@3.0.0: dependencies: dequal: 2.0.3 + json-schema-traverse@0.4.1: {} + json-schema-traverse@1.0.0: {} + json-stable-stringify-without-jsonify@1.0.1: {} + json5@2.2.3: {} jsonrepair@3.13.1: {} @@ -1833,16 +5047,96 @@ snapshots: jwa: 2.0.1 safe-buffer: 5.2.1 + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + light-my-request@6.6.0: dependencies: cookie: 1.0.2 process-warning: 4.0.1 set-cookie-parser: 2.7.1 + lightningcss-android-arm64@1.30.2: + optional: true + + lightningcss-darwin-arm64@1.30.2: + optional: true + + lightningcss-darwin-x64@1.30.2: + optional: true + + lightningcss-freebsd-x64@1.30.2: + optional: true + + lightningcss-linux-arm-gnueabihf@1.30.2: + optional: true + + lightningcss-linux-arm64-gnu@1.30.2: + optional: true + + lightningcss-linux-arm64-musl@1.30.2: + optional: true + + lightningcss-linux-x64-gnu@1.30.2: + optional: true + + lightningcss-linux-x64-musl@1.30.2: + optional: true + + lightningcss-win32-arm64-msvc@1.30.2: + optional: true + + lightningcss-win32-x64-msvc@1.30.2: + optional: true + + lightningcss@1.30.2: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.30.2 + lightningcss-darwin-arm64: 1.30.2 + lightningcss-darwin-x64: 1.30.2 + lightningcss-freebsd-x64: 1.30.2 + lightningcss-linux-arm-gnueabihf: 1.30.2 + lightningcss-linux-arm64-gnu: 1.30.2 + lightningcss-linux-arm64-musl: 1.30.2 + lightningcss-linux-x64-gnu: 1.30.2 + lightningcss-linux-x64-musl: 1.30.2 + lightningcss-win32-arm64-msvc: 1.30.2 + lightningcss-win32-x64-msvc: 1.30.2 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + loglevel@1.9.2: {} lru-cache@11.2.2: {} + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lucide-react@0.525.0(react@19.2.3): + dependencies: + react: 19.2.3 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + make-error@1.3.6: {} + + marked@14.0.0: {} + merge2@1.4.1: {} micromatch@4.0.8: @@ -1856,14 +5150,31 @@ snapshots: dependencies: '@isaacs/brace-expansion': 5.0.0 + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.2 + minimist@1.2.8: {} minipass@7.1.2: {} + monaco-editor@0.55.1: + dependencies: + dompurify: 3.2.7 + marked: 14.0.0 + ms@2.1.3: {} mute-stream@1.0.0: {} + nanoid@3.3.11: {} + + natural-compare@1.4.0: {} + nice-try@1.0.5: {} node-domexception@1.0.0: {} @@ -1878,6 +5189,8 @@ snapshots: fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 + node-releases@2.0.27: {} + npm-run-path@2.0.2: dependencies: path-key: 2.0.1 @@ -1894,12 +5207,35 @@ snapshots: openurl@1.1.1: {} + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + os-tmpdir@1.0.2: {} p-finally@1.0.0: {} + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + package-json-from-dist@1.0.1: {} + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + path-key@2.0.1: {} path-key@3.1.1: {} @@ -1911,8 +5247,12 @@ snapshots: lru-cache: 11.2.2 minipass: 7.1.2 + picocolors@1.1.1: {} + picomatch@2.3.1: {} + picomatch@4.0.3: {} + pino-abstract-transport@2.0.0: dependencies: split2: 4.2.0 @@ -1933,6 +5273,16 @@ snapshots: sonic-boom: 4.2.0 thread-stream: 3.1.0 + postcss-value-parser@4.2.0: {} + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + process-warning@4.0.1: {} process-warning@5.0.0: {} @@ -1942,18 +5292,109 @@ snapshots: end-of-stream: 1.4.5 once: 1.4.0 + punycode@2.3.1: {} + queue-microtask@1.2.3: {} quick-format-unescaped@4.0.4: {} + react-colorful@5.6.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + react-dnd-html5-backend@16.0.1: + dependencies: + dnd-core: 16.0.1 + + react-dnd@16.0.1(@types/node@24.7.0)(@types/react@19.2.7)(react@19.2.3): + dependencies: + '@react-dnd/invariant': 4.0.2 + '@react-dnd/shallowequal': 4.0.2 + dnd-core: 16.0.1 + fast-deep-equal: 3.1.3 + hoist-non-react-statics: 3.3.2 + react: 19.2.3 + optionalDependencies: + '@types/node': 24.7.0 + '@types/react': 19.2.7 + + react-dom@19.2.3(react@19.2.3): + dependencies: + react: 19.2.3 + scheduler: 0.27.0 + + react-i18next@15.7.4(i18next@25.7.3(typescript@5.8.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.8.3): + dependencies: + '@babel/runtime': 7.28.4 + html-parse-stringify: 3.0.1 + i18next: 25.7.3(typescript@5.8.3) + react: 19.2.3 + optionalDependencies: + react-dom: 19.2.3(react@19.2.3) + typescript: 5.8.3 + + react-is@16.13.1: {} + + react-refresh@0.17.0: {} + + react-remove-scroll-bar@2.3.8(@types/react@19.2.7)(react@19.2.3): + dependencies: + react: 19.2.3 + react-style-singleton: 2.2.3(@types/react@19.2.7)(react@19.2.3) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.7 + + react-remove-scroll@2.7.2(@types/react@19.2.7)(react@19.2.3): + dependencies: + react: 19.2.3 + react-remove-scroll-bar: 2.3.8(@types/react@19.2.7)(react@19.2.3) + react-style-singleton: 2.2.3(@types/react@19.2.7)(react@19.2.3) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@19.2.7)(react@19.2.3) + use-sidecar: 1.1.3(@types/react@19.2.7)(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.7 + + react-router-dom@7.11.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + react-router: 7.11.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + + react-router@7.11.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + cookie: 1.0.2 + react: 19.2.3 + set-cookie-parser: 2.7.1 + optionalDependencies: + react-dom: 19.2.3(react@19.2.3) + + react-style-singleton@2.2.3(@types/react@19.2.7)(react@19.2.3): + dependencies: + get-nonce: 1.0.1 + react: 19.2.3 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.7 + + react@19.2.3: {} + real-require@0.2.0: {} rechoir@0.6.2: dependencies: resolve: 1.22.10 + redux@4.2.1: + dependencies: + '@babel/runtime': 7.28.4 + require-from-string@2.0.2: {} + resolve-from@4.0.0: {} + resolve@1.22.10: dependencies: is-core-module: 2.16.1 @@ -1966,6 +5407,34 @@ snapshots: rfdc@1.4.1: {} + rollup@4.54.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.54.0 + '@rollup/rollup-android-arm64': 4.54.0 + '@rollup/rollup-darwin-arm64': 4.54.0 + '@rollup/rollup-darwin-x64': 4.54.0 + '@rollup/rollup-freebsd-arm64': 4.54.0 + '@rollup/rollup-freebsd-x64': 4.54.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.54.0 + '@rollup/rollup-linux-arm-musleabihf': 4.54.0 + '@rollup/rollup-linux-arm64-gnu': 4.54.0 + '@rollup/rollup-linux-arm64-musl': 4.54.0 + '@rollup/rollup-linux-loong64-gnu': 4.54.0 + '@rollup/rollup-linux-ppc64-gnu': 4.54.0 + '@rollup/rollup-linux-riscv64-gnu': 4.54.0 + '@rollup/rollup-linux-riscv64-musl': 4.54.0 + '@rollup/rollup-linux-s390x-gnu': 4.54.0 + '@rollup/rollup-linux-x64-gnu': 4.54.0 + '@rollup/rollup-linux-x64-musl': 4.54.0 + '@rollup/rollup-openharmony-arm64': 4.54.0 + '@rollup/rollup-win32-arm64-msvc': 4.54.0 + '@rollup/rollup-win32-ia32-msvc': 4.54.0 + '@rollup/rollup-win32-x64-gnu': 4.54.0 + '@rollup/rollup-win32-x64-msvc': 4.54.0 + fsevents: 2.3.3 + rotating-file-stream@3.2.7: {} run-parallel@1.2.0: @@ -1982,10 +5451,14 @@ snapshots: safer-buffer@2.1.2: {} + scheduler@0.27.0: {} + secure-json-parse@4.1.0: {} semver@5.7.2: {} + semver@6.3.1: {} + semver@7.7.2: {} set-cookie-parser@2.7.1: {} @@ -2028,8 +5501,12 @@ snapshots: dependencies: atomic-sleep: 1.0.0 + source-map-js@1.2.1: {} + split2@4.2.0: {} + state-local@1.0.7: {} + statuses@2.0.1: {} string-width@4.2.3: @@ -2054,18 +5531,35 @@ snapshots: strip-eof@1.0.0: {} + strip-json-comments@3.1.1: {} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 supports-preserve-symlinks-flag@1.0.0: {} + tailwind-merge@3.4.0: {} + + tailwindcss-animate@1.0.7(tailwindcss@4.1.18): + dependencies: + tailwindcss: 4.1.18 + + tailwindcss@4.1.18: {} + + tapable@2.3.0: {} + thread-stream@3.1.0: dependencies: real-require: 0.2.0 tiktoken@1.0.22: {} + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 @@ -2080,8 +5574,51 @@ snapshots: tr46@0.0.3: {} + ts-api-utils@2.1.0(typescript@5.8.3): + dependencies: + typescript: 5.8.3 + + ts-node@10.9.2(@types/node@24.7.0)(typescript@5.8.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.12 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 24.7.0 + acorn: 8.15.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.8.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + tslib@2.8.1: {} + + tw-animate-css@1.4.0: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + type-fest@0.21.3: {} + typescript-eslint@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.8.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.50.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.8.3) + '@typescript-eslint/parser': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.8.3) + '@typescript-eslint/utils': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.8.3) + eslint: 9.39.2(jiti@2.6.1) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + typescript@5.8.3: {} + typescript@5.9.3: {} undici-types@6.21.0: {} @@ -2090,10 +5627,59 @@ snapshots: undici@7.16.0: {} + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + use-callback-ref@1.3.3(@types/react@19.2.7)(react@19.2.3): + dependencies: + react: 19.2.3 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.7 + + use-sidecar@1.1.3(@types/react@19.2.7)(react@19.2.3): + dependencies: + detect-node-es: 1.1.0 + react: 19.2.3 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.7 + uuid@11.1.0: {} uuid@9.0.1: {} + v8-compile-cache-lib@3.0.1: {} + + vite-plugin-singlefile@2.3.0(rollup@4.54.0)(vite@7.3.0(@types/node@24.7.0)(jiti@2.6.1)(lightningcss@1.30.2)): + dependencies: + micromatch: 4.0.8 + rollup: 4.54.0 + vite: 7.3.0(@types/node@24.7.0)(jiti@2.6.1)(lightningcss@1.30.2) + + vite@7.3.0(@types/node@24.7.0)(jiti@2.6.1)(lightningcss@1.30.2): + dependencies: + esbuild: 0.27.2 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.54.0 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.7.0 + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.30.2 + + void-elements@3.1.0: {} + web-streams-polyfill@3.3.3: {} webidl-conversions@3.0.1: {} @@ -2111,6 +5697,8 @@ snapshots: dependencies: isexe: 2.0.0 + word-wrap@1.2.5: {} + wrap-ansi@6.2.0: dependencies: ansi-styles: 4.3.0 @@ -2133,4 +5721,10 @@ snapshots: ws@8.18.3: {} + yallist@3.1.1: {} + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} + yoctocolors-cjs@2.1.3: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..18ec407 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - 'packages/*' diff --git a/scripts/build-cli.js b/scripts/build-cli.js new file mode 100644 index 0000000..a6c86f1 --- /dev/null +++ b/scripts/build-cli.js @@ -0,0 +1,90 @@ +#!/usr/bin/env node + +const { execSync } = require('child_process'); +const path = require('path'); +const fs = require('fs'); + +console.log('Building CLI package...'); + +try { + const rootDir = path.join(__dirname, '..'); + const sharedDir = path.join(rootDir, 'packages/shared'); + const cliDir = path.join(rootDir, 'packages/cli'); + const serverDir = path.join(rootDir, 'packages/server'); + const uiDir = path.join(rootDir, 'packages/ui'); + + // Step 0: Ensure shared package is built first + console.log('Ensuring shared package is built...'); + const sharedDistDir = path.join(sharedDir, 'dist'); + if (!fs.existsSync(sharedDistDir) || !fs.existsSync(path.join(sharedDistDir, 'index.js'))) { + console.log('Shared package not found, building it first...'); + execSync('node scripts/build-shared.js', { + stdio: 'inherit', + cwd: rootDir + }); + } + + // Step 1: Build Server package first + console.log('Building Server package...'); + execSync('node scripts/build-server.js', { + stdio: 'inherit', + cwd: rootDir + }); + + // Step 2: Build UI package + console.log('Building UI package...'); + execSync('pnpm build', { + stdio: 'inherit', + cwd: uiDir + }); + + // Step 3: Create CLI dist directory + const cliDistDir = path.join(cliDir, 'dist'); + if (!fs.existsSync(cliDistDir)) { + fs.mkdirSync(cliDistDir, { recursive: true }); + } + + // Step 4: Build the CLI application + console.log('Building CLI application...'); + execSync('esbuild src/cli.ts --bundle --platform=node --outfile=dist/cli.js', { + stdio: 'inherit', + cwd: cliDir + }); + + // Step 5: Copy tiktoken WASM file from server dist to CLI dist + console.log('Copying tiktoken_bg.wasm from server to CLI dist...'); + const tiktokenSource = path.join(serverDir, 'dist/tiktoken_bg.wasm'); + const tiktokenDest = path.join(cliDistDir, 'tiktoken_bg.wasm'); + + if (fs.existsSync(tiktokenSource)) { + fs.copyFileSync(tiktokenSource, tiktokenDest); + console.log('✓ tiktoken_bg.wasm copied successfully!'); + } else { + console.warn('⚠ Warning: tiktoken_bg.wasm not found in server dist, skipping...'); + } + + // Step 6: Copy UI index.html from UI dist to CLI dist + console.log('Copying index.html from UI to CLI dist...'); + const uiSource = path.join(uiDir, 'dist/index.html'); + const uiDest = path.join(cliDistDir, 'index.html'); + + if (fs.existsSync(uiSource)) { + fs.copyFileSync(uiSource, uiDest); + console.log('✓ index.html copied successfully!'); + } else { + console.warn('⚠ Warning: index.html not found in UI dist, skipping...'); + } + + console.log('CLI build completed successfully!'); + console.log('\nCLI dist contents:'); + const files = fs.readdirSync(cliDistDir); + files.forEach(file => { + const filePath = path.join(cliDistDir, file); + const stats = fs.statSync(filePath); + const size = (stats.size / 1024 / 1024).toFixed(2); + console.log(` - ${file} (${size} MB)`); + }); +} catch (error) { + console.error('CLI build failed:', error.message); + process.exit(1); +} diff --git a/scripts/build-server.js b/scripts/build-server.js new file mode 100644 index 0000000..0a4955b --- /dev/null +++ b/scripts/build-server.js @@ -0,0 +1,40 @@ +#!/usr/bin/env node + +const { execSync } = require('child_process'); +const path = require('path'); +const fs = require('fs'); + +console.log('Building Server package...'); + +try { + // Create dist directory + const distDir = path.join(__dirname, '../packages/server/dist'); + if (!fs.existsSync(distDir)) { + fs.mkdirSync(distDir, { recursive: true }); + } + + // Build the server application + console.log('Building server application...'); + // 使用 minify 和 tree-shaking 优化体积 + execSync('esbuild src/index.ts --bundle --platform=node --minify --tree-shaking=true --outfile=dist/index.js', { + stdio: 'inherit', + cwd: path.join(__dirname, '../packages/server') + }); + + // Copy the tiktoken WASM file + console.log('Copying tiktoken WASM file...'); + const tiktokenSource = path.join(__dirname, '../packages/server/node_modules/tiktoken/tiktoken_bg.wasm'); + const tiktokenDest = path.join(__dirname, '../packages/server/dist/tiktoken_bg.wasm'); + + if (fs.existsSync(tiktokenSource)) { + fs.copyFileSync(tiktokenSource, tiktokenDest); + console.log('Tiktoken WASM file copied successfully!'); + } else { + console.warn('Warning: tiktoken_bg.wasm not found, skipping...'); + } + + console.log('Server build completed successfully!'); +} catch (error) { + console.error('Server build failed:', error.message); + process.exit(1); +} diff --git a/scripts/build-shared.js b/scripts/build-shared.js new file mode 100644 index 0000000..643c9f1 --- /dev/null +++ b/scripts/build-shared.js @@ -0,0 +1,36 @@ +#!/usr/bin/env node + +const { execSync } = require('child_process'); +const path = require('path'); +const fs = require('fs'); + +console.log('Building Shared package...'); + +try { + const sharedDir = path.join(__dirname, '../packages/shared'); + + // Create dist directory + const distDir = path.join(sharedDir, 'dist'); + if (!fs.existsSync(distDir)) { + fs.mkdirSync(distDir, { recursive: true }); + } + + // Generate type declaration files + console.log('Generating type declaration files...'); + execSync('tsc --emitDeclarationOnly', { + stdio: 'inherit', + cwd: sharedDir + }); + + // Build the shared package + console.log('Building shared package...'); + execSync('esbuild src/index.ts --bundle --platform=node --minify --tree-shaking=true --outfile=dist/index.js', { + stdio: 'inherit', + cwd: sharedDir + }); + + console.log('Shared package build completed successfully!'); +} catch (error) { + console.error('Shared package build failed:', error.message); + process.exit(1); +} diff --git a/scripts/build.js b/scripts/build.js index 5786b9f..3b0446c 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -1,34 +1,24 @@ #!/usr/bin/env node const { execSync } = require('child_process'); -const path = require('path'); -const fs = require('fs'); -console.log('Building Claude Code Router...'); +console.log('Building Claude Code Router (Monorepo)...'); try { - // Build the main CLI application - console.log('Building CLI application...'); - execSync('esbuild src/cli.ts --bundle --platform=node --outfile=dist/cli.js', { stdio: 'inherit' }); - - // Copy the tiktoken WASM file - console.log('Copying tiktoken WASM file...'); - execSync('shx cp node_modules/tiktoken/tiktoken_bg.wasm dist/tiktoken_bg.wasm', { stdio: 'inherit' }); - - // Build the UI - console.log('Building UI...'); - // Check if node_modules exists in ui directory, if not install dependencies - if (!fs.existsSync('ui/node_modules')) { - console.log('Installing UI dependencies...'); - execSync('cd ui && npm install', { stdio: 'inherit' }); - } - execSync('cd ui && npm run build', { stdio: 'inherit' }); - - // Copy the built UI index.html to dist - console.log('Copying UI build artifacts...'); - execSync('shx cp ui/dist/index.html dist/index.html', { stdio: 'inherit' }); - - console.log('Build completed successfully!'); + // Build shared package first + console.log('Building shared package...'); + execSync('node scripts/build-shared.js', { stdio: 'inherit' }); + + // Build CLI package (which will also build server and ui) + console.log('Building CLI package (includes server and ui)...'); + execSync('node scripts/build-cli.js', { stdio: 'inherit' }); + + console.log('\n✅ Build completed successfully!'); + console.log('\nArtifacts are available in packages/*/dist:'); + console.log(' - packages/shared/dist/ (Shared package)'); + console.log(' - packages/cli/dist/ (CLI + UI + tiktoken)'); + console.log(' - packages/server/dist/ (Server standalone)'); + console.log(' - packages/ui/dist/ (UI standalone)'); } catch (error) { console.error('Build failed:', error.message); process.exit(1); diff --git a/src/utils/close.ts b/src/utils/close.ts deleted file mode 100644 index 27de6ab..0000000 --- a/src/utils/close.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { isServiceRunning, cleanupPidFile, getReferenceCount } from './processCheck'; -import { readFileSync } from 'fs'; -import { HOME_DIR } from '../constants'; -import { join } from 'path'; - -export async function closeService() { - const PID_FILE = join(HOME_DIR, '.claude-code-router.pid'); - const isRunning = await isServiceRunning() - - if (!isRunning) { - console.log("No service is currently running."); - return; - } - - if (getReferenceCount() > 0) { - return; - } - - try { - const pid = parseInt(readFileSync(PID_FILE, 'utf-8')); - process.kill(pid); - cleanupPidFile(); - console.log("claude code router service has been successfully stopped."); - } catch (e) { - console.log("Failed to stop the service. It may have already been stopped."); - cleanupPidFile(); - } -} diff --git a/src/utils/logCleanup.ts b/src/utils/logCleanup.ts deleted file mode 100644 index 1e21219..0000000 --- a/src/utils/logCleanup.ts +++ /dev/null @@ -1,44 +0,0 @@ -import fs from "node:fs/promises"; -import path from "node:path"; -import { HOME_DIR } from "../constants"; - -/** - * Cleans up old log files, keeping only the most recent ones - * @param maxFiles - Maximum number of log files to keep (default: 9) - */ -export async function cleanupLogFiles(maxFiles: number = 9): Promise { - try { - const logsDir = path.join(HOME_DIR, "logs"); - - // Check if logs directory exists - try { - await fs.access(logsDir); - } catch { - // Logs directory doesn't exist, nothing to clean up - return; - } - - // Read all files in the logs directory - const files = await fs.readdir(logsDir); - - // Filter for log files (files starting with 'ccr-' and ending with '.log') - const logFiles = files - .filter(file => file.startsWith('ccr-') && file.endsWith('.log')) - .sort() - .reverse(); // Sort in descending order (newest first) - - // Delete files exceeding the maxFiles limit - if (logFiles.length > maxFiles) { - for (let i = maxFiles; i < logFiles.length; i++) { - const filePath = path.join(logsDir, logFiles[i]); - try { - await fs.unlink(filePath); - } catch (error) { - console.warn(`Failed to delete log file ${filePath}:`, error); - } - } - } - } catch (error) { - console.warn("Failed to clean up log files:", error); - } -} diff --git a/src/utils/statusline.ts b/src/utils/statusline.ts deleted file mode 100644 index deb2f2a..0000000 --- a/src/utils/statusline.ts +++ /dev/null @@ -1,813 +0,0 @@ -import fs from "node:fs/promises"; -import { execSync } from "child_process"; -import path from "node:path"; -import { CONFIG_FILE, HOME_DIR } from "../constants"; -import JSON5 from "json5"; - -export interface StatusLineModuleConfig { - type: string; - icon?: string; - text: string; - color?: string; - background?: string; - scriptPath?: string; // 用于script类型的模块,指定要执行的Node.js脚本文件路径 -} - -export interface StatusLineThemeConfig { - modules: StatusLineModuleConfig[]; -} - -export interface StatusLineInput { - hook_event_name: string; - session_id: string; - transcript_path: string; - cwd: string; - model: { - id: string; - display_name: string; - }; - workspace: { - current_dir: string; - project_dir: string; - }; -} - -export interface AssistantMessage { - type: "assistant"; - message: { - model: string; - usage: { - input_tokens: number; - output_tokens: number; - }; - }; -} - -// ANSIColor代码 -const COLORS: Record = { - reset: "\x1b[0m", - bold: "\x1b[1m", - dim: "\x1b[2m", - // 标准颜色 - black: "\x1b[30m", - red: "\x1b[31m", - green: "\x1b[32m", - yellow: "\x1b[33m", - blue: "\x1b[34m", - magenta: "\x1b[35m", - cyan: "\x1b[36m", - white: "\x1b[37m", - // 亮色 - bright_black: "\x1b[90m", - bright_red: "\x1b[91m", - bright_green: "\x1b[92m", - bright_yellow: "\x1b[93m", - bright_blue: "\x1b[94m", - bright_magenta: "\x1b[95m", - bright_cyan: "\x1b[96m", - bright_white: "\x1b[97m", - // 背景颜色 - bg_black: "\x1b[40m", - bg_red: "\x1b[41m", - bg_green: "\x1b[42m", - bg_yellow: "\x1b[43m", - bg_blue: "\x1b[44m", - bg_magenta: "\x1b[45m", - bg_cyan: "\x1b[46m", - bg_white: "\x1b[47m", - // 亮背景色 - bg_bright_black: "\x1b[100m", - bg_bright_red: "\x1b[101m", - bg_bright_green: "\x1b[102m", - bg_bright_yellow: "\x1b[103m", - bg_bright_blue: "\x1b[104m", - bg_bright_magenta: "\x1b[105m", - bg_bright_cyan: "\x1b[106m", - bg_bright_white: "\x1b[107m", -}; - -// 使用TrueColor(24位色)支持十六进制颜色 -const TRUE_COLOR_PREFIX = "\x1b[38;2;"; -const TRUE_COLOR_BG_PREFIX = "\x1b[48;2;"; - -// 将十六进制颜色转为RGB格式 -function hexToRgb(hex: string): { r: number; g: number; b: number } | null { - // 移除#和空格 - hex = hex.replace(/^#/, '').trim(); - - // 处理简写形式 (#RGB -> #RRGGBB) - if (hex.length === 3) { - hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; - } - - if (hex.length !== 6) { - return null; - } - - const r = parseInt(hex.substring(0, 2), 16); - const g = parseInt(hex.substring(2, 4), 16); - const b = parseInt(hex.substring(4, 6), 16); - - // 验证RGB值是否有效 - if (isNaN(r) || isNaN(g) || isNaN(b) || r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) { - return null; - } - - return { r, g, b }; -} - -// 获取颜色代码 -function getColorCode(colorName: string): string { - // 检查是否是十六进制颜色 - if (colorName.startsWith('#') || /^[0-9a-fA-F]{6}$/.test(colorName) || /^[0-9a-fA-F]{3}$/.test(colorName)) { - const rgb = hexToRgb(colorName); - if (rgb) { - return `${TRUE_COLOR_PREFIX}${rgb.r};${rgb.g};${rgb.b}m`; - } - } - - // 默认返回空字符串 - return ""; -} - - -// 变量替换函数,支持{{var}}格式的变量替换 -function replaceVariables(text: string, variables: Record): string { - return text.replace(/\{\{(\w+)\}\}/g, (_match, varName) => { - return variables[varName] || ""; - }); -} - -// 执行脚本并获取输出 -async function executeScript(scriptPath: string, variables: Record): Promise { - try { - // 检查文件是否存在 - await fs.access(scriptPath); - - // 使用require动态加载脚本模块 - const scriptModule = require(scriptPath); - - // 如果导出的是函数,则调用它并传入变量 - if (typeof scriptModule === 'function') { - const result = scriptModule(variables); - // 如果返回的是Promise,则等待它完成 - if (result instanceof Promise) { - return await result; - } - return result; - } - - // 如果导出的是default函数,则调用它 - if (scriptModule.default && typeof scriptModule.default === 'function') { - const result = scriptModule.default(variables); - // 如果返回的是Promise,则等待它完成 - if (result instanceof Promise) { - return await result; - } - return result; - } - - // 如果导出的是字符串,则直接返回 - if (typeof scriptModule === 'string') { - return scriptModule; - } - - // 如果导出的是default字符串,则返回它 - if (scriptModule.default && typeof scriptModule.default === 'string') { - return scriptModule.default; - } - - // 默认情况下返回空字符串 - return ""; - } catch (error) { - console.error(`执行脚本 ${scriptPath} 时出错:`, error); - return ""; - } -} - -// 默认主题配置 - 使用Nerd Fonts图标和美观配色 -const DEFAULT_THEME: StatusLineThemeConfig = { - modules: [ - { - type: "workDir", - icon: "󰉋", // nf-md-folder_outline - text: "{{workDirName}}", - color: "bright_blue" - }, - { - type: "gitBranch", - icon: "", // nf-dev-git_branch - text: "{{gitBranch}}", - color: "bright_magenta" - }, - { - type: "model", - icon: "󰚩", // nf-md-robot_outline - text: "{{model}}", - color: "bright_cyan" - }, - { - type: "usage", - icon: "↑", // 上箭头 - text: "{{inputTokens}}", - color: "bright_green" - }, - { - type: "usage", - icon: "↓", // 下箭头 - text: "{{outputTokens}}", - color: "bright_yellow" - } - ] -}; - -// Powerline风格主题配置 -const POWERLINE_THEME: StatusLineThemeConfig = { - modules: [ - { - type: "workDir", - icon: "󰉋", // nf-md-folder_outline - text: "{{workDirName}}", - color: "white", - background: "bg_bright_blue" - }, - { - type: "gitBranch", - icon: "", // nf-dev-git_branch - text: "{{gitBranch}}", - color: "white", - background: "bg_bright_magenta" - }, - { - type: "model", - icon: "󰚩", // nf-md-robot_outline - text: "{{model}}", - color: "white", - background: "bg_bright_cyan" - }, - { - type: "usage", - icon: "↑", // 上箭头 - text: "{{inputTokens}}", - color: "white", - background: "bg_bright_green" - }, - { - type: "usage", - icon: "↓", // 下箭头 - text: "{{outputTokens}}", - color: "white", - background: "bg_bright_yellow" - } - ] -}; - -// 简单文本主题配置 - 用于图标无法显示时的fallback -const SIMPLE_THEME: StatusLineThemeConfig = { - modules: [ - { - type: "workDir", - icon: "", - text: "{{workDirName}}", - color: "bright_blue" - }, - { - type: "gitBranch", - icon: "", - text: "{{gitBranch}}", - color: "bright_magenta" - }, - { - type: "model", - icon: "", - text: "{{model}}", - color: "bright_cyan" - }, - { - type: "usage", - icon: "↑", - text: "{{inputTokens}}", - color: "bright_green" - }, - { - type: "usage", - icon: "↓", - text: "{{outputTokens}}", - color: "bright_yellow" - } - ] -}; - -// 格式化usage信息,如果大于1000则使用k单位 -function formatUsage(input_tokens: number, output_tokens: number): string { - if (input_tokens > 1000 || output_tokens > 1000) { - const inputFormatted = input_tokens > 1000 ? `${(input_tokens / 1000).toFixed(1)}k` : `${input_tokens}`; - const outputFormatted = output_tokens > 1000 ? `${(output_tokens / 1000).toFixed(1)}k` : `${output_tokens}`; - return `${inputFormatted} ${outputFormatted}`; - } - return `${input_tokens} ${output_tokens}`; -} - -// 读取用户主目录的主题配置 -async function getProjectThemeConfig(): Promise<{ theme: StatusLineThemeConfig | null, style: string }> { - try { - // 只使用主目录的固定配置文件 - const configPath = CONFIG_FILE; - - // 检查配置文件是否存在 - try { - await fs.access(configPath); - } catch { - return { theme: null, style: 'default' }; - } - - const configContent = await fs.readFile(configPath, "utf-8"); - const config = JSON5.parse(configContent); - - // 检查是否有StatusLine配置 - if (config.StatusLine) { - // 获取当前使用的风格,默认为default - const currentStyle = config.StatusLine.currentStyle || 'default'; - - // 检查是否有对应风格的配置 - if (config.StatusLine[currentStyle] && config.StatusLine[currentStyle].modules) { - return { theme: config.StatusLine[currentStyle], style: currentStyle }; - } - } - } catch (error) { - // 如果读取失败,返回null - // console.error("Failed to read theme config:", error); - } - - return { theme: null, style: 'default' }; -} - -// 检查是否应该使用简单主题(fallback方案) -// 当环境变量 USE_SIMPLE_ICONS 被设置时,或者当检测到可能不支持Nerd Fonts的终端时 -function shouldUseSimpleTheme(): boolean { - // 检查环境变量 - if (process.env.USE_SIMPLE_ICONS === 'true') { - return true; - } - - // 检查终端类型(一些常见的不支持复杂图标的终端) - const term = process.env.TERM || ''; - const unsupportedTerms = ['dumb', 'unknown']; - if (unsupportedTerms.includes(term)) { - return true; - } - - // 默认情况下,假设终端支持Nerd Fonts - return false; -} - -// 检查Nerd Fonts图标是否能正确显示 -// 通过检查终端字体信息或使用试探性方法 -function canDisplayNerdFonts(): boolean { - // 如果环境变量明确指定使用简单图标,则不能显示Nerd Fonts - if (process.env.USE_SIMPLE_ICONS === 'true') { - return false; - } - - // 检查一些常见的支持Nerd Fonts的终端环境变量 - const fontEnvVars = ['NERD_FONT', 'NERDFONT', 'FONT']; - for (const envVar of fontEnvVars) { - const value = process.env[envVar]; - if (value && (value.includes('Nerd') || value.includes('nerd'))) { - return true; - } - } - - // 检查终端类型 - const termProgram = process.env.TERM_PROGRAM || ''; - const supportedTerminals = ['iTerm.app', 'vscode', 'Hyper', 'kitty', 'alacritty']; - if (supportedTerminals.includes(termProgram)) { - return true; - } - - // 检查COLORTERM环境变量 - const colorTerm = process.env.COLORTERM || ''; - if (colorTerm.includes('truecolor') || colorTerm.includes('24bit')) { - return true; - } - - // 默认情况下,假设可以显示Nerd Fonts(但允许用户通过环境变量覆盖) - return process.env.USE_SIMPLE_ICONS !== 'true'; -} - -// 检查特定Unicode字符是否能正确显示 -// 这是一个简单的试探性检查 -function canDisplayUnicodeCharacter(char: string): boolean { - // 对于Nerd Fonts图标,我们假设支持UTF-8的终端可以显示 - // 但实际上很难准确检测,所以我们依赖环境变量和终端类型检测 - try { - // 检查终端是否支持UTF-8 - const lang = process.env.LANG || process.env.LC_ALL || process.env.LC_CTYPE || ''; - if (lang.includes('UTF-8') || lang.includes('utf8') || lang.includes('UTF8')) { - return true; - } - - // 检查LC_*环境变量 - const lcVars = ['LC_ALL', 'LC_CTYPE', 'LANG']; - for (const lcVar of lcVars) { - const value = process.env[lcVar]; - if (value && (value.includes('UTF-8') || value.includes('utf8'))) { - return true; - } - } - } catch (e) { - // 如果检查失败,默认返回true - return true; - } - - // 默认情况下,假设可以显示 - return true; -} - -export async function parseStatusLineData(input: StatusLineInput): Promise { - try { - // 检查是否应该使用简单主题 - const useSimpleTheme = shouldUseSimpleTheme(); - - // 检查是否可以显示Nerd Fonts图标 - const canDisplayNerd = canDisplayNerdFonts(); - - // 确定使用的主题:如果用户强制使用简单主题或无法显示Nerd Fonts,则使用简单主题 - const effectiveTheme = useSimpleTheme || !canDisplayNerd ? SIMPLE_THEME : DEFAULT_THEME; - - // 获取主目录的主题配置,如果没有则使用确定的默认配置 - const { theme: projectTheme, style: currentStyle } = await getProjectThemeConfig(); - const theme = projectTheme || effectiveTheme; - - // 获取当前工作目录和Git分支 - const workDir = input.workspace.current_dir; - let gitBranch = ""; - - try { - // 尝试获取Git分支名 - gitBranch = execSync("git branch --show-current", { - cwd: workDir, - stdio: ["pipe", "pipe", "ignore"], - }) - .toString() - .trim(); - } catch (error) { - // 如果不是Git仓库或获取失败,则忽略错误 - } - - // 从transcript_path文件中读取最后一条assistant消息 - const transcriptContent = await fs.readFile(input.transcript_path, "utf-8"); - const lines = transcriptContent.trim().split("\n"); - - // 反向遍历寻找最后一条assistant消息 - let model = ""; - let inputTokens = 0; - let outputTokens = 0; - - for (let i = lines.length - 1; i >= 0; i--) { - try { - const message: AssistantMessage = JSON.parse(lines[i]); - if (message.type === "assistant" && message.message.model) { - model = message.message.model; - - if (message.message.usage) { - inputTokens = message.message.usage.input_tokens; - outputTokens = message.message.usage.output_tokens; - } - break; - } - } catch (parseError) { - // 忽略解析错误,继续查找 - continue; - } - } - - // 如果没有从transcript中获取到模型名称,则尝试从配置文件中获取 - if (!model) { - try { - // 获取项目配置文件路径 - const projectConfigPath = path.join(workDir, ".claude-code-router", "config.json"); - let configPath = projectConfigPath; - - // 检查项目配置文件是否存在,如果不存在则使用用户主目录的配置文件 - try { - await fs.access(projectConfigPath); - } catch { - configPath = CONFIG_FILE; - } - - // 读取配置文件 - const configContent = await fs.readFile(configPath, "utf-8"); - const config = JSON5.parse(configContent); - - // 从Router字段的default内容中获取模型名称 - if (config.Router && config.Router.default) { - const [, defaultModel] = config.Router.default.split(","); - if (defaultModel) { - model = defaultModel.trim(); - } - } - } catch (configError) { - // 如果配置文件读取失败,则忽略错误 - } - } - - // 如果仍然没有获取到模型名称,则使用传入的JSON数据中的model字段的display_name - if (!model) { - model = input.model.display_name; - } - - // 获取工作目录名 - const workDirName = workDir.split("/").pop() || ""; - - // 格式化usage信息 - const usage = formatUsage(inputTokens, outputTokens); - const [formattedInputTokens, formattedOutputTokens] = usage.split(" "); - - // 定义变量替换映射 - const variables = { - workDirName, - gitBranch, - model, - inputTokens: formattedInputTokens, - outputTokens: formattedOutputTokens - }; - - // 确定使用的风格 - const isPowerline = currentStyle === 'powerline'; - - // 根据风格渲染状态行 - if (isPowerline) { - return await renderPowerlineStyle(theme, variables); - } else { - return await renderDefaultStyle(theme, variables); - } - } catch (error) { - // 发生错误时返回空字符串 - return ""; - } -} - -// 读取用户主目录的主题配置(指定风格) -async function getProjectThemeConfigForStyle(style: string): Promise { - try { - // 只使用主目录的固定配置文件 - const configPath = CONFIG_FILE; - - // 检查配置文件是否存在 - try { - await fs.access(configPath); - } catch { - return null; - } - - const configContent = await fs.readFile(configPath, "utf-8"); - const config = JSON5.parse(configContent); - - // 检查是否有StatusLine配置 - if (config.StatusLine && config.StatusLine[style] && config.StatusLine[style].modules) { - return config.StatusLine[style]; - } - } catch (error) { - // 如果读取失败,返回null - // console.error("Failed to read theme config:", error); - } - - return null; -} - -// 渲染默认风格的状态行 -async function renderDefaultStyle( - theme: StatusLineThemeConfig, - variables: Record -): Promise { - const modules = theme.modules || DEFAULT_THEME.modules; - const parts: string[] = []; - - // 遍历模块数组,渲染每个模块 - for (let i = 0; i < Math.min(modules.length, 5); i++) { - const module = modules[i]; - const color = module.color ? getColorCode(module.color) : ""; - const background = module.background ? getColorCode(module.background) : ""; - const icon = module.icon || ""; - - // 如果是script类型,执行脚本获取文本 - let text = ""; - if (module.type === "script" && module.scriptPath) { - text = await executeScript(module.scriptPath, variables); - } else { - text = replaceVariables(module.text, variables); - } - - // 构建显示文本 - let displayText = ""; - if (icon) { - displayText += `${icon} `; - } - displayText += text; - - // 如果displayText为空,或者只有图标没有实际文本,则跳过该模块 - if (!displayText || !text) { - continue; - } - - // 构建模块字符串 - let part = `${background}${color}`; - part += `${displayText}${COLORS.reset}`; - - parts.push(part); - } - - // 使用空格连接所有部分 - return parts.join(" "); -} - -// Powerline符号 -const SEP_RIGHT = "\uE0B0"; //  - -// 颜色编号(256色表) -const COLOR_MAP: Record = { - // 基础颜色映射到256色 - black: 0, - red: 1, - green: 2, - yellow: 3, - blue: 4, - magenta: 5, - cyan: 6, - white: 7, - bright_black: 8, - bright_red: 9, - bright_green: 10, - bright_yellow: 11, - bright_blue: 12, - bright_magenta: 13, - bright_cyan: 14, - bright_white: 15, - // 亮背景色映射 - bg_black: 0, - bg_red: 1, - bg_green: 2, - bg_yellow: 3, - bg_blue: 4, - bg_magenta: 5, - bg_cyan: 6, - bg_white: 7, - bg_bright_black: 8, - bg_bright_red: 9, - bg_bright_green: 10, - bg_bright_yellow: 11, - bg_bright_blue: 12, - bg_bright_magenta: 13, - bg_bright_cyan: 14, - bg_bright_white: 15, - // 自定义颜色映射 - bg_bright_orange: 202, - bg_bright_purple: 129, -}; - -// 获取TrueColor的RGB值 -function getTrueColorRgb(colorName: string): { r: number; g: number; b: number } | null { - // 如果是预定义颜色,返回对应RGB - if (COLOR_MAP[colorName] !== undefined) { - const color256 = COLOR_MAP[colorName]; - return color256ToRgb(color256); - } - - // 处理十六进制颜色 - if (colorName.startsWith('#') || /^[0-9a-fA-F]{6}$/.test(colorName) || /^[0-9a-fA-F]{3}$/.test(colorName)) { - return hexToRgb(colorName); - } - - // 处理背景色十六进制 - if (colorName.startsWith('bg_#')) { - return hexToRgb(colorName.substring(3)); - } - - return null; -} - -// 将256色表索引转换为RGB值 -function color256ToRgb(index: number): { r: number; g: number; b: number } | null { - if (index < 0 || index > 255) return null; - - // ANSI 256色表转换 - if (index < 16) { - // 基本颜色 - const basicColors = [ - [0, 0, 0], [128, 0, 0], [0, 128, 0], [128, 128, 0], - [0, 0, 128], [128, 0, 128], [0, 128, 128], [192, 192, 192], - [128, 128, 128], [255, 0, 0], [0, 255, 0], [255, 255, 0], - [0, 0, 255], [255, 0, 255], [0, 255, 255], [255, 255, 255] - ]; - return { r: basicColors[index][0], g: basicColors[index][1], b: basicColors[index][2] }; - } else if (index < 232) { - // 216色:6×6×6的颜色立方体 - const i = index - 16; - const r = Math.floor(i / 36); - const g = Math.floor((i % 36) / 6); - const b = i % 6; - const rgb = [0, 95, 135, 175, 215, 255]; - return { r: rgb[r], g: rgb[g], b: rgb[b] }; - } else { - // 灰度色 - const gray = 8 + (index - 232) * 10; - return { r: gray, g: gray, b: gray }; - } -} - -// 生成一个无缝拼接的段:文本在 bgN 上显示,分隔符从 bgN 过渡到 nextBgN -function segment(text: string, textFg: string, bgColor: string, nextBgColor: string | null): string { - const bgRgb = getTrueColorRgb(bgColor); - if (!bgRgb) { - // 如果无法获取RGB,使用默认蓝色背景 - const defaultBlueRgb = { r: 33, g: 150, b: 243 }; - const curBg = `\x1b[48;2;${defaultBlueRgb.r};${defaultBlueRgb.g};${defaultBlueRgb.b}m`; - const fgColor = `\x1b[38;2;255;255;255m`; - const body = `${curBg}${fgColor} ${text} \x1b[0m`; - return body; - } - - const curBg = `\x1b[48;2;${bgRgb.r};${bgRgb.g};${bgRgb.b}m`; - - // 获取前景色RGB - let fgRgb = { r: 255, g: 255, b: 255 }; // 默认前景色为白色 - const textFgRgb = getTrueColorRgb(textFg); - if (textFgRgb) { - fgRgb = textFgRgb; - } - - const fgColor = `\x1b[38;2;${fgRgb.r};${fgRgb.g};${fgRgb.b}m`; - const body = `${curBg}${fgColor} ${text} \x1b[0m`; - - if (nextBgColor != null) { - const nextBgRgb = getTrueColorRgb(nextBgColor); - if (nextBgRgb) { - // 分隔符:前景色是当前段的背景色,背景色是下一段的背景色 - const sepCurFg = `\x1b[38;2;${bgRgb.r};${bgRgb.g};${bgRgb.b}m`; - const sepNextBg = `\x1b[48;2;${nextBgRgb.r};${nextBgRgb.g};${nextBgRgb.b}m`; - const sep = `${sepCurFg}${sepNextBg}${SEP_RIGHT}\x1b[0m`; - return body + sep; - } - // 如果没有下一个背景色,假设终端背景为黑色并渲染黑色箭头 - const sepCurFg = `\x1b[38;2;${bgRgb.r};${bgRgb.g};${bgRgb.b}m`; - const sepNextBg = `\x1b[48;2;0;0;0m`; // 黑色背景 - const sep = `${sepCurFg}${sepNextBg}${SEP_RIGHT}\x1b[0m`; - return body + sep; - } - - return body; -} - -// 渲染Powerline风格的状态行 -async function renderPowerlineStyle( - theme: StatusLineThemeConfig, - variables: Record -): Promise { - const modules = theme.modules || POWERLINE_THEME.modules; - const segments: string[] = []; - - // 遍历模块数组,渲染每个模块 - for (let i = 0; i < Math.min(modules.length, 5); i++) { - const module = modules[i]; - const color = module.color || "white"; - const backgroundName = module.background || ""; - const icon = module.icon || ""; - - // 如果是script类型,执行脚本获取文本 - let text = ""; - if (module.type === "script" && module.scriptPath) { - text = await executeScript(module.scriptPath, variables); - } else { - text = replaceVariables(module.text, variables); - } - - // 构建显示文本 - let displayText = ""; - if (icon) { - displayText += `${icon} `; - } - displayText += text; - - // 如果displayText为空,或者只有图标没有实际文本,则跳过该模块 - if (!displayText || !text) { - continue; - } - - // 获取下一个模块的背景色(用于分隔符) - let nextBackground: string | null = null; - if (i < modules.length - 1) { - const nextModule = modules[i + 1]; - nextBackground = nextModule.background || null; - } - - // 使用模块定义的背景色,或者为Powerline风格提供默认背景色 - const actualBackground = backgroundName || "bg_bright_blue"; - - // 生成段,支持十六进制颜色 - const segmentStr = segment(displayText, color, actualBackground, nextBackground); - segments.push(segmentStr); - } - - return segments.join(""); -} diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 0000000..70dd96f --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "CommonJS", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "noImplicitAny": true, + "allowSyntheticDefaultImports": true, + "sourceMap": true, + "declaration": true, + "typeRoots": ["./node_modules/@types", "./packages/*/node_modules/@types"] + } +} diff --git a/ui/CLAUDE.md b/ui/CLAUDE.md deleted file mode 100644 index 1ca8a16..0000000 --- a/ui/CLAUDE.md +++ /dev/null @@ -1,33 +0,0 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Project Overview - -This is a frontend project for a configuration settings UI. The goal is to produce a single, self-contained HTML file with all JavaScript and CSS inlined. The application should be designed with a clean, modern UI and support both English and Chinese languages. - -## Tech Stack - -- **Package Manager:** pnpm -- **Build Tool:** Vite.js -- **Framework:** React.js -- **Styling:** Tailwind CSS with shadcn-ui -- **Languages:** TypeScript, English, Chinese - -## Key Commands - -- **Run development server:** `pnpm dev` -- **Build for production:** `pnpm build` (This produces a single HTML file) -- **Lint files:** `pnpm lint` -- **Preview production build:** `pnpm preview` - -## Architecture & Development Notes - -- **Configuration:** The application's configuration structure is defined in `config.example.json`. This file should be used as a reference for mocking data, as no backend APIs will be implemented. -- **Build Target:** The final build output must be a single HTML file. This is configured in `vite.config.ts` using `vite-plugin-singlefile`. -- **Internationalization (i18n):** The project uses `i18next` to support both English and Chinese. Locale files are located in `src/locales/`. When adding or changing text, ensure it is properly added to the translation files. -- **UI:** The UI is built with `shadcn-ui` components. Refer to existing components in `src/components/ui/` for styling conventions. -- **API Client:** The project uses a custom `ApiClient` class for handling HTTP requests with baseUrl and API key authentication. The class is defined in `src/lib/api.ts` and provides methods for GET, POST, PUT, and DELETE requests. - -## 项目描述 -参考`PROJECT.md`文件 \ No newline at end of file diff --git a/ui/tsconfig.tsbuildinfo b/ui/tsconfig.tsbuildinfo deleted file mode 100644 index 28cd675..0000000 --- a/ui/tsconfig.tsbuildinfo +++ /dev/null @@ -1 +0,0 @@ -{"root":["./src/app.tsx","./src/i18n.ts","./src/main.tsx","./src/routes.tsx","./src/types.ts","./src/vite-env.d.ts","./src/components/configprovider.tsx","./src/components/debugpage.tsx","./src/components/jsoneditor.tsx","./src/components/logviewer.tsx","./src/components/login.tsx","./src/components/protectedroute.tsx","./src/components/providerlist.tsx","./src/components/providers.tsx","./src/components/publicroute.tsx","./src/components/requesthistorydrawer.tsx","./src/components/router.tsx","./src/components/settingsdialog.tsx","./src/components/statuslineconfigdialog.tsx","./src/components/statuslineimportexport.tsx","./src/components/transformerlist.tsx","./src/components/transformers.tsx","./src/components/ui/badge.tsx","./src/components/ui/button.tsx","./src/components/ui/card.tsx","./src/components/ui/color-picker.tsx","./src/components/ui/combo-input.tsx","./src/components/ui/combobox.tsx","./src/components/ui/command.tsx","./src/components/ui/dialog.tsx","./src/components/ui/input.tsx","./src/components/ui/label.tsx","./src/components/ui/multi-combobox.tsx","./src/components/ui/popover.tsx","./src/components/ui/switch.tsx","./src/components/ui/tabs.tsx","./src/components/ui/toast.tsx","./src/lib/api.ts","./src/lib/db.ts","./src/lib/utils.ts","./src/utils/statusline.ts"],"version":"5.8.3"} \ No newline at end of file