@codedir/mimir-code 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +556 -16
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/platform/FileSystemAdapter.ts","../src/config/schemas.ts","../src/utils/logger.ts","../src/config/AllowlistLoader.ts","../src/config/ConfigLoader.ts","../src/cli/utils/firstRunDetector.ts","../src/cli/commands/SetupCommand.ts","../src/cli/components/SetupWizard.tsx","../src/cli/components/WizardLayout.tsx","../src/cli/components/WizardHead.tsx","../src/cli/theme-colors.ts","../src/cli/components/logo.ts","../src/cli/components/SecurityWarning.tsx","../src/utils/keyboardFormatter.ts","../src/cli/components/ThemeSelector.tsx","../src/config/themes/theme-schema.ts","../src/config/themes/definitions/mimir.json","../src/config/themes/definitions/dark.json","../src/config/themes/definitions/light.json","../src/config/themes/definitions/dark-colorblind.json","../src/config/themes/definitions/light-colorblind.json","../src/config/themes/definitions/dark-ansi.json","../src/config/themes/definitions/light-ansi.json","../src/config/themes/index.ts","../src/cli/utils/syntaxHighlight.ts","../src/cli/commands/ChatCommand.ts","../src/cli/components/ChatApp.tsx","../src/cli/components/ChatInterface.tsx","../src/cli/components/MimirHeader.tsx","../src/cli/components/MessageList.tsx","../src/cli/components/InputBox.tsx","../src/core/SlashCommandParser.ts","../src/cli/components/CommandAutocomplete.tsx","../src/cli/hooks/useTerminalSize.ts","../src/cli/components/Footer.tsx","../src/cli/components/tips.ts","../src/cli/keyboard/KeyboardEventBus.ts","../src/cli/keyboard/KeyboardContext.tsx","../src/utils/KeyBindings.ts","../src/cli/keyboard/useKeyboardAction.ts","../src/cli/keyboard/useKeyboardInput.ts","../src/core/SlashCommand.ts","../src/core/CustomCommandLoader.ts","../src/cli/utils/signalHandler.ts","../src/cli/commands/slashCommands/NewCommand.ts","../src/cli/commands/slashCommands/ModelCommand.ts","../src/cli/commands/slashCommands/ModeCommand.ts","../src/cli/commands/slashCommands/HelpCommand.ts","../src/cli/commands/slashCommands/ThemeCommand.ts","../src/storage/Database.ts","../src/storage/seed.ts","../src/core/MimirInitializer.ts","../src/providers/DeepSeekProvider.ts","../src/utils/errors.ts","../src/providers/BaseLLMProvider.ts","../src/providers/utils/apiClient.ts","../src/providers/pricing/pricingData.ts","../src/providers/utils/toolFormatters.ts","../src/providers/utils/streamParsers.ts","../src/providers/AnthropicProvider.ts","../src/providers/ProviderFactory.ts","../src/cli/commands/InitCommand.ts"],"sourcesContent":["/**\n * Mimir CLI entry point\n *\n * Note: Shebang is NOT included in source code.\n * - npm adds it automatically based on package.json bin field\n * - pkg adds it automatically when creating binaries\n */\n\nimport { Command } from 'commander';\nimport { FileSystemAdapter } from './platform/FileSystemAdapter.js';\nimport { ConfigLoader } from './config/ConfigLoader.js';\nimport { FirstRunDetector } from './cli/utils/firstRunDetector.js';\nimport { SetupCommand } from './cli/commands/SetupCommand.js';\nimport { ChatCommand } from './cli/commands/ChatCommand.js';\nimport { InitCommand } from './cli/commands/InitCommand.js';\nimport { logger } from './utils/logger.js';\n\n// Initialize dependencies\nconst fs = new FileSystemAdapter();\nconst configLoader = new ConfigLoader(fs);\nconst firstRunDetector = new FirstRunDetector(fs);\nconst setupCommand = new SetupCommand(configLoader);\nconst chatCommand = new ChatCommand(configLoader, firstRunDetector, setupCommand, fs);\nconst initCommand = new InitCommand(fs, configLoader);\n\nconst program = new Command();\n\nprogram.name('mimir').description('Platform-agnostic, BYOK AI coding agent CLI').version('0.1.0');\n\n// Setup wizard\nprogram\n .command('setup')\n .description('Run setup wizard')\n .action(async () => {\n await setupCommand.execute();\n process.exit(0);\n });\n\n// Main interactive chat command\nprogram\n .command('chat', { isDefault: true })\n .description('Start interactive chat session')\n .action(async () => {\n await chatCommand.execute();\n process.exit(0);\n });\n\n// Initialize project\nprogram\n .command('init')\n .description('Initialize Mimir in current project')\n .option('--no-interactive', 'Run without interactive prompts (for automated setup)')\n .option('-q, --quiet', 'Suppress output')\n .action(async (options: { interactive?: boolean; quiet?: boolean }) => {\n await initCommand.execute(undefined, options);\n process.exit(0);\n });\n\n// History management\nconst history = program.command('history').description('Manage conversation history');\n\nhistory\n .command('list')\n .description('List recent conversations')\n .action(() => {\n logger.warn('Listing conversations... (not implemented yet)');\n });\n\nhistory\n .command('resume <id>')\n .description('Resume a conversation')\n .action((id: string) => {\n logger.warn(`Resuming conversation ${id}... (not implemented yet)`);\n });\n\nhistory\n .command('export <id>')\n .description('Export conversation to file')\n .action((id: string) => {\n logger.warn(`Exporting conversation ${id}... (not implemented yet)`);\n });\n\nhistory\n .command('clear')\n .description('Clear conversation history')\n .action(() => {\n logger.warn('Clearing history... (not implemented yet)');\n });\n\n// Cost analytics\nconst cost = program.command('cost').description('View cost analytics');\n\ncost\n .command('today')\n .description(\"Show today's spending\")\n .action(() => {\n logger.warn(\"Fetching today's costs... (not implemented yet)\");\n });\n\ncost\n .command('week')\n .description('Show weekly spending')\n .action(() => {\n logger.warn('Fetching weekly costs... (not implemented yet)');\n });\n\ncost\n .command('month')\n .description('Show monthly spending')\n .action(() => {\n logger.warn('Fetching monthly costs... (not implemented yet)');\n });\n\ncost\n .command('compare')\n .description('Compare provider costs')\n .action(() => {\n logger.warn('Comparing providers... (not implemented yet)');\n });\n\n// Diagnostics\nprogram\n .command('doctor')\n .description('Run diagnostics')\n .action(() => {\n logger.warn('Running diagnostics... (not implemented yet)');\n });\n\n// Permissions management\nconst permissions = program.command('permissions').description('Manage command permissions');\n\npermissions\n .command('list')\n .description('List allowed commands')\n .action(() => {\n logger.warn('Listing permissions... (not implemented yet)');\n });\n\npermissions\n .command('add <pattern>')\n .description('Add command to allowlist')\n .action((pattern: string) => {\n logger.warn(`Adding ${pattern} to allowlist... (not implemented yet)`);\n });\n\npermissions\n .command('remove <pattern>')\n .description('Remove command from allowlist')\n .action((pattern: string) => {\n logger.warn(`Removing ${pattern} from allowlist... (not implemented yet)`);\n });\n\nprogram.parse();\n","/**\n * FileSystemAdapter - Cross-platform file system implementation\n * Uses Node.js fs/promises + fast-glob for file operations\n */\n\nimport { IFileSystem, Stats } from './IFileSystem.js';\nimport fs from 'fs/promises';\nimport fg from 'fast-glob';\n\nexport class FileSystemAdapter implements IFileSystem {\n async readFile(path: string, encoding: BufferEncoding = 'utf-8'): Promise<string> {\n return fs.readFile(path, encoding);\n }\n\n async writeFile(\n path: string,\n content: string,\n encoding: BufferEncoding = 'utf-8'\n ): Promise<void> {\n await fs.writeFile(path, content, encoding);\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n await fs.access(path);\n return true;\n } catch {\n return false;\n }\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n await fs.mkdir(path, options);\n }\n\n async readdir(path: string): Promise<string[]> {\n return fs.readdir(path);\n }\n\n async stat(path: string): Promise<Stats> {\n const stats = await fs.stat(path);\n return {\n isFile: () => stats.isFile(),\n isDirectory: () => stats.isDirectory(),\n size: stats.size,\n mtime: stats.mtime,\n };\n }\n\n async unlink(path: string): Promise<void> {\n await fs.unlink(path);\n }\n\n async rmdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n await fs.rmdir(path, options);\n }\n\n async copyFile(src: string, dest: string): Promise<void> {\n await fs.copyFile(src, dest);\n }\n\n async glob(pattern: string, options?: { cwd?: string; ignore?: string[] }): Promise<string[]> {\n return fg(pattern, {\n cwd: options?.cwd,\n ignore: options?.ignore,\n });\n }\n}\n","/**\n * Configuration schemas with Zod validation\n */\n\nimport { z } from 'zod';\n\n// Theme options matching Claude Code + Mimir Nordic theme\nexport const ThemeSchema = z.enum([\n 'mimir',\n 'dark',\n 'light',\n 'dark-colorblind',\n 'light-colorblind',\n 'dark-ansi',\n 'light-ansi',\n]);\n\nexport const UIConfigSchema = z.object({\n theme: ThemeSchema.default('mimir'),\n syntaxHighlighting: z.boolean().default(true),\n showLineNumbers: z.boolean().default(true),\n compactMode: z.boolean().default(false),\n // Autocomplete behavior\n autocompleteAutoShow: z.boolean().default(true), // Automatically show autocomplete when suggestions available\n autocompleteExecuteOnSelect: z.boolean().default(true), // Execute command immediately if no more parameters needed\n});\n\nexport const LLMConfigSchema = z.object({\n provider: z.enum(['deepseek', 'anthropic', 'openai', 'google', 'gemini', 'qwen', 'ollama']),\n model: z.string(),\n apiKey: z.string().optional(),\n baseURL: z.string().optional(),\n temperature: z.number().min(0).max(2).default(0.7),\n maxTokens: z.number().default(4096),\n});\n\nexport const PermissionsConfigSchema = z.object({\n autoAccept: z.boolean().default(false),\n acceptRiskLevel: z.enum(['low', 'medium', 'high', 'critical']).default('medium'),\n alwaysAcceptCommands: z\n .array(z.string())\n .nullable()\n .default([])\n .transform((val) => val ?? []),\n});\n\n// Helper to accept string or array of strings for shortcuts\nconst shortcutSchema = z\n .union([z.string(), z.array(z.string()).min(1)])\n .transform((val) => (Array.isArray(val) ? val : [val]));\n\nexport const KeyBindingsConfigSchema = z.object({\n // Core actions - Ctrl+C and Escape share the same 'interrupt' logic\n interrupt: shortcutSchema.default(['Ctrl+C', 'Escape']),\n accept: shortcutSchema.default(['Enter']),\n\n // Mode and navigation\n modeSwitch: shortcutSchema.default(['Shift+Tab']),\n editCommand: shortcutSchema.default(['Ctrl+E']),\n\n // Autocomplete/tooltips\n showTooltip: shortcutSchema.default(['Ctrl+Space', 'Tab']),\n navigateUp: shortcutSchema.default(['ArrowUp']),\n navigateDown: shortcutSchema.default(['ArrowDown']),\n\n // Utility\n help: shortcutSchema.default(['?']),\n clearScreen: shortcutSchema.default(['Ctrl+L']),\n undo: shortcutSchema.default(['Ctrl+Z']),\n redo: shortcutSchema.default(['Ctrl+Y']), // Auto-converted to Cmd+Shift+Z on Mac\n\n // Legacy/deprecated - kept for backwards compatibility\n reject: shortcutSchema.default([]).optional(),\n});\n\nexport const DockerConfigSchema = z.object({\n enabled: z.boolean().default(true),\n baseImage: z.string().default('alpine:latest'),\n cpuLimit: z.number().optional(),\n memoryLimit: z.string().optional(),\n});\n\nexport const MonitoringConfigSchema = z.object({\n metricsRetentionDays: z.number().min(1).max(365).default(90),\n enableHealthChecks: z.boolean().default(true),\n healthCheckIntervalSeconds: z.number().min(10).max(3600).default(300),\n slowOperationThresholdMs: z.number().min(100).default(5000),\n batchWriteIntervalSeconds: z.number().min(1).max(60).default(10),\n});\n\nexport const BudgetConfigSchema = z.object({\n enabled: z.boolean().default(false),\n dailyLimit: z.number().min(0).optional(), // USD\n weeklyLimit: z.number().min(0).optional(),\n monthlyLimit: z.number().min(0).optional(),\n warningThreshold: z.number().min(0).max(1).default(0.8), // 80%\n});\n\nexport const RateLimitConfigSchema = z.object({\n enabled: z.boolean().default(true),\n commandsPerMinute: z.number().min(1).default(60),\n toolExecutionsPerMinute: z.number().min(1).default(30),\n llmCallsPerMinute: z.number().min(1).default(20),\n maxFileSizeMB: z.number().min(1).default(100),\n});\n\nexport const ConfigSchema = z.object({\n llm: LLMConfigSchema,\n permissions: PermissionsConfigSchema,\n keyBindings: KeyBindingsConfigSchema,\n docker: DockerConfigSchema,\n ui: UIConfigSchema,\n monitoring: MonitoringConfigSchema,\n budget: BudgetConfigSchema,\n rateLimit: RateLimitConfigSchema,\n});\n\nexport type Theme = z.infer<typeof ThemeSchema>;\nexport type UIConfig = z.infer<typeof UIConfigSchema>;\nexport type LLMConfig = z.infer<typeof LLMConfigSchema>;\nexport type PermissionsConfig = z.infer<typeof PermissionsConfigSchema>;\nexport type KeyBindingsConfig = z.infer<typeof KeyBindingsConfigSchema>;\nexport type DockerConfig = z.infer<typeof DockerConfigSchema>;\nexport type MonitoringConfig = z.infer<typeof MonitoringConfigSchema>;\nexport type BudgetConfig = z.infer<typeof BudgetConfigSchema>;\nexport type RateLimitConfig = z.infer<typeof RateLimitConfigSchema>;\nexport type Config = z.infer<typeof ConfigSchema>;\n","/**\n * Logging utility using winston\n */\n\nimport winston from 'winston';\nimport DailyRotateFile from 'winston-daily-rotate-file';\nimport fs from 'fs';\nimport path from 'path';\n\nexport type LogLevel = 'error' | 'warn' | 'info' | 'debug';\n\nexport class Logger {\n private logger: winston.Logger;\n private fileLoggingEnabled = false;\n private consoleTransport: winston.transport;\n\n constructor(logDir = '.mimir/logs') {\n // Resolve to absolute path for clarity\n const absoluteLogDir = path.resolve(process.cwd(), logDir);\n\n // Attempt to create log directory (synchronous to work in constructor)\n // Gracefully degrade to console-only logging if this fails\n try {\n if (!fs.existsSync(absoluteLogDir)) {\n fs.mkdirSync(absoluteLogDir, { recursive: true });\n }\n this.fileLoggingEnabled = true;\n } catch (error) {\n // Degrade gracefully - warn but don't crash\n console.warn(\n `[Logger] Warning: Failed to create log directory at ${absoluteLogDir}. File logging disabled. Error: ${error}`\n );\n this.fileLoggingEnabled = false;\n }\n\n // Build transports array conditionally\n // Create console transport (can be disabled later for Ink UI)\n this.consoleTransport = new winston.transports.Console({\n format: winston.format.combine(winston.format.colorize(), winston.format.simple()),\n });\n\n const transports: winston.transport[] = [this.consoleTransport];\n\n // Only add file transports if directory creation succeeded\n if (this.fileLoggingEnabled) {\n transports.push(\n // Error logs with daily rotation\n new DailyRotateFile({\n dirname: absoluteLogDir,\n filename: '%DATE%-error.log',\n datePattern: 'YYYYMMDD',\n level: 'error',\n maxSize: '10m', // Rotate when file reaches 10MB\n maxFiles: '30d', // Keep logs for 30 days\n zippedArchive: true, // Compress old logs\n }),\n // Combined logs with daily rotation\n new DailyRotateFile({\n dirname: absoluteLogDir,\n filename: '%DATE%.log',\n datePattern: 'YYYYMMDD',\n maxSize: '10m', // Rotate when file reaches 10MB\n maxFiles: '30d', // Keep logs for 30 days\n zippedArchive: true, // Compress old logs\n })\n );\n }\n\n this.logger = winston.createLogger({\n level: process.env.LOG_LEVEL || 'info',\n format: winston.format.combine(\n winston.format.timestamp(),\n winston.format.errors({ stack: true }),\n winston.format.json()\n ),\n transports,\n });\n }\n\n error(message: string, meta?: Record<string, unknown>): void {\n this.logger.error(message, meta);\n }\n\n warn(message: string, meta?: Record<string, unknown>): void {\n this.logger.warn(message, meta);\n }\n\n info(message: string, meta?: Record<string, unknown>): void {\n this.logger.info(message, meta);\n }\n\n debug(message: string, meta?: Record<string, unknown>): void {\n this.logger.debug(message, meta);\n }\n\n /**\n * Disable console logging (useful when Ink UI is active)\n */\n disableConsole(): void {\n this.logger.remove(this.consoleTransport);\n }\n\n /**\n * Enable console logging\n */\n enableConsole(): void {\n if (!this.logger.transports.includes(this.consoleTransport)) {\n this.logger.add(this.consoleTransport);\n }\n }\n}\n\n// Singleton instance\nexport const logger = new Logger();\n","/**\n * Allowlist loader for team-shared command permissions\n * Loads from .mimir/allowlist.yml\n */\n\nimport { IFileSystem } from '../platform/IFileSystem.js';\nimport { logger } from '../utils/logger.js';\nimport yaml from 'yaml';\nimport path from 'path';\nimport { z } from 'zod';\n\n/**\n * Allowlist schema\n */\nexport const AllowlistSchema = z.object({\n // Command patterns that are always allowed\n commands: z.array(z.string()).default([]),\n\n // File patterns that can be modified without confirmation\n files: z.array(z.string()).default([]),\n\n // Network destinations that are allowed\n urls: z.array(z.string()).default([]),\n\n // Environment variables that can be accessed\n envVars: z.array(z.string()).default([]),\n\n // Specific bash commands that are safe\n bashCommands: z.array(z.string()).default([]),\n});\n\nexport type Allowlist = z.infer<typeof AllowlistSchema>;\n\nexport class AllowlistLoader {\n constructor(private fs: IFileSystem) {}\n\n /**\n * Load allowlist from project .mimir/allowlist.yml\n */\n async loadProjectAllowlist(projectRoot: string): Promise<Allowlist | null> {\n const allowlistPath = path.join(projectRoot, '.mimir', 'allowlist.yml');\n return await this.loadAllowlistFile(allowlistPath, 'project');\n }\n\n /**\n * Load allowlist from global ~/.mimir/allowlist.yml\n */\n async loadGlobalAllowlist(): Promise<Allowlist | null> {\n const homeDir = process.env.HOME || process.env.USERPROFILE || '~';\n const allowlistPath = path.join(homeDir, '.mimir', 'allowlist.yml');\n return await this.loadAllowlistFile(allowlistPath, 'global');\n }\n\n /**\n * Load and parse allowlist file\n */\n private async loadAllowlistFile(\n filePath: string,\n scope: 'global' | 'project'\n ): Promise<Allowlist | null> {\n try {\n if (!(await this.fs.exists(filePath))) {\n logger.debug(`No ${scope} allowlist found`, { path: filePath });\n return null;\n }\n\n const content = await this.fs.readFile(filePath);\n const parsed = yaml.parse(content) as unknown;\n\n // Validate schema\n const allowlist = AllowlistSchema.parse(parsed);\n\n logger.info(`Loaded ${scope} allowlist`, {\n path: filePath,\n commands: allowlist.commands.length,\n files: allowlist.files.length,\n urls: allowlist.urls.length,\n });\n\n return allowlist;\n } catch (error) {\n logger.error(`Failed to load ${scope} allowlist`, {\n path: filePath,\n error,\n });\n return null;\n }\n }\n\n /**\n * Merge multiple allowlists (global + project)\n * Project allowlist takes precedence\n */\n merge(global: Allowlist | null, project: Allowlist | null): Allowlist {\n const merged: Allowlist = {\n commands: [],\n files: [],\n urls: [],\n envVars: [],\n bashCommands: [],\n };\n\n // Merge global\n if (global) {\n merged.commands.push(...global.commands);\n merged.files.push(...global.files);\n merged.urls.push(...global.urls);\n merged.envVars.push(...global.envVars);\n merged.bashCommands.push(...global.bashCommands);\n }\n\n // Merge project (deduplicates)\n if (project) {\n // Use Set to deduplicate\n merged.commands = [...new Set([...merged.commands, ...project.commands])];\n merged.files = [...new Set([...merged.files, ...project.files])];\n merged.urls = [...new Set([...merged.urls, ...project.urls])];\n merged.envVars = [...new Set([...merged.envVars, ...project.envVars])];\n merged.bashCommands = [...new Set([...merged.bashCommands, ...project.bashCommands])];\n }\n\n return merged;\n }\n\n /**\n * Create example allowlist file\n */\n async createExample(filePath: string, scope: 'global' | 'project'): Promise<void> {\n const exampleContent = scope === 'global' ? this.getGlobalExample() : this.getProjectExample();\n\n try {\n const dir = path.dirname(filePath);\n if (!(await this.fs.exists(dir))) {\n await this.fs.mkdir(dir, { recursive: true });\n }\n\n await this.fs.writeFile(filePath, exampleContent);\n logger.info(`Created example ${scope} allowlist`, { path: filePath });\n } catch (error) {\n logger.error(`Failed to create example allowlist`, {\n path: filePath,\n error,\n });\n throw error;\n }\n }\n\n /**\n * Get example global allowlist\n */\n private getGlobalExample(): string {\n return `# Global Allowlist\n# Commands, files, and operations that are safe across all projects\n\n# Commands that don't require permission prompt\ncommands:\n - '/status' # Git status\n - '/diff' # Git diff\n - '/help' # Show help\n - '/version' # Show version\n - '/doctor' # System diagnostics\n\n# Safe bash commands\nbashCommands:\n - 'git status'\n - 'git diff'\n - 'git log'\n - 'ls'\n - 'pwd'\n - 'echo *'\n - 'cat *.md'\n\n# Files that can be modified without confirmation (use globs)\nfiles:\n - '**/*.md' # Documentation files\n - '**/*.txt' # Text files\n - '**/README.*' # README files\n\n# URLs that can be accessed without confirmation\nurls:\n - 'https://api.github.com/**'\n - 'https://registry.npmjs.org/**'\n\n# Environment variables that can be read\nenvVars:\n - 'NODE_ENV'\n - 'PATH'\n - 'USER'\n - 'HOME'\n`;\n }\n\n /**\n * Get example project allowlist\n */\n private getProjectExample(): string {\n return `# Project Allowlist\n# Team-shared permissions for this project\n# Commit this file to version control for consistent team experience\n\n# Custom slash commands that are safe to run\ncommands:\n - '/test' # Run test suite\n - '/lint' # Run linter\n - '/build' # Build project\n - '/test-coverage' # Run tests with coverage\n\n# Safe bash commands specific to this project\nbashCommands:\n - 'yarn test'\n - 'yarn lint'\n - 'yarn build'\n - 'npm run test'\n - 'npm run lint'\n\n# Files that can be auto-formatted or modified\nfiles:\n - 'src/**/*.ts' # TypeScript source files\n - 'src/**/*.tsx' # React TypeScript files\n - 'tests/**/*.ts' # Test files\n - '*.json' # JSON config files\n - '.prettierrc.*' # Prettier config\n - '.eslintrc.*' # ESLint config\n\n# API endpoints used by this project\nurls:\n - 'https://api.example.com/**'\n - 'https://staging.example.com/**'\n\n# Environment variables specific to this project\nenvVars:\n - 'API_KEY'\n - 'DATABASE_URL'\n - 'REDIS_URL'\n`;\n }\n}\n","/**\n * Configuration loader with hierarchy support\n * Priority: CLI flags > env vars > project config > global config > defaults\n */\n\nimport { Config, ConfigSchema } from './schemas.js';\nimport { IFileSystem } from '../platform/IFileSystem.js';\nimport { AllowlistLoader, Allowlist } from './AllowlistLoader.js';\nimport yaml from 'yaml';\nimport path from 'path';\nimport os from 'os';\nimport dotenv from 'dotenv';\nimport { logger } from '../utils/logger.js';\n\nexport interface ConfigLoadOptions {\n projectRoot?: string;\n cliFlags?: Partial<Config>;\n}\n\nexport interface ConfigLoadResult {\n config: Config;\n allowlist: Allowlist;\n}\n\nexport class ConfigLoader {\n private allowlistLoader: AllowlistLoader;\n\n constructor(private fs: IFileSystem) {\n this.allowlistLoader = new AllowlistLoader(fs);\n }\n\n /**\n * Load configuration with full hierarchy:\n * 1. Default config\n * 2. Global (~/.mimir/config.yml)\n * 3. Project (.mimir/config.yml)\n * 4. Environment variables (.env)\n * 5. CLI flags\n *\n * Also loads allowlist from:\n * 1. Global (~/.mimir/allowlist.yml)\n * 2. Project (.mimir/allowlist.yml)\n */\n async load(options: ConfigLoadOptions = {}): Promise<ConfigLoadResult> {\n // 1. Start with defaults\n let config = this.getDefaults();\n\n // 2. Load global config\n const globalConfig = await this.loadGlobalConfig();\n if (globalConfig) {\n config = this.merge(config, globalConfig);\n }\n\n // 3. Load project config\n if (options.projectRoot) {\n const projectConfig = await this.loadProjectConfig(options.projectRoot);\n if (projectConfig) {\n config = this.merge(config, projectConfig);\n }\n }\n\n // 4. Load .env file\n const envConfig = this.loadEnvConfig(options.projectRoot);\n if (envConfig) {\n config = this.merge(config, envConfig);\n }\n\n // 5. Apply CLI flags\n if (options.cliFlags) {\n config = this.merge(config, options.cliFlags);\n }\n\n // Validate final config\n const validatedConfig = ConfigSchema.parse(config);\n\n // Load allowlists\n const globalAllowlist = await this.allowlistLoader.loadGlobalAllowlist();\n const projectAllowlist = options.projectRoot\n ? await this.allowlistLoader.loadProjectAllowlist(options.projectRoot)\n : null;\n\n const mergedAllowlist = this.allowlistLoader.merge(globalAllowlist, projectAllowlist);\n\n // Merge allowlist commands with config.yml alwaysAcceptCommands\n if (mergedAllowlist.commands.length > 0) {\n validatedConfig.permissions.alwaysAcceptCommands = [\n ...new Set([\n ...validatedConfig.permissions.alwaysAcceptCommands,\n ...mergedAllowlist.commands,\n ]),\n ];\n }\n\n return {\n config: validatedConfig,\n allowlist: mergedAllowlist,\n };\n }\n\n private getDefaults(): Config {\n // Platform-specific defaults\n const isWindows = process.platform === 'win32';\n\n return {\n llm: {\n provider: 'deepseek',\n model: 'deepseek-chat',\n temperature: 0.7,\n maxTokens: 4096,\n },\n permissions: {\n autoAccept: false,\n acceptRiskLevel: 'medium',\n alwaysAcceptCommands: [],\n },\n keyBindings: {\n interrupt: ['Ctrl+C', 'Escape'],\n accept: ['Enter'],\n modeSwitch: ['Shift+Tab'],\n editCommand: ['Ctrl+E'],\n // Windows: Ctrl+Space is intercepted by terminal - use Tab only\n // macOS/Linux: Both work\n showTooltip: isWindows ? ['Tab'] : ['Ctrl+Space', 'Tab'],\n navigateUp: ['ArrowUp'],\n navigateDown: ['ArrowDown'],\n help: ['?'],\n clearScreen: ['Ctrl+L'],\n undo: ['Ctrl+Z'],\n redo: ['Ctrl+Y'],\n },\n docker: {\n enabled: true,\n baseImage: 'alpine:latest',\n },\n ui: {\n theme: 'mimir',\n syntaxHighlighting: true,\n showLineNumbers: true,\n compactMode: false,\n autocompleteAutoShow: true,\n autocompleteExecuteOnSelect: true,\n },\n monitoring: {\n metricsRetentionDays: 90,\n enableHealthChecks: true,\n healthCheckIntervalSeconds: 300,\n slowOperationThresholdMs: 5000,\n batchWriteIntervalSeconds: 10,\n },\n budget: {\n enabled: false,\n warningThreshold: 0.8,\n },\n rateLimit: {\n enabled: true,\n commandsPerMinute: 60,\n toolExecutionsPerMinute: 30,\n llmCallsPerMinute: 20,\n maxFileSizeMB: 100,\n },\n };\n }\n\n private async loadGlobalConfig(): Promise<Partial<Config> | null> {\n try {\n const configPath = path.join(os.homedir(), '.mimir', 'config.yml');\n if (!(await this.fs.exists(configPath))) {\n return null;\n }\n const content = await this.fs.readFile(configPath);\n return yaml.parse(content) as Partial<Config>;\n } catch (error) {\n logger.warn('Failed to load global config', { error });\n return null;\n }\n }\n\n private async loadProjectConfig(projectRoot: string): Promise<Partial<Config> | null> {\n try {\n const configPath = path.join(projectRoot, '.mimir', 'config.yml');\n if (!(await this.fs.exists(configPath))) {\n return null;\n }\n const content = await this.fs.readFile(configPath);\n return yaml.parse(content) as Partial<Config>;\n } catch (error) {\n logger.warn('Failed to load project config', { error });\n return null;\n }\n }\n\n private loadEnvConfig(projectRoot?: string): Partial<Config> | null {\n try {\n // Load .env from project root if provided, otherwise cwd\n const envPath = projectRoot ? path.join(projectRoot, '.env') : '.env';\n dotenv.config({ path: envPath });\n\n const envConfig: Record<string, unknown> = {};\n\n // Map environment variables to config structure\n if (\n process.env.DEEPSEEK_API_KEY ||\n process.env.ANTHROPIC_API_KEY ||\n process.env.OPENAI_API_KEY\n ) {\n const provider = process.env.LLM_PROVIDER?.toUpperCase();\n const apiKey = provider ? process.env[`${provider}_API_KEY`] : undefined;\n const baseURL = provider ? process.env[`${provider}_BASE_URL`] : undefined;\n\n if (apiKey || baseURL) {\n envConfig.llm = {\n ...(apiKey && { apiKey }),\n ...(baseURL && { baseURL }),\n };\n }\n }\n\n if (process.env.DOCKER_ENABLED) {\n envConfig.docker = {\n enabled: process.env.DOCKER_ENABLED === 'true',\n };\n }\n\n if (process.env.MIMIR_THEME) {\n envConfig.ui = {\n theme: process.env.MIMIR_THEME,\n };\n }\n\n return Object.keys(envConfig).length > 0 ? (envConfig as Partial<Config>) : null;\n } catch (error) {\n logger.warn('Failed to load .env config', { error });\n return null;\n }\n }\n\n private merge(base: Config, override: Partial<Config>): Config {\n return {\n llm: { ...base.llm, ...override.llm },\n permissions: { ...base.permissions, ...override.permissions },\n keyBindings: { ...base.keyBindings, ...override.keyBindings },\n docker: { ...base.docker, ...override.docker },\n ui: { ...base.ui, ...override.ui },\n monitoring: { ...base.monitoring, ...override.monitoring },\n budget: { ...base.budget, ...override.budget },\n rateLimit: { ...base.rateLimit, ...override.rateLimit },\n };\n }\n\n async save(\n config: Partial<Config>,\n scope: 'global' | 'project',\n projectRoot?: string\n ): Promise<void> {\n const configPath =\n scope === 'global'\n ? path.join(os.homedir(), '.mimir', 'config.yml')\n : path.join(projectRoot || process.cwd(), '.mimir', 'config.yml');\n\n const configDir = path.dirname(configPath);\n\n // Ensure directory exists\n if (!(await this.fs.exists(configDir))) {\n await this.fs.mkdir(configDir, { recursive: true });\n }\n\n const yamlContent = yaml.stringify(config);\n await this.fs.writeFile(configPath, yamlContent);\n logger.info(`Config saved to ${configPath}`);\n }\n\n validate(config: unknown): Config {\n return ConfigSchema.parse(config);\n }\n}\n","/**\n * First-run detection utility\n * Checks if this is the first time Mimir is being run (no global config exists)\n */\n\nimport { IFileSystem } from '../../platform/IFileSystem.js';\nimport path from 'path';\nimport os from 'os';\n\nexport class FirstRunDetector {\n constructor(private fs: IFileSystem) {}\n\n async isFirstRun(): Promise<boolean> {\n const globalConfigPath = this.getGlobalConfigPath();\n const exists = await this.fs.exists(globalConfigPath);\n return !exists;\n }\n\n getGlobalConfigPath(): string {\n const homeDir = os.homedir();\n return path.join(homeDir, '.mimir', 'config.yml');\n }\n\n async getGlobalConfigDir(): Promise<string> {\n const homeDir = os.homedir();\n return path.join(homeDir, '.mimir');\n }\n}\n","/**\n * Setup command handler\n * Runs setup wizard and saves configuration\n */\n\nimport React from 'react';\nimport { render } from 'ink';\nimport { SetupWizard } from '../components/SetupWizard.js';\nimport { ConfigLoader } from '../../config/ConfigLoader.js';\nimport { Theme } from '../../config/schemas.js';\nimport { logger } from '../../utils/logger.js';\n\nexport class SetupCommand {\n constructor(private configLoader: ConfigLoader) {}\n\n async execute(): Promise<void> {\n // Enter alternate screen buffer for wizard\n process.stdout.write('\\x1b[?1049h');\n\n // Load current configuration to get keyboard bindings\n const { config } = await this.configLoader.load();\n\n return new Promise((resolve, reject) => {\n const { waitUntilExit, clear } = render(\n React.createElement(SetupWizard, {\n keyBindings: config.keyBindings,\n onComplete: async (theme: Theme): Promise<void> => {\n try {\n // Save configuration to global config\n await this.configLoader.save(\n {\n ui: {\n theme,\n syntaxHighlighting: true,\n showLineNumbers: true,\n compactMode: false,\n autocompleteAutoShow: true,\n autocompleteExecuteOnSelect: true,\n },\n },\n 'global'\n );\n\n logger.info('Setup completed successfully');\n // Exit alternate screen buffer\n process.stdout.write('\\x1b[?1049l');\n setTimeout(() => resolve(), 500); // Brief delay to show completion message\n } catch (error) {\n logger.error('Setup failed', { error });\n // Exit alternate screen buffer on error\n process.stdout.write('\\x1b[?1049l');\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n },\n onCancel: (): void => {\n logger.info('Setup cancelled by user');\n // Exit alternate screen buffer on cancel\n process.stdout.write('\\x1b[?1049l');\n resolve();\n },\n }),\n {\n // Prevent console patching to avoid layout shifts\n patchConsole: false,\n }\n );\n\n // Handle process interruption (Ctrl+C)\n const cleanup = (): void => {\n process.stdout.write('\\x1b[?1049l');\n clear();\n process.exit(0);\n };\n\n process.on('SIGINT', cleanup);\n process.on('SIGTERM', cleanup);\n\n void waitUntilExit().then(() => {\n // Remove cleanup handlers\n process.off('SIGINT', cleanup);\n process.off('SIGTERM', cleanup);\n });\n });\n }\n}\n","/**\n * Setup wizard component\n * Orchestrates first-run setup flow: security warning → theme selection\n */\n\nimport React, { useState } from 'react';\nimport { Box } from 'ink';\nimport { WizardLayout } from './WizardLayout.js';\nimport { SecurityWarning } from './SecurityWarning.js';\nimport { ThemeSelector } from './ThemeSelector.js';\nimport { Theme, KeyBindingsConfig } from '../../config/schemas.js';\n\nexport interface SetupWizardProps {\n onComplete: (theme: Theme) => void | Promise<void>;\n onCancel: () => void;\n keyBindings: KeyBindingsConfig;\n}\n\ntype WizardStep = 'security' | 'theme';\n\nexport const SetupWizard: React.FC<SetupWizardProps> = ({ onComplete, onCancel, keyBindings }) => {\n const [step, setStep] = useState<WizardStep>('security');\n\n const handleSecurityAccept = () => {\n setStep('theme');\n };\n\n const handleThemeSelect = (theme: Theme) => {\n void onComplete(theme);\n };\n\n return (\n <Box flexDirection=\"column\">\n {step === 'security' && (\n <WizardLayout title=\"Welcome to Mimir Code\">\n <SecurityWarning\n onAccept={handleSecurityAccept}\n onCancel={onCancel}\n keyBindings={keyBindings}\n />\n </WizardLayout>\n )}\n {step === 'theme' && (\n <WizardLayout title=\"\">\n <ThemeSelector\n onSelect={handleThemeSelect}\n onCancel={onCancel}\n keyBindings={keyBindings}\n />\n </WizardLayout>\n )}\n </Box>\n );\n};\n","/**\n * Wizard layout component\n * Provides consistent layout with header for wizard steps\n */\n\nimport React from 'react';\nimport { Box, Text } from 'ink';\nimport { WizardHead } from './WizardHead.js';\nimport { MimirColors } from '../theme-colors.js';\n\nexport interface WizardLayoutProps {\n title: string;\n children: React.ReactNode;\n}\n\nexport const WizardLayout: React.FC<WizardLayoutProps> = ({ title, children }) => {\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1}>\n <WizardHead />\n {title && (\n <Box marginBottom={1}>\n <Text color={MimirColors.snowStorm3}>{title}</Text>\n </Box>\n )}\n {children}\n </Box>\n );\n};\n","/**\n * Wizard head ASCII art component\n * Simple wizard icon for use in setup wizard\n */\n\nimport React from 'react';\nimport { Box, Text } from 'ink';\nimport chalk from 'chalk';\nimport { MimirColors } from '../theme-colors.js';\nimport { MIMIR_LOGO } from './logo.js';\n\nexport const WizardHead: React.FC = () => {\n const nordFrost = chalk.hex(MimirColors.frost3);\n\n return (\n <Box flexDirection=\"column\" marginBottom={1} alignItems=\"center\">\n {MIMIR_LOGO.map((line, index) => (\n <Text key={index}>{nordFrost.bold(line)}</Text>\n ))}\n </Box>\n );\n};\n","/**\n * Mimir theme color constants\n * Nordic/cold blue palette for use across the entire CLI\n */\n\nexport const MimirColors = {\n // Polar Night (dark backgrounds)\n polarNight1: '#2E3440',\n polarNight2: '#3B4252',\n polarNight3: '#434C5E',\n polarNight4: '#4C566A',\n\n // Snow Storm (light foregrounds)\n snowStorm1: '#D8DEE9',\n snowStorm2: '#E5E9F0',\n snowStorm3: '#ECEFF4',\n\n // Frost (blues/cyans)\n frost1: '#8FBCBB', // Cyan\n frost2: '#88C0D0', // Bright Cyan\n frost3: '#81A1C1', // Blue\n frost4: '#5E81AC', // Dark Blue\n\n // Aurora (accent colors)\n auroraRed: '#BF616A',\n auroraOrange: '#D08770',\n auroraYellow: '#EBCB8B',\n auroraGreen: '#A3BE8C',\n auroraPurple: '#B48EAD',\n} as const;\n\nexport type MimirColor = (typeof MimirColors)[keyof typeof MimirColors];\n","/**\n * Mimir wizard ASCII art logo\n * Easily editable - each line is a separate string\n */\n\nexport const MIMIR_LOGO = ['▗█▗█▖', '█████', '▜▆█▆▛', ' ▆▅▆ '];\n","/**\n * Security warning component\n * Displays security disclosure on first run\n */\n\nimport React, { useMemo } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport figures from 'figures';\nimport chalk from 'chalk';\nimport { MimirColors } from '../theme-colors.js';\nimport { KeyBindingsConfig } from '../../config/schemas.js';\nimport { formatKeyboardShortcut } from '../../utils/keyboardFormatter.js';\n\nexport interface SecurityWarningProps {\n onAccept: () => void;\n onCancel: () => void;\n keyBindings: KeyBindingsConfig;\n}\n\nexport const SecurityWarning: React.FC<SecurityWarningProps> = ({\n onAccept,\n onCancel,\n keyBindings,\n}) => {\n useInput((_input, key) => {\n if (key.return) {\n onAccept();\n } else if (key.escape) {\n onCancel();\n }\n });\n\n const nordRed = chalk.hex(MimirColors.auroraRed);\n const nordGreen = chalk.hex(MimirColors.auroraGreen);\n\n // Format shortcuts for display\n const acceptShortcut = useMemo(\n () => formatKeyboardShortcut(keyBindings.accept),\n [keyBindings.accept]\n );\n const cancelShortcut = useMemo(\n () => formatKeyboardShortcut(keyBindings.interrupt),\n [keyBindings.interrupt]\n );\n\n return (\n <Box flexDirection=\"column\">\n <Box marginBottom={1}>\n <Text color=\"yellow\" bold>\n {figures.warning} Security Warning\n </Text>\n </Box>\n\n <Box marginBottom={1}>\n <Text>Mimir Code can execute commands and modify files on your system.</Text>\n </Box>\n\n <Box marginBottom={1}>\n <Text dimColor>You'll approve commands before execution via the permission system.</Text>\n </Box>\n\n <Box>\n <Text>\n Press {nordGreen(acceptShortcut)} to continue or {nordRed(cancelShortcut)} to cancel\n </Text>\n </Box>\n </Box>\n );\n};\n","/**\n * Keyboard shortcut formatting utility\n * Converts keyboard shortcuts to user-friendly display format with icons\n */\n\nimport os from 'os';\n\n/**\n * Icon mappings for keyboard keys\n */\nconst KEY_ICONS: Record<string, string> = {\n // Arrow keys\n ArrowUp: '↑',\n ArrowDown: '↓',\n ArrowLeft: '←',\n ArrowRight: '→',\n Up: '↑',\n Down: '↓',\n Left: '←',\n Right: '→',\n\n // Special keys\n Enter: '↵',\n Return: '↵',\n Backspace: '⌫',\n Delete: '⌦',\n Del: '⌦',\n Space: '␣',\n\n // Modifiers\n Shift: '⇧',\n Control: '⌃',\n Ctrl: '⌃',\n Command: '⌘',\n Cmd: '⌘',\n Meta: '⌘',\n};\n\n/**\n * Platform-specific modifier names\n */\nconst PLATFORM_MODIFIERS: Record<string, Record<string, string>> = {\n darwin: {\n Ctrl: 'Cmd',\n Control: 'Command',\n },\n win32: {\n Cmd: 'Ctrl',\n Command: 'Control',\n },\n linux: {\n Cmd: 'Ctrl',\n Command: 'Control',\n },\n};\n\nexport interface KeyboardFormatterOptions {\n /**\n * Use icons instead of text (default: true)\n * When true: ArrowUp → ↑, Enter → ↵, Ctrl → ⌃\n * When false: ArrowUp → Arrow Up, Enter → Enter, Ctrl → Ctrl\n */\n useIcons?: boolean;\n\n /**\n * Use icons for modifiers (default: false)\n * When true: Ctrl+C → ⌃C\n * When false: Ctrl+C → Ctrl+C\n */\n useModifierIcons?: boolean;\n\n /**\n * Platform override (default: current platform)\n * Used to convert Ctrl/Cmd based on platform\n */\n platform?: NodeJS.Platform;\n\n /**\n * Separator for multiple shortcuts (default: ', ')\n * Example: 'Ctrl+C, Escape' vs 'Ctrl+C / Escape'\n */\n separator?: string;\n\n /**\n * Show only first shortcut when multiple are provided (default: false)\n */\n showFirstOnly?: boolean;\n}\n\n/**\n * Normalize key name for consistent formatting\n * Handles case variations and aliases\n */\nfunction normalizeKeyName(key: string): string {\n return key\n .replace(/Control/gi, 'Ctrl')\n .replace(/Command/gi, 'Cmd')\n .replace(/Delete/gi, 'Del')\n .replace(/Escape/gi, 'Esc')\n .split('+')\n .map((part) => part.trim())\n .map((part) => {\n const lower = part.toLowerCase();\n\n // Handle arrow keys with proper casing (case-insensitive input)\n if (lower === 'arrowup' || lower === 'up') return 'ArrowUp';\n if (lower === 'arrowdown' || lower === 'down') return 'ArrowDown';\n if (lower === 'arrowleft' || lower === 'left') return 'ArrowLeft';\n if (lower === 'arrowright' || lower === 'right') return 'ArrowRight';\n\n // Standard case: capitalize first letter\n const normalized = part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();\n\n // Map common aliases\n if (normalized === 'Meta') return 'Cmd';\n if (normalized === 'Option') return 'Alt';\n\n return normalized;\n })\n .join('+');\n}\n\n/**\n * Apply platform-specific modifier conversions\n */\nfunction applyPlatformModifiers(key: string, platform: NodeJS.Platform): string {\n const modifiers = PLATFORM_MODIFIERS[platform] || PLATFORM_MODIFIERS.linux;\n if (!modifiers) return key;\n\n let result = key;\n\n for (const [from, to] of Object.entries(modifiers)) {\n // Replace modifier keys, being careful with word boundaries\n result = result.replace(new RegExp(`\\\\b${from}\\\\b`, 'g'), to);\n }\n\n return result;\n}\n\n/**\n * Format a single keyboard shortcut with icons\n */\nfunction formatSingleShortcut(\n shortcut: string,\n options: Required<KeyboardFormatterOptions>\n): string {\n const { useIcons, useModifierIcons, platform } = options;\n\n // Normalize and apply platform modifiers\n let normalized = normalizeKeyName(shortcut);\n normalized = applyPlatformModifiers(normalized, platform);\n\n // Split into parts (e.g., \"Ctrl+Shift+C\" → [\"Ctrl\", \"Shift\", \"C\"])\n const parts = normalized.split('+').map((p) => p.trim());\n\n // Format each part\n const formatted = parts.map((part, index) => {\n const isModifier = index < parts.length - 1; // All parts except the last are modifiers\n const icon = KEY_ICONS[part];\n\n if (useIcons && icon) {\n // Use icon if available\n if (isModifier && !useModifierIcons) {\n // For modifiers, respect useModifierIcons option\n return part;\n }\n return icon;\n }\n\n // No icon - format as readable text\n if (part.startsWith('Arrow')) {\n // ArrowUp → Up (when not using icons)\n return part.replace('Arrow', '');\n }\n\n return part;\n });\n\n // Join with '+' for modifier combinations, or directly for single keys\n if (formatted.length === 1) {\n return formatted[0] ?? '';\n }\n\n // Join modifiers with '+' or '' depending on whether we're using modifier icons\n if (useModifierIcons && formatted.every((f) => f.length === 1)) {\n // All single chars (icons) - no separator needed (e.g., ⌘⇧C)\n return formatted.join('');\n }\n\n return formatted.join('+');\n}\n\n/**\n * Format keyboard shortcut(s) for display\n *\n * @param shortcuts - Single shortcut string or array of shortcuts\n * @param options - Formatting options\n * @returns Formatted shortcut string\n *\n * @example\n * ```typescript\n * // Single shortcut with icons\n * formatKeyboardShortcut('ArrowUp');\n * // → '↑'\n *\n * // Multiple shortcuts\n * formatKeyboardShortcut(['Ctrl+C', 'Escape']);\n * // → 'Ctrl+C, Esc'\n *\n * // With modifier icons\n * formatKeyboardShortcut('Ctrl+Shift+C', { useModifierIcons: true });\n * // → '⌃⇧C'\n *\n * // Without icons\n * formatKeyboardShortcut('Enter', { useIcons: false });\n * // → 'Enter'\n *\n * // Navigation keys for footer\n * formatKeyboardShortcut(['ArrowUp', 'ArrowDown'], { separator: '/' });\n * // → '↑/↓'\n * ```\n */\nexport function formatKeyboardShortcut(\n shortcuts: string | string[],\n options: KeyboardFormatterOptions = {}\n): string {\n const opts: Required<KeyboardFormatterOptions> = {\n useIcons: options.useIcons ?? true,\n useModifierIcons: options.useModifierIcons ?? false,\n platform: options.platform ?? os.platform(),\n separator: options.separator ?? ', ',\n showFirstOnly: options.showFirstOnly ?? false,\n };\n\n // Handle array of shortcuts\n if (Array.isArray(shortcuts)) {\n if (shortcuts.length === 0) return '';\n if (opts.showFirstOnly) {\n const first = shortcuts[0];\n if (!first) return '';\n return formatSingleShortcut(first, opts);\n }\n return shortcuts.map((s) => formatSingleShortcut(s, opts)).join(opts.separator);\n }\n\n // Single shortcut\n return formatSingleShortcut(shortcuts, opts);\n}\n\n/**\n * Helper for navigation arrows (↑↓)\n * Common pattern in UI footers\n */\nexport function formatNavigationArrows(\n upShortcut: string | string[],\n downShortcut: string | string[],\n options: KeyboardFormatterOptions = {}\n): string {\n const up = formatKeyboardShortcut(upShortcut, { ...options, showFirstOnly: true });\n const down = formatKeyboardShortcut(downShortcut, { ...options, showFirstOnly: true });\n return `${up}${down}`;\n}\n\n/**\n * Helper for building UI footer text with shortcuts\n *\n * @example\n * ```typescript\n * buildFooterText([\n * { shortcut: ['ArrowUp', 'ArrowDown'], label: 'navigate' },\n * { shortcut: 'Enter', label: 'select' },\n * { shortcut: ['Ctrl+C', 'Escape'], label: 'cancel' },\n * ]);\n * // → '↑↓ navigate | Enter select | Ctrl+C, Esc cancel'\n * ```\n */\nexport function buildFooterText(\n items: Array<{ shortcut: string | string[]; label: string }>,\n options: KeyboardFormatterOptions = {}\n): string {\n return items\n .map(({ shortcut, label }) => {\n const formatted = formatKeyboardShortcut(shortcut, options);\n return `${formatted} ${label}`;\n })\n .join(' | ');\n}\n","/**\n * Theme selector component with code preview\n * Allows user to choose from available themes with live preview\n */\n\nimport React, { useState, useMemo } from 'react';\nimport { Box, Text } from 'ink';\nimport SelectInput from 'ink-select-input';\nimport chalk from 'chalk';\nimport { Theme, KeyBindingsConfig } from '../../config/schemas.js';\nimport { getTheme, getAllThemes, getThemeMetadata } from '../../config/themes/index.js';\nimport { getPreviewWithDiff } from '../utils/syntaxHighlight.js';\nimport { buildFooterText } from '../../utils/keyboardFormatter.js';\n\nexport interface ThemeSelectorProps {\n onSelect: (theme: Theme) => void;\n onCancel: () => void;\n keyBindings: KeyBindingsConfig;\n}\n\nexport const ThemeSelector: React.FC<ThemeSelectorProps> = ({\n onSelect,\n onCancel: _onCancel,\n keyBindings,\n}) => {\n const [highlightedIndex, setHighlightedIndex] = useState(0);\n\n // Get all available themes dynamically\n const availableThemes = getAllThemes();\n const items = availableThemes.map((themeKey) => {\n const metadata = getThemeMetadata(themeKey);\n return {\n label: metadata.name,\n value: themeKey,\n };\n });\n\n const currentThemeKey = availableThemes[highlightedIndex];\n if (!currentThemeKey) return null;\n const themeColors = getTheme(currentThemeKey);\n const preview = getPreviewWithDiff();\n\n const bg = chalk.bgHex('#1e1e1e');\n const fg = chalk.hex('#eceff4');\n\n // Build footer text from keyboard shortcuts\n const footerText = useMemo(() => {\n const navUp = keyBindings.navigateUp[0] ?? 'ArrowUp';\n const navDown = keyBindings.navigateDown[0] ?? 'ArrowDown';\n return buildFooterText([\n { shortcut: [navUp, navDown], label: 'navigate' },\n { shortcut: keyBindings.accept ?? 'Enter', label: 'select' },\n { shortcut: keyBindings.interrupt ?? 'Escape', label: 'cancel' },\n ]);\n }, [keyBindings]);\n\n return (\n <Box flexDirection=\"column\">\n <Text>{bg(fg.bold(' Select your theme: '))}</Text>\n <Text>{bg(' ')}</Text>\n\n <Box flexDirection=\"column\">\n <SelectInput\n items={items}\n onSelect={(item) => onSelect(item.value)}\n onHighlight={(item) => {\n const index = availableThemes.findIndex((t) => t === item.value);\n if (index !== -1) setHighlightedIndex(index);\n }}\n />\n </Box>\n\n <Text>{bg(' ')}</Text>\n <Text>{bg(fg(' Preview: '))}</Text>\n {preview.map((item, idx) => (\n <Text key={idx}>\n {item.type === 'remove' && bg(themeColors.colors.diffRemoveLine(`- ${item.line}`))}\n {item.type === 'add' && bg(themeColors.colors.diffAddLine(`+ ${item.line}`))}\n {item.type === 'normal' &&\n bg(\n fg(\n ` ${themeColors.colors.keyword(item.line.match(/return/)?.[0] || '')}${item.line.replace(/return/, '')}`\n )\n )}\n </Text>\n ))}\n <Text>{bg(' ')}</Text>\n\n <Text>{bg(chalk.dim(` ${footerText} `))}</Text>\n </Box>\n );\n};\n","/**\n * Theme JSON schema and parser\n * Converts JSON theme definitions to chalk-based themes\n */\n\nimport chalk from 'chalk';\nimport type { ThemeDefinition, ThemeColors } from './index.js';\n\nexport interface ThemeColorJSON {\n fg?: string; // Foreground color (hex)\n bg?: string; // Background color (hex)\n bold?: boolean;\n dim?: boolean;\n italic?: boolean;\n underline?: boolean;\n}\n\nexport interface ThemeJSON {\n name: string;\n supportsFullColor: boolean;\n colors: {\n // UI Elements\n headerBg: ThemeColorJSON;\n headerText: ThemeColorJSON;\n footerBg: ThemeColorJSON;\n footerText: ThemeColorJSON;\n inputPrompt: ThemeColorJSON;\n inputText: ThemeColorJSON;\n autocompleteBg: ThemeColorJSON;\n\n // Autocomplete specific\n autocompleteText: ThemeColorJSON;\n autocompleteSelectedBg: ThemeColorJSON;\n autocompleteSelectedText: ThemeColorJSON;\n autocompleteHeaderText: ThemeColorJSON;\n autocompleteFooterText: ThemeColorJSON;\n autocompleteMoreIndicator: ThemeColorJSON;\n\n // Mode indicators\n modePlan: ThemeColorJSON;\n modeAct: ThemeColorJSON;\n modeDiscuss: ThemeColorJSON;\n\n // Message roles\n userMessage: ThemeColorJSON;\n assistantMessage: ThemeColorJSON;\n systemMessage: ThemeColorJSON;\n\n // Syntax highlighting\n keyword: ThemeColorJSON;\n string: ThemeColorJSON;\n number: ThemeColorJSON;\n comment: ThemeColorJSON;\n function: ThemeColorJSON;\n variable: ThemeColorJSON;\n\n // Status indicators\n success: ThemeColorJSON;\n warning: ThemeColorJSON;\n error: ThemeColorJSON;\n info: ThemeColorJSON;\n\n // Diff colors\n diffAddLine: ThemeColorJSON;\n diffRemoveLine: ThemeColorJSON;\n };\n}\n\n/**\n * Parse a JSON theme color definition into a chalk instance\n */\nfunction parseColor(color: ThemeColorJSON): typeof chalk {\n let result = chalk;\n\n if (color.bg) {\n result = result.bgHex(color.bg);\n }\n if (color.fg) {\n result = result.hex(color.fg);\n }\n if (color.bold) {\n result = result.bold;\n }\n if (color.dim) {\n result = result.dim;\n }\n if (color.italic) {\n result = result.italic;\n }\n if (color.underline) {\n result = result.underline;\n }\n\n return result;\n}\n\n/**\n * Convert a JSON theme definition to a ThemeDefinition\n */\nexport function parseThemeJSON(json: ThemeJSON): ThemeDefinition {\n const colors: ThemeColors = {\n headerBg: parseColor(json.colors.headerBg),\n headerText: parseColor(json.colors.headerText),\n footerBg: parseColor(json.colors.footerBg),\n footerText: parseColor(json.colors.footerText),\n inputPrompt: parseColor(json.colors.inputPrompt),\n inputText: parseColor(json.colors.inputText),\n autocompleteBg: parseColor(json.colors.autocompleteBg),\n\n autocompleteText: parseColor(json.colors.autocompleteText),\n autocompleteSelectedBg: parseColor(json.colors.autocompleteSelectedBg),\n autocompleteSelectedText: parseColor(json.colors.autocompleteSelectedText),\n autocompleteHeaderText: parseColor(json.colors.autocompleteHeaderText),\n autocompleteFooterText: parseColor(json.colors.autocompleteFooterText),\n autocompleteMoreIndicator: parseColor(json.colors.autocompleteMoreIndicator),\n\n modePlan: parseColor(json.colors.modePlan),\n modeAct: parseColor(json.colors.modeAct),\n modeDiscuss: parseColor(json.colors.modeDiscuss),\n\n userMessage: parseColor(json.colors.userMessage),\n assistantMessage: parseColor(json.colors.assistantMessage),\n systemMessage: parseColor(json.colors.systemMessage),\n\n keyword: parseColor(json.colors.keyword),\n string: parseColor(json.colors.string),\n number: parseColor(json.colors.number),\n comment: parseColor(json.colors.comment),\n function: parseColor(json.colors.function),\n variable: parseColor(json.colors.variable),\n\n success: parseColor(json.colors.success),\n warning: parseColor(json.colors.warning),\n error: parseColor(json.colors.error),\n info: parseColor(json.colors.info),\n\n diffAddLine: parseColor(json.colors.diffAddLine),\n diffRemoveLine: parseColor(json.colors.diffRemoveLine),\n };\n\n return {\n name: json.name,\n colors,\n supportsFullColor: json.supportsFullColor,\n rawColors: {\n autocompleteBg: json.colors.autocompleteBg.bg,\n autocompleteSelectedBg: json.colors.autocompleteSelectedBg.bg,\n },\n };\n}\n","{\n \"name\": \"Mimir\",\n \"supportsFullColor\": true,\n \"colors\": {\n \"headerBg\": { \"bg\": \"#2E3440\", \"fg\": \"#ECEFF4\" },\n \"headerText\": { \"fg\": \"#D8DEE9\" },\n \"footerBg\": { \"bg\": \"#3B4252\" },\n \"footerText\": { \"fg\": \"#4C566A\" },\n \"inputPrompt\": { \"fg\": \"#88C0D0\" },\n \"inputText\": { \"fg\": \"#ECEFF4\" },\n \"autocompleteBg\": { \"bg\": \"#3B4252\" },\n\n \"autocompleteText\": { \"fg\": \"#ECEFF4\" },\n \"autocompleteSelectedBg\": { \"bg\": \"#88C0D0\", \"fg\": \"#2E3440\" },\n \"autocompleteSelectedText\": { \"fg\": \"#2E3440\" },\n \"autocompleteHeaderText\": { \"fg\": \"#88C0D0\", \"bold\": true },\n \"autocompleteFooterText\": { \"fg\": \"#616E88\" },\n \"autocompleteMoreIndicator\": { \"fg\": \"#616E88\" },\n\n \"modePlan\": { \"fg\": \"#5E81AC\" },\n \"modeAct\": { \"fg\": \"#A3BE8C\" },\n \"modeDiscuss\": { \"fg\": \"#B48EAD\" },\n\n \"userMessage\": { \"fg\": \"#8FBCBB\" },\n \"assistantMessage\": { \"fg\": \"#81A1C1\" },\n \"systemMessage\": { \"fg\": \"#5E81AC\" },\n\n \"keyword\": { \"fg\": \"#81A1C1\" },\n \"string\": { \"fg\": \"#A3BE8C\" },\n \"number\": { \"fg\": \"#B48EAD\" },\n \"comment\": { \"fg\": \"#616E88\" },\n \"function\": { \"fg\": \"#88C0D0\" },\n \"variable\": { \"fg\": \"#D8DEE9\" },\n\n \"success\": { \"fg\": \"#A3BE8C\" },\n \"warning\": { \"fg\": \"#EBCB8B\" },\n \"error\": { \"fg\": \"#BF616A\" },\n \"info\": { \"fg\": \"#88C0D0\" },\n\n \"diffAddLine\": { \"bg\": \"#A3BE8C\", \"fg\": \"#FFFFFF\" },\n \"diffRemoveLine\": { \"bg\": \"#D08770\", \"fg\": \"#FFFFFF\" }\n }\n}\n","{\n \"name\": \"Dark\",\n \"supportsFullColor\": true,\n \"colors\": {\n \"headerBg\": { \"bg\": \"#1a1a1a\", \"fg\": \"#ffffff\" },\n \"headerText\": { \"fg\": \"#e0e0e0\" },\n \"footerBg\": { \"bg\": \"#2d2d2d\" },\n \"footerText\": { \"fg\": \"#888888\" },\n \"inputPrompt\": { \"fg\": \"#00d4ff\" },\n \"inputText\": { \"fg\": \"#ffffff\" },\n \"autocompleteBg\": { \"bg\": \"#2d2d2d\" },\n\n \"autocompleteText\": { \"fg\": \"#ffffff\" },\n \"autocompleteSelectedBg\": { \"bg\": \"#00d4ff\", \"fg\": \"#000000\" },\n \"autocompleteSelectedText\": { \"fg\": \"#000000\" },\n \"autocompleteHeaderText\": { \"fg\": \"#00d4ff\", \"bold\": true },\n \"autocompleteFooterText\": { \"fg\": \"#666666\" },\n \"autocompleteMoreIndicator\": { \"fg\": \"#666666\" },\n\n \"modePlan\": { \"fg\": \"#2196F3\" },\n \"modeAct\": { \"fg\": \"#4CAF50\" },\n \"modeDiscuss\": { \"fg\": \"#C792EA\" },\n\n \"userMessage\": { \"fg\": \"#4CAF50\" },\n \"assistantMessage\": { \"fg\": \"#2196F3\" },\n \"systemMessage\": { \"fg\": \"#FF9800\" },\n\n \"keyword\": { \"fg\": \"#C792EA\" },\n \"string\": { \"fg\": \"#C3E88D\" },\n \"number\": { \"fg\": \"#F78C6C\" },\n \"comment\": { \"fg\": \"#546E7A\" },\n \"function\": { \"fg\": \"#82AAFF\" },\n \"variable\": { \"fg\": \"#EEFFFF\" },\n\n \"success\": { \"fg\": \"#4CAF50\" },\n \"warning\": { \"fg\": \"#FFC107\" },\n \"error\": { \"fg\": \"#F44336\" },\n \"info\": { \"fg\": \"#2196F3\" },\n\n \"diffAddLine\": { \"bg\": \"#22863a\", \"fg\": \"#ffffff\" },\n \"diffRemoveLine\": { \"bg\": \"#cb2431\", \"fg\": \"#ffffff\" }\n }\n}\n","{\n \"name\": \"Light\",\n \"supportsFullColor\": true,\n \"colors\": {\n \"headerBg\": { \"bg\": \"#f5f5f5\", \"fg\": \"#000000\" },\n \"headerText\": { \"fg\": \"#424242\" },\n \"footerBg\": { \"bg\": \"#e0e0e0\" },\n \"footerText\": { \"fg\": \"#757575\" },\n \"inputPrompt\": { \"fg\": \"#0288D1\" },\n \"inputText\": { \"fg\": \"#212121\" },\n \"autocompleteBg\": { \"bg\": \"#e0e0e0\" },\n\n \"autocompleteText\": { \"fg\": \"#212121\" },\n \"autocompleteSelectedBg\": { \"bg\": \"#0288D1\", \"fg\": \"#ffffff\" },\n \"autocompleteSelectedText\": { \"fg\": \"#ffffff\" },\n \"autocompleteHeaderText\": { \"fg\": \"#0288D1\", \"bold\": true },\n \"autocompleteFooterText\": { \"fg\": \"#9E9E9E\" },\n \"autocompleteMoreIndicator\": { \"fg\": \"#9E9E9E\" },\n\n \"modePlan\": { \"fg\": \"#1565C0\" },\n \"modeAct\": { \"fg\": \"#2E7D32\" },\n \"modeDiscuss\": { \"fg\": \"#7B1FA2\" },\n\n \"userMessage\": { \"fg\": \"#2E7D32\" },\n \"assistantMessage\": { \"fg\": \"#1565C0\" },\n \"systemMessage\": { \"fg\": \"#EF6C00\" },\n\n \"keyword\": { \"fg\": \"#7B1FA2\" },\n \"string\": { \"fg\": \"#558B2F\" },\n \"number\": { \"fg\": \"#D84315\" },\n \"comment\": { \"fg\": \"#9E9E9E\" },\n \"function\": { \"fg\": \"#1976D2\" },\n \"variable\": { \"fg\": \"#424242\" },\n\n \"success\": { \"fg\": \"#2E7D32\" },\n \"warning\": { \"fg\": \"#F57C00\" },\n \"error\": { \"fg\": \"#C62828\" },\n \"info\": { \"fg\": \"#1565C0\" },\n\n \"diffAddLine\": { \"bg\": \"#d1f4d1\", \"fg\": \"#000000\" },\n \"diffRemoveLine\": { \"bg\": \"#ffeef0\", \"fg\": \"#000000\" }\n }\n}\n","{\n \"name\": \"Dark Colorblind\",\n \"supportsFullColor\": true,\n \"colors\": {\n \"headerBg\": { \"bg\": \"#1a1a1a\", \"fg\": \"#ffffff\" },\n \"headerText\": { \"fg\": \"#e0e0e0\" },\n \"footerBg\": { \"bg\": \"#2d2d2d\" },\n \"footerText\": { \"fg\": \"#888888\" },\n \"inputPrompt\": { \"fg\": \"#64B5F6\" },\n \"inputText\": { \"fg\": \"#ffffff\" },\n \"autocompleteBg\": { \"bg\": \"#2d2d2d\" },\n\n \"autocompleteText\": { \"fg\": \"#ffffff\" },\n \"autocompleteSelectedBg\": { \"bg\": \"#64B5F6\", \"fg\": \"#000000\" },\n \"autocompleteSelectedText\": { \"fg\": \"#000000\" },\n \"autocompleteHeaderText\": { \"fg\": \"#64B5F6\", \"bold\": true },\n \"autocompleteFooterText\": { \"fg\": \"#757575\" },\n \"autocompleteMoreIndicator\": { \"fg\": \"#757575\" },\n\n \"modePlan\": { \"fg\": \"#64B5F6\" },\n \"modeAct\": { \"fg\": \"#81C784\" },\n \"modeDiscuss\": { \"fg\": \"#9575CD\" },\n\n \"userMessage\": { \"fg\": \"#64B5F6\" },\n \"assistantMessage\": { \"fg\": \"#FFB74D\" },\n \"systemMessage\": { \"fg\": \"#9575CD\" },\n\n \"keyword\": { \"fg\": \"#E1BEE7\" },\n \"string\": { \"fg\": \"#FFE082\" },\n \"number\": { \"fg\": \"#FFAB91\" },\n \"comment\": { \"fg\": \"#757575\" },\n \"function\": { \"fg\": \"#90CAF9\" },\n \"variable\": { \"fg\": \"#E0E0E0\" },\n\n \"success\": { \"fg\": \"#81C784\" },\n \"warning\": { \"fg\": \"#FFB74D\" },\n \"error\": { \"fg\": \"#E57373\" },\n \"info\": { \"fg\": \"#64B5F6\" },\n\n \"diffAddLine\": { \"bg\": \"#1976D2\", \"fg\": \"#ffffff\" },\n \"diffRemoveLine\": { \"bg\": \"#EF6C00\", \"fg\": \"#ffffff\" }\n }\n}\n","{\n \"name\": \"Light Colorblind\",\n \"supportsFullColor\": true,\n \"colors\": {\n \"headerBg\": { \"bg\": \"#f5f5f5\", \"fg\": \"#000000\" },\n \"headerText\": { \"fg\": \"#424242\" },\n \"footerBg\": { \"bg\": \"#e0e0e0\" },\n \"footerText\": { \"fg\": \"#757575\" },\n \"inputPrompt\": { \"fg\": \"#1976D2\" },\n \"inputText\": { \"fg\": \"#212121\" },\n \"autocompleteBg\": { \"bg\": \"#e0e0e0\" },\n\n \"autocompleteText\": { \"fg\": \"#212121\" },\n \"autocompleteSelectedBg\": { \"bg\": \"#1976D2\", \"fg\": \"#ffffff\" },\n \"autocompleteSelectedText\": { \"fg\": \"#ffffff\" },\n \"autocompleteHeaderText\": { \"fg\": \"#1976D2\", \"bold\": true },\n \"autocompleteFooterText\": { \"fg\": \"#9E9E9E\" },\n \"autocompleteMoreIndicator\": { \"fg\": \"#9E9E9E\" },\n\n \"modePlan\": { \"fg\": \"#1976D2\" },\n \"modeAct\": { \"fg\": \"#388E3C\" },\n \"modeDiscuss\": { \"fg\": \"#7B1FA2\" },\n\n \"userMessage\": { \"fg\": \"#1976D2\" },\n \"assistantMessage\": { \"fg\": \"#F57C00\" },\n \"systemMessage\": { \"fg\": \"#7B1FA2\" },\n\n \"keyword\": { \"fg\": \"#8E24AA\" },\n \"string\": { \"fg\": \"#F9A825\" },\n \"number\": { \"fg\": \"#D84315\" },\n \"comment\": { \"fg\": \"#9E9E9E\" },\n \"function\": { \"fg\": \"#1565C0\" },\n \"variable\": { \"fg\": \"#424242\" },\n\n \"success\": { \"fg\": \"#388E3C\" },\n \"warning\": { \"fg\": \"#F57C00\" },\n \"error\": { \"fg\": \"#D32F2F\" },\n \"info\": { \"fg\": \"#1976D2\" },\n\n \"diffAddLine\": { \"bg\": \"#BBDEFB\", \"fg\": \"#000000\" },\n \"diffRemoveLine\": { \"bg\": \"#FFE0B2\", \"fg\": \"#000000\" }\n }\n}\n","{\n \"name\": \"Dark ANSI\",\n \"supportsFullColor\": false,\n \"colors\": {\n \"headerBg\": { \"bg\": \"#000000\", \"fg\": \"#FFFFFF\" },\n \"headerText\": { \"fg\": \"#FFFFFF\" },\n \"footerBg\": { \"bg\": \"#000000\" },\n \"footerText\": { \"fg\": \"#808080\" },\n \"inputPrompt\": { \"fg\": \"#00FFFF\" },\n \"inputText\": { \"fg\": \"#FFFFFF\" },\n \"autocompleteBg\": { \"bg\": \"#000000\" },\n\n \"autocompleteText\": { \"fg\": \"#FFFFFF\" },\n \"autocompleteSelectedBg\": { \"bg\": \"#00FFFF\", \"fg\": \"#000000\" },\n \"autocompleteSelectedText\": { \"fg\": \"#000000\" },\n \"autocompleteHeaderText\": { \"fg\": \"#00FFFF\", \"bold\": true },\n \"autocompleteFooterText\": { \"fg\": \"#808080\" },\n \"autocompleteMoreIndicator\": { \"fg\": \"#808080\" },\n\n \"modePlan\": { \"fg\": \"#0000FF\" },\n \"modeAct\": { \"fg\": \"#00FF00\" },\n \"modeDiscuss\": { \"fg\": \"#FF00FF\" },\n\n \"userMessage\": { \"fg\": \"#00FF00\" },\n \"assistantMessage\": { \"fg\": \"#0000FF\" },\n \"systemMessage\": { \"fg\": \"#FFFF00\" },\n\n \"keyword\": { \"fg\": \"#FF00FF\" },\n \"string\": { \"fg\": \"#00FF00\" },\n \"number\": { \"fg\": \"#FF0000\" },\n \"comment\": { \"fg\": \"#808080\" },\n \"function\": { \"fg\": \"#0000FF\" },\n \"variable\": { \"fg\": \"#FFFFFF\" },\n\n \"success\": { \"fg\": \"#00FF00\" },\n \"warning\": { \"fg\": \"#FFFF00\" },\n \"error\": { \"fg\": \"#FF0000\" },\n \"info\": { \"fg\": \"#0000FF\" },\n\n \"diffAddLine\": { \"bg\": \"#008000\", \"fg\": \"#FFFFFF\" },\n \"diffRemoveLine\": { \"bg\": \"#800000\", \"fg\": \"#FFFFFF\" }\n }\n}\n","{\n \"name\": \"Light ANSI\",\n \"supportsFullColor\": false,\n \"colors\": {\n \"headerBg\": { \"bg\": \"#FFFFFF\", \"fg\": \"#000000\" },\n \"headerText\": { \"fg\": \"#000000\" },\n \"footerBg\": { \"bg\": \"#FFFFFF\" },\n \"footerText\": { \"fg\": \"#808080\" },\n \"inputPrompt\": { \"fg\": \"#0000FF\" },\n \"inputText\": { \"fg\": \"#000000\" },\n \"autocompleteBg\": { \"bg\": \"#FFFFFF\" },\n\n \"autocompleteText\": { \"fg\": \"#000000\" },\n \"autocompleteSelectedBg\": { \"bg\": \"#0000FF\", \"fg\": \"#FFFFFF\" },\n \"autocompleteSelectedText\": { \"fg\": \"#FFFFFF\" },\n \"autocompleteHeaderText\": { \"fg\": \"#0000FF\", \"bold\": true },\n \"autocompleteFooterText\": { \"fg\": \"#808080\" },\n \"autocompleteMoreIndicator\": { \"fg\": \"#808080\" },\n\n \"modePlan\": { \"fg\": \"#0000FF\" },\n \"modeAct\": { \"fg\": \"#00FF00\" },\n \"modeDiscuss\": { \"fg\": \"#FF00FF\" },\n\n \"userMessage\": { \"fg\": \"#00FF00\" },\n \"assistantMessage\": { \"fg\": \"#0000FF\" },\n \"systemMessage\": { \"fg\": \"#FFFF00\" },\n\n \"keyword\": { \"fg\": \"#FF00FF\" },\n \"string\": { \"fg\": \"#00FF00\" },\n \"number\": { \"fg\": \"#FF0000\" },\n \"comment\": { \"fg\": \"#808080\" },\n \"function\": { \"fg\": \"#0000FF\" },\n \"variable\": { \"fg\": \"#000000\" },\n\n \"success\": { \"fg\": \"#00FF00\" },\n \"warning\": { \"fg\": \"#FFFF00\" },\n \"error\": { \"fg\": \"#FF0000\" },\n \"info\": { \"fg\": \"#0000FF\" },\n\n \"diffAddLine\": { \"bg\": \"#90EE90\", \"fg\": \"#000000\" },\n \"diffRemoveLine\": { \"bg\": \"#FFB6C1\", \"fg\": \"#000000\" }\n }\n}\n","/**\n * Theme registry and definitions\n */\n\nimport { Theme } from '../schemas.js';\nimport chalk from 'chalk';\n\nexport interface ThemeColors {\n // UI Elements\n headerBg: typeof chalk;\n headerText: typeof chalk;\n footerBg: typeof chalk;\n footerText: typeof chalk;\n inputPrompt: typeof chalk;\n inputText: typeof chalk;\n autocompleteBg: typeof chalk;\n\n // Autocomplete specific\n autocompleteText: typeof chalk;\n autocompleteSelectedBg: typeof chalk;\n autocompleteSelectedText: typeof chalk;\n autocompleteHeaderText: typeof chalk;\n autocompleteFooterText: typeof chalk;\n autocompleteMoreIndicator: typeof chalk;\n\n // Mode indicators\n modePlan: typeof chalk;\n modeAct: typeof chalk;\n modeDiscuss: typeof chalk;\n\n // Message roles\n userMessage: typeof chalk;\n assistantMessage: typeof chalk;\n systemMessage: typeof chalk;\n\n // Syntax highlighting\n keyword: typeof chalk;\n string: typeof chalk;\n number: typeof chalk;\n comment: typeof chalk;\n function: typeof chalk;\n variable: typeof chalk;\n\n // Status indicators\n success: typeof chalk;\n warning: typeof chalk;\n error: typeof chalk;\n info: typeof chalk;\n\n // Diff colors\n diffAddLine: typeof chalk;\n diffRemoveLine: typeof chalk;\n}\n\nexport interface ThemeDefinition {\n name: string;\n colors: ThemeColors;\n supportsFullColor: boolean; // true for 24-bit, false for ANSI-only\n rawColors: {\n autocompleteBg?: string; // Raw hex color for components that need it\n autocompleteSelectedBg?: string; // Raw hex color for selected autocomplete item\n };\n}\n\n// Theme registry\nconst themes = new Map<Theme, ThemeDefinition>();\n\nexport function registerTheme(theme: Theme, definition: ThemeDefinition): void {\n themes.set(theme, definition);\n}\n\nexport function getTheme(theme: Theme): ThemeDefinition {\n const definition = themes.get(theme);\n if (!definition) {\n throw new Error(`Theme ${theme} not found`);\n }\n return definition;\n}\n\nexport function getAllThemes(): Theme[] {\n return Array.from(themes.keys());\n}\n\nexport function getThemeMetadata(theme: Theme): { name: string } {\n const definition = getTheme(theme);\n return {\n name: definition.name,\n };\n}\n\n// Initialize all themes from JSON dynamically\nimport { parseThemeJSON, ThemeJSON } from './theme-schema.js';\nimport mimirJSON from './definitions/mimir.json' assert { type: 'json' };\nimport darkJSON from './definitions/dark.json' assert { type: 'json' };\nimport lightJSON from './definitions/light.json' assert { type: 'json' };\nimport darkColorblindJSON from './definitions/dark-colorblind.json' assert { type: 'json' };\nimport lightColorblindJSON from './definitions/light-colorblind.json' assert { type: 'json' };\nimport darkAnsiJSON from './definitions/dark-ansi.json' assert { type: 'json' };\nimport lightAnsiJSON from './definitions/light-ansi.json' assert { type: 'json' };\n\n// Map of theme key to JSON\nconst themeDefinitions: Record<string, ThemeJSON> = {\n mimir: mimirJSON as ThemeJSON,\n dark: darkJSON as ThemeJSON,\n light: lightJSON as ThemeJSON,\n 'dark-colorblind': darkColorblindJSON as ThemeJSON,\n 'light-colorblind': lightColorblindJSON as ThemeJSON,\n 'dark-ansi': darkAnsiJSON as ThemeJSON,\n 'light-ansi': lightAnsiJSON as ThemeJSON,\n};\n\n// Register all themes\nObject.entries(themeDefinitions).forEach(([key, json]) => {\n registerTheme(key as Theme, parseThemeJSON(json));\n});\n","/**\n * Syntax highlighting utility\n * Highlights code snippets using theme colors\n */\n\nimport { ThemeColors } from '../../config/themes/index.js';\n\nexport interface HighlightedToken {\n text: string;\n color: typeof import('chalk');\n}\n\n/**\n * Simple regex-based syntax highlighter for TypeScript/JavaScript\n */\nexport function highlightCode(code: string, themeColors: ThemeColors): string {\n let result = code;\n\n // Keywords\n const keywords =\n /\\b(const|let|var|function|class|interface|type|export|import|from|return|if|else|for|while|async|await|new|this|extends|implements)\\b/g;\n result = result.replace(keywords, (match) => themeColors.keyword(match));\n\n // Strings (both single and double quotes)\n const strings = /(['\"`])(?:(?=(\\\\?))\\2.)*?\\1/g;\n result = result.replace(strings, (match) => themeColors.string(match));\n\n // Numbers\n const numbers = /\\b\\d+(\\.\\d+)?\\b/g;\n result = result.replace(numbers, (match) => themeColors.number(match));\n\n // Comments\n const comments = /\\/\\/.*$/gm;\n result = result.replace(comments, (match) => themeColors.comment(match));\n\n // Function calls\n const functionCalls = /\\b([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*\\(/g;\n result = result.replace(functionCalls, (_match, name) => themeColors.function(name) + '(');\n\n return result;\n}\n\n/**\n * Get sample code for theme preview (hacker news meme with inline diff)\n */\nexport function getPreviewWithDiff(): Array<{ type: 'add' | 'remove' | 'normal'; line: string }> {\n return [\n { type: 'remove', line: 'function getRandomNumber() {' },\n { type: 'add', line: 'function getRandomNumber(): number {' },\n { type: 'normal', line: ' return 4;' },\n { type: 'normal', line: '}' },\n ];\n}\n","/**\n * Chat command handler\n * Main interactive chat session\n */\n\nimport React from 'react';\nimport { render } from 'ink';\nimport { ChatApp } from '../components/ChatApp.js';\nimport { ConfigLoader } from '../../config/ConfigLoader.js';\nimport { Config, Theme as ThemeType } from '../../config/schemas.js';\nimport { FirstRunDetector } from '../utils/firstRunDetector.js';\nimport { SetupCommand } from './SetupCommand.js';\nimport { IFileSystem } from '../../platform/IFileSystem.js';\nimport { Message } from '../../types/index.js';\nimport { logger } from '../../utils/logger.js';\nimport { SlashCommandRegistry } from '../../core/SlashCommand.js';\nimport { CustomCommandLoader } from '../../core/CustomCommandLoader.js';\nimport { SlashCommandParser } from '../../core/SlashCommandParser.js';\nimport { installSignalHandlers } from '../utils/signalHandler.js';\nimport {\n NewCommand,\n ModelCommand,\n ModeCommand,\n HelpCommand,\n ThemeCommand,\n} from './slashCommands/index.js';\nimport { MimirInitializer } from '../../core/MimirInitializer.js';\nimport { ProviderFactory } from '../../providers/ProviderFactory.js';\nimport { ILLMProvider } from '../../providers/ILLMProvider.js';\nimport { ConfigurationError } from '../../utils/errors.js';\nimport path from 'path';\nimport yaml from 'yaml';\n\nexport class ChatCommand {\n private commandRegistry: SlashCommandRegistry;\n\n constructor(\n private configLoader: ConfigLoader,\n private firstRunDetector: FirstRunDetector,\n private setupCommand: SetupCommand,\n private fs: IFileSystem\n ) {\n this.commandRegistry = new SlashCommandRegistry();\n }\n\n private async initializeCommands(projectRoot: string): Promise<void> {\n // Register built-in commands\n this.commandRegistry.register(new NewCommand());\n this.commandRegistry.register(new ModelCommand());\n this.commandRegistry.register(new ModeCommand());\n this.commandRegistry.register(new ThemeCommand());\n this.commandRegistry.register(new HelpCommand(this.commandRegistry));\n\n // Load custom commands\n const customLoader = new CustomCommandLoader(this.fs);\n const customCommands = await customLoader.loadAll(projectRoot);\n\n // Register custom commands, skip if conflicts with built-in\n customCommands.forEach((cmd) => {\n if (this.commandRegistry.has(cmd.name)) {\n logger.warn('Custom command conflicts with built-in, skipping', {\n name: cmd.name,\n });\n return;\n }\n this.commandRegistry.register(cmd);\n });\n\n logger.info('Slash commands initialized', {\n total: this.commandRegistry.getAll().length,\n });\n }\n\n /**\n * Initialize LLM provider with config\n * Returns provider instance or error message\n */\n private initializeProvider(config: Config): { provider?: ILLMProvider; error?: string } {\n try {\n const provider = ProviderFactory.create(config.llm);\n return { provider };\n } catch (error) {\n if (error instanceof ConfigurationError) {\n return { error: error.message };\n }\n return { error: `Failed to initialize provider: ${(error as Error).message}` };\n }\n }\n\n /**\n * Save config changes to project config file\n */\n private async saveConfig(projectRoot: string, config: Config): Promise<void> {\n try {\n const configPath = path.join(projectRoot, '.mimir', 'config.yml');\n const yamlContent = yaml.stringify(config);\n await this.fs.writeFile(configPath, yamlContent);\n logger.info('Config saved', { path: configPath });\n } catch (error) {\n logger.error('Failed to save config', { error });\n throw new Error(`Failed to save config: ${(error as Error).message}`);\n }\n }\n\n /**\n * Process user message through LLM provider\n */\n private async processMessage(\n provider: ILLMProvider,\n messages: Message[],\n userInput: string\n ): Promise<Message> {\n const startTime = Date.now();\n\n try {\n // Add user message to history\n const userMessage: Message = {\n role: 'user',\n content: userInput,\n };\n messages.push(userMessage);\n\n // Call LLM\n const response = await provider.chat(messages);\n const duration = Date.now() - startTime;\n\n // Create assistant message with metadata\n const assistantMessage: Message = {\n role: 'assistant',\n content: response.content,\n metadata: {\n timestamp: Date.now(),\n duration,\n usage: response.usage,\n cost: provider.calculateCost(response.usage.inputTokens, response.usage.outputTokens),\n model: provider.getModelName(),\n provider: provider.getProviderName(),\n },\n };\n\n messages.push(assistantMessage);\n return assistantMessage;\n } catch (error) {\n const duration = Date.now() - startTime;\n logger.error('LLM call failed', { error });\n\n // Return error message\n const errorMessage: Message = {\n role: 'assistant',\n content: `❌ Error: ${(error as Error).message}`,\n metadata: {\n timestamp: Date.now(),\n duration,\n model: provider.getModelName(),\n provider: provider.getProviderName(),\n },\n };\n\n messages.push(errorMessage);\n return errorMessage;\n }\n }\n\n async execute(workspaceRoot?: string): Promise<void> {\n // Use provided workspace root or fall back to process.cwd()\n // In production, this should be passed from CLI entry point\n const cwd = workspaceRoot ?? process.cwd();\n\n // Check if first run\n if (await this.firstRunDetector.isFirstRun()) {\n logger.info('First run detected, launching setup wizard');\n await this.setupCommand.execute();\n // Wizard exits alternate screen buffer on completion, returning to main buffer\n }\n\n // Auto-initialize workspace if .mimir doesn't exist\n const initializer = new MimirInitializer(this.fs, this.configLoader);\n if (!(await initializer.isWorkspaceInitialized(cwd))) {\n logger.info('Workspace not initialized. Running setup...');\n const result = await initializer.initializeWorkspace(cwd);\n\n if (!result.success) {\n const errorMsg = 'Failed to initialize workspace: ' + result.errors.join(', ');\n logger.error(errorMsg);\n throw new Error('Workspace initialization failed');\n }\n\n logger.info('Workspace initialized successfully');\n }\n\n // Enter alternate screen buffer to prevent layout shifts\n // This ensures the app renders in a separate buffer and doesn't push content down\n process.stdout.write('\\x1b[?1049h');\n\n // Load configuration\n const { config } = await this.configLoader.load({\n projectRoot: cwd,\n });\n\n // Initialize slash commands\n await this.initializeCommands(cwd);\n\n // Initialize LLM provider\n let providerResult = this.initializeProvider(config);\n\n // Initialize chat state\n const state = {\n messages: [] as Message[],\n currentMode: 'discuss' as 'plan' | 'act' | 'discuss',\n totalCost: 0,\n provider: providerResult.provider,\n config,\n };\n\n // Show welcome message or error if provider not configured\n if (!state.provider && providerResult.error) {\n state.messages.push({\n role: 'assistant',\n content: `⚠️ ${providerResult.error}\\n\\nTo use the chat, you need to:\\n1. Set up an API key as an environment variable (e.g., DEEPSEEK_API_KEY or ANTHROPIC_API_KEY)\\n2. Or use /model <provider> <model> to switch to a configured provider\\n\\nAvailable providers: deepseek, anthropic`,\n });\n }\n\n return new Promise((resolve) => {\n // Render function to update UI\n const renderUI = (rerender: (element: React.ReactElement) => void): void => {\n const element = React.createElement(ChatApp, {\n fs: this.fs,\n projectRoot: process.cwd(),\n config: state.config,\n messages: state.messages,\n currentMode: state.currentMode,\n totalCost: state.totalCost,\n commandRegistry: this.commandRegistry,\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n onUserInput: async (input: string) => {\n // Parse for slash command\n const parseResult = SlashCommandParser.parse(input);\n\n if (parseResult.isCommand && parseResult.commandName) {\n // Execute slash command\n const result = await this.commandRegistry.execute(\n parseResult.commandName,\n parseResult.args || [],\n {\n currentMode: state.currentMode,\n currentProvider: state.config.llm.provider,\n currentModel: state.config.llm.model,\n messageCount: state.messages.length,\n requestModeSwitch: (mode): void => {\n state.currentMode = mode;\n logger.info('Mode switched via command', { mode });\n // Force rerender to update mode colors (MimirHeader logo, etc.)\n renderUI(rerender);\n },\n requestModelSwitch: async (provider, model): Promise<void> => {\n logger.info('Model switch requested', { provider, model });\n\n // Validate provider type\n const validProviders = [\n 'deepseek',\n 'anthropic',\n 'openai',\n 'google',\n 'gemini',\n 'qwen',\n 'ollama',\n ] as const;\n if (!validProviders.includes(provider as (typeof validProviders)[number])) {\n state.messages.push({\n role: 'assistant',\n content: `❌ Invalid provider: ${provider}. Valid providers: ${validProviders.join(', ')}`,\n });\n return;\n }\n\n // Update config\n state.config.llm.provider = provider as (typeof validProviders)[number];\n\n // Set model - use provided model or default for provider\n if (model) {\n state.config.llm.model = model;\n } else {\n // Set default model for provider\n switch (provider.toLowerCase()) {\n case 'deepseek':\n state.config.llm.model = 'deepseek-chat';\n break;\n case 'anthropic':\n state.config.llm.model = 'claude-sonnet-4-5-20250929';\n break;\n case 'openai':\n state.config.llm.model = 'gpt-4';\n break;\n case 'google':\n case 'gemini':\n state.config.llm.model = 'gemini-pro';\n break;\n default:\n state.config.llm.model = provider; // fallback\n }\n }\n\n // Save config\n try {\n await this.saveConfig(cwd, state.config);\n\n // Reinitialize provider\n const newProviderResult = this.initializeProvider(state.config);\n if (newProviderResult.provider) {\n state.provider = newProviderResult.provider;\n state.messages.push({\n role: 'assistant',\n content: `✓ Switched to ${provider}${model ? `/${model}` : ''}`,\n });\n } else {\n state.messages.push({\n role: 'assistant',\n content: `❌ Failed to switch: ${newProviderResult.error}`,\n });\n }\n } catch (error) {\n state.messages.push({\n role: 'assistant',\n content: `❌ Failed to save config: ${(error as Error).message}`,\n });\n }\n },\n requestNewChat: (): void => {\n state.messages = [];\n state.totalCost = 0;\n logger.info('New chat started');\n },\n requestThemeChange: async (theme): Promise<void> => {\n // Create new config object with updated theme to trigger React rerender\n state.config = {\n ...state.config,\n ui: {\n ...state.config.ui,\n theme: theme as ThemeType,\n },\n };\n\n try {\n await this.saveConfig(cwd, state.config);\n logger.info('Theme changed and saved', { theme });\n\n // Force immediate rerender with new theme\n renderUI(rerender);\n } catch (error) {\n logger.error('Failed to save theme change', { error });\n }\n },\n sendPrompt: (prompt) => {\n // For custom commands - add as user message\n state.messages.push({\n role: 'user',\n content: prompt,\n });\n // TODO: Process through agent\n state.messages.push({\n role: 'assistant',\n content: `Received prompt from command: ${prompt}`,\n });\n },\n }\n );\n\n if (!result.success) {\n // Show error message\n state.messages.push({\n role: 'assistant',\n content: `Error: ${result.error}`,\n });\n }\n\n // Re-render\n renderUI(rerender);\n return;\n }\n\n // Normal message handling\n logger.info('User input received', { input });\n\n // Check if provider is available\n if (!state.provider) {\n state.messages.push({\n role: 'user',\n content: input,\n });\n state.messages.push({\n role: 'assistant',\n content:\n '❌ No LLM provider configured. Please use /model <provider> <model> to set up a provider.',\n });\n renderUI(rerender);\n return;\n }\n\n // Process through LLM\n await this.processMessage(state.provider, state.messages, input);\n\n // Update total cost\n const lastMessage = state.messages[state.messages.length - 1];\n if (lastMessage?.metadata?.cost) {\n state.totalCost += lastMessage.metadata.cost;\n }\n\n // Re-render with updated messages\n renderUI(rerender);\n },\n onModeSwitch: (mode: 'plan' | 'act' | 'discuss'): void => {\n state.currentMode = mode;\n logger.info('Mode switched', { mode });\n // Force rerender to sync mode changes (e.g., from Shift+Tab)\n renderUI(rerender);\n },\n onExit: (): void => {\n logger.info('Chat session ended');\n resolve();\n },\n });\n\n rerender(element);\n };\n\n // Disable console logging while Ink UI is active to prevent log pollution\n logger.disableConsole();\n\n // NOTE: Do NOT manually call process.stdin.setRawMode()!\n // Ink manages raw mode internally via its stdin handling.\n // Manual manipulation causes UV_HANDLE_CLOSING crashes on exit.\n\n const { waitUntilExit, rerender, clear } = render(\n React.createElement(ChatApp, {\n fs: this.fs,\n projectRoot: process.cwd(),\n config: state.config,\n messages: state.messages,\n currentMode: state.currentMode,\n totalCost: state.totalCost,\n commandRegistry: this.commandRegistry,\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n onUserInput: async (input: string) => {\n // Parse for slash command\n const parseResult = SlashCommandParser.parse(input);\n\n if (parseResult.isCommand && parseResult.commandName) {\n // Execute slash command\n const result = await this.commandRegistry.execute(\n parseResult.commandName,\n parseResult.args || [],\n {\n currentMode: state.currentMode,\n currentProvider: state.config.llm.provider,\n currentModel: state.config.llm.model,\n messageCount: state.messages.length,\n requestModeSwitch: (mode): void => {\n state.currentMode = mode;\n logger.info('Mode switched via command', { mode });\n // Force rerender to update mode colors (MimirHeader logo, etc.)\n renderUI(rerender);\n },\n requestModelSwitch: async (provider, model): Promise<void> => {\n logger.info('Model switch requested', { provider, model });\n\n // Validate provider type\n const validProviders = [\n 'deepseek',\n 'anthropic',\n 'openai',\n 'google',\n 'gemini',\n 'qwen',\n 'ollama',\n ] as const;\n if (!validProviders.includes(provider as (typeof validProviders)[number])) {\n state.messages.push({\n role: 'assistant',\n content: `❌ Invalid provider: ${provider}. Valid providers: ${validProviders.join(', ')}`,\n });\n return;\n }\n\n // Update config\n state.config.llm.provider = provider as (typeof validProviders)[number];\n\n // Set model - use provided model or default for provider\n if (model) {\n state.config.llm.model = model;\n } else {\n // Set default model for provider\n switch (provider.toLowerCase()) {\n case 'deepseek':\n state.config.llm.model = 'deepseek-chat';\n break;\n case 'anthropic':\n state.config.llm.model = 'claude-sonnet-4-5-20250929';\n break;\n case 'openai':\n state.config.llm.model = 'gpt-4';\n break;\n case 'google':\n case 'gemini':\n state.config.llm.model = 'gemini-pro';\n break;\n default:\n state.config.llm.model = provider; // fallback\n }\n }\n\n // Save config\n try {\n await this.saveConfig(cwd, state.config);\n\n // Reinitialize provider\n const newProviderResult = this.initializeProvider(state.config);\n if (newProviderResult.provider) {\n state.provider = newProviderResult.provider;\n state.messages.push({\n role: 'assistant',\n content: `✓ Switched to ${provider}${model ? `/${model}` : ''}`,\n });\n } else {\n state.messages.push({\n role: 'assistant',\n content: `❌ Failed to switch: ${newProviderResult.error}`,\n });\n }\n } catch (error) {\n state.messages.push({\n role: 'assistant',\n content: `❌ Failed to save config: ${(error as Error).message}`,\n });\n }\n },\n requestNewChat: (): void => {\n state.messages = [];\n state.totalCost = 0;\n logger.info('New chat started');\n },\n requestThemeChange: async (theme): Promise<void> => {\n // Create new config object with updated theme to trigger React rerender\n state.config = {\n ...state.config,\n ui: {\n ...state.config.ui,\n theme: theme as ThemeType,\n },\n };\n\n try {\n await this.saveConfig(cwd, state.config);\n logger.info('Theme changed and saved', { theme });\n\n // Force immediate rerender with new theme\n renderUI(rerender);\n } catch (error) {\n logger.error('Failed to save theme change', { error });\n }\n },\n sendPrompt: (prompt): void => {\n // For custom commands - add as user message\n state.messages.push({\n role: 'user',\n content: prompt,\n });\n // TODO: Process through agent\n state.messages.push({\n role: 'assistant',\n content: `Received prompt from command: ${prompt}`,\n });\n },\n }\n );\n\n if (!result.success) {\n // Show error message\n state.messages.push({\n role: 'assistant',\n content: `Error: ${result.error}`,\n });\n }\n\n // Re-render\n renderUI(rerender);\n return;\n }\n\n // Normal message handling\n logger.info('User input received', { input });\n\n // Check if provider is available\n if (!state.provider) {\n state.messages.push({\n role: 'user',\n content: input,\n });\n state.messages.push({\n role: 'assistant',\n content:\n '❌ No LLM provider configured. Please use /model <provider> <model> to set up a provider.',\n });\n renderUI(rerender);\n return;\n }\n\n // Process through LLM\n await this.processMessage(state.provider, state.messages, input);\n\n // Update total cost\n const lastMessage = state.messages[state.messages.length - 1];\n if (lastMessage?.metadata?.cost) {\n state.totalCost += lastMessage.metadata.cost;\n }\n\n renderUI(rerender);\n },\n onModeSwitch: (mode: 'plan' | 'act' | 'discuss'): void => {\n state.currentMode = mode;\n logger.info('Mode switched', { mode });\n // Force rerender to sync mode changes (e.g., from Shift+Tab)\n renderUI(rerender);\n },\n onExit: (): void => {\n logger.info('Chat session ended');\n // Exit alternate screen buffer before resolving\n process.stdout.write('\\x1b[?1049l');\n resolve();\n },\n }),\n {\n // Prevent console patching to avoid layout shifts from console.log\n patchConsole: false,\n // CRITICAL: Disable Ink's default Ctrl+C exit behavior\n // We handle Ctrl+C manually through our keyboard system\n exitOnCtrlC: false,\n }\n );\n\n // Handle process termination with SignalHandler\n const signalHandler = installSignalHandlers({\n keyBindings: config.keyBindings,\n onCleanup: async () => {\n // Re-enable console logging for cleanup messages\n logger.enableConsole();\n // NOTE: Do NOT call setRawMode here - Ink handles cleanup\n // Manually restoring raw mode causes UV_HANDLE_CLOSING crashes\n // Exit alternate screen buffer\n process.stdout.write('\\x1b[?1049l');\n // Clear Ink render\n clear();\n logger.info('Chat interface cleanup completed');\n },\n emergencyExitCount: 3,\n cleanupTimeout: 5000,\n });\n\n waitUntilExit()\n .then(() => {\n // Re-enable console logging after UI exits\n logger.enableConsole();\n logger.info('Chat interface exited');\n // NOTE: Do NOT call setRawMode here - Ink handles cleanup\n // Exit alternate screen buffer on normal exit\n process.stdout.write('\\x1b[?1049l');\n // Remove signal handlers\n signalHandler.uninstall();\n resolve();\n })\n .catch((error) => {\n logger.error('Error during UI cleanup', { error });\n // Re-enable console and exit alternate screen even on error\n logger.enableConsole();\n process.stdout.write('\\x1b[?1049l');\n signalHandler.uninstall();\n resolve();\n });\n });\n }\n}\n","/**\n * Top-level chat app component\n * Wraps ChatInterface with KeyboardProvider and sets up keyboard input capture\n */\n\nimport React, { useEffect } from 'react';\nimport { useStdin } from 'ink';\nimport { ChatInterface, ChatInterfaceProps } from './ChatInterface.js';\nimport { KeyboardProvider, useKeyboardInput } from '../keyboard/index.js';\nimport { IFileSystem } from '../../platform/IFileSystem.js';\nimport { logger } from '../../utils/logger.js';\n\nexport interface ChatAppProps extends ChatInterfaceProps {\n fs: IFileSystem;\n projectRoot?: string;\n}\n\n/**\n * Inner component that uses keyboard hooks\n * Must be inside KeyboardProvider\n */\nfunction ChatInterfaceWithKeyboard(props: ChatInterfaceProps): React.JSX.Element {\n const { stdin: _stdin, setRawMode, isRawModeSupported } = useStdin();\n\n // Enable raw mode using Ink's API (not process.stdin directly)\n useEffect(() => {\n if (isRawModeSupported) {\n setRawMode(true);\n logger.debug('Raw mode enabled via Ink useStdin', {\n isRawModeSupported,\n platform: process.platform,\n });\n } else {\n logger.warn('Raw mode not supported in this environment', {\n platform: process.platform,\n isTTY: process.stdin.isTTY,\n });\n }\n\n // Cleanup: Ink handles restoring raw mode automatically\n // DO NOT manually call setRawMode(false) here - causes UV_HANDLE_CLOSING\n return () => {\n // Intentionally empty - Ink handles cleanup\n };\n }, [setRawMode, isRawModeSupported]);\n\n // Capture keyboard input at top level\n useKeyboardInput({ isActive: true });\n\n return <ChatInterface {...props} />;\n}\n\n/**\n * Top-level chat app with keyboard handling\n */\nexport function ChatApp({ fs, projectRoot, ...chatProps }: ChatAppProps): JSX.Element {\n return (\n <KeyboardProvider\n bindingsConfig={chatProps.config.keyBindings}\n fs={fs}\n projectRoot={projectRoot}\n >\n <ChatInterfaceWithKeyboard {...chatProps} />\n </KeyboardProvider>\n );\n}\n","/**\n * Main chat interface component\n * Composes Header, MessageList, InputBox, and Footer\n */\n\nimport React, { useState, useMemo, useCallback, useRef, useEffect } from 'react';\nimport { Box, Text } from 'ink';\nimport { MimirHeader } from './MimirHeader.js';\nimport { MessageList } from './MessageList.js';\nimport { InputBox } from './InputBox.js';\nimport { Footer } from './Footer.js';\nimport { Message } from '../../types/index.js';\nimport { Config } from '../../config/schemas.js';\nimport { useTerminalSize } from '../hooks/useTerminalSize.js';\nimport { SlashCommandRegistry } from '../../core/SlashCommand.js';\nimport { useKeyboard, useKeyboardAction } from '../keyboard/index.js';\n\nexport interface ChatInterfaceProps {\n config: Config;\n messages: Message[];\n onUserInput: (input: string) => void;\n onExit: () => void;\n currentMode: 'plan' | 'act' | 'discuss';\n onModeSwitch?: (mode: 'plan' | 'act' | 'discuss') => void;\n totalCost: number;\n version?: string;\n workspace?: string;\n isAgentRunning?: boolean;\n commandRegistry?: SlashCommandRegistry;\n}\n\nexport const ChatInterface: React.FC<ChatInterfaceProps> = ({\n config,\n messages,\n onUserInput,\n onExit,\n currentMode,\n onModeSwitch,\n totalCost,\n version = '0.1.0',\n workspace = process.cwd(),\n isAgentRunning = false,\n commandRegistry,\n}) => {\n const [input, setInput] = useState('');\n const [mode, setMode] = useState<'plan' | 'act' | 'discuss'>(currentMode);\n const [interruptPressCount, setInterruptPressCount] = useState(0);\n const [isAutocompleteShowing, setIsAutocompleteShowing] = useState(false);\n const [autocompleteSelectedIndex, setAutocompleteSelectedIndex] = useState(0);\n const [autocompleteItemCount, setAutocompleteItemCount] = useState(0);\n const [manuallyClosedAutocomplete, setManuallyClosedAutocomplete] = useState(false);\n const acceptSelectionRef = useRef<(() => void) | null>(null);\n const interruptTimerRef = useRef<NodeJS.Timeout | null>(null);\n const { width: terminalWidth, height: terminalHeight } = useTerminalSize();\n const { updateContext } = useKeyboard();\n\n // Sync mode with currentMode prop\n useEffect(() => {\n setMode(currentMode);\n }, [currentMode]);\n\n // Update keyboard context when state changes\n useEffect(() => {\n updateContext({\n isAutocompleteVisible: isAutocompleteShowing,\n isAgentRunning,\n isInputFocused: true,\n });\n }, [isAutocompleteShowing, isAgentRunning, updateContext]);\n\n // Memoize divider width - only recalculate when terminal width changes\n // This ensures Ink only updates the divider line on resize, not entire UI\n const dividerWidth = useMemo(() => {\n return Math.max(1, terminalWidth);\n }, [terminalWidth]);\n\n // Reset interrupt count after 2 seconds of no interrupt presses\n useEffect(() => {\n if (interruptPressCount > 0) {\n if (interruptTimerRef.current) {\n clearTimeout(interruptTimerRef.current);\n }\n interruptTimerRef.current = setTimeout(() => {\n setInterruptPressCount(0);\n }, 2000);\n }\n return () => {\n if (interruptTimerRef.current) {\n clearTimeout(interruptTimerRef.current);\n }\n };\n }, [interruptPressCount]);\n\n // Track actual autocomplete height for dynamic message area sizing\n const [actualAutocompleteHeight, setActualAutocompleteHeight] = useState(0);\n\n // Auto-show autocomplete when suggestions available (unless manually closed)\n const handleAutocompleteStateChange = useCallback(\n (state: {\n itemCount: number;\n isParameterMode: boolean;\n shouldShow: boolean;\n actualHeight?: number;\n }) => {\n setAutocompleteItemCount(state.itemCount);\n\n // Update actual height if provided\n if (state.actualHeight !== undefined) {\n setActualAutocompleteHeight(state.actualHeight);\n }\n\n // Auto-show autocomplete if:\n // 1. Config flag is enabled (autocompleteAutoShow)\n // 2. Should show (has suggestions)\n // 3. User hasn't manually closed it\n // 4. Item count > 0\n if (\n config.ui.autocompleteAutoShow &&\n state.shouldShow &&\n !manuallyClosedAutocomplete &&\n state.itemCount > 0\n ) {\n setIsAutocompleteShowing((prev) => {\n // Only reset selected index when first showing autocomplete\n if (!prev) {\n setAutocompleteSelectedIndex(0);\n }\n return true;\n });\n } else if (!state.shouldShow) {\n // Hide if no suggestions\n setIsAutocompleteShowing(false);\n setActualAutocompleteHeight(0);\n }\n },\n [manuallyClosedAutocomplete, config.ui.autocompleteAutoShow]\n );\n\n // Reset manual close flag when input changes\n const handleInputChange = useCallback((newValue: string) => {\n setInput(newValue);\n // Reset manual close flag to allow autocomplete to show again\n setManuallyClosedAutocomplete(false);\n // Reset selected index when typing (not when navigating)\n setAutocompleteSelectedIndex(0);\n }, []);\n\n // KEYBOARD ACTIONS - Using centralized keyboard system\n\n // Navigate up in autocomplete (priority: 10 - child handler)\n useKeyboardAction(\n 'navigateUp',\n (event) => {\n if (!event.context.isAutocompleteVisible || autocompleteItemCount === 0) {\n return false; // Not handled, let others try\n }\n\n setAutocompleteSelectedIndex((prev) => (prev > 0 ? prev - 1 : autocompleteItemCount - 1));\n return true; // Handled, stop propagation\n },\n { priority: 10 }\n );\n\n // Navigate down in autocomplete (priority: 10 - child handler)\n useKeyboardAction(\n 'navigateDown',\n (event) => {\n if (!event.context.isAutocompleteVisible || autocompleteItemCount === 0) {\n return false; // Not handled\n }\n\n setAutocompleteSelectedIndex((prev) => (prev < autocompleteItemCount - 1 ? prev + 1 : 0));\n return true; // Handled\n },\n { priority: 10 }\n );\n\n // Accept autocomplete selection (Tab/Enter) (priority: 10 - child handler)\n useKeyboardAction(\n 'accept',\n (event) => {\n if (!event.context.isAutocompleteVisible || autocompleteItemCount === 0) {\n return false; // Not handled\n }\n\n if (acceptSelectionRef.current) {\n acceptSelectionRef.current();\n }\n setAutocompleteSelectedIndex(0);\n return true; // Handled\n },\n { priority: 10 }\n );\n\n // Show tooltip/autocomplete (Tab/Ctrl+Space) (priority: 0 - normal handler)\n useKeyboardAction(\n 'showTooltip',\n (event) => {\n if (event.context.isAutocompleteVisible && autocompleteItemCount > 0) {\n // Autocomplete is showing - Tab should select item (same as Enter)\n if (acceptSelectionRef.current) {\n acceptSelectionRef.current();\n }\n setAutocompleteSelectedIndex(0);\n return true; // Handled\n }\n\n // Not showing or no items - show autocomplete\n setIsAutocompleteShowing(true);\n setManuallyClosedAutocomplete(false);\n setAutocompleteSelectedIndex(0);\n return true; // Handled\n },\n { priority: 0 }\n );\n\n // Interrupt (Ctrl+C and Escape) - Shared logic for both keys\n // Priority 10 ensures autocomplete close is handled before exit\n useKeyboardAction(\n 'interrupt',\n (event) => {\n // If autocomplete showing, close it first (priority handling)\n if (event.context.isAutocompleteVisible) {\n setIsAutocompleteShowing(false);\n setManuallyClosedAutocomplete(true);\n setAutocompleteSelectedIndex(0);\n return true; // Handled, don't exit app\n }\n\n // Handle interrupt/exit logic\n const newCount = interruptPressCount + 1;\n setInterruptPressCount(newCount);\n\n if (event.context.isAgentRunning) {\n if (newCount === 1) {\n // First press: interrupt agent (TODO: implement agent interruption)\n // For now, just count it\n } else if (newCount >= 2) {\n // Second press: exit\n onExit();\n }\n } else {\n if (newCount >= 2) {\n // Not running and second press: exit\n onExit();\n }\n }\n\n return true; // Handled\n },\n { priority: 10 }\n );\n\n // Mode switch (Shift+Tab) (priority: 0 - normal handler)\n useKeyboardAction(\n 'modeSwitch',\n (event) => {\n if (event.context.isAutocompleteVisible) {\n return false; // Don't switch modes while autocomplete showing\n }\n\n const modes: Array<'plan' | 'act' | 'discuss'> = ['plan', 'act', 'discuss'];\n const currentIndex = modes.indexOf(mode);\n const nextIndex = (currentIndex + 1) % modes.length;\n const nextMode = modes[nextIndex];\n if (nextMode) {\n setMode(nextMode);\n if (onModeSwitch) {\n onModeSwitch(nextMode);\n }\n }\n return true; // Handled\n },\n { priority: 0 }\n );\n\n // Memoize submit handler to prevent InputBox from re-rendering unnecessarily\n // Accepts optional value parameter from autocomplete to avoid stale state issues\n const handleSubmit = useCallback(\n (value?: string) => {\n const submittedValue = value !== undefined ? value : input;\n if (submittedValue.trim()) {\n onUserInput(submittedValue);\n setInput('');\n }\n },\n [input, onUserInput]\n );\n\n // Memoize divider content - only recalculate when width changes\n const dividerContent = useMemo(() => '─'.repeat(dividerWidth), [dividerWidth]);\n\n // Create context for slash command parameter autocomplete\n const commandContext = useMemo(\n () => ({\n currentMode: mode,\n currentProvider: config.llm.provider,\n currentModel: config.llm.model,\n messageCount: messages.length,\n }),\n [mode, config.llm.provider, config.llm.model, messages.length]\n );\n\n // Layout structure (from top to bottom):\n // MimirHeader (4) + Divider (1) + MessageList (flex) + InputBox + Divider (1) + Footer (1)\n // InputBox contains: Input (1) + Autocomplete (0-N when visible)\n //\n // Fixed UI lines: Header (4) + Divider (1) + Input (1) + Divider (1) + Footer (1) = 8\n // Variable: MessageList + Autocomplete\n\n const fixedUIHeight = 8;\n const minMessageLines = 3;\n\n // Calculate space for autocomplete dynamically:\n // Total available = terminalHeight - fixedUI - minMessages\n // Autocomplete structure: Header (1) + moreAbove (0-1) + items (N) + moreBelow (0-1) + Footer (1)\n const autocompleteOverhead = 4; // header + footer + max 2 pagination indicators\n const availableForAutocomplete = terminalHeight - fixedUIHeight - minMessageLines;\n const availableForAutocompleteItems = Math.max(\n 0,\n availableForAutocomplete - autocompleteOverhead\n );\n\n // maxVisible clamped between 5-10 items\n const maxVisibleItems = Math.max(5, Math.min(10, availableForAutocompleteItems));\n\n // Use actualAutocompleteHeight if available, otherwise reserve space based on maxVisibleItems\n // This prevents overflow during the initial render before height is calculated\n // Add generous buffer for potential parameter tooltips (worst case: up to 12 extra lines for params + padding)\n const parameterTooltipBuffer = 12;\n const estimatedAutocompleteHeight = isAutocompleteShowing\n ? actualAutocompleteHeight || maxVisibleItems + autocompleteOverhead + parameterTooltipBuffer\n : 0;\n\n const messageAreaHeight = Math.max(\n minMessageLines,\n terminalHeight - fixedUIHeight - estimatedAutocompleteHeight\n );\n\n return (\n <Box flexDirection=\"column\" height={terminalHeight}>\n {/* Fixed header */}\n <MimirHeader\n version={version}\n provider={config.llm.provider}\n model={config.llm.model}\n workspace={workspace}\n theme={config.ui.theme}\n mode={mode}\n />\n\n <Box>\n <Text dimColor>{dividerContent}</Text>\n </Box>\n\n {/* Scrollable message area - shrinks when autocomplete appears */}\n <Box height={messageAreaHeight}>\n <MessageList\n messages={messages}\n theme={config.ui.theme}\n syntaxHighlighting={config.ui.syntaxHighlighting}\n />\n </Box>\n\n {/* Fixed bottom section: Input + Autocomplete (below input) + Footer */}\n {/* Autocomplete grows downward from input when visible, pushing footer down */}\n <InputBox\n value={input}\n onChange={handleInputChange}\n onSubmit={handleSubmit}\n theme={config.ui.theme}\n commandRegistry={commandRegistry}\n context={commandContext}\n onAutocompleteChange={setIsAutocompleteShowing}\n forceShowAutocomplete={isAutocompleteShowing}\n onAutocompleteStateChange={handleAutocompleteStateChange}\n autocompleteIndex={autocompleteSelectedIndex}\n onAcceptSelectionRef={acceptSelectionRef}\n maxVisible={maxVisibleItems}\n keyBindings={config.keyBindings}\n autocompleteExecuteOnSelect={config.ui.autocompleteExecuteOnSelect}\n />\n\n <Box>\n <Text dimColor>{dividerContent}</Text>\n </Box>\n\n <Footer\n theme={config.ui.theme}\n shortcuts={config.keyBindings}\n mode={mode}\n cost={totalCost}\n interruptPressCount={interruptPressCount}\n isAgentRunning={isAgentRunning}\n />\n </Box>\n );\n};\n","/**\n * Mimir header component with wizard ASCII art\n * Layout inspired by Claude Code with wizard head on left, info on right\n */\n\nimport React from 'react';\nimport { Box, Text } from 'ink';\nimport { Theme } from '../../config/schemas.js';\nimport { getTheme } from '../../config/themes/index.js';\nimport { MIMIR_LOGO } from './logo.js';\n\nexport interface MimirHeaderProps {\n version: string;\n provider: string;\n model: string;\n workspace: string;\n theme: Theme;\n mode: 'plan' | 'act' | 'discuss';\n}\n\nexport const MimirHeader: React.FC<MimirHeaderProps> = ({\n version,\n provider,\n model,\n workspace,\n theme,\n mode,\n}) => {\n const themeDefinition = getTheme(theme);\n\n // Logo color changes based on current mode\n const logoColor =\n mode === 'plan'\n ? themeDefinition.colors.modePlan\n : mode === 'act'\n ? themeDefinition.colors.modeAct\n : themeDefinition.colors.modeDiscuss;\n\n const versionColor = themeDefinition.colors.warning;\n const providerColor = themeDefinition.colors.success;\n const dimText = themeDefinition.colors.comment;\n\n const infoLines = [\n versionColor(`Mimir Code v${version}`),\n providerColor(`${provider} · ${model}`),\n dimText(workspace),\n themeDefinition.colors.info(`Theme: ${themeDefinition.name}`),\n ];\n\n // Fixed width for logo column to ensure consistent alignment\n const LOGO_WIDTH = 7;\n\n return (\n <Box flexDirection=\"column\" height={MIMIR_LOGO.length} flexShrink={0}>\n {MIMIR_LOGO.map((logoLine, index) => (\n <Box key={index}>\n <Box width={LOGO_WIDTH}>\n <Text>{logoColor.bold(logoLine)}</Text>\n </Box>\n {infoLines[index] && <Text>{infoLines[index]}</Text>}\n </Box>\n ))}\n </Box>\n );\n};\n","/**\n * Message list component\n * Displays conversation messages with role-based colors and thinking indicators\n * Uses Static component to prevent re-rendering of existing messages\n */\n\nimport React from 'react';\nimport { Box, Text, Static } from 'ink';\nimport { Message } from '../../types/index.js';\nimport { Theme } from '../../config/schemas.js';\nimport { getTheme } from '../../config/themes/index.js';\n\nexport interface MessageListProps {\n messages: Message[];\n theme: Theme;\n syntaxHighlighting: boolean;\n}\n\nexport const MessageList: React.FC<MessageListProps> = ({\n messages,\n theme,\n syntaxHighlighting: _syntaxHighlighting,\n}) => {\n const themeDefinition = getTheme(theme);\n const { userMessage, assistantMessage, systemMessage } = themeDefinition.colors;\n\n const getRoleChalk = (role: Message['role']) => {\n switch (role) {\n case 'user':\n return userMessage;\n case 'assistant':\n return assistantMessage;\n case 'system':\n return systemMessage;\n default:\n return assistantMessage;\n }\n };\n\n const formatDuration = (ms: number): string => {\n if (ms < 1000) return `${Math.round(ms)}ms`;\n return `${(ms / 1000).toFixed(1)}s`;\n };\n\n const formatCost = (cost: number): string => {\n if (cost === 0) return '$0.00';\n if (cost < 0.0001) return `$${cost.toExponential(2)}`;\n return `$${cost.toFixed(4)}`;\n };\n\n const renderThinkingIndicator = (message: Message) => {\n if (!message.metadata) return null;\n\n const { duration, usage, cost, model, provider } = message.metadata;\n\n const parts: string[] = [];\n\n // Model/Provider\n if (provider && model) {\n parts.push(`${provider}/${model}`);\n } else if (model) {\n parts.push(model);\n }\n\n // Duration\n if (duration != null) {\n parts.push(formatDuration(duration));\n }\n\n // Tokens\n if (usage) {\n parts.push(`${usage.inputTokens}→${usage.outputTokens} tokens`);\n }\n\n // Cost\n if (cost != null) {\n parts.push(formatCost(cost));\n }\n\n if (parts.length === 0) return null;\n\n return (\n <Box marginTop={0}>\n <Text dimColor italic>\n ({parts.join(' • ')})\n </Text>\n </Box>\n );\n };\n\n const renderMessage = (message: Message, index: number) => (\n <Box key={index} flexDirection=\"column\" marginBottom={1}>\n <Text>{getRoleChalk(message.role).bold(`[${message.role.toUpperCase()}]:`)}</Text>\n <Text>{message.content}</Text>\n {message.role === 'assistant' && renderThinkingIndicator(message)}\n </Box>\n );\n\n return (\n <Box flexDirection=\"column\" paddingX={1} paddingY={1} flexGrow={1}>\n {messages.length === 0 && <Text dimColor>No messages yet. Start typing below...</Text>}\n {messages.length > 0 && (\n <Static items={messages}>{(message, index) => renderMessage(message, index)}</Static>\n )}\n </Box>\n );\n};\n","/**\n * Input box component\n * User input field with prompt and autocomplete support\n *\n * Keyboard behavior (based on terminal CLI best practices):\n * - **Tab**: Show/trigger autocomplete (traditional shell pattern, works on all platforms)\n * - **Ctrl+Space**: Alternative autocomplete trigger (macOS/Linux only - Windows terminal intercepts it)\n * - **Escape**: Close autocomplete (or pass to parent if not showing)\n * - **Ctrl+C**: Close autocomplete FIRST (or pass to parent for exit if not showing)\n * - **Up/Down**: Navigate autocomplete items\n * - **Enter**: Accept selected item (or execute command if not showing)\n *\n * Note: On Windows, Ctrl+Space is intercepted by PowerShell/Windows Terminal and never\n * reaches the application. Tab is the recommended universal shortcut for autocomplete.\n *\n * Parameter detection (bash COMP_WORDS pattern):\n * - `/command param ` (trailing space) → shows NEXT parameter if exists\n * - `/command param` (no space) → shows completions for CURRENT parameter\n * - No autocomplete shown if no more parameters available\n *\n * Architecture:\n * - Global keyboard event bus with action-based routing\n * - Keyboard events managed via KeyboardContext\n * - Pre-allocated space to prevent layout shifts\n * - Autocomplete positioned below input line (standard terminal pattern)\n */\n\nimport React, { useState, useCallback, useEffect } from 'react';\nimport { Box, Text } from 'ink';\nimport TextInput from 'ink-text-input';\nimport { Theme, KeyBindingsConfig } from '../../config/schemas.js';\nimport { getTheme } from '../../config/themes/index.js';\nimport { SlashCommandRegistry, SlashCommandContext } from '../../core/SlashCommand.js';\nimport { SlashCommandParser } from '../../core/SlashCommandParser.js';\nimport { CommandAutocomplete } from './CommandAutocomplete.js';\nimport { ISlashCommand } from '../../core/SlashCommand.js';\n\nexport interface InputBoxProps {\n value: string;\n onChange: (value: string) => void;\n onSubmit: (value?: string) => void;\n theme: Theme;\n commandRegistry?: SlashCommandRegistry;\n // Context for parameter autocomplete\n context?: SlashCommandContext;\n // Callback when autocomplete visibility changes\n onAutocompleteChange?: (isShowing: boolean) => void;\n // Externally controlled autocomplete visibility (from parent keyboard handler)\n forceShowAutocomplete?: boolean;\n // Callback to report autocomplete state (item count for navigation, actual height for layout)\n onAutocompleteStateChange?: (state: {\n itemCount: number;\n isParameterMode: boolean;\n shouldShow: boolean;\n actualHeight?: number;\n }) => void;\n // Maximum number of visible items in autocomplete (dynamically calculated from terminal height)\n maxVisible?: number;\n // Selected autocomplete index (controlled from parent)\n autocompleteIndex?: number;\n // Ref to expose accept selection function to parent\n onAcceptSelectionRef?: React.MutableRefObject<(() => void) | null>;\n // Keyboard bindings for autocomplete footer\n keyBindings: KeyBindingsConfig;\n // Execute command immediately if no more parameters needed\n autocompleteExecuteOnSelect?: boolean;\n}\n\nexport const InputBox: React.FC<InputBoxProps> = React.memo(\n ({\n value,\n onChange,\n onSubmit,\n theme,\n commandRegistry,\n context,\n onAutocompleteChange,\n forceShowAutocomplete,\n onAutocompleteStateChange,\n autocompleteIndex,\n onAcceptSelectionRef,\n maxVisible = 5,\n keyBindings,\n autocompleteExecuteOnSelect = true,\n }) => {\n const themeDefinition = getTheme(theme);\n const [filteredCommands, setFilteredCommands] = useState<ISlashCommand[]>([]);\n const [parameterSuggestions, setParameterSuggestions] = useState<string[]>([]);\n const [parameterName, setParameterName] = useState<string>('');\n const [isParameterMode, setIsParameterMode] = useState(false);\n const [inputKey, setInputKey] = useState(0);\n const [autocompleteHeight, setAutocompleteHeight] = useState(0);\n\n // Use controlled autocomplete state from parent, with local fallback\n const showAutocomplete = forceShowAutocomplete !== undefined ? forceShowAutocomplete : false;\n const selectedIndex = autocompleteIndex !== undefined ? autocompleteIndex : 0;\n\n // Notify parent when autocomplete visibility changes\n useEffect(() => {\n if (onAutocompleteChange) {\n onAutocompleteChange(showAutocomplete);\n }\n }, [showAutocomplete, onAutocompleteChange]);\n\n // Calculate autocomplete suggestions based on current input\n // Based on bash COMP_WORDS pattern - detect parameter boundaries with space\n const calculateSuggestions = useCallback(() => {\n if (!commandRegistry) {\n return { show: false, isParam: false, commands: [], params: [], paramName: '' };\n }\n\n const trimmed = value.trim();\n\n // Not a slash command at all\n if (!trimmed.startsWith('/')) {\n return { show: false, isParam: false, commands: [], params: [], paramName: '' };\n }\n\n const parsed = SlashCommandParser.parse(value);\n\n // Check for parameter mode - when there's a space after command\n if (parsed.isCommand && parsed.commandName && value.includes(' ')) {\n const command = commandRegistry.get(parsed.commandName);\n\n // Only show parameter autocomplete if command has parameter suggestions\n if (command?.getParameterSuggestions && context) {\n const currentInput = parsed.rawArgs || '';\n\n // Split into word boundaries (like bash COMP_WORDS)\n // Filter out empty strings\n const parts = currentInput.split(/\\s+/).filter((a) => a.length > 0);\n\n // Detect if we're at a parameter boundary (trailing space after last param)\n // Pattern: \"/command param \" vs \"/command param\"\n // Check original value for trailing space (handles \"/theme \" where rawArgs is empty)\n const endsWithSpace = /\\s$/.test(value);\n\n let paramIndex: number;\n let partialValue: string;\n\n if (endsWithSpace) {\n // Trailing space = finished with current param, ready for NEXT parameter\n // e.g., \"/model deepseek \" -> parts=['deepseek'], paramIndex=1\n // Only show autocomplete if the NEXT parameter exists\n paramIndex = parts.length;\n partialValue = '';\n\n // Check if next parameter exists\n // Pass already-typed args so commands can provide context-aware suggestions\n const nextParamSuggestions = command.getParameterSuggestions(\n paramIndex,\n context,\n parts\n );\n if (nextParamSuggestions.length === 0) {\n // No next parameter - don't show autocomplete\n return { show: false, isParam: false, commands: [], params: [], paramName: '' };\n }\n\n return {\n show: true,\n isParam: true,\n commands: [],\n params: nextParamSuggestions,\n paramName: command.parameters?.[paramIndex]?.name || 'parameter',\n };\n } else if (parts.length === 0) {\n // No arguments yet \" \" after command - first parameter\n paramIndex = 0;\n partialValue = '';\n } else {\n // No trailing space = still typing current parameter\n // e.g., \"/model dee\" -> parts=['dee'], paramIndex=0\n paramIndex = parts.length - 1;\n partialValue = parts[parts.length - 1]?.toLowerCase() || '';\n }\n\n // Pass completed args (all but the last partial one) for context-aware suggestions\n const completedArgs = paramIndex > 0 ? parts.slice(0, paramIndex) : [];\n const allSuggestions = command.getParameterSuggestions(\n paramIndex,\n context,\n completedArgs\n );\n\n // Filter suggestions based on partial value\n const filteredSuggestions = partialValue\n ? allSuggestions.filter((s) => s.toLowerCase().startsWith(partialValue))\n : allSuggestions;\n\n if (filteredSuggestions.length > 0) {\n return {\n show: true,\n isParam: true,\n commands: [],\n params: filteredSuggestions,\n paramName: command.parameters?.[paramIndex]?.name || 'parameter',\n };\n }\n }\n\n // No parameter suggestions available\n return { show: false, isParam: false, commands: [], params: [], paramName: '' };\n }\n\n // Command autocomplete mode - only if no space yet (still typing command name)\n const partialName = SlashCommandParser.getPartialCommandName(value);\n\n if (partialName === null) {\n return { show: false, isParam: false, commands: [], params: [], paramName: '' };\n }\n\n // Only show command autocomplete if there's no space (still typing command name)\n const hasSpace = value.includes(' ');\n if (hasSpace) {\n return { show: false, isParam: false, commands: [], params: [], paramName: '' };\n }\n\n const matches = commandRegistry.search(partialName);\n\n return {\n show: matches.length > 0,\n isParam: false,\n commands: matches,\n params: [],\n paramName: '',\n };\n }, [value, commandRegistry, context]);\n\n // Update autocomplete suggestions when input changes\n useEffect(() => {\n const suggestions = calculateSuggestions();\n\n setIsParameterMode(suggestions.isParam);\n setFilteredCommands(suggestions.commands);\n setParameterSuggestions(suggestions.params);\n setParameterName(suggestions.paramName);\n\n // Notify parent about autocomplete state (item count for navigation)\n const itemCount = suggestions.isParam\n ? suggestions.params.length\n : suggestions.commands.length;\n\n if (onAutocompleteStateChange) {\n onAutocompleteStateChange({\n itemCount,\n isParameterMode: suggestions.isParam,\n shouldShow: suggestions.show && itemCount > 0,\n });\n }\n }, [calculateSuggestions, onAutocompleteStateChange]);\n\n // Callback to receive actual rendered height from CommandAutocomplete\n const handleHeightCalculated = useCallback((height: number) => {\n setAutocompleteHeight(height);\n }, []);\n\n // Reset height when autocomplete is hidden\n useEffect(() => {\n if (!showAutocomplete) {\n setAutocompleteHeight(0);\n }\n }, [showAutocomplete]);\n\n // Report autocomplete state changes to parent\n useEffect(() => {\n const itemCount = isParameterMode ? parameterSuggestions.length : filteredCommands.length;\n\n if (onAutocompleteStateChange) {\n onAutocompleteStateChange({\n itemCount,\n isParameterMode,\n shouldShow: showAutocomplete && itemCount > 0,\n actualHeight: showAutocomplete ? autocompleteHeight : 0,\n });\n }\n }, [\n autocompleteHeight,\n isParameterMode,\n parameterSuggestions.length,\n filteredCommands.length,\n showAutocomplete,\n onAutocompleteStateChange,\n ]);\n\n // Accept autocomplete selection (called by parent when Tab/Enter pressed)\n const acceptSelection = useCallback(() => {\n const itemCount = isParameterMode ? parameterSuggestions.length : filteredCommands.length;\n if (itemCount === 0) return;\n\n if (isParameterMode) {\n // Select parameter suggestion\n const selected = parameterSuggestions[selectedIndex];\n if (selected) {\n const parsed = SlashCommandParser.parse(value);\n const currentInput = parsed.rawArgs || '';\n\n // Split into word boundaries\n const parts = currentInput.split(/\\s+/).filter((a) => a.length > 0);\n const endsWithSpace = currentInput.length > 0 && /\\s$/.test(currentInput);\n\n let completedArgs: string[];\n if (endsWithSpace || parts.length === 0) {\n // Adding new argument\n completedArgs = [...parts, selected];\n } else {\n // Replacing last partial argument\n completedArgs = [...parts.slice(0, -1), selected];\n }\n\n const commandName = parsed.commandName;\n if (!commandName) return;\n\n const baseCommand = `/${commandName}`;\n const newValue = `${baseCommand} ${completedArgs.join(' ')} `;\n\n // Check if there are more parameters expected\n const command = commandRegistry?.get(commandName);\n const hasMoreParams =\n command?.getParameterSuggestions && context\n ? command.getParameterSuggestions(completedArgs.length, context, completedArgs)\n .length > 0\n : false;\n\n if (!hasMoreParams && autocompleteExecuteOnSelect) {\n // No more parameters - auto-execute (if enabled)\n setInputKey((prev) => prev + 1);\n const finalValue = newValue.trim();\n onChange(finalValue);\n // Pass value directly to onSubmit to avoid stale state issues\n setTimeout(() => {\n onSubmit(finalValue);\n }, 0);\n } else {\n // More parameters expected or auto-execute disabled - add trailing space and continue\n setInputKey((prev) => prev + 1);\n onChange(newValue);\n }\n }\n } else {\n // Select command\n const selectedCommand = filteredCommands[selectedIndex];\n if (selectedCommand) {\n const newValue = `/${selectedCommand.name} `;\n\n // Check if command has parameters\n const hasParams =\n selectedCommand.getParameterSuggestions && context\n ? selectedCommand.getParameterSuggestions(0, context, []).length > 0\n : false;\n\n if (!hasParams && autocompleteExecuteOnSelect) {\n // No parameters - auto-execute (if enabled)\n setInputKey((prev) => prev + 1);\n const finalValue = newValue.trim();\n onChange(finalValue);\n // Pass value directly to onSubmit to avoid stale state issues\n setTimeout(() => {\n onSubmit(finalValue);\n }, 0);\n } else {\n // Has parameters or auto-execute disabled - add trailing space and continue\n setInputKey((prev) => prev + 1);\n onChange(newValue);\n }\n }\n }\n }, [\n isParameterMode,\n parameterSuggestions,\n filteredCommands,\n selectedIndex,\n value,\n onChange,\n onSubmit,\n commandRegistry,\n context,\n autocompleteExecuteOnSelect,\n ]);\n\n // Expose accept selection function to parent via ref\n useEffect(() => {\n if (onAcceptSelectionRef) {\n onAcceptSelectionRef.current = acceptSelection;\n }\n }, [onAcceptSelectionRef, acceptSelection]);\n\n const handleSubmit = useCallback(() => {\n // Only submit if autocomplete is not showing\n if (!showAutocomplete) {\n onSubmit(undefined);\n }\n }, [showAutocomplete, onSubmit]);\n\n return (\n <Box flexDirection=\"column\" flexShrink={0}>\n {/* Input line - always anchored at same position */}\n <Box paddingX={1} flexShrink={0}>\n <Text>{themeDefinition.colors.inputPrompt('> ')}</Text>\n <TextInput key={inputKey} value={value} onChange={onChange} onSubmit={handleSubmit} />\n </Box>\n\n {/* Autocomplete appears BELOW input line */}\n {showAutocomplete && (\n <CommandAutocomplete\n commands={isParameterMode ? undefined : filteredCommands}\n parameterSuggestions={isParameterMode ? parameterSuggestions : undefined}\n parameterName={isParameterMode ? parameterName : undefined}\n selectedIndex={selectedIndex}\n showParameterInfo={!isParameterMode}\n selectedCommand={isParameterMode ? undefined : filteredCommands[selectedIndex]}\n theme={theme}\n maxVisible={maxVisible}\n keyBindings={keyBindings}\n onHeightCalculated={handleHeightCalculated}\n />\n )}\n </Box>\n );\n }\n);\n\nInputBox.displayName = 'InputBox';\n","/**\n * Parser for slash commands\n * Handles detection and parsing of slash commands from user input\n */\n\n/**\n * Parse result from input string\n */\nexport interface ParseResult {\n isCommand: boolean;\n commandName?: string;\n args?: string[];\n rawArgs?: string;\n}\n\n/**\n * Parser for slash commands\n */\nexport class SlashCommandParser {\n private static readonly COMMAND_REGEX = /^\\/(\\w+)(?:\\s+(.*))?$/;\n\n /**\n * Check if input starts with /\n */\n static isCommandPrefix(input: string): boolean {\n return input.trimStart().startsWith('/');\n }\n\n /**\n * Parse slash command from input\n * Examples:\n * \"/new\" -> { isCommand: true, commandName: 'new', args: [] }\n * \"/model deepseek\" -> { isCommand: true, commandName: 'model', args: ['deepseek'] }\n * \"/custom arg1 arg2\" -> { isCommand: true, commandName: 'custom', args: ['arg1', 'arg2'], rawArgs: 'arg1 arg2' }\n */\n static parse(input: string): ParseResult {\n const trimmed = input.trim();\n\n if (!this.isCommandPrefix(trimmed)) {\n return { isCommand: false };\n }\n\n const match = this.COMMAND_REGEX.exec(trimmed);\n\n if (!match) {\n return { isCommand: false };\n }\n\n const commandName = match[1];\n const rawArgs = match[2] || '';\n const args = rawArgs ? rawArgs.trim().split(/\\s+/) : [];\n\n return {\n isCommand: true,\n commandName,\n args,\n rawArgs,\n };\n }\n\n /**\n * Get partial command name for autocomplete\n * \"/mod\" -> \"mod\"\n * \"/\" -> \"\"\n */\n static getPartialCommandName(input: string): string | null {\n const trimmed = input.trimStart();\n\n if (!trimmed.startsWith('/')) {\n return null;\n }\n\n // Extract command name (before first space)\n const spaceIndex = trimmed.indexOf(' ');\n if (spaceIndex === -1) {\n return trimmed.substring(1); // Remove /\n }\n\n return trimmed.substring(1, spaceIndex);\n }\n}\n","/**\n * Command autocomplete dropdown\n * Shows available commands or parameter suggestions\n */\n\nimport React, { useMemo } from 'react';\nimport { Box, Text } from 'ink';\nimport chalk from 'chalk';\nimport { ISlashCommand } from '../../core/SlashCommand.js';\nimport { Theme, KeyBindingsConfig } from '../../config/schemas.js';\nimport { getTheme } from '../../config/themes/index.js';\nimport { formatNavigationArrows, formatKeyboardShortcut } from '../../utils/keyboardFormatter.js';\nimport { useTerminalSize } from '../hooks/useTerminalSize.js';\n\n/**\n * Adjust hex color brightness by a factor\n * @param hex - Hex color string (e.g., '#3B4252')\n * @param factor - Adjustment factor (-1 to 1, negative for darker, positive for lighter)\n * @returns Adjusted hex color\n */\nfunction adjustHexBrightness(hex: string, factor: number): string {\n // Remove # if present\n const cleanHex = hex.replace('#', '');\n\n // Parse RGB components\n const r = parseInt(cleanHex.substring(0, 2), 16);\n const g = parseInt(cleanHex.substring(2, 4), 16);\n const b = parseInt(cleanHex.substring(4, 6), 16);\n\n // Adjust brightness\n const adjust = (value: number) => {\n const adjusted =\n factor < 0\n ? value * (1 + factor) // Darken\n : value + (255 - value) * factor; // Lighten\n return Math.max(0, Math.min(255, Math.round(adjusted)));\n };\n\n const newR = adjust(r);\n const newG = adjust(g);\n const newB = adjust(b);\n\n // Convert back to hex\n const toHex = (n: number) => n.toString(16).padStart(2, '0');\n return `#${toHex(newR)}${toHex(newG)}${toHex(newB)}`;\n}\n\nexport interface CommandAutocompleteProps {\n // For command autocomplete\n commands?: ISlashCommand[];\n // For parameter autocomplete\n parameterSuggestions?: string[];\n parameterName?: string;\n selectedIndex: number;\n maxVisible?: number;\n // Show parameter info for selected command\n showParameterInfo?: boolean;\n selectedCommand?: ISlashCommand;\n // Theme for styling\n theme: Theme;\n // Keyboard shortcuts for footer\n keyBindings: KeyBindingsConfig;\n // Callback to report actual rendered height\n onHeightCalculated?: (height: number) => void;\n}\n\nexport const CommandAutocomplete: React.FC<CommandAutocompleteProps> = ({\n commands,\n parameterSuggestions,\n parameterName,\n selectedIndex,\n maxVisible = 5,\n showParameterInfo = false,\n selectedCommand: _selectedCommand,\n theme,\n keyBindings,\n onHeightCalculated,\n}) => {\n const themeDefinition = getTheme(theme);\n const bgColorHex = themeDefinition.rawColors.autocompleteBg || '#2e3440';\n const bg = chalk.bgHex(bgColorHex);\n const autocompleteText = themeDefinition.colors.autocompleteText;\n const autocompleteSelectedBgHex = themeDefinition.rawColors.autocompleteSelectedBg || '#88c0d0';\n const autocompleteSelectedBg = chalk.bgHex(autocompleteSelectedBgHex);\n const autocompleteSelectedText = themeDefinition.colors.autocompleteSelectedText;\n const autocompleteHeaderText = themeDefinition.colors.autocompleteHeaderText;\n const autocompleteFooterText = themeDefinition.colors.autocompleteFooterText;\n const autocompleteMoreIndicator = themeDefinition.colors.autocompleteMoreIndicator;\n\n // Subtle background for parameter rows (slightly darker)\n const paramBgHex = adjustHexBrightness(bgColorHex, -0.05); // 5% darker\n const paramBg = chalk.bgHex(paramBgHex);\n\n // Get terminal width to constrain autocomplete\n const { width: terminalWidth } = useTerminalSize();\n const maxAllowedWidth = Math.max(30, terminalWidth - 4); // Leave 4 chars margin, minimum 30\n\n // Helper to truncate text with ellipsis if it exceeds max width\n const truncateText = (text: string, maxLen: number): string => {\n // Strip ANSI codes for accurate length calculation\n // eslint-disable-next-line no-control-regex\n const stripped = text.replace(/\\x1B\\[[0-9;]*m/g, '');\n if (stripped.length <= maxLen) {\n return stripped; // Always return stripped version for consistent formatting\n }\n // Truncate stripped text and add ellipsis\n return stripped.slice(0, maxLen - 3) + '...';\n };\n\n // Helper to create full-width background line\n const bgLine = (content: string, width: number, chalkFn = autocompleteText) => {\n const truncated = truncateText(content, width);\n // truncateText already strips ANSI codes, so we can use length directly\n const padding = Math.max(0, width - truncated.length);\n return bg(chalkFn(truncated + ' '.repeat(padding)));\n };\n\n // Build footer text from keyboard shortcuts with icons\n const footerText = useMemo(() => {\n const navigateKeys = formatNavigationArrows(keyBindings.navigateUp, keyBindings.navigateDown);\n // Show all accept keys (Tab, Enter, etc.)\n const acceptKeys = formatKeyboardShortcut(keyBindings.showTooltip.concat(keyBindings.accept));\n const cancelKeys = formatKeyboardShortcut(keyBindings.interrupt);\n return ` ${navigateKeys} navigate | ${acceptKeys} select | ${cancelKeys} cancel `;\n }, [keyBindings]);\n\n // Parameter autocomplete mode\n if (parameterSuggestions && parameterSuggestions.length > 0) {\n // Guard: Ensure selectedIndex is within bounds\n const safeSelectedIndex = Math.max(0, Math.min(selectedIndex, parameterSuggestions.length - 1));\n\n const { visibleSuggestions, startIndex, endIndex } = useMemo(() => {\n if (parameterSuggestions.length <= maxVisible) {\n return {\n visibleSuggestions: parameterSuggestions,\n startIndex: 0,\n endIndex: parameterSuggestions.length,\n };\n }\n\n // Calculate window to ensure selected item is ALWAYS visible\n let startIndex: number;\n let endIndex: number;\n\n if (safeSelectedIndex < Math.floor(maxVisible / 2)) {\n // Near start - show from beginning\n startIndex = 0;\n endIndex = maxVisible;\n } else if (safeSelectedIndex >= parameterSuggestions.length - Math.floor(maxVisible / 2)) {\n // Near end - show last maxVisible items\n startIndex = parameterSuggestions.length - maxVisible;\n endIndex = parameterSuggestions.length;\n } else {\n // Middle - center the selected item\n startIndex = safeSelectedIndex - Math.floor(maxVisible / 2);\n endIndex = startIndex + maxVisible;\n }\n\n // Safety bounds\n startIndex = Math.max(0, startIndex);\n endIndex = Math.min(parameterSuggestions.length, endIndex);\n\n return {\n visibleSuggestions: parameterSuggestions.slice(startIndex, endIndex),\n startIndex,\n endIndex,\n };\n }, [parameterSuggestions, safeSelectedIndex, maxVisible]);\n\n const moreAbove = startIndex > 0;\n const moreBelow = endIndex < parameterSuggestions.length;\n const moreAboveCount = startIndex;\n const moreBelowCount = parameterSuggestions.length - endIndex;\n\n // Calculate exact rendered height by counting lines we're about to render:\n // 1. Header line\n // 2. More above indicator (conditional)\n // 3. Each visible suggestion (1 line each)\n // 4. More below indicator (conditional)\n // 5. Footer line\n const actualHeight = useMemo(() => {\n let height = 0;\n height += 1; // header\n if (moreAbove) height += 1; // more above indicator\n height += visibleSuggestions.length; // all visible items\n if (moreBelow) height += 1; // more below indicator\n height += 1; // footer\n return height;\n }, [moreAbove, visibleSuggestions.length, moreBelow]);\n\n // Report height to parent\n React.useEffect(() => {\n if (onHeightCalculated) {\n onHeightCalculated(actualHeight);\n }\n }, [onHeightCalculated, actualHeight]);\n\n // Calculate max width for consistent backgrounds, clamped to terminal width\n const maxWidth = useMemo(() => {\n const header = ` ${parameterName || 'Parameter'} (${parameterSuggestions.length}) `;\n const moreText = moreAbove ? ` ▲ ${moreAboveCount} more above ` : '';\n const moreBelowText = moreBelow ? ` ▼ ${moreBelowCount} more below ` : '';\n const items = visibleSuggestions.map((s) => ` ${s}`);\n\n const lengths = [\n header.length,\n footerText.length,\n moreText.length,\n moreBelowText.length,\n ...items.map((i) => i.length),\n ];\n const idealWidth = Math.max(...lengths, 50); // Minimum 50 chars\n return Math.min(idealWidth, maxAllowedWidth); // Clamp to terminal width\n }, [\n parameterName,\n parameterSuggestions.length,\n visibleSuggestions,\n moreAbove,\n moreBelow,\n moreAboveCount,\n moreBelowCount,\n footerText,\n maxAllowedWidth,\n ]);\n\n return (\n <Box flexDirection=\"column\" flexShrink={0}>\n <Text>\n {bgLine(\n ` ${parameterName || 'Parameter'} (${parameterSuggestions.length}) `,\n maxWidth,\n autocompleteHeaderText\n )}\n </Text>\n {moreAbove && (\n <Text>\n {bgLine(` ▲ ${moreAboveCount} more above `, maxWidth, autocompleteMoreIndicator)}\n </Text>\n )}\n {visibleSuggestions.map((suggestion, idx) => {\n // Calculate actual index in original array\n const actualIndex = startIndex + idx;\n const isSelected = actualIndex === safeSelectedIndex;\n const prefix = isSelected ? '> ' : ' ';\n const content = `${prefix}${suggestion}`;\n\n return (\n <Text key={`${actualIndex}-${suggestion}`}>\n {isSelected\n ? autocompleteSelectedBg(\n autocompleteSelectedText(truncateText(content, maxWidth).padEnd(maxWidth, ' '))\n )\n : bgLine(content, maxWidth)}\n </Text>\n );\n })}\n {moreBelow && (\n <Text>\n {bgLine(` ▼ ${moreBelowCount} more below `, maxWidth, autocompleteMoreIndicator)}\n </Text>\n )}\n <Text>{bgLine(footerText, maxWidth, autocompleteFooterText)}</Text>\n </Box>\n );\n }\n\n // Command autocomplete mode\n if (!commands || commands.length === 0) {\n return null;\n }\n\n // Guard: Ensure selectedIndex is within bounds\n const safeSelectedIndex = Math.max(0, Math.min(selectedIndex, commands.length - 1));\n\n const { visibleCommands, startIndex, endIndex } = useMemo(() => {\n // Helper: count lines a command takes (1 + params if selected and showing param info)\n const countLines = (cmd: ISlashCommand | undefined, idx: number) => {\n if (!cmd) return 1; // Safety: treat undefined as 1 line\n let lines = 1; // Command itself\n if (showParameterInfo && idx === safeSelectedIndex && cmd.parameters) {\n lines += cmd.parameters.length; // Add parameter lines\n }\n return lines;\n };\n\n // Calculate total lines if we show all commands\n const totalLines = commands.reduce((sum, cmd, idx) => sum + countLines(cmd, idx), 0);\n\n // If total lines fit in maxVisible, show all\n if (totalLines <= maxVisible) {\n return {\n visibleCommands: commands,\n startIndex: 0,\n endIndex: commands.length,\n };\n }\n\n // Need to window - calculate visible range accounting for line counts\n // Strategy: Start from selected item and expand outward until we hit maxVisible lines\n let startIndex = safeSelectedIndex;\n let endIndex = safeSelectedIndex + 1;\n let lineCount = countLines(commands[safeSelectedIndex], safeSelectedIndex);\n\n // Expand downward first (items after selected)\n while (endIndex < commands.length && lineCount < maxVisible) {\n const nextLines = countLines(commands[endIndex], endIndex);\n if (lineCount + nextLines > maxVisible) break;\n lineCount += nextLines;\n endIndex++;\n }\n\n // Then expand upward (items before selected) if we have room\n while (startIndex > 0 && lineCount < maxVisible) {\n const prevLines = countLines(commands[startIndex - 1], startIndex - 1);\n if (lineCount + prevLines > maxVisible) break;\n lineCount += prevLines;\n startIndex--;\n }\n\n return {\n visibleCommands: commands.slice(startIndex, endIndex),\n startIndex,\n endIndex,\n };\n }, [commands, safeSelectedIndex, maxVisible, showParameterInfo]);\n\n const moreAbove = startIndex > 0;\n const moreBelow = endIndex < commands.length;\n const moreAboveCount = startIndex;\n const moreBelowCount = commands.length - endIndex;\n\n // Calculate parameter tooltip lines for selected command\n const safeIndex = Math.max(0, Math.min(selectedIndex, commands.length - 1));\n const selectedCmd = commands[safeIndex];\n const paramTooltipLines =\n showParameterInfo && selectedCmd?.parameters ? selectedCmd.parameters.length : 0;\n\n // Calculate exact rendered height by counting lines we're about to render:\n // 1. Header line\n // 2. More above indicator (conditional)\n // 3. Each visible command (1 line each)\n // 4. Parameter tooltips for selected command (conditional, N lines)\n // 5. More below indicator (conditional)\n // 6. Footer line\n const actualHeight = useMemo(() => {\n let height = 0;\n height += 1; // header\n if (moreAbove) height += 1; // more above indicator\n height += visibleCommands.length; // all visible command items\n height += paramTooltipLines; // parameter tooltips for selected command\n if (moreBelow) height += 1; // more below indicator\n height += 1; // footer\n return height;\n }, [moreAbove, visibleCommands.length, paramTooltipLines, moreBelow]);\n\n // Report height to parent\n React.useEffect(() => {\n if (onHeightCalculated) {\n onHeightCalculated(actualHeight);\n }\n }, [onHeightCalculated, actualHeight]);\n\n // Calculate max width for consistent backgrounds, clamped to terminal width\n const maxWidth = useMemo(() => {\n const header = ` Commands (${commands.length}) `;\n const moreText = moreAbove ? ` ▲ ${moreAboveCount} more above ` : '';\n const moreBelowText = moreBelow ? ` ▼ ${moreBelowCount} more below ` : '';\n\n const cmdLengths = visibleCommands.map((cmd) => {\n const cmdLine = ` /${cmd.name} - ${cmd.description}`;\n let maxLen = cmdLine.length;\n if (showParameterInfo && cmd.parameters) {\n cmd.parameters.forEach((param) => {\n const paramLine = ` <${param.name}>: ${param.description}`;\n maxLen = Math.max(maxLen, paramLine.length);\n });\n }\n return maxLen;\n });\n\n const lengths = [\n header.length,\n footerText.length,\n moreText.length,\n moreBelowText.length,\n ...cmdLengths,\n ];\n const idealWidth = Math.max(...lengths, 50); // Minimum 50 chars\n return Math.min(idealWidth, maxAllowedWidth); // Clamp to terminal width\n }, [\n commands.length,\n visibleCommands,\n showParameterInfo,\n moreAbove,\n moreBelow,\n moreAboveCount,\n moreBelowCount,\n footerText,\n maxAllowedWidth,\n ]);\n\n return (\n <Box flexDirection=\"column\" flexShrink={0}>\n <Text>{bgLine(` Commands (${commands.length}) `, maxWidth, autocompleteHeaderText)}</Text>\n {moreAbove && (\n <Text>\n {bgLine(` ▲ ${moreAboveCount} more above `, maxWidth, autocompleteMoreIndicator)}\n </Text>\n )}\n {(() => {\n // Calculate consistent column width for all commands (table layout)\n // Find longest command name in the visible set\n const longestCmdName = Math.max(...visibleCommands.map((c) => c.name.length));\n const cmdColumnWidth = longestCmdName + 2; // +2 for '/' and spacing\n\n // Also check parameters if showing\n let longestParamSig = 0;\n if (showParameterInfo) {\n for (const cmd of visibleCommands) {\n if (cmd.parameters) {\n for (const p of cmd.parameters) {\n const paramSig = `/${cmd.name} <${p.name}>`.length;\n longestParamSig = Math.max(longestParamSig, paramSig);\n }\n }\n }\n }\n const signatureColumnWidth = Math.max(cmdColumnWidth, longestParamSig + 2);\n\n return visibleCommands.map((command, idx) => {\n const actualIndex = startIndex + idx;\n const isSelected = actualIndex === safeSelectedIndex;\n const prefix = isSelected ? '> ' : ' ';\n\n // Build table row: [prefix][/name][padding][description]\n const cmdName = `${prefix}/${command.name}`;\n const cmdPadding = ' '.repeat(Math.max(1, signatureColumnWidth - cmdName.length + 2));\n const cmdLine = cmdName + cmdPadding + command.description;\n const cmdTruncated = truncateText(cmdLine, maxWidth);\n\n // Split at description boundary\n const descStartIdx = cmdName.length + cmdPadding.length;\n const cmdPart = cmdTruncated.substring(0, Math.min(descStartIdx, cmdTruncated.length));\n const descPart = cmdTruncated.substring(Math.min(descStartIdx, cmdTruncated.length));\n const rowPadding = ' '.repeat(Math.max(0, maxWidth - cmdTruncated.length));\n\n return (\n <React.Fragment key={`${actualIndex}-${command.name}`}>\n <Text>\n {isSelected\n ? autocompleteSelectedBg(\n autocompleteSelectedText(cmdPart) +\n autocompleteSelectedText(chalk.dim(descPart)) +\n autocompleteSelectedText(rowPadding)\n )\n : bg(\n autocompleteText(cmdPart) +\n autocompleteText(chalk.dim(descPart)) +\n autocompleteText(rowPadding)\n )}\n </Text>\n {isSelected &&\n showParameterInfo &&\n command.parameters &&\n command.parameters.length > 0 &&\n command.parameters.map((param) => {\n // Parameter row: [ <param>][padding][description] (indented by 2 spaces)\n const paramSig = ` <${param.name}>`;\n const paramPadding = ' '.repeat(\n Math.max(1, signatureColumnWidth - paramSig.length + 2)\n );\n const paramLine = paramSig + paramPadding + param.description;\n const paramTruncated = truncateText(paramLine, maxWidth);\n\n const paramDescStartIdx = paramSig.length + paramPadding.length;\n const paramSigPart = paramTruncated.substring(\n 0,\n Math.min(paramDescStartIdx, paramTruncated.length)\n );\n const paramDescPart = paramTruncated.substring(\n Math.min(paramDescStartIdx, paramTruncated.length)\n );\n const paramRowPadding = ' '.repeat(Math.max(0, maxWidth - paramTruncated.length));\n\n return (\n <Text key={`${actualIndex}-${command.name}-${param.name}`}>\n {paramBg(\n autocompleteText(chalk.dim(paramSigPart)) +\n autocompleteText(chalk.hex('#8b95a8')(paramDescPart)) +\n autocompleteText(paramRowPadding)\n )}\n </Text>\n );\n })}\n </React.Fragment>\n );\n });\n })()}\n {moreBelow && (\n <Text>\n {bgLine(` ▼ ${moreBelowCount} more below `, maxWidth, autocompleteMoreIndicator)}\n </Text>\n )}\n <Text>{bgLine(footerText, maxWidth, autocompleteFooterText)}</Text>\n </Box>\n );\n};\n","import { useEffect, useState } from 'react';\nimport { useStdout } from 'ink';\n\n/**\n * Custom hook for reactive terminal dimensions\n *\n * Unlike useStdout() which provides static dimensions,\n * this hook ensures component re-renders when terminal is resized.\n *\n * @returns {width: number, height: number} - Current terminal dimensions\n */\nexport const useTerminalSize = (): { width: number; height: number } => {\n const { stdout } = useStdout();\n\n // Initialize with current dimensions or fallback to 80x24\n const [dimensions, setDimensions] = useState({\n width: stdout?.columns || 80,\n height: stdout?.rows || 24,\n });\n\n useEffect(() => {\n if (!stdout) return;\n\n // Handler for terminal resize events (SIGWINCH)\n const handleResize = () => {\n setDimensions({\n width: stdout.columns || 80,\n height: stdout.rows || 24,\n });\n };\n\n // Listen for resize events\n // Ink automatically handles SIGWINCH and emits 'resize' on stdout\n stdout.on('resize', handleResize);\n\n // Update dimensions immediately in case they changed before listener was attached\n handleResize();\n\n // Cleanup listener on unmount\n return () => {\n stdout.off('resize', handleResize);\n };\n }, [stdout]);\n\n return dimensions;\n};\n","/**\n * Chat footer component\n * Displays mode, cost, keyboard shortcuts and help tips\n */\n\nimport React, { useState, useEffect } from 'react';\nimport { Box, Text } from 'ink';\nimport { Theme, KeyBindingsConfig } from '../../config/schemas.js';\nimport { getTheme } from '../../config/themes/index.js';\nimport { getRandomTip } from './tips.js';\nimport { formatKeyboardShortcut } from '../../utils/keyboardFormatter.js';\n\nexport interface FooterProps {\n theme: Theme;\n shortcuts: KeyBindingsConfig;\n mode: 'plan' | 'act' | 'discuss';\n cost: number;\n interruptPressCount?: number;\n isAgentRunning?: boolean;\n}\n\nexport const Footer: React.FC<FooterProps> = ({\n theme,\n shortcuts,\n mode,\n cost,\n interruptPressCount = 0,\n isAgentRunning = false,\n}) => {\n const themeDefinition = getTheme(theme);\n\n // Get mode display with icon, color, and capitalization\n const getModeDisplay = (): JSX.Element => {\n switch (mode) {\n case 'plan':\n return <Text>{themeDefinition.colors.modePlan('□ PLAN ')}</Text>;\n case 'act':\n return <Text>{themeDefinition.colors.modeAct('▶ ACT ')}</Text>;\n case 'discuss':\n return <Text>{themeDefinition.colors.modeDiscuss('◉ DISCUSS')}</Text>;\n }\n };\n\n // Random tip that rotates every 10 seconds\n const [currentTip, setCurrentTip] = useState(getRandomTip(shortcuts));\n\n useEffect(() => {\n const interval = setInterval(() => {\n setCurrentTip(getRandomTip(shortcuts));\n }, 10000); // Change tip every 10 seconds\n\n return () => clearInterval(interval);\n }, [shortcuts]);\n\n // Get message to display below shortcuts\n const getMessage = () => {\n if (interruptPressCount === 1) {\n const interruptKey = formatKeyboardShortcut(shortcuts.interrupt);\n if (isAgentRunning) {\n return (\n <Text>\n {themeDefinition.colors.warning(\n `Agent interrupted. Press ${interruptKey} again to exit`\n )}\n </Text>\n );\n } else {\n return <Text>{themeDefinition.colors.warning(`Press ${interruptKey} again to exit`)}</Text>;\n }\n }\n return <Text dimColor>{currentTip}</Text>;\n };\n\n return (\n <Box flexDirection=\"column\">\n <Box>\n <Text>\n Mode: {getModeDisplay()}\n {' | '}\n Cost: <Text>{themeDefinition.colors.warning(`$${cost.toFixed(4)}`)}</Text>\n </Text>\n </Box>\n <Box>\n <Text dimColor>\n {formatKeyboardShortcut(shortcuts.interrupt)}=Cancel |{' '}\n {formatKeyboardShortcut(shortcuts.modeSwitch)}=Mode | /help=Commands\n </Text>\n </Box>\n <Box>{getMessage()}</Box>\n </Box>\n );\n};\n","/**\n * Random tips displayed in the footer\n */\n\nimport { KeyBindingsConfig } from '../../config/schemas.js';\nimport { formatKeyboardShortcut } from '../../utils/keyboardFormatter.js';\n\n/**\n * Generate tips array with dynamic keyboard shortcuts\n */\nfunction generateTips(keyBindings: KeyBindingsConfig): string[] {\n const modeSwitchKey = formatKeyboardShortcut(keyBindings.modeSwitch, { showFirstOnly: true });\n const editKey = formatKeyboardShortcut(keyBindings.editCommand, { showFirstOnly: true });\n\n return [\n 'Tip: Use /help to see all available commands',\n `Tip: Switch modes with ${modeSwitchKey} (Plan → Act → Discuss)`,\n 'Tip: Type /plan <task> to create an execution plan',\n 'Tip: Use /discuss <topic> to enter architect/discuss mode',\n 'Tip: Your conversation history is automatically saved',\n 'Tip: Check total costs with /cost to track your spending',\n `Tip: Use ${editKey} to edit your last command (coming soon)`,\n 'Tip: The permission system keeps your code safe - review commands before they run',\n 'Tip: Docker sandboxing isolates untrusted code execution',\n 'Tip: MCP servers extend Mimir with custom tools and capabilities',\n 'Tip: Use /model <provider> to switch between LLM providers',\n 'Tip: Create checkpoints with /checkpoint to save your progress',\n 'Tip: Configuration can be customized in .mimir/config.yml',\n ];\n}\n\n/**\n * Get a random tip with dynamic keyboard shortcuts\n */\nexport function getRandomTip(keyBindings: KeyBindingsConfig): string {\n const tips = generateTips(keyBindings);\n const randomIndex = Math.floor(Math.random() * tips.length);\n return tips[randomIndex] ?? 'Tip: Use keyboard shortcuts for faster navigation';\n}\n","/**\n * Central keyboard event bus for dispatching keyboard actions\n * Supports event propagation control and priority-based handling\n */\n\nimport { EventEmitter } from 'events';\nimport { KeyBindingAction, KeyBindingsManager } from '../../utils/KeyBindings.js';\nimport { logger } from '../../utils/logger.js';\n\nexport interface KeyboardEventContext {\n /** Is autocomplete/tooltip currently showing? */\n isAutocompleteVisible: boolean;\n /** Is the agent currently running? */\n isAgentRunning: boolean;\n /** Is there text input currently focused? */\n isInputFocused: boolean;\n /** Custom context data */\n [key: string]: unknown;\n}\n\nexport interface KeyboardEvent {\n /** The semantic action triggered */\n action: KeyBindingAction;\n /** Raw key that was pressed */\n rawKey: string;\n /** Current context when event was triggered */\n context: Readonly<KeyboardEventContext>;\n /** Stop propagation to parent handlers */\n stopPropagation(): void;\n /** Was propagation stopped? */\n isPropagationStopped(): boolean;\n}\n\nexport interface KeyboardEventHandler {\n /** The action this handler responds to */\n action: KeyBindingAction;\n /** Handler function */\n handler: (event: KeyboardEvent) => void | boolean;\n /** Priority (higher = runs first). Default: 0 */\n priority?: number;\n /** Unique ID for this handler (for cleanup) */\n id: string;\n}\n\n/**\n * Central keyboard event bus\n * Manages keyboard event routing with priority and propagation control\n */\nexport class KeyboardEventBus extends EventEmitter {\n private handlers: Map<KeyBindingAction, KeyboardEventHandler[]> = new Map();\n private context: KeyboardEventContext = {\n isAutocompleteVisible: false,\n isAgentRunning: false,\n isInputFocused: true,\n };\n\n constructor(private bindingsManager: KeyBindingsManager) {\n super();\n this.setMaxListeners(50); // Allow many components to subscribe\n }\n\n /**\n * Update keyboard context\n */\n updateContext(updates: Partial<KeyboardEventContext>): void {\n this.context = { ...this.context, ...updates };\n }\n\n /**\n * Get current context (readonly)\n */\n getContext(): Readonly<KeyboardEventContext> {\n return Object.freeze({ ...this.context });\n }\n\n /**\n * Subscribe to keyboard action\n * Returns unsubscribe function\n */\n subscribe(\n action: KeyBindingAction,\n handler: (event: KeyboardEvent) => void | boolean,\n options: { priority?: number; id?: string } = {}\n ): () => void {\n const handlerObj: KeyboardEventHandler = {\n action,\n handler,\n priority: options.priority ?? 0,\n id: options.id ?? `${action}-${Date.now()}-${Math.random()}`,\n };\n\n const handlers = this.handlers.get(action) || [];\n handlers.push(handlerObj);\n\n // Sort by priority (descending)\n handlers.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));\n\n this.handlers.set(action, handlers);\n\n // Return unsubscribe function\n return () => {\n const handlers = this.handlers.get(action);\n if (handlers) {\n const index = handlers.findIndex((h) => h.id === handlerObj.id);\n if (index !== -1) {\n handlers.splice(index, 1);\n }\n }\n };\n }\n\n /**\n * Dispatch a raw key press\n * Converts to action and emits to handlers\n */\n dispatch(rawKey: string): boolean {\n const action = this.bindingsManager.getActionForKey(rawKey);\n\n if (!action) {\n return false;\n }\n\n return this.dispatchAction(action, rawKey);\n }\n\n /**\n * Dispatch a specific action\n * @returns true if event was handled, false otherwise\n */\n dispatchAction(action: KeyBindingAction, rawKey?: string): boolean {\n const handlers = this.handlers.get(action);\n\n if (!handlers || handlers.length === 0) {\n return false;\n }\n\n let propagationStopped = false;\n\n const event: KeyboardEvent = {\n action,\n rawKey: rawKey ?? action,\n context: this.getContext(),\n stopPropagation: () => {\n propagationStopped = true;\n },\n isPropagationStopped: () => propagationStopped,\n };\n\n // Execute handlers in priority order\n for (const { handler, id, priority } of handlers) {\n if (propagationStopped) {\n break;\n }\n\n try {\n const result = handler(event);\n\n // Handler can return false to continue, true to stop propagation\n if (result === false) {\n continue;\n } else if (result === true) {\n event.stopPropagation();\n }\n } catch (error) {\n logger.error(`Error in keyboard handler for ${action}`, {\n error,\n handlerId: id,\n priority,\n });\n }\n }\n\n return true;\n }\n\n /**\n * Remove all handlers for an action\n */\n clearAction(action: KeyBindingAction): void {\n this.handlers.delete(action);\n }\n\n /**\n * Remove all handlers\n */\n clearAll(): void {\n this.handlers.clear();\n }\n\n /**\n * Get all registered actions\n */\n getRegisteredActions(): KeyBindingAction[] {\n return Array.from(this.handlers.keys());\n }\n\n /**\n * Get handler count for action\n */\n getHandlerCount(action: KeyBindingAction): number {\n return this.handlers.get(action)?.length ?? 0;\n }\n}\n","/**\n * React context for keyboard event bus\n * Provides centralized keyboard handling to all components\n */\n\nimport { createContext, useContext, useEffect, useState, ReactNode } from 'react';\nimport { KeyboardEventBus, KeyboardEventContext } from './KeyboardEventBus.js';\nimport { KeyBindingsManager } from '../../utils/KeyBindings.js';\nimport { IFileSystem } from '../../platform/IFileSystem.js';\nimport { KeyBindingsConfig } from '../../config/schemas.js';\n\ninterface KeyboardContextValue {\n eventBus: KeyboardEventBus;\n bindingsManager: KeyBindingsManager;\n updateContext: (updates: Partial<KeyboardEventContext>) => void;\n getContext: () => Readonly<KeyboardEventContext>;\n}\n\nconst KeyboardContext = createContext<KeyboardContextValue | null>(null);\n\nexport interface KeyboardProviderProps {\n children: ReactNode;\n bindingsConfig: KeyBindingsConfig;\n fs: IFileSystem;\n projectRoot?: string;\n}\n\n/**\n * Provider for keyboard system\n * Must wrap the entire app to enable keyboard handling\n */\nexport function KeyboardProvider({\n children,\n bindingsConfig,\n fs: _fs,\n projectRoot: _projectRoot,\n}: KeyboardProviderProps): JSX.Element {\n const [contextValue] = useState<KeyboardContextValue>(() => {\n const bindingsManager = new KeyBindingsManager(bindingsConfig);\n const eventBus = new KeyboardEventBus(bindingsManager);\n\n return {\n eventBus,\n bindingsManager,\n updateContext: (updates) => eventBus.updateContext(updates),\n getContext: () => eventBus.getContext(),\n };\n });\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n contextValue.eventBus.clearAll();\n };\n }, [contextValue]);\n\n return <KeyboardContext.Provider value={contextValue}>{children}</KeyboardContext.Provider>;\n}\n\n/**\n * Hook to access keyboard system\n */\nexport function useKeyboard(): KeyboardContextValue {\n const context = useContext(KeyboardContext);\n\n if (!context) {\n throw new Error('useKeyboard must be used within KeyboardProvider');\n }\n\n return context;\n}\n","/**\n * Keyboard shortcuts with platform-specific bindings\n * Loads from .mimir/config.yml\n */\n\nimport { KeyBindingsConfig } from '../config/schemas.js';\nimport { logger } from './logger.js';\nimport os from 'os';\n\nexport interface KeyBinding {\n keys: string[]; // Now supports multiple shortcuts per action\n displayName: string; // Primary key for display\n action: string;\n description: string;\n}\n\nexport type KeyBindingAction =\n | 'interrupt' // Ctrl+C and Escape - cancel/interrupt operation\n | 'accept' // Enter - confirm action\n | 'modeSwitch' // Shift+Tab - switch modes\n | 'editCommand' // Ctrl+E - edit instruction\n | 'showTooltip' // Ctrl+Space and Tab - show autocomplete\n | 'navigateUp' // Arrow Up - navigate up in lists\n | 'navigateDown' // Arrow Down - navigate down in lists\n | 'help' // ? - show help\n | 'clearScreen' // Ctrl+L - clear screen\n | 'undo' // Ctrl+Z - undo\n | 'redo' // Ctrl+Y (Cmd+Shift+Z on Mac) - redo\n | 'reject'; // @deprecated - use 'interrupt' instead\n\nexport class KeyBindingsManager {\n private bindings: Map<KeyBindingAction, KeyBinding> = new Map();\n private platform: 'darwin' | 'win32' | 'linux';\n\n constructor(private config: KeyBindingsConfig) {\n this.platform = os.platform() as 'darwin' | 'win32' | 'linux';\n this.initializeDefaults();\n }\n\n /**\n * Initialize default platform-specific bindings\n */\n private initializeDefaults(): void {\n const isMac = this.platform === 'darwin';\n const modKey = isMac ? 'Cmd' : 'Ctrl';\n\n // Helper to convert config keys to platform-specific\n const toPlatform = (keys: string[]): string[] => {\n return keys.map((key) => key.replace(/Ctrl/g, modKey));\n };\n\n // Core bindings from config\n this.addBinding('interrupt', {\n keys: toPlatform(this.config.interrupt),\n displayName: toPlatform(this.config.interrupt)[0] ?? 'Ctrl+C',\n action: 'interrupt',\n description: 'Cancel/interrupt current operation',\n });\n\n this.addBinding('accept', {\n keys: this.config.accept,\n displayName: this.config.accept[0] ?? 'Enter',\n action: 'accept',\n description: 'Accept/confirm action',\n });\n\n // Note: 'reject' action is deprecated - use 'interrupt' instead\n // Only add if explicitly configured for backwards compatibility\n if (this.config.reject && this.config.reject.length > 0) {\n this.addBinding('reject', {\n keys: this.config.reject,\n displayName: this.config.reject[0] ?? 'Escape',\n action: 'reject',\n description: 'Reject/cancel prompt (deprecated)',\n });\n }\n\n this.addBinding('modeSwitch', {\n keys: this.config.modeSwitch,\n displayName: this.config.modeSwitch[0] ?? 'Shift+Tab',\n action: 'modeSwitch',\n description: 'Switch between modes',\n });\n\n this.addBinding('editCommand', {\n keys: toPlatform(this.config.editCommand),\n displayName: toPlatform(this.config.editCommand)[0] ?? `${modKey}+E`,\n action: 'editCommand',\n description: 'Edit alternative instruction',\n });\n\n this.addBinding('showTooltip', {\n keys: toPlatform(this.config.showTooltip),\n displayName: toPlatform(this.config.showTooltip)[0] ?? `${modKey}+Space`,\n action: 'showTooltip',\n description: 'Show autocomplete/tooltip',\n });\n\n this.addBinding('navigateUp', {\n keys: this.config.navigateUp,\n displayName: this.config.navigateUp[0] ?? 'ArrowUp',\n action: 'navigateUp',\n description: 'Navigate up in list',\n });\n\n this.addBinding('navigateDown', {\n keys: this.config.navigateDown,\n displayName: this.config.navigateDown[0] ?? 'ArrowDown',\n action: 'navigateDown',\n description: 'Navigate down in list',\n });\n\n this.addBinding('help', {\n keys: this.config.help,\n displayName: this.config.help[0] ?? '?',\n action: 'help',\n description: 'Show help overlay',\n });\n\n this.addBinding('clearScreen', {\n keys: toPlatform(this.config.clearScreen),\n displayName: toPlatform(this.config.clearScreen)[0] ?? `${modKey}+L`,\n action: 'clearScreen',\n description: 'Clear screen',\n });\n\n this.addBinding('undo', {\n keys: toPlatform(this.config.undo),\n displayName: toPlatform(this.config.undo)[0] ?? `${modKey}+Z`,\n action: 'undo',\n description: 'Undo last action',\n });\n\n // Redo has platform-specific default\n const redoKeys = isMac ? [`${modKey}+Shift+Z`] : toPlatform(this.config.redo);\n\n this.addBinding('redo', {\n keys: redoKeys,\n displayName: redoKeys[0] ?? `${modKey}+Y`,\n action: 'redo',\n description: 'Redo last undone action',\n });\n }\n\n /**\n * Add or override a key binding\n */\n private addBinding(action: KeyBindingAction, binding: KeyBinding): void {\n this.bindings.set(action, binding);\n }\n\n /**\n * Get binding for action\n */\n getBinding(action: KeyBindingAction): KeyBinding | undefined {\n return this.bindings.get(action);\n }\n\n /**\n * Get all bindings\n */\n getAllBindings(): Map<KeyBindingAction, KeyBinding> {\n return new Map(this.bindings);\n }\n\n /**\n * Get help text for all shortcuts\n */\n getHelpText(): string {\n const lines = ['Keyboard Shortcuts:', ''];\n\n for (const [, binding] of this.bindings) {\n // Format multiple keys as \"Ctrl+C, Escape\"\n const keysDisplay = binding.keys.join(', ');\n lines.push(` ${keysDisplay.padEnd(20)} ${binding.description}`);\n }\n\n return lines.join('\\n');\n }\n\n /**\n * Normalize key string for comparison\n * Handles: Ctrl/Control, Cmd/Command, variations in case\n */\n static normalizeKey(key: string): string {\n return key\n .replace(/Control/gi, 'Ctrl')\n .replace(/Command/gi, 'Cmd')\n .replace(/Delete/gi, 'Del')\n .replace(/Escape/gi, 'Esc')\n .split('+')\n .map((part) => part.trim())\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())\n .join('+');\n }\n\n /**\n * Check if pressed key matches any binding for the action\n */\n matches(pressedKey: string, action: KeyBindingAction): boolean {\n const binding = this.bindings.get(action);\n if (!binding || !binding.keys) return false;\n\n const normalizedPressed = KeyBindingsManager.normalizeKey(pressedKey);\n\n // Check if pressed key matches any of the bound keys\n return binding.keys.some((key) => {\n const normalizedBinding = KeyBindingsManager.normalizeKey(key);\n return normalizedPressed === normalizedBinding;\n });\n }\n\n /**\n * Get action for a pressed key (reverse lookup)\n */\n getActionForKey(pressedKey: string): KeyBindingAction | null {\n const normalizedPressed = KeyBindingsManager.normalizeKey(pressedKey);\n\n for (const [action, binding] of this.bindings) {\n // Defensive check: skip if binding is somehow undefined\n if (!binding || !binding.keys) {\n logger.warn(`Invalid binding for action: ${action}`, { binding });\n continue;\n }\n\n if (binding.keys.some((key) => KeyBindingsManager.normalizeKey(key) === normalizedPressed)) {\n return action;\n }\n }\n\n return null;\n }\n\n /**\n * Get platform-specific modifier key name\n */\n static getModifierKey(platform?: NodeJS.Platform): string {\n const p = platform || os.platform();\n return p === 'darwin' ? 'Cmd' : 'Ctrl';\n }\n\n /**\n * Convert config binding to platform-specific display\n */\n static toPlatformBinding(binding: string, platform?: NodeJS.Platform): string {\n const modKey = KeyBindingsManager.getModifierKey(platform);\n return binding.replace(/Ctrl|Cmd/gi, modKey);\n }\n}\n","/**\n * React hook for subscribing to keyboard actions\n * Components use this to handle specific keyboard shortcuts\n */\n\nimport { useEffect, useRef } from 'react';\nimport { KeyBindingAction } from '../../utils/KeyBindings.js';\nimport { KeyboardEvent } from './KeyboardEventBus.js';\nimport { useKeyboard } from './KeyboardContext.js';\n\nexport interface UseKeyboardActionOptions {\n /**\n * Priority for this handler (higher = runs first)\n * Use this for nested components where child should handle before parent\n * Default: 0\n */\n priority?: number;\n\n /**\n * Enable/disable this handler\n * Default: true\n */\n enabled?: boolean;\n\n /**\n * Unique ID for this handler (for debugging)\n * Default: auto-generated\n */\n id?: string;\n}\n\n/**\n * Subscribe to a keyboard action\n * Handler can return true to stop propagation to parent handlers\n *\n * @example\n * // Handle Escape in a tooltip (child component)\n * useKeyboardAction('reject', (event) => {\n * if (!isTooltipVisible) return false; // Let parent handle it\n * hideTooltip();\n * return true; // Stop propagation - we handled it\n * }, { priority: 10 }); // Higher priority than parent\n *\n * // Handle Escape in main interface (parent component)\n * useKeyboardAction('reject', (event) => {\n * showExitConfirmation();\n * return true;\n * }, { priority: 0 });\n */\nexport function useKeyboardAction(\n action: KeyBindingAction,\n handler: (event: KeyboardEvent) => void | boolean,\n options: UseKeyboardActionOptions = {}\n): void {\n const { eventBus } = useKeyboard();\n const { priority = 0, enabled = true, id } = options;\n\n // Use ref to avoid recreating handler on every render\n const handlerRef = useRef(handler);\n useEffect(() => {\n handlerRef.current = handler;\n }, [handler]);\n\n useEffect(() => {\n if (!enabled) return;\n\n // Wrap handler to use latest version from ref\n const wrappedHandler = (event: KeyboardEvent) => {\n return handlerRef.current(event);\n };\n\n const unsubscribe = eventBus.subscribe(action, wrappedHandler, {\n priority,\n id,\n });\n\n return unsubscribe;\n }, [eventBus, action, priority, enabled, id]);\n}\n\n/**\n * Subscribe to multiple keyboard actions with the same handler\n */\nexport function useKeyboardActions(\n actions: KeyBindingAction[],\n handler: (event: KeyboardEvent) => void | boolean,\n options: UseKeyboardActionOptions = {}\n): void {\n const { eventBus } = useKeyboard();\n const { priority = 0, enabled = true } = options;\n\n const handlerRef = useRef(handler);\n useEffect(() => {\n handlerRef.current = handler;\n }, [handler]);\n\n useEffect(() => {\n if (!enabled) return;\n\n const wrappedHandler = (event: KeyboardEvent) => {\n return handlerRef.current(event);\n };\n\n const unsubscribers = actions.map((action) =>\n eventBus.subscribe(action, wrappedHandler, {\n priority,\n id: options.id ? `${options.id}-${action}` : undefined,\n })\n );\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n };\n }, [eventBus, actions.join(','), priority, enabled, options.id]);\n}\n","/**\n * Top-level keyboard input capture\n * Wraps Ink's useInput and dispatches to KeyboardEventBus\n */\n\nimport { useInput } from 'ink';\nimport { useKeyboard } from './KeyboardContext.js';\n\n/**\n * Ink Key object type\n * Based on Ink's useInput hook callback signature\n */\ninterface InkKey {\n return?: boolean;\n escape?: boolean;\n tab?: boolean;\n shift?: boolean;\n backspace?: boolean;\n delete?: boolean;\n upArrow?: boolean;\n downArrow?: boolean;\n leftArrow?: boolean;\n rightArrow?: boolean;\n pageUp?: boolean;\n pageDown?: boolean;\n ctrl?: boolean;\n meta?: boolean;\n}\n\n/**\n * ASCII control character mapping (0x00-0x1F)\n * Maps character codes to Ctrl+ key combinations\n */\nconst CONTROL_CHAR_MAP: Record<number, string> = {\n 0x00: 'Space',\n 0x01: 'A',\n 0x02: 'B',\n 0x03: 'C',\n 0x04: 'D',\n 0x05: 'E',\n 0x06: 'F',\n 0x07: 'G',\n 0x08: 'H',\n 0x09: 'I',\n 0x0a: 'J',\n 0x0b: 'K',\n 0x0c: 'L',\n 0x0d: 'M',\n 0x0e: 'N',\n 0x0f: 'O',\n 0x10: 'P',\n 0x11: 'Q',\n 0x12: 'R',\n 0x13: 'S',\n 0x14: 'T',\n 0x15: 'U',\n 0x16: 'V',\n 0x17: 'W',\n 0x18: 'X',\n 0x19: 'Y',\n 0x1a: 'Z',\n 0x1b: '[',\n 0x1c: '\\\\',\n 0x1d: ']',\n 0x1e: '^',\n 0x1f: '_',\n};\n\n/**\n * Convert Ink key event to normalized key string\n */\nfunction inkKeyToString(input: string, key: InkKey): string {\n // Special keys\n if (key.return) return 'Enter';\n if (key.escape) return 'Escape';\n if (key.tab) return key.shift ? 'Shift+Tab' : 'Tab';\n if (key.backspace) return 'Backspace';\n if (key.delete) return 'Delete';\n if (key.upArrow) return 'ArrowUp';\n if (key.downArrow) return 'ArrowDown';\n if (key.leftArrow) return 'ArrowLeft';\n if (key.rightArrow) return 'ArrowRight';\n if (key.pageUp) return 'PageUp';\n if (key.pageDown) return 'PageDown';\n\n const charCode = input.length > 0 ? input.charCodeAt(0) : -1;\n\n // Ctrl combinations\n if (key.ctrl) {\n // Control characters (0x00-0x1F)\n if (charCode >= 0x00 && charCode <= 0x1f) {\n const letter = CONTROL_CHAR_MAP[charCode];\n if (letter) {\n return `Ctrl+${letter}`;\n }\n }\n\n // Printable characters\n if (input.length === 1) {\n return `Ctrl+${input.toUpperCase()}`;\n }\n\n return `Ctrl`;\n }\n\n // Meta/Cmd combinations (macOS)\n if (key.meta) {\n if (key.shift && input.length === 1) {\n return `Cmd+Shift+${input.toUpperCase()}`;\n }\n if (input.length === 1) {\n return `Cmd+${input.toUpperCase()}`;\n }\n return `Cmd`;\n }\n\n // Shift combinations\n if (key.shift && input.length === 1) {\n return input;\n }\n\n return input;\n}\n\nexport interface UseKeyboardInputOptions {\n isActive?: boolean;\n}\n\n/**\n * Capture keyboard input and dispatch to event bus\n */\nexport function useKeyboardInput(options: UseKeyboardInputOptions = {}): void {\n const { isActive = true } = options;\n const { eventBus, bindingsManager } = useKeyboard();\n\n useInput(\n (input, key) => {\n if (!isActive) return;\n\n const keyString = inkKeyToString(input, key);\n const action = bindingsManager.getActionForKey(keyString);\n\n if (action) {\n eventBus.dispatchAction(action, keyString);\n }\n },\n { isActive }\n );\n}\n","/**\n * Slash command interface and registry\n * Provides foundation for built-in and custom slash commands in chat interface\n */\n\nimport { z } from 'zod';\n\n/**\n * Result of executing a slash command\n */\nexport interface SlashCommandResult {\n success: boolean;\n // For built-in commands that manipulate state\n action?: 'new_chat' | 'switch_mode' | 'switch_model' | 'send_prompt' | 'open_theme_selector';\n data?: unknown;\n error?: string;\n // For custom commands that inject prompts\n prompt?: string;\n}\n\n/**\n * Context provided to slash commands during execution\n */\nexport interface SlashCommandContext {\n // Current chat state (read-only for commands)\n currentMode: 'plan' | 'act' | 'discuss';\n currentProvider: string;\n currentModel: string;\n messageCount: number;\n // Callbacks for commands to request actions\n requestModeSwitch?: (mode: 'plan' | 'act' | 'discuss') => void;\n requestModelSwitch?: (provider: string, model?: string) => void | Promise<void>;\n requestNewChat?: () => void;\n requestThemeChange?: (theme: string) => void | Promise<void>;\n // For custom commands - send prompt to agent\n sendPrompt?: (prompt: string) => void;\n}\n\n/**\n * Parameter definition for commands\n */\nexport interface CommandParameter {\n name: string;\n description: string;\n required: boolean;\n // For autocomplete - provide suggestions\n suggestions?: string[];\n}\n\n/**\n * Slash command interface\n */\nexport interface ISlashCommand {\n name: string;\n description: string;\n usage: string;\n aliases?: string[];\n // Parameter definitions for help and autocomplete\n parameters?: CommandParameter[];\n // Zod schema for argument validation (optional)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n argsSchema?: z.ZodSchema<any>;\n // Execute the command with parsed arguments\n execute(args: string[], context: SlashCommandContext): Promise<SlashCommandResult>;\n // Get parameter suggestions for autocomplete (optional)\n // currentArgs: already-typed arguments (e.g., for \"/model deepseek \", currentArgs = [\"deepseek\"])\n getParameterSuggestions?: (\n paramIndex: number,\n context: SlashCommandContext,\n currentArgs?: string[]\n ) => string[];\n}\n\n/**\n * Registry for slash commands\n */\nexport class SlashCommandRegistry {\n private commands: Map<string, ISlashCommand> = new Map();\n private aliases: Map<string, string> = new Map();\n\n register(command: ISlashCommand): void {\n this.commands.set(command.name, command);\n\n // Register aliases\n if (command.aliases) {\n command.aliases.forEach((alias) => {\n this.aliases.set(alias, command.name);\n });\n }\n }\n\n unregister(commandName: string): void {\n const command = this.commands.get(commandName);\n if (command?.aliases) {\n command.aliases.forEach((alias) => this.aliases.delete(alias));\n }\n this.commands.delete(commandName);\n }\n\n get(nameOrAlias: string): ISlashCommand | undefined {\n // Check if it's an alias first\n const actualName = this.aliases.get(nameOrAlias) ?? nameOrAlias;\n return this.commands.get(actualName);\n }\n\n getAll(): ISlashCommand[] {\n return Array.from(this.commands.values());\n }\n\n has(nameOrAlias: string): boolean {\n return this.aliases.has(nameOrAlias) || this.commands.has(nameOrAlias);\n }\n\n async execute(\n nameOrAlias: string,\n args: string[],\n context: SlashCommandContext\n ): Promise<SlashCommandResult> {\n const command = this.get(nameOrAlias);\n\n if (!command) {\n return {\n success: false,\n error: `Command not found: /${nameOrAlias}`,\n };\n }\n\n try {\n // Validate args if schema provided\n if (command.argsSchema) {\n command.argsSchema.parse(args);\n }\n\n return await command.execute(args, context);\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n // For autocomplete\n search(prefix: string): ISlashCommand[] {\n const results: ISlashCommand[] = [];\n const lowerPrefix = prefix.toLowerCase();\n\n for (const command of this.commands.values()) {\n if (command.name.toLowerCase().startsWith(lowerPrefix)) {\n results.push(command);\n } else if (command.aliases?.some((a) => a.toLowerCase().startsWith(lowerPrefix))) {\n results.push(command);\n }\n }\n\n // Sort results alphabetically by name for consistent, predictable ordering\n return results.sort((a, b) => a.name.localeCompare(b.name));\n }\n}\n","/**\n * Custom command loader\n * Loads custom slash commands from YAML files in .mimir/commands/\n */\n\nimport { z } from 'zod';\nimport yaml from 'yaml';\nimport path from 'path';\nimport os from 'os';\nimport { IFileSystem } from '../platform/IFileSystem.js';\nimport { ISlashCommand, SlashCommandContext, SlashCommandResult } from './SlashCommand.js';\nimport { logger } from '../utils/logger.js';\n\n/**\n * Schema for custom command YAML files\n */\nconst CustomCommandSchema = z.object({\n name: z\n .string()\n .regex(/^[a-z][a-z0-9-]*$/, 'Command name must be lowercase alphanumeric with hyphens'),\n description: z.string(),\n usage: z.string(),\n aliases: z.array(z.string()).optional(),\n prompt: z.string(),\n});\n\ntype CustomCommandDefinition = z.infer<typeof CustomCommandSchema>;\n\n/**\n * Custom command loaded from YAML file\n */\nclass CustomCommand implements ISlashCommand {\n constructor(private definition: CustomCommandDefinition) {}\n\n get name(): string {\n return this.definition.name;\n }\n\n get description(): string {\n return this.definition.description;\n }\n\n get usage(): string {\n return this.definition.usage;\n }\n\n get aliases(): string[] | undefined {\n return this.definition.aliases;\n }\n\n async execute(args: string[], context: SlashCommandContext): Promise<SlashCommandResult> {\n // Substitute placeholders in prompt\n let prompt = this.definition.prompt;\n\n // $1, $2, $3... for individual args\n args.forEach((arg, index) => {\n const placeholder = `$${index + 1}`;\n prompt = prompt.replace(new RegExp(`\\\\${placeholder}`, 'g'), arg);\n });\n\n // $ARGUMENTS for all args joined\n const allArgs = args.join(' ');\n prompt = prompt.replace(/\\$ARGUMENTS/g, allArgs);\n\n // Send prompt to agent via context\n if (context.sendPrompt) {\n context.sendPrompt(prompt);\n return {\n success: true,\n action: 'send_prompt',\n prompt,\n };\n }\n\n return {\n success: false,\n error: 'Context does not support sending prompts',\n };\n }\n}\n\n/**\n * Loads custom commands from .yml files\n */\nexport class CustomCommandLoader {\n constructor(private fs: IFileSystem) {}\n\n /**\n * Load custom commands from both global and project directories\n */\n async loadAll(projectRoot?: string): Promise<ISlashCommand[]> {\n const commandMap = new Map<string, ISlashCommand>();\n\n // Load global commands first\n const globalCommands = await this.loadFromDirectory(\n path.join(os.homedir(), '.mimir', 'commands')\n );\n globalCommands.forEach((cmd) => commandMap.set(cmd.name, cmd));\n\n // Project commands override global\n if (projectRoot) {\n const projectCommands = await this.loadFromDirectory(\n path.join(projectRoot, '.mimir', 'commands')\n );\n projectCommands.forEach((cmd) => {\n if (commandMap.has(cmd.name)) {\n logger.info('Project command overrides global', { name: cmd.name });\n }\n commandMap.set(cmd.name, cmd);\n });\n }\n\n return Array.from(commandMap.values());\n }\n\n /**\n * Load commands from a specific directory\n */\n private async loadFromDirectory(dirPath: string): Promise<ISlashCommand[]> {\n const commands: ISlashCommand[] = [];\n\n try {\n if (!(await this.fs.exists(dirPath))) {\n return commands;\n }\n\n const files = await this.fs.glob('*.yml', { cwd: dirPath });\n\n for (const file of files) {\n const fullPath = path.join(dirPath, file);\n const command = await this.loadCommand(fullPath);\n if (command) {\n commands.push(command);\n }\n }\n\n logger.info('Loaded custom commands', {\n directory: dirPath,\n count: commands.length,\n });\n } catch (error) {\n logger.warn('Failed to load commands from directory', {\n directory: dirPath,\n error,\n });\n }\n\n return commands;\n }\n\n /**\n * Load a single command from YAML file\n */\n private async loadCommand(filePath: string): Promise<ISlashCommand | null> {\n try {\n const content = await this.fs.readFile(filePath);\n const data = yaml.parse(content) as unknown;\n const definition = CustomCommandSchema.parse(data);\n\n return new CustomCommand(definition);\n } catch (error) {\n logger.warn('Failed to load custom command', {\n file: filePath,\n error,\n });\n return null;\n }\n }\n\n /**\n * Validate custom command file without loading\n */\n async validate(filePath: string): Promise<{ valid: boolean; error?: string }> {\n try {\n const content = await this.fs.readFile(filePath);\n const data = yaml.parse(content) as unknown;\n CustomCommandSchema.parse(data);\n return { valid: true };\n } catch (error) {\n return {\n valid: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n}\n","/**\n * Graceful signal handling (SIGINT, SIGTERM)\n * Handles Ctrl+C and termination signals at the application level\n */\n\nimport { logger } from '../../utils/logger.js';\nimport { KeyBindingsConfig } from '../../config/schemas.js';\nimport { formatKeyboardShortcut } from '../../utils/keyboardFormatter.js';\n\nexport interface SignalHandlerOptions {\n /**\n * Callback to run before exit\n * For cleanup: close DB, stop containers, etc.\n */\n onCleanup?: () => Promise<void> | void;\n\n /**\n * Number of Ctrl+C presses before emergency exit\n * Default: 3\n */\n emergencyExitCount?: number;\n\n /**\n * Timeout in ms for cleanup\n * If cleanup takes longer, force exit\n * Default: 5000 (5 seconds)\n */\n cleanupTimeout?: number;\n\n /**\n * Time window in ms for counting rapid presses\n * Default: 2000 (2 seconds)\n */\n rapidPressWindow?: number;\n\n /**\n * Keyboard bindings configuration for displaying interrupt key\n * Optional - if not provided, defaults to \"Ctrl+C\"\n */\n keyBindings?: KeyBindingsConfig;\n}\n\nexport class SignalHandler {\n private sigintCount = 0;\n private cleanupTimeout: NodeJS.Timeout | null = null;\n private rapidPressTimeout: NodeJS.Timeout | null = null;\n private isCleaningUp = false;\n private cleanupPromise: Promise<void> | null = null;\n\n private readonly emergencyExitCount: number;\n private readonly cleanupTimeoutMs: number;\n private readonly rapidPressWindowMs: number;\n private readonly onCleanup?: () => Promise<void> | void;\n private readonly interruptKeyDisplay: string;\n\n constructor(options: SignalHandlerOptions = {}) {\n this.emergencyExitCount = options.emergencyExitCount ?? 3;\n this.cleanupTimeoutMs = options.cleanupTimeout ?? 5000;\n this.rapidPressWindowMs = options.rapidPressWindow ?? 2000;\n this.onCleanup = options.onCleanup;\n\n // Format interrupt key for display (defaults to Ctrl+C if no bindings provided)\n this.interruptKeyDisplay = options.keyBindings\n ? formatKeyboardShortcut(options.keyBindings.interrupt, { showFirstOnly: true })\n : 'Ctrl+C';\n }\n\n /**\n * Install signal handlers\n * Call this once at app startup\n */\n install(): void {\n // Handle SIGINT (Ctrl+C)\n process.on('SIGINT', () => void this.handleSigint());\n\n // Handle SIGTERM (kill command)\n process.on('SIGTERM', () => void this.handleSigterm());\n\n // Handle SIGBREAK (Ctrl+Break on Windows)\n // On Windows, this is sometimes triggered instead of SIGINT\n if (process.platform === 'win32') {\n process.on('SIGBREAK', () => void this.handleSigint());\n }\n\n logger.debug('Signal handlers installed', {\n platform: process.platform,\n emergencyExitCount: this.emergencyExitCount,\n cleanupTimeout: this.cleanupTimeoutMs,\n });\n }\n\n /**\n * Handle SIGINT (Ctrl+C)\n * Allows multiple presses for emergency exit\n */\n private async handleSigint(): Promise<void> {\n this.sigintCount++;\n\n // Reset counter after rapid press window\n if (this.rapidPressTimeout) {\n clearTimeout(this.rapidPressTimeout);\n }\n this.rapidPressTimeout = setTimeout(() => {\n this.sigintCount = 0;\n }, this.rapidPressWindowMs);\n\n logger.debug(`SIGINT received (${this.sigintCount}/${this.emergencyExitCount})`);\n\n // Emergency exit on Nth press\n if (this.sigintCount >= this.emergencyExitCount) {\n logger.warn('Emergency exit triggered');\n this.emergencyExit();\n return;\n }\n\n // First press: start graceful cleanup\n if (this.sigintCount === 1) {\n await this.gracefulExit('SIGINT');\n } else {\n // Subsequent presses: warn user\n console.error(\n `\\nPress ${this.interruptKeyDisplay} ${this.emergencyExitCount - this.sigintCount} more time(s) to force exit`\n );\n }\n }\n\n /**\n * Handle SIGTERM (kill command)\n * Always does graceful cleanup\n */\n private async handleSigterm(): Promise<void> {\n logger.debug('SIGTERM received');\n await this.gracefulExit('SIGTERM');\n }\n\n /**\n * Perform graceful exit with cleanup\n */\n private async gracefulExit(signal: string): Promise<void> {\n if (this.isCleaningUp) {\n logger.debug('Cleanup already in progress');\n // Wait for existing cleanup to finish\n if (this.cleanupPromise) {\n await this.cleanupPromise;\n }\n return;\n }\n\n this.isCleaningUp = true;\n\n logger.info(`Graceful shutdown initiated (${signal})`);\n\n // Set cleanup timeout\n this.cleanupTimeout = setTimeout(() => {\n logger.warn('Cleanup timeout exceeded, forcing exit');\n this.forceExit(1);\n }, this.cleanupTimeoutMs);\n\n // Run cleanup\n this.cleanupPromise = this.runCleanup();\n\n try {\n await this.cleanupPromise;\n logger.info('Cleanup completed successfully');\n this.exit(0);\n } catch (error) {\n logger.error('Error during cleanup', { error });\n this.exit(1);\n } finally {\n if (this.cleanupTimeout) {\n clearTimeout(this.cleanupTimeout);\n }\n }\n }\n\n /**\n * Run user-provided cleanup function\n */\n private async runCleanup(): Promise<void> {\n if (!this.onCleanup) {\n return;\n }\n\n try {\n await this.onCleanup();\n } catch (error) {\n logger.error('Cleanup function threw error', { error });\n throw error;\n }\n }\n\n /**\n * Emergency exit without cleanup\n */\n private emergencyExit(): void {\n console.error('\\n\\nEmergency exit - no cleanup performed');\n this.forceExit(130); // Standard exit code for Ctrl+C\n }\n\n /**\n * Normal exit after cleanup\n */\n private exit(code: number): void {\n // Clear alternate screen buffer if in use\n process.stdout.write('\\x1b[?1049l');\n\n process.exit(code);\n }\n\n /**\n * Force exit immediately\n */\n private forceExit(code: number): void {\n process.stdout.write('\\x1b[?1049l');\n process.exit(code);\n }\n\n /**\n * Remove signal handlers\n * For testing or if you need to uninstall\n */\n uninstall(): void {\n process.removeAllListeners('SIGINT');\n process.removeAllListeners('SIGTERM');\n\n // Remove SIGBREAK listener on Windows\n if (process.platform === 'win32') {\n process.removeAllListeners('SIGBREAK');\n }\n\n if (this.rapidPressTimeout) {\n clearTimeout(this.rapidPressTimeout);\n }\n if (this.cleanupTimeout) {\n clearTimeout(this.cleanupTimeout);\n }\n\n logger.debug('Signal handlers removed');\n }\n}\n\n/**\n * Install signal handlers with cleanup callback\n * Returns SignalHandler instance for manual control if needed\n */\nexport function installSignalHandlers(options: SignalHandlerOptions = {}): SignalHandler {\n const handler = new SignalHandler(options);\n handler.install();\n return handler;\n}\n","/**\n * /new command\n * Starts a new chat conversation\n */\n\nimport {\n ISlashCommand,\n SlashCommandContext,\n SlashCommandResult,\n} from '../../../core/SlashCommand.js';\n\nexport class NewCommand implements ISlashCommand {\n name = 'new';\n description = 'Start a new chat conversation';\n usage = '/new';\n aliases = ['n', 'clear'];\n\n async execute(_args: string[], context: SlashCommandContext): Promise<SlashCommandResult> {\n if (context.requestNewChat) {\n context.requestNewChat();\n return {\n success: true,\n action: 'new_chat',\n };\n }\n\n return {\n success: false,\n error: 'New chat not supported in this context',\n };\n }\n}\n","/**\n * /model command\n * Switch LLM provider/model\n */\n\nimport { z } from 'zod';\nimport {\n ISlashCommand,\n SlashCommandContext,\n SlashCommandResult,\n CommandParameter,\n} from '../../../core/SlashCommand.js';\n\nexport class ModelCommand implements ISlashCommand {\n name = 'model';\n description = 'Switch LLM provider/model';\n usage = '/model <provider> [model]';\n aliases = ['provider', 'm'];\n\n parameters: CommandParameter[] = [\n {\n name: 'provider',\n description: 'The LLM provider to use',\n required: true,\n suggestions: ['deepseek', 'anthropic', 'openai', 'google', 'gemini', 'qwen', 'ollama'],\n },\n {\n name: 'model',\n description: 'Optional specific model name',\n required: false,\n },\n ];\n\n argsSchema = z.tuple([\n z.enum(['deepseek', 'anthropic', 'openai', 'google', 'gemini', 'qwen', 'ollama']),\n z.string().optional(),\n ]);\n\n getParameterSuggestions(\n paramIndex: number,\n context: SlashCommandContext,\n currentArgs?: string[]\n ): string[] {\n if (paramIndex === 0) {\n return ['deepseek', 'anthropic', 'openai', 'google', 'gemini', 'qwen', 'ollama'];\n }\n\n // Model suggestions based on provider\n // Use the provider the user is currently typing (currentArgs[0]), not the configured provider\n if (paramIndex === 1) {\n const provider = currentArgs?.[0]?.toLowerCase() || context.currentProvider.toLowerCase();\n switch (provider) {\n case 'deepseek':\n return ['deepseek-chat', 'deepseek-reasoner'];\n case 'anthropic':\n return ['claude-sonnet-4-5-20250929', 'claude-opus-4-5-20251101', 'claude-haiku-4-5'];\n case 'openai':\n return ['gpt-4', 'gpt-4-turbo', 'gpt-3.5-turbo'];\n case 'google':\n case 'gemini':\n return ['gemini-pro', 'gemini-ultra'];\n default:\n return [];\n }\n }\n\n return [];\n }\n\n async execute(args: string[], context: SlashCommandContext): Promise<SlashCommandResult> {\n if (args.length === 0) {\n return {\n success: false,\n error: 'Usage: /model <provider> [model]',\n };\n }\n\n const provider = args[0];\n const model = args[1] ?? undefined;\n\n if (context.requestModelSwitch && provider) {\n void context.requestModelSwitch(provider, model);\n return {\n success: true,\n action: 'switch_model',\n data: { provider, model },\n };\n }\n\n return {\n success: false,\n error: 'Model switching not supported in this context',\n };\n }\n}\n","/**\n * /mode command\n * Switch chat mode (plan/act/discuss)\n */\n\nimport { z } from 'zod';\nimport {\n ISlashCommand,\n SlashCommandContext,\n SlashCommandResult,\n CommandParameter,\n} from '../../../core/SlashCommand.js';\n\nexport class ModeCommand implements ISlashCommand {\n name = 'mode';\n description = 'Switch chat mode (plan/act/discuss)';\n usage = '/mode <plan|act|discuss>';\n\n parameters: CommandParameter[] = [\n {\n name: 'mode',\n description: 'The mode to switch to',\n required: true,\n suggestions: ['plan', 'act', 'discuss'],\n },\n ];\n\n argsSchema = z.tuple([z.enum(['plan', 'act', 'discuss'])]);\n\n getParameterSuggestions(\n paramIndex: number,\n _context: SlashCommandContext,\n _currentArgs?: string[]\n ): string[] {\n if (paramIndex === 0) {\n return ['plan', 'act', 'discuss'];\n }\n return [];\n }\n\n async execute(args: string[], context: SlashCommandContext): Promise<SlashCommandResult> {\n if (args.length === 0) {\n return {\n success: false,\n error: 'Usage: /mode <plan|act|discuss>',\n };\n }\n\n const mode = args[0] as 'plan' | 'act' | 'discuss';\n\n if (context.requestModeSwitch) {\n context.requestModeSwitch(mode);\n return {\n success: true,\n action: 'switch_mode',\n data: { mode },\n };\n }\n\n return {\n success: false,\n error: 'Mode switching not supported in this context',\n };\n }\n}\n","/**\n * /help command\n * Show available slash commands\n */\n\nimport {\n ISlashCommand,\n SlashCommandContext,\n SlashCommandResult,\n} from '../../../core/SlashCommand.js';\nimport { SlashCommandRegistry } from '../../../core/SlashCommand.js';\n\nexport class HelpCommand implements ISlashCommand {\n name = 'help';\n description = 'Show available slash commands';\n usage = '/help [command]';\n aliases = ['?', 'h'];\n\n constructor(private registry: SlashCommandRegistry) {}\n\n async execute(args: string[], context: SlashCommandContext): Promise<SlashCommandResult> {\n // Show help for specific command\n if (args.length > 0) {\n const commandName = args[0];\n if (!commandName) {\n return {\n success: false,\n error: 'Command name is required',\n };\n }\n const command = this.registry.get(commandName);\n\n if (!command) {\n return {\n success: false,\n error: `Command not found: /${commandName}`,\n };\n }\n\n const helpText = [\n `Command: /${command.name}`,\n `Description: ${command.description}`,\n `Usage: ${command.usage}`,\n command.aliases?.length ? `Aliases: ${command.aliases.map((a) => `/${a}`).join(', ')}` : '',\n ]\n .filter(Boolean)\n .join('\\n');\n\n if (context.sendPrompt) {\n context.sendPrompt(helpText);\n }\n\n return {\n success: true,\n data: { helpText },\n };\n }\n\n // Show all commands\n const allCommands = this.registry.getAll();\n const helpText = [\n 'Available Commands:',\n '',\n ...allCommands.map((cmd) => ` /${cmd.name.padEnd(15)} - ${cmd.description}`),\n '',\n 'Type /help <command> for more details',\n ].join('\\n');\n\n if (context.sendPrompt) {\n context.sendPrompt(helpText);\n }\n\n return {\n success: true,\n data: { helpText },\n };\n }\n}\n","/**\n * /theme command\n * Lists available themes or changes to specified theme\n */\n\nimport {\n ISlashCommand,\n SlashCommandContext,\n SlashCommandResult,\n CommandParameter,\n} from '../../../core/SlashCommand.js';\nimport { getAllThemes, getThemeMetadata } from '../../../config/themes/index.js';\n\nexport class ThemeCommand implements ISlashCommand {\n name = 'theme';\n description = 'Show available themes or change to specified theme';\n usage = '/theme [theme-name]';\n aliases = ['t'];\n\n parameters: CommandParameter[] = [\n {\n name: 'theme',\n description: 'Theme to switch to (leave empty to list all)',\n required: false,\n suggestions: getAllThemes(),\n },\n ];\n\n getParameterSuggestions(\n paramIndex: number,\n _context: SlashCommandContext,\n _currentArgs?: string[]\n ): string[] {\n if (paramIndex === 0) {\n return getAllThemes();\n }\n return [];\n }\n\n async execute(args: string[], context: SlashCommandContext): Promise<SlashCommandResult> {\n // If no arguments, list available themes\n if (args.length === 0) {\n const themes = getAllThemes();\n const themeList = themes\n .map((t, i) => {\n const meta = getThemeMetadata(t);\n return ` ${i + 1}. ${t} - ${meta.name}`;\n })\n .join('\\n');\n\n const message = `Available themes:\\n${themeList}\\n\\nUse /theme <name> to switch (e.g., /theme dark)`;\n\n return {\n success: true,\n action: 'send_prompt',\n prompt: message,\n };\n }\n\n // Change to specified theme\n const themeName = args[0]?.toLowerCase();\n if (!themeName) {\n return {\n success: false,\n error: 'Theme name is required',\n };\n }\n\n const themes = getAllThemes();\n type ThemeName =\n | 'mimir'\n | 'dark'\n | 'light'\n | 'dark-colorblind'\n | 'light-colorblind'\n | 'dark-ansi'\n | 'light-ansi';\n\n if (!themes.includes(themeName as ThemeName)) {\n return {\n success: false,\n error: `Theme '${themeName}' not found. Available: ${themes.join(', ')}`,\n };\n }\n\n // Request theme change\n if (context.requestThemeChange) {\n await context.requestThemeChange(themeName as ThemeName);\n return {\n success: true,\n action: 'send_prompt',\n prompt: `Theme changed to '${themeName}'`,\n };\n }\n\n return {\n success: false,\n error: 'Theme change not available in this context',\n };\n }\n}\n","/**\n * Database Manager using sql.js\n * Handles automatic initialization, migrations, and seeding\n */\n\nimport initSqlJs, { Database as SqlJsDatabase } from 'sql.js';\nimport { defaultPricing } from './seed.js';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { readFileSync, existsSync } from 'fs';\nimport type { IFileSystem } from '../platform/IFileSystem.js';\n\nexport interface DatabaseConfig {\n path: string;\n verbose?: boolean;\n fileSystem?: IFileSystem;\n}\n\ninterface RunResult {\n changes: number;\n lastInsertRowid: number;\n}\n\n/**\n * Locate sql.js WASM file\n * Tries multiple locations in order:\n * 1. resources/ directory (for standalone binaries)\n * 2. node_modules/sql.js/dist/ (for development)\n */\nfunction locateWasmFile(): ArrayBuffer {\n const wasmFileName = 'sql-wasm.wasm';\n\n // Determine the binary directory\n // For Bun compiled binaries, process.argv[0] is the executable path\n // For Node.js, use process.execPath\n const executablePath = process.argv[0] || process.execPath;\n const binaryDir = dirname(executablePath);\n\n // Location 1: resources directory (for production binaries)\n // Standalone binaries will have: /path/to/mimir (executable) + /path/to/resources/sql-wasm.wasm\n const resourcesPaths = [\n // Next to the binary (same directory) - most common for our installers\n join(binaryDir, 'resources', wasmFileName),\n // For development/testing\n join(process.cwd(), 'resources', wasmFileName),\n // Parent directory of binary (for some install layouts)\n join(binaryDir, '..', 'resources', wasmFileName),\n ];\n\n for (const resourcePath of resourcesPaths) {\n if (existsSync(resourcePath)) {\n const buffer = readFileSync(resourcePath);\n // Convert Node.js Buffer to ArrayBuffer\n return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);\n }\n }\n\n // Location 2: node_modules (for development only)\n const currentDir = dirname(fileURLToPath(import.meta.url));\n const nodeModulesPaths = [\n join(currentDir, '..', '..', 'node_modules', 'sql.js', 'dist', wasmFileName),\n join(process.cwd(), 'node_modules', 'sql.js', 'dist', wasmFileName),\n ];\n\n for (const modulePath of nodeModulesPaths) {\n if (existsSync(modulePath)) {\n const buffer = readFileSync(modulePath);\n // Convert Node.js Buffer to ArrayBuffer\n return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);\n }\n }\n\n // Enhanced error message with diagnostic information\n const diagnostics = [\n `process.argv[0]: ${process.argv[0]}`,\n `process.execPath: ${process.execPath}`,\n `executablePath: ${executablePath}`,\n `binaryDir: ${binaryDir}`,\n `currentDir: ${currentDir}`,\n `process.cwd(): ${process.cwd()}`,\n ];\n\n throw new Error(\n `Could not locate ${wasmFileName}.\\n\\nDiagnostics:\\n${diagnostics.join('\\n')}\\n\\nTried:\\n` +\n [...resourcesPaths, ...nodeModulesPaths].map((p) => ` - ${p}`).join('\\n')\n );\n}\n\n/**\n * DatabaseManager with automatic initialization and migrations\n */\nexport class DatabaseManager {\n private db!: SqlJsDatabase;\n private config: DatabaseConfig;\n private SQL: any;\n private nodeFs: typeof import('fs') | null = null;\n\n private constructor(config: DatabaseConfig, SQL: any) {\n this.config = config;\n this.SQL = SQL;\n }\n\n /**\n * Create DatabaseManager instance with proper directory setup\n */\n static async create(config: DatabaseConfig): Promise<DatabaseManager> {\n // Ensure database directory exists\n const dbDir = dirname(config.path);\n\n if (config.fileSystem) {\n const dirExists = await config.fileSystem.exists(dbDir);\n if (!dirExists) {\n await config.fileSystem.mkdir(dbDir, { recursive: true });\n }\n } else {\n const { existsSync, mkdirSync } = await import('fs');\n if (!existsSync(dbDir)) {\n mkdirSync(dbDir, { recursive: true });\n }\n }\n\n // Initialize sql.js with WASM binary from file system\n const wasmBinary = locateWasmFile();\n const SQL = await initSqlJs({\n wasmBinary,\n });\n const manager = new DatabaseManager(config, SQL);\n\n // Load Node.js fs module for sync operations\n manager.nodeFs = await import('fs');\n\n // Load or create database\n await manager.loadDatabase();\n\n // Initialize schema and seed data\n manager.initialize();\n\n // Save database after initialization (creates tables and seeds data)\n await manager.save();\n\n return manager;\n }\n\n /**\n * Load database from file or create new\n */\n private async loadDatabase(): Promise<void> {\n try {\n if (this.config.fileSystem) {\n const exists = await this.config.fileSystem.exists(this.config.path);\n if (exists) {\n const buffer = await this.config.fileSystem.readFile(\n this.config.path,\n 'binary' as BufferEncoding\n );\n const uint8Array = new Uint8Array(Buffer.from(buffer as any, 'binary'));\n this.db = new this.SQL.Database(uint8Array);\n if (this.config.verbose) {\n console.log('Loaded existing database from', this.config.path);\n }\n } else {\n this.db = new this.SQL.Database();\n if (this.config.verbose) {\n console.log('Created new database');\n }\n }\n } else {\n const { existsSync, readFileSync } = await import('fs');\n if (existsSync(this.config.path)) {\n const buffer = readFileSync(this.config.path);\n this.db = new this.SQL.Database(buffer);\n } else {\n this.db = new this.SQL.Database();\n }\n }\n } catch (error) {\n this.db = new this.SQL.Database();\n if (this.config.verbose) {\n console.log('Created new database after error:', error);\n }\n }\n }\n\n /**\n * Save database to disk (async version)\n */\n async save(): Promise<void> {\n const data = this.db.export();\n const buffer = Buffer.from(data);\n\n if (this.config.fileSystem) {\n await this.config.fileSystem.writeFile(\n this.config.path,\n buffer.toString('binary'),\n 'binary' as BufferEncoding\n );\n } else {\n const { writeFileSync } = await import('fs');\n writeFileSync(this.config.path, buffer);\n }\n }\n\n /**\n * Save database to disk (sync version for auto-save)\n * Uses sync fs operations to avoid async in execute/transaction\n */\n private saveSync(): void {\n const data = this.db.export();\n const buffer = Buffer.from(data);\n\n // Use pre-loaded Node.js fs module for sync operations\n if (this.nodeFs) {\n this.nodeFs.writeFileSync(this.config.path, buffer);\n }\n }\n\n /**\n * Initialize database with migrations and seed data\n */\n private initialize(): void {\n try {\n this.createTablesManually();\n this.seedDatabase();\n } catch (error) {\n console.error('Database initialization failed:', error);\n throw error;\n }\n }\n\n /**\n * Manually create tables from schema\n */\n private createTablesManually(): void {\n const createTablesSQL = `\n CREATE TABLE IF NOT EXISTS migrations (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n version TEXT NOT NULL UNIQUE,\n applied_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now'))\n );\n\n CREATE TABLE IF NOT EXISTS conversations (\n id TEXT PRIMARY KEY,\n title TEXT,\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n total_tokens INTEGER DEFAULT 0,\n total_cost REAL DEFAULT 0.0,\n provider TEXT,\n model TEXT,\n status TEXT DEFAULT 'active' CHECK(status IN ('active', 'archived', 'deleted'))\n );\n\n CREATE INDEX IF NOT EXISTS idx_conversations_created_at ON conversations(created_at DESC);\n CREATE INDEX IF NOT EXISTS idx_conversations_status ON conversations(status);\n\n CREATE TABLE IF NOT EXISTS messages (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n role TEXT NOT NULL CHECK(role IN ('system', 'user', 'assistant')),\n content TEXT NOT NULL,\n timestamp INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n input_tokens INTEGER DEFAULT 0,\n output_tokens INTEGER DEFAULT 0,\n cost REAL DEFAULT 0.0,\n metadata TEXT,\n FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_messages_conversation_id ON messages(conversation_id);\n CREATE INDEX IF NOT EXISTS idx_messages_timestamp ON messages(timestamp);\n\n CREATE TABLE IF NOT EXISTS tool_calls (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n message_id TEXT,\n tool_name TEXT NOT NULL,\n arguments TEXT NOT NULL,\n result TEXT,\n status TEXT DEFAULT 'pending' CHECK(status IN ('pending', 'running', 'success', 'failed')),\n error TEXT,\n started_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n completed_at INTEGER,\n duration_ms INTEGER,\n FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE,\n FOREIGN KEY (message_id) REFERENCES messages(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_tool_calls_conversation_id ON tool_calls(conversation_id);\n CREATE INDEX IF NOT EXISTS idx_tool_calls_status ON tool_calls(status);\n CREATE INDEX IF NOT EXISTS idx_tool_calls_started_at ON tool_calls(started_at DESC);\n\n CREATE TABLE IF NOT EXISTS permissions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n conversation_id TEXT,\n command TEXT NOT NULL,\n risk_level TEXT NOT NULL CHECK(risk_level IN ('low', 'medium', 'high', 'critical')),\n decision TEXT NOT NULL CHECK(decision IN ('allow', 'deny', 'always', 'never')),\n user_confirmed INTEGER DEFAULT 0,\n timestamp INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n context TEXT,\n FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_permissions_conversation_id ON permissions(conversation_id);\n CREATE INDEX IF NOT EXISTS idx_permissions_timestamp ON permissions(timestamp DESC);\n CREATE INDEX IF NOT EXISTS idx_permissions_decision ON permissions(decision);\n\n CREATE TABLE IF NOT EXISTS checkpoints (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n description TEXT,\n files_snapshot TEXT NOT NULL,\n git_diff TEXT,\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_checkpoints_conversation_id ON checkpoints(conversation_id);\n CREATE INDEX IF NOT EXISTS idx_checkpoints_created_at ON checkpoints(created_at DESC);\n\n CREATE TABLE IF NOT EXISTS cost_summary (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n date TEXT NOT NULL,\n provider TEXT NOT NULL,\n model TEXT NOT NULL,\n total_tokens INTEGER DEFAULT 0,\n input_tokens INTEGER DEFAULT 0,\n output_tokens INTEGER DEFAULT 0,\n total_cost REAL DEFAULT 0.0,\n request_count INTEGER DEFAULT 0,\n UNIQUE(date, provider, model)\n );\n\n CREATE INDEX IF NOT EXISTS idx_cost_summary_date ON cost_summary(date DESC);\n CREATE INDEX IF NOT EXISTS idx_cost_summary_provider ON cost_summary(provider);\n\n CREATE TABLE IF NOT EXISTS session_state (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n agent_state TEXT NOT NULL,\n iteration INTEGER DEFAULT 0,\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_session_state_conversation_id ON session_state(conversation_id);\n\n CREATE TABLE IF NOT EXISTS metrics (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n operation TEXT NOT NULL,\n duration_ms INTEGER NOT NULL,\n conversation_id TEXT,\n session_id TEXT,\n provider TEXT,\n model TEXT,\n input_tokens INTEGER,\n output_tokens INTEGER,\n total_tokens INTEGER,\n cost REAL,\n tool_name TEXT,\n tool_args TEXT,\n tool_result_size INTEGER,\n query_type TEXT,\n table_name TEXT,\n rows_affected INTEGER,\n success INTEGER DEFAULT 1,\n error TEXT,\n memory_mb REAL,\n cpu_percent REAL,\n metadata TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_metrics_timestamp ON metrics(timestamp DESC);\n CREATE INDEX IF NOT EXISTS idx_metrics_operation ON metrics(operation);\n CREATE INDEX IF NOT EXISTS idx_metrics_conversation_id ON metrics(conversation_id);\n CREATE INDEX IF NOT EXISTS idx_metrics_provider ON metrics(provider);\n CREATE INDEX IF NOT EXISTS idx_metrics_success ON metrics(success);\n\n CREATE TABLE IF NOT EXISTS pricing (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n provider TEXT NOT NULL,\n model TEXT NOT NULL,\n input_price_per_1m REAL NOT NULL,\n output_price_per_1m REAL NOT NULL,\n effective_from INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n effective_until INTEGER,\n currency TEXT DEFAULT 'USD',\n notes TEXT,\n UNIQUE(provider, model, effective_from)\n );\n\n CREATE INDEX IF NOT EXISTS idx_pricing_provider_model ON pricing(provider, model);\n CREATE INDEX IF NOT EXISTS idx_pricing_effective ON pricing(effective_from DESC);\n `;\n\n const statements = createTablesSQL.split(';').filter((s) => s.trim());\n for (const statement of statements) {\n try {\n this.db.run(statement);\n } catch (error) {\n if (this.config.verbose) {\n console.log('Table creation warning:', error);\n }\n }\n }\n\n if (this.config.verbose) {\n console.log('Database tables created successfully');\n }\n }\n\n /**\n * Seed database with initial data\n */\n private seedDatabase(): void {\n const pricingCount = this.db.exec(\n \"SELECT COUNT(*) as count FROM sqlite_master WHERE type='table' AND name='pricing'\"\n );\n\n if (pricingCount.length === 0 || pricingCount[0]?.values[0]?.[0] === 0) {\n this.createTablesManually();\n }\n\n const existingPricing = this.db.exec('SELECT COUNT(*) as count FROM pricing');\n const count = existingPricing.length > 0 ? existingPricing[0]?.values[0]?.[0] : 0;\n\n if (count === 0) {\n for (const price of defaultPricing) {\n const stmt = this.db.prepare(\n `INSERT INTO pricing (provider, model, input_price_per_1m, output_price_per_1m, effective_from, currency)\n VALUES (?, ?, ?, ?, ?, ?)`\n );\n // sql.js doesn't accept undefined - convert to null or use defaults\n const effectiveFrom = price.effectiveFrom\n ? typeof price.effectiveFrom === 'number'\n ? price.effectiveFrom\n : Math.floor(price.effectiveFrom.getTime() / 1000)\n : Math.floor(Date.now() / 1000);\n\n stmt.run([\n price.provider,\n price.model,\n price.inputPricePer1M,\n price.outputPricePer1M,\n effectiveFrom,\n price.currency ?? 'USD',\n ]);\n stmt.free();\n }\n\n if (this.config.verbose) {\n console.log(`Seeded ${defaultPricing.length} pricing entries`);\n }\n }\n\n try {\n const migrationExists = this.db.exec(\n \"SELECT COUNT(*) as count FROM migrations WHERE version = '1.0.0'\"\n );\n const migCount = migrationExists.length > 0 ? migrationExists[0]?.values[0]?.[0] : 0;\n\n if (migCount === 0) {\n this.db.run(\"INSERT INTO migrations (version) VALUES ('1.0.0')\");\n }\n } catch (error) {\n // Migration table might not exist yet\n }\n }\n\n /**\n * Execute a raw SQL query (auto-saves for write operations)\n */\n execute(sql: string, params?: unknown[]): RunResult {\n const stmt = this.db.prepare(sql);\n stmt.bind((params || []) as (string | number | null | Uint8Array)[]);\n stmt.step();\n const info = this.db.getRowsModified();\n stmt.free();\n\n // Auto-save for write operations (INSERT, UPDATE, DELETE)\n const isWrite = /^\\s*(INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)/i.test(sql);\n if (isWrite && info > 0) {\n // Save synchronously (sql.js export is sync, fs write would be async but we'll handle that)\n this.saveSync();\n }\n\n return {\n changes: info,\n lastInsertRowid: 0, // sql.js doesn't provide this easily\n };\n }\n\n /**\n * Query a raw SQL statement\n */\n query<T = unknown>(sql: string, params?: unknown[]): T[] {\n const stmt = this.db.prepare(sql);\n stmt.bind((params || []) as (string | number | null | Uint8Array)[]);\n const results: T[] = [];\n\n while (stmt.step()) {\n const row = stmt.getAsObject();\n results.push(row as T);\n }\n stmt.free();\n return results;\n }\n\n /**\n * Execute a query and return a single row\n */\n queryOne<T>(sql: string, params?: unknown[]): T | null {\n try {\n const stmt = this.db.prepare(sql);\n stmt.bind((params || []) as (string | number | null | Uint8Array)[]);\n if (stmt.step()) {\n const row = stmt.getAsObject();\n stmt.free();\n return row as T;\n }\n stmt.free();\n return null;\n } catch (error) {\n console.error('Query failed:', error);\n return null;\n }\n }\n\n /**\n * Run a transaction (auto-saves after commit)\n */\n transaction<T>(fn: (db: DatabaseManager) => T): T {\n this.db.run('BEGIN TRANSACTION');\n try {\n const result = fn(this);\n this.db.run('COMMIT');\n // Save after successful commit\n this.saveSync();\n return result;\n } catch (error) {\n this.db.run('ROLLBACK');\n throw error;\n }\n }\n\n /**\n * Close database connection\n */\n close(): void {\n this.db.close();\n }\n\n /**\n * Vacuum database to optimize storage\n */\n vacuum(): void {\n this.db.run('VACUUM');\n }\n\n /**\n * Get database statistics\n */\n getStats(): {\n pageCount: number;\n pageSize: number;\n sizeBytes: number;\n walMode: boolean;\n } {\n const pageCount = this.queryOne<{ page_count: number }>('PRAGMA page_count');\n const pageSize = this.queryOne<{ page_size: number }>('PRAGMA page_size');\n\n return {\n pageCount: pageCount?.page_count || 0,\n pageSize: pageSize?.page_size || 0,\n sizeBytes: (pageCount?.page_count || 0) * (pageSize?.page_size || 0),\n walMode: false, // sql.js doesn't support WAL mode\n };\n }\n\n /**\n * Perform a database health check\n */\n async healthCheck(): Promise<boolean> {\n try {\n const result = this.queryOne<{ integrity_check: string }>('PRAGMA integrity_check');\n return result?.integrity_check === 'ok';\n } catch (error) {\n console.error('Health check failed:', error);\n return false;\n }\n }\n}\n\n// Singleton instance for the application\nlet dbInstance: DatabaseManager | null = null;\n\n/**\n * Get or create database manager instance (async)\n */\nexport async function getDatabaseManagerAsync(config?: DatabaseConfig): Promise<DatabaseManager> {\n if (!dbInstance && config) {\n dbInstance = await DatabaseManager.create(config);\n }\n if (!dbInstance) {\n throw new Error('DatabaseManager not initialized. Call with config first.');\n }\n return dbInstance;\n}\n\n/**\n * Close database connection\n */\nexport function closeDatabaseManager(): void {\n if (dbInstance) {\n dbInstance.close();\n dbInstance = null;\n }\n}\n","/**\n * Database seed data for initial setup\n */\n\nimport { NewPricing } from './schema.js';\n\n/**\n * Default pricing data for LLM providers (as of January 2025)\n */\nexport const defaultPricing: NewPricing[] = [\n // DeepSeek\n {\n provider: 'deepseek',\n model: 'deepseek-chat',\n inputPricePer1M: 0.14,\n outputPricePer1M: 0.28,\n notes: 'DeepSeek-V3 pricing',\n },\n {\n provider: 'deepseek',\n model: 'deepseek-coder',\n inputPricePer1M: 0.14,\n outputPricePer1M: 0.28,\n notes: 'DeepSeek Coder pricing',\n },\n\n // Anthropic Claude\n {\n provider: 'anthropic',\n model: 'claude-3-5-sonnet-20241022',\n inputPricePer1M: 3.0,\n outputPricePer1M: 15.0,\n notes: 'Claude 3.5 Sonnet',\n },\n {\n provider: 'anthropic',\n model: 'claude-3-5-haiku-20241022',\n inputPricePer1M: 0.8,\n outputPricePer1M: 4.0,\n notes: 'Claude 3.5 Haiku',\n },\n {\n provider: 'anthropic',\n model: 'claude-3-opus-20240229',\n inputPricePer1M: 15.0,\n outputPricePer1M: 75.0,\n notes: 'Claude 3 Opus',\n },\n\n // OpenAI\n {\n provider: 'openai',\n model: 'gpt-4-turbo',\n inputPricePer1M: 10.0,\n outputPricePer1M: 30.0,\n notes: 'GPT-4 Turbo',\n },\n {\n provider: 'openai',\n model: 'gpt-4o',\n inputPricePer1M: 2.5,\n outputPricePer1M: 10.0,\n notes: 'GPT-4o',\n },\n {\n provider: 'openai',\n model: 'gpt-4o-mini',\n inputPricePer1M: 0.15,\n outputPricePer1M: 0.6,\n notes: 'GPT-4o Mini',\n },\n {\n provider: 'openai',\n model: 'gpt-3.5-turbo',\n inputPricePer1M: 0.5,\n outputPricePer1M: 1.5,\n notes: 'GPT-3.5 Turbo',\n },\n\n // Google Gemini\n {\n provider: 'google',\n model: 'gemini-2.0-flash-exp',\n inputPricePer1M: 0.0,\n outputPricePer1M: 0.0,\n notes: 'Free during preview',\n },\n {\n provider: 'google',\n model: 'gemini-1.5-pro',\n inputPricePer1M: 1.25,\n outputPricePer1M: 5.0,\n notes: 'Gemini 1.5 Pro',\n },\n {\n provider: 'google',\n model: 'gemini-1.5-flash',\n inputPricePer1M: 0.075,\n outputPricePer1M: 0.3,\n notes: 'Gemini 1.5 Flash',\n },\n\n // Qwen\n {\n provider: 'qwen',\n model: 'qwen-max',\n inputPricePer1M: 0.4,\n outputPricePer1M: 1.2,\n notes: 'Qwen Max estimated pricing',\n },\n {\n provider: 'qwen',\n model: 'qwen-plus',\n inputPricePer1M: 0.2,\n outputPricePer1M: 0.6,\n notes: 'Qwen Plus estimated pricing',\n },\n\n // Ollama (local models)\n {\n provider: 'ollama',\n model: 'llama3',\n inputPricePer1M: 0.0,\n outputPricePer1M: 0.0,\n notes: 'Local model - no API costs',\n },\n {\n provider: 'ollama',\n model: 'mistral',\n inputPricePer1M: 0.0,\n outputPricePer1M: 0.0,\n notes: 'Local model - no API costs',\n },\n {\n provider: 'ollama',\n model: 'codellama',\n inputPricePer1M: 0.0,\n outputPricePer1M: 0.0,\n notes: 'Local model - no API costs',\n },\n];\n","/**\n * Centralized initialization service for Mimir\n * Handles workspace setup, database creation, and configuration\n */\n\nimport { IFileSystem } from '../platform/IFileSystem.js';\nimport { ConfigLoader } from '../config/ConfigLoader.js';\nimport { getDatabaseManagerAsync, closeDatabaseManager } from '../storage/Database.js';\nimport { logger } from '../utils/logger.js';\nimport path, { dirname } from 'path';\n\nexport interface InitializationResult {\n success: boolean;\n created: string[];\n errors: string[];\n dbInitialized: boolean;\n configCreated: boolean;\n}\n\nexport class MimirInitializer {\n constructor(\n private fs: IFileSystem,\n private configLoader: ConfigLoader\n ) {}\n\n /**\n * Initialize workspace with full Mimir setup\n * Creates directories, database, config, and gitignore\n */\n async initializeWorkspace(workspaceRoot: string): Promise<InitializationResult> {\n const result: InitializationResult = {\n success: true,\n created: [],\n errors: [],\n dbInitialized: false,\n configCreated: false,\n };\n\n try {\n const mimirDir = path.join(workspaceRoot, '.mimir');\n\n // 1. Create .mimir directory\n if (!(await this.fs.exists(mimirDir))) {\n await this.fs.mkdir(mimirDir, { recursive: true });\n result.created.push('.mimir/');\n logger.info('Created .mimir directory', { path: mimirDir });\n }\n\n // 2. Create subdirectories\n const subdirs = [\n { name: 'logs', purpose: 'Application logs' },\n { name: 'commands', purpose: 'Custom slash commands' },\n { name: 'checkpoints', purpose: 'Undo/restore checkpoints' },\n { name: 'themes', purpose: 'UI theme definitions' },\n ];\n\n for (const { name, purpose } of subdirs) {\n const subdir = path.join(mimirDir, name);\n if (!(await this.fs.exists(subdir))) {\n await this.fs.mkdir(subdir, { recursive: true });\n result.created.push(`.mimir/${name}/`);\n logger.info(`Created ${name} directory`, { path: subdir, purpose });\n }\n }\n\n // 3. Create .gitignore for .mimir directory\n await this.createMimirGitignore(mimirDir, result);\n\n // 4. Copy default themes\n await this.copyDefaultThemes(mimirDir, result);\n\n // 5. Copy example commands\n await this.copyExampleCommands(mimirDir, result);\n\n // 6. Initialize SQLite database\n await this.initializeDatabase(mimirDir, result);\n\n // 7. Create config.yml if it doesn't exist\n await this.createConfigIfNeeded(mimirDir, result);\n\n // 8. Create README in .mimir folder\n await this.createReadme(mimirDir, result);\n } catch (error) {\n result.success = false;\n result.errors.push(\n `Initialization failed: ${error instanceof Error ? error.message : String(error)}`\n );\n logger.error('Workspace initialization failed', { error });\n }\n\n return result;\n }\n\n /**\n * Check if workspace is initialized\n */\n async isWorkspaceInitialized(workspaceRoot: string): Promise<boolean> {\n const mimirDir = path.join(workspaceRoot, '.mimir');\n const dbPath = path.join(mimirDir, 'mimir.db');\n\n // Check if both .mimir directory and database exist\n return (await this.fs.exists(mimirDir)) && (await this.fs.exists(dbPath));\n }\n\n /**\n * Create .gitignore inside .mimir directory\n */\n private async createMimirGitignore(\n mimirDir: string,\n result: InitializationResult\n ): Promise<void> {\n const gitignorePath = path.join(mimirDir, '.gitignore');\n\n if (await this.fs.exists(gitignorePath)) {\n return; // Already exists\n }\n\n const gitignoreContent = `# Mimir workspace-specific ignores\n# Ignore sensitive data and logs\n\n# Databases and backups\n*.db\n*.db-shm\n*.db-wal\n*.db.backup\n\n# Logs\nlogs/\n*.log\n\n# Checkpoints (may contain code snapshots)\ncheckpoints/\n\n# Temporary files\n*.tmp\n*.temp\n\n# Keep config.yml tracked (share with team)\n!config.yml\n!config.example.yml\n\n# Keep custom commands tracked\n!commands/\n`;\n\n try {\n await this.fs.writeFile(gitignorePath, gitignoreContent);\n result.created.push('.mimir/.gitignore');\n logger.info('Created .mimir/.gitignore');\n } catch (error) {\n result.errors.push(\n `Failed to create .gitignore: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * Copy default theme files to .mimir/themes/ directory\n */\n private async copyDefaultThemes(mimirDir: string, result: InitializationResult): Promise<void> {\n const themesDir = path.join(mimirDir, 'themes');\n\n // Default themes to copy\n const defaultThemes = [\n 'mimir.json',\n 'dark.json',\n 'light.json',\n 'dark-colorblind.json',\n 'light-colorblind.json',\n ];\n\n try {\n // Get the source themes directory (from installed package)\n // For Bun compiled binaries: use process.argv[0] to get binary location\n // Resources are in: ~/.local/bin/resources/themes/\n const executablePath = process.argv[0] || process.execPath;\n const binaryDir = dirname(executablePath);\n\n // Try multiple locations for theme files\n const possibleSourceDirs = [\n path.join(binaryDir, 'resources', 'themes'), // Compiled binary: ~/.local/bin/resources/themes/\n path.join(binaryDir, '../cli/themes'), // Development: dist/core/../cli/themes\n path.join(binaryDir, '../../src/cli/themes'), // Development: dist/core/../../src/cli/themes\n ];\n\n for (const themeFile of defaultThemes) {\n const destPath = path.join(themesDir, themeFile);\n\n // Skip if theme already exists (idempotency)\n if (await this.fs.exists(destPath)) {\n continue;\n }\n\n // Try each possible source directory\n let copied = false;\n for (const sourceDir of possibleSourceDirs) {\n try {\n const sourcePath = path.join(sourceDir, themeFile);\n const themeContent = await this.fs.readFile(sourcePath, 'utf-8');\n\n // Write to workspace themes directory\n await this.fs.writeFile(destPath, themeContent);\n result.created.push(`.mimir/themes/${themeFile}`);\n logger.info('Copied default theme', { theme: themeFile, from: sourceDir });\n copied = true;\n break;\n } catch (error) {\n // Try next location\n continue;\n }\n }\n\n if (!copied) {\n logger.warn(`Failed to copy theme ${themeFile}, will use built-in fallback`, {\n triedLocations: possibleSourceDirs,\n });\n }\n }\n } catch (error) {\n result.errors.push(\n `Failed to copy default themes: ${error instanceof Error ? error.message : String(error)}`\n );\n logger.error('Failed to copy themes', { error });\n }\n }\n\n /**\n * Copy example command files to .mimir/commands/ directory\n */\n private async copyExampleCommands(mimirDir: string, result: InitializationResult): Promise<void> {\n const commandsDir = path.join(mimirDir, 'commands');\n\n // Example command to copy\n const exampleCommands = ['update-docs.yml'];\n\n try {\n // Get the source commands directory (from installed package)\n // For Bun compiled binaries: use process.argv[0] to get binary location\n // Resources are in: ~/.local/bin/resources/commands/\n const executablePath = process.argv[0] || process.execPath;\n const binaryDir = dirname(executablePath);\n\n // Try multiple locations for command files\n const possibleSourceDirs = [\n path.join(binaryDir, 'resources', 'commands'), // Compiled binary: ~/.local/bin/resources/commands/\n path.join(binaryDir, '../../scripts/templates/commands'), // Development: dist/core/../../scripts/templates/commands\n path.join(binaryDir, '../../../scripts/templates/commands'), // Alternative dev path\n ];\n\n for (const commandFile of exampleCommands) {\n const destPath = path.join(commandsDir, commandFile);\n\n // Skip if command already exists (idempotency)\n if (await this.fs.exists(destPath)) {\n continue;\n }\n\n // Try each possible source directory\n let copied = false;\n for (const sourceDir of possibleSourceDirs) {\n try {\n const sourcePath = path.join(sourceDir, commandFile);\n const commandContent = await this.fs.readFile(sourcePath, 'utf-8');\n\n // Write to workspace commands directory\n await this.fs.writeFile(destPath, commandContent);\n result.created.push(`.mimir/commands/${commandFile}`);\n logger.info('Copied example command', { command: commandFile, from: sourceDir });\n copied = true;\n break;\n } catch (error) {\n // Try next location\n continue;\n }\n }\n\n if (!copied) {\n logger.warn(`Failed to copy command ${commandFile}, continuing`, {\n triedLocations: possibleSourceDirs,\n });\n }\n }\n } catch (error) {\n result.errors.push(\n `Failed to copy example commands: ${error instanceof Error ? error.message : String(error)}`\n );\n logger.error('Failed to copy commands', { error });\n }\n }\n\n /**\n * Initialize SQLite database with Drizzle ORM\n */\n private async initializeDatabase(mimirDir: string, result: InitializationResult): Promise<void> {\n const dbPath = path.join(mimirDir, 'mimir.db');\n\n // Check if database already exists (idempotency)\n if (await this.fs.exists(dbPath)) {\n logger.info('Database already exists, skipping initialization', { path: dbPath });\n return;\n }\n\n try {\n // DatabaseManager auto-creates tables and seeds pricing\n // Use async factory with IFileSystem abstraction\n const db = await getDatabaseManagerAsync({\n path: dbPath,\n verbose: false,\n fileSystem: this.fs,\n });\n\n // Perform a write operation to ensure database file is created\n // better-sqlite3 may delay file creation until first write\n db.execute('SELECT 1');\n\n // Close database connection and clear singleton (flushes to disk)\n closeDatabaseManager();\n\n // Now verify database was created (after close flushes it)\n if (await this.fs.exists(dbPath)) {\n result.created.push('.mimir/mimir.db');\n result.dbInitialized = true;\n logger.info('Database initialized', { path: dbPath });\n } else {\n result.errors.push('Database file was not created on disk');\n }\n } catch (error) {\n result.errors.push(\n `Database initialization failed: ${error instanceof Error ? error.message : String(error)}`\n );\n logger.error('Failed to initialize database', { error });\n }\n }\n\n /**\n * Format array for YAML - creates inline array syntax [item1, item2]\n */\n private formatYamlArray(arr: string[]): string {\n if (!arr || arr.length === 0) return '[]';\n if (arr.length === 1) {\n // Quote special YAML characters: ?, *, &, !, |, >, @, `\n const val = arr[0];\n if (!val) return '[]';\n if (/^[?*&!|>@`]/.test(val) || val === '?' || val === '*') {\n return `\"${val}\"`;\n }\n return val;\n }\n // For arrays, quote each item if needed\n const quoted = arr.map((item) => {\n if (/^[?*&!|>@`]/.test(item) || item === '?' || item === '*') {\n return `\"${item}\"`;\n }\n return item;\n });\n return `[${quoted.join(', ')}]`;\n }\n\n /**\n * Create config.yml if it doesn't exist\n */\n private async createConfigIfNeeded(\n mimirDir: string,\n result: InitializationResult\n ): Promise<void> {\n const configPath = path.join(mimirDir, 'config.yml');\n\n if (await this.fs.exists(configPath)) {\n return; // Config already exists\n }\n\n try {\n // Get default config from ConfigLoader (platform-specific)\n const { config: defaults } = await this.configLoader.load();\n\n // Create user-friendly config with comments\n const configContent = `# Mimir Configuration\n# This file can be committed to version control for team sharing\n# Store API keys in .env or environment variables instead\n\n# LLM Provider Configuration\nllm:\n provider: ${defaults.llm.provider} # deepseek | anthropic | openai | google | gemini | qwen | ollama\n model: ${defaults.llm.model}\n # apiKey: \\${DEEPSEEK_API_KEY} # Use environment variable (recommended)\n # baseURL: https://api.deepseek.com # Optional: override API endpoint\n temperature: ${defaults.llm.temperature}\n maxTokens: ${defaults.llm.maxTokens}\n\n# Permission System\npermissions:\n autoAccept: ${defaults.permissions.autoAccept} # DANGEROUS: Auto-approve all commands\n acceptRiskLevel: ${defaults.permissions.acceptRiskLevel} # low | medium | high | critical\n alwaysAcceptCommands: ${this.formatYamlArray(defaults.permissions.alwaysAcceptCommands)}\n\n# Keyboard Shortcuts (supports both single string and array)\n# Examples:\n# accept: Enter (single shortcut)\n# interrupt: [Ctrl+C, Escape] (multiple shortcuts)\n#\n# Note: On Windows, Ctrl+Space is intercepted by the terminal and won't work.\n# Tab is the recommended shortcut for autocomplete on all platforms.\nkeyBindings:\n interrupt: ${this.formatYamlArray(defaults.keyBindings.interrupt)}\n accept: ${this.formatYamlArray(defaults.keyBindings.accept)}\n modeSwitch: ${this.formatYamlArray(defaults.keyBindings.modeSwitch)}\n editCommand: ${this.formatYamlArray(defaults.keyBindings.editCommand)}\n showTooltip: ${this.formatYamlArray(defaults.keyBindings.showTooltip)} # Tab recommended (Ctrl+Space doesn't work on Windows)\n navigateUp: ${this.formatYamlArray(defaults.keyBindings.navigateUp)}\n navigateDown: ${this.formatYamlArray(defaults.keyBindings.navigateDown)}\n help: ${this.formatYamlArray(defaults.keyBindings.help)}\n clearScreen: ${this.formatYamlArray(defaults.keyBindings.clearScreen)}\n undo: ${this.formatYamlArray(defaults.keyBindings.undo)}\n redo: ${this.formatYamlArray(defaults.keyBindings.redo)}\n\n# Docker Sandbox (for running untrusted code)\ndocker:\n enabled: ${defaults.docker.enabled}\n baseImage: ${defaults.docker.baseImage}\n\n# User Interface\nui:\n theme: ${defaults.ui.theme} # mimir | dark | light | dark-colorblind | light-colorblind\n syntaxHighlighting: ${defaults.ui.syntaxHighlighting}\n showLineNumbers: ${defaults.ui.showLineNumbers}\n compactMode: ${defaults.ui.compactMode}\n autocompleteAutoShow: ${defaults.ui.autocompleteAutoShow} # Auto-show autocomplete when suggestions available\n autocompleteExecuteOnSelect: ${defaults.ui.autocompleteExecuteOnSelect} # Execute command if no more params needed\n\n# Monitoring & Metrics\nmonitoring:\n metricsRetentionDays: ${defaults.monitoring.metricsRetentionDays} # Keep metrics for N days\n enableHealthChecks: ${defaults.monitoring.enableHealthChecks}\n healthCheckIntervalSeconds: ${defaults.monitoring.healthCheckIntervalSeconds}\n slowOperationThresholdMs: ${defaults.monitoring.slowOperationThresholdMs}\n batchWriteIntervalSeconds: ${defaults.monitoring.batchWriteIntervalSeconds}\n\n# Budget Limits (prevents runaway costs)\nbudget:\n enabled: ${defaults.budget.enabled}\n # dailyLimit: 10.00 # USD per day (optional)\n # weeklyLimit: 50.00 # USD per week (optional)\n # monthlyLimit: 100.00 # USD per month (optional)\n warningThreshold: ${defaults.budget.warningThreshold} # Warn at 80% of limit\n\n# Rate Limiting (prevents excessive operations)\nrateLimit:\n enabled: ${defaults.rateLimit.enabled}\n commandsPerMinute: ${defaults.rateLimit.commandsPerMinute}\n toolExecutionsPerMinute: ${defaults.rateLimit.toolExecutionsPerMinute}\n llmCallsPerMinute: ${defaults.rateLimit.llmCallsPerMinute}\n maxFileSizeMB: ${defaults.rateLimit.maxFileSizeMB}\n`;\n\n await this.fs.writeFile(configPath, configContent);\n result.created.push('.mimir/config.yml');\n result.configCreated = true;\n logger.info('Created config.yml', { path: configPath });\n } catch (error) {\n result.errors.push(\n `Failed to create config.yml: ${error instanceof Error ? error.message : String(error)}`\n );\n logger.error('Failed to create config', { error });\n }\n }\n\n /**\n * Create README in .mimir directory\n */\n private async createReadme(mimirDir: string, result: InitializationResult): Promise<void> {\n const readmePath = path.join(mimirDir, 'README.md');\n\n if (await this.fs.exists(readmePath)) {\n return; // README already exists\n }\n\n const readmeContent = `# Mimir Workspace\n\nThis directory contains Mimir's workspace-specific data and configuration.\n\n## Directory Structure\n\n\\`\\`\\`\n.mimir/\n├── config.yml # Workspace configuration (tracked in git)\n├── mimir.db # Conversation history and metrics (ignored)\n├── logs/ # Application logs (ignored)\n├── commands/ # Custom slash commands (tracked)\n├── themes/ # UI theme definitions (tracked)\n├── checkpoints/ # Undo/restore checkpoints (ignored)\n├── .gitignore # Ignores sensitive data\n└── README.md # This file\n\\`\\`\\`\n\n## Files You Should Track in Git\n\n✅ **config.yml** - Team configuration (shared settings, allowlists)\n✅ **commands/** - Custom slash commands for your team\n✅ **themes/** - Custom UI themes for your team\n❌ **mimir.db** - Local conversation history (private)\n❌ **logs/** - Application logs (private)\n❌ **checkpoints/** - Code snapshots (private)\n\n## Configuration\n\nEdit \\`config.yml\\` to customize Mimir's behavior for this workspace:\n- LLM provider and model settings\n- Permission system (command allowlists)\n- Rate limiting and budget controls\n- UI preferences (including themes)\n\n**API Keys:** Store in \\`.env\\` file in project root, not in config.yml!\n\n## Database\n\n\\`mimir.db\\` is a SQLite database containing:\n- Conversation history\n- Message tokens and costs\n- Tool execution records\n- Performance metrics\n- Permission audit trail\n\nUse \\`mimir history\\` commands to manage conversations.\n\n## Custom Commands\n\nCustom slash commands extend Mimir's capabilities with team-specific workflows.\n\n### Example Commands Provided\n\nSix example commands are pre-installed in \\`commands/\\`:\n- **\\`/security\\`** - Analyze git diffs for security vulnerabilities\n- **\\`/refactor\\`** - Suggest code refactoring improvements\n- **\\`/test\\`** - Generate comprehensive test cases\n- **\\`/docs\\`** - Generate or improve documentation\n- **\\`/review\\`** - Perform comprehensive code review\n- **\\`/perf\\`** - Analyze performance issues and optimizations\n\n### Creating Custom Commands\n\nCommands are defined in YAML files in \\`commands/\\` directory:\n\n\\`\\`\\`yaml\n# .mimir/commands/deploy.yml\nname: deploy\ndescription: Deploy application to specified environment\nusage: /deploy [environment]\naliases: [d]\nprompt: |\n Deploy the application to $1 environment.\n\n Steps:\n 1. Run tests to ensure code quality\n 2. Build production bundle\n 3. Deploy to $1 environment\n 4. Run smoke tests\n 5. Monitor for errors\n\n Environment: $1 (or production if not specified)\n\\`\\`\\`\n\n**Placeholders:**\n- \\`$1\\`, \\`$2\\`, \\`$3\\` - Individual arguments\n- \\`$ARGUMENTS\\` - All arguments joined together\n\n**Usage:**\n\\`\\`\\`bash\n/deploy staging # Deploys to staging\n/security src/auth.ts # Security analysis of auth file\n/test src/utils.ts # Generate tests for utils\n\\`\\`\\`\n\n### Command Customization\n\nModify the example commands to match your workflow:\n- Add team-specific context to prompts\n- Customize analysis criteria\n- Add project-specific checks\n- Create domain-specific commands (e.g., \\`/api-design\\`, \\`/schema-migration\\`)\n\nCommands in this directory are tracked in git and shared with your team.\n\n## Custom Themes\n\nCustomize Mimir's appearance by creating theme files in \\`themes/\\` directory:\n\\`\\`\\`bash\n.mimir/themes/mimir.json # Default theme (provided)\n.mimir/themes/dark.json # Dark theme (provided)\n.mimir/themes/company-theme.json # Your custom theme\n\\`\\`\\`\n\nSelect theme in \\`config.yml\\`:\n\\`\\`\\`yaml\nui:\n theme: company-theme # Loads from themes/company-theme.json\n\\`\\`\\`\n\nSee the theme documentation for creating custom themes.\n\n---\n\n**Generated by Mimir v0.1.0**\n`;\n\n try {\n await this.fs.writeFile(readmePath, readmeContent);\n result.created.push('.mimir/README.md');\n logger.info('Created README.md');\n } catch (error) {\n result.errors.push(\n `Failed to create README: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * Print initialization summary\n */\n printSummary(result: InitializationResult, workspaceRoot: string): void {\n /* eslint-disable no-console */\n console.log('\\n🚀 Mimir Workspace Initialized!\\n');\n\n if (result.created.length > 0) {\n console.log('Created:');\n result.created.forEach((item) => console.log(` ✓ ${item}`));\n }\n\n if (result.dbInitialized) {\n console.log('\\n📊 Database:');\n console.log(' ✓ SQLite database created and seeded with pricing data');\n }\n\n if (result.configCreated) {\n console.log('\\n⚙️ Configuration:');\n console.log(' ✓ config.yml created with default settings');\n console.log(' 💡 Edit .mimir/config.yml to customize settings');\n console.log(' 💡 Store API keys in .env file, not in config.yml');\n }\n\n if (result.errors.length > 0) {\n console.log('\\n⚠️ Warnings:');\n result.errors.forEach((error) => console.log(` ! ${error}`));\n }\n\n console.log('\\n📁 Workspace structure:');\n console.log(` ${path.join(workspaceRoot, '.mimir')}`);\n console.log(' ├── config.yml (tracked in git)');\n console.log(' ├── mimir.db (ignored)');\n console.log(' ├── logs/ (ignored)');\n console.log(' ├── commands/ (tracked - 6 example commands provided)');\n console.log(' ├── themes/ (tracked - custom UI themes)');\n console.log(' └── checkpoints/ (ignored)');\n\n console.log('\\n💡 Custom Commands:');\n console.log(' Six example slash commands are ready to use:');\n console.log(' • /security - Analyze git diffs for security vulnerabilities');\n console.log(' • /refactor - Suggest code refactoring improvements');\n console.log(' • /test - Generate comprehensive test cases');\n console.log(' • /docs - Generate or improve documentation');\n console.log(' • /review - Perform comprehensive code review');\n console.log(' • /perf - Analyze performance issues');\n console.log('\\n Edit .mimir/commands/*.yml to customize or create your own!');\n\n console.log('\\n✨ Ready to use! Run \"mimir\" to start an interactive chat session.\\n');\n /* eslint-enable no-console */\n }\n}\n","/**\n * DeepSeek LLM Provider\n * OpenAI-compatible API with cost-effective pricing\n */\n\nimport { encode } from 'gpt-tokenizer';\nimport { BaseLLMProvider } from './BaseLLMProvider.js';\nimport { ILLMProvider, LLMTool } from './ILLMProvider.js';\nimport { Message, ChatResponse, ChatChunk, LLMConfig } from '../types/index.js';\nimport { APIClient } from './utils/apiClient.js';\nimport { getStaticPricing } from './pricing/pricingData.js';\nimport {\n toOpenAITools,\n parseOpenAIToolCalls,\n mapOpenAIFinishReason,\n} from './utils/toolFormatters.js';\nimport { parseOpenAIStream } from './utils/streamParsers.js';\nimport { ConfigurationError } from '../utils/errors.js';\n\nexport class DeepSeekProvider extends BaseLLMProvider implements ILLMProvider {\n private apiClient: APIClient;\n\n constructor(config: LLMConfig) {\n super(config);\n\n const apiKey = config.apiKey || process.env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n throw new ConfigurationError(\n 'DEEPSEEK_API_KEY not found in config or environment variables. ' +\n 'Please set DEEPSEEK_API_KEY in your .env file or pass it via config.'\n );\n }\n\n const baseURL = config.baseURL || 'https://api.deepseek.com';\n\n this.apiClient = new APIClient({\n baseURL,\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n timeout: 60000,\n });\n }\n\n async chat(messages: Message[], tools?: LLMTool[]): Promise<ChatResponse> {\n return this.withRetry(async () => {\n const requestBody = {\n model: this.config.model,\n messages: this.formatMessages(messages),\n tools: tools ? toOpenAITools(tools) : undefined,\n temperature: this.config.temperature,\n max_tokens: this.config.maxTokens,\n };\n\n const response = await this.apiClient.post<DeepSeekChatResponse>(\n '/chat/completions',\n requestBody\n );\n\n return this.parseResponse(response);\n });\n }\n\n async *streamChat(messages: Message[], tools?: LLMTool[]): AsyncGenerator<ChatChunk> {\n const requestBody = {\n model: this.config.model,\n messages: this.formatMessages(messages),\n tools: tools ? toOpenAITools(tools) : undefined,\n temperature: this.config.temperature,\n max_tokens: this.config.maxTokens,\n stream: true,\n };\n\n const stream = this.apiClient.stream('/chat/completions', requestBody);\n\n for await (const chunk of parseOpenAIStream(stream)) {\n yield chunk;\n }\n }\n\n countTokens(text: string): number {\n return encode(text).length;\n }\n\n calculateCost(inputTokens: number, outputTokens: number): number {\n const pricing = getStaticPricing('deepseek', this.config.model);\n if (!pricing) {\n return 0; // Unknown model, return 0 cost\n }\n\n return (\n (inputTokens / 1_000_000) * pricing.inputPerMillionTokens +\n (outputTokens / 1_000_000) * pricing.outputPerMillionTokens\n );\n }\n\n /**\n * Format messages for OpenAI-compatible API\n */\n private formatMessages(\n messages: Message[]\n ): Array<{ role: string; content: string; name?: string }> {\n return messages.map((msg) => ({\n role: msg.role,\n content: msg.content,\n name: msg.name,\n }));\n }\n\n /**\n * Parse DeepSeek API response\n */\n private parseResponse(response: DeepSeekChatResponse): ChatResponse {\n const choice = response.choices[0];\n const message = choice?.message;\n const usage = response.usage;\n\n if (!choice || !message) {\n throw new Error('Invalid response from DeepSeek API: missing choice or message');\n }\n\n return {\n content: message.content || '',\n toolCalls: parseOpenAIToolCalls(response),\n finishReason: mapOpenAIFinishReason(choice.finish_reason),\n usage: {\n inputTokens: usage.prompt_tokens,\n outputTokens: usage.completion_tokens,\n totalTokens: usage.total_tokens,\n },\n };\n }\n}\n\n/**\n * DeepSeek API response type\n */\ninterface DeepSeekChatResponse {\n id: string;\n object: string;\n created: number;\n model: string;\n choices: Array<{\n index: number;\n message: {\n role: string;\n content: string | null;\n tool_calls?: Array<{\n id: string;\n type: string;\n function: {\n name: string;\n arguments: string;\n };\n }>;\n };\n finish_reason: string;\n }>;\n usage: {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n prompt_cache_hit_tokens?: number;\n prompt_cache_miss_tokens?: number;\n };\n}\n","/**\n * Custom error classes\n */\n\nexport class MimirError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'MimirError';\n }\n}\n\nexport class ConfigurationError extends MimirError {\n constructor(message: string) {\n super(message);\n this.name = 'ConfigurationError';\n }\n}\n\nexport class ProviderError extends MimirError {\n constructor(\n message: string,\n public readonly provider?: string\n ) {\n super(message);\n this.name = 'ProviderError';\n }\n}\n\nexport class ToolExecutionError extends MimirError {\n constructor(\n message: string,\n public readonly toolName?: string\n ) {\n super(message);\n this.name = 'ToolExecutionError';\n }\n}\n\nexport class PermissionDeniedError extends MimirError {\n constructor(\n message: string,\n public readonly command?: string\n ) {\n super(message);\n this.name = 'PermissionDeniedError';\n }\n}\n\nexport class DockerError extends MimirError {\n constructor(message: string) {\n super(message);\n this.name = 'DockerError';\n }\n}\n\nexport class NetworkError extends MimirError {\n constructor(\n message: string,\n public readonly statusCode?: number\n ) {\n super(message);\n this.name = 'NetworkError';\n }\n}\n\nexport class RateLimitError extends MimirError {\n constructor(\n message: string,\n public readonly retryAfter?: number\n ) {\n super(message);\n this.name = 'RateLimitError';\n }\n}\n","/**\n * Base LLM Provider implementation\n * Contains common logic for retry, error handling, etc.\n */\n\nimport { ILLMProvider, LLMTool } from './ILLMProvider.js';\nimport { Message, ChatResponse, ChatChunk, LLMConfig } from '../types/index.js';\nimport { NetworkError } from '../utils/errors.js';\n\nexport interface RetryConfig {\n maxRetries: number;\n retryDelay: number;\n backoffMultiplier: number;\n}\n\nexport abstract class BaseLLMProvider implements ILLMProvider {\n protected config: LLMConfig;\n protected retryConfig: RetryConfig;\n\n constructor(config: LLMConfig, retryConfig?: RetryConfig) {\n this.config = config;\n this.retryConfig = retryConfig ?? {\n maxRetries: 3,\n retryDelay: 1000,\n backoffMultiplier: 2,\n };\n }\n\n abstract chat(messages: Message[], tools?: LLMTool[]): Promise<ChatResponse>;\n abstract streamChat(messages: Message[], tools?: LLMTool[]): AsyncGenerator<ChatChunk>;\n abstract countTokens(text: string): number;\n abstract calculateCost(inputTokens: number, outputTokens: number): number;\n\n getProviderName(): string {\n return this.config.provider;\n }\n\n getModelName(): string {\n return this.config.model;\n }\n\n /**\n * Retry wrapper for API calls\n * Only retries on NetworkError (5xx server errors)\n * Does NOT retry on auth errors, rate limits, or client errors\n */\n protected async withRetry<T>(fn: () => Promise<T>): Promise<T> {\n let lastError: Error | undefined;\n let delay = this.retryConfig.retryDelay;\n\n for (let attempt = 0; attempt <= this.retryConfig.maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error as Error;\n\n // Only retry on NetworkError (transient server issues)\n // Don't retry on auth errors, rate limits, or client errors\n const shouldRetry = error instanceof NetworkError && attempt < this.retryConfig.maxRetries;\n\n if (shouldRetry) {\n await this.sleep(delay);\n delay *= this.retryConfig.backoffMultiplier;\n } else {\n // For non-retryable errors, throw immediately\n throw lastError;\n }\n }\n }\n\n throw lastError;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","/**\n * HTTP API client wrapper around axios\n * Handles request/response, error mapping, and streaming\n */\n\nimport axios, { AxiosInstance, AxiosError, AxiosResponse } from 'axios';\nimport { ProviderError, NetworkError, RateLimitError } from '../../utils/errors.js';\n\nexport interface APIClientConfig {\n baseURL: string;\n headers: Record<string, string>;\n timeout?: number;\n}\n\nexport class APIClient {\n private axiosInstance: AxiosInstance;\n private providerName: string;\n\n constructor(config: APIClientConfig) {\n this.axiosInstance = axios.create({\n baseURL: config.baseURL,\n headers: config.headers,\n timeout: config.timeout || 60000, // 60 seconds default\n });\n\n // Extract provider name from base URL for error messages\n this.providerName = this.extractProviderName(config.baseURL);\n }\n\n /**\n * POST request with JSON payload\n */\n async post<T>(endpoint: string, data: unknown): Promise<T> {\n try {\n const response: AxiosResponse<T> = await this.axiosInstance.post(endpoint, data);\n return response.data;\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n /**\n * GET request\n */\n async get<T>(endpoint: string): Promise<T> {\n try {\n const response: AxiosResponse<T> = await this.axiosInstance.get(endpoint);\n return response.data;\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n /**\n * Stream request for Server-Sent Events (SSE)\n * Returns async iterable of string chunks\n */\n async *stream(endpoint: string, data: unknown): AsyncGenerator<string, void, unknown> {\n try {\n const response = await this.axiosInstance.post(endpoint, data, {\n responseType: 'stream',\n headers: {\n Accept: 'text/event-stream',\n },\n });\n\n const stream = response.data;\n\n // Read stream chunks\n for await (const chunk of stream) {\n const chunkStr = chunk.toString('utf-8');\n yield chunkStr;\n }\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n /**\n * Map axios errors to custom error types\n */\n private mapError(error: unknown): Error {\n if (!axios.isAxiosError(error)) {\n return error as Error;\n }\n\n const axiosError = error as AxiosError;\n const status = axiosError.response?.status;\n const errorData = axiosError.response?.data as {\n error?: { message?: string };\n message?: string;\n };\n const message = errorData?.error?.message || errorData?.message || axiosError.message;\n\n // Rate limit error (429)\n if (status === 429) {\n const retryAfter = parseInt((axiosError.response?.headers['retry-after'] as string) || '60');\n return new RateLimitError(`${this.providerName} rate limit exceeded: ${message}`, retryAfter);\n }\n\n // Auth errors (401, 403)\n if (status === 401 || status === 403) {\n return new ProviderError(\n `${this.providerName} authentication failed: ${message}`,\n this.providerName\n );\n }\n\n // Server errors (5xx)\n if (status && status >= 500) {\n return new NetworkError(`${this.providerName} server error: ${message}`, status);\n }\n\n // Client errors (4xx)\n if (status && status >= 400) {\n return new ProviderError(`${this.providerName} request error: ${message}`, this.providerName);\n }\n\n // Network/timeout errors\n if (axiosError.code === 'ECONNABORTED' || axiosError.code === 'ETIMEDOUT') {\n return new NetworkError(`${this.providerName} request timeout: ${message}`);\n }\n\n // Generic provider error\n return new ProviderError(`${this.providerName} error: ${message}`, this.providerName);\n }\n\n /**\n * Extract provider name from base URL\n */\n private extractProviderName(baseURL: string): string {\n try {\n const url = new URL(baseURL);\n const hostname = url.hostname;\n\n if (hostname.includes('deepseek')) return 'DeepSeek';\n if (hostname.includes('anthropic')) return 'Anthropic';\n if (hostname.includes('openai')) return 'OpenAI';\n if (hostname.includes('google')) return 'Google';\n\n return hostname;\n } catch {\n return 'Unknown Provider';\n }\n }\n}\n","/**\n * Pricing data for LLM providers\n * Hybrid approach: Fetch from API first, fallback to static table\n */\n\nexport interface ModelPricing {\n inputPerMillionTokens: number;\n outputPerMillionTokens: number;\n}\n\n// Static fallback pricing (updated as of 2025-12-25)\nconst STATIC_PRICING_TABLE: Record<string, Record<string, ModelPricing>> = {\n deepseek: {\n 'deepseek-chat': {\n inputPerMillionTokens: 0.14,\n outputPerMillionTokens: 0.28,\n },\n 'deepseek-reasoner': {\n inputPerMillionTokens: 0.55,\n outputPerMillionTokens: 2.19,\n },\n },\n anthropic: {\n 'claude-opus-4-5-20251101': {\n inputPerMillionTokens: 15,\n outputPerMillionTokens: 75,\n },\n 'claude-opus-4-5': {\n inputPerMillionTokens: 15,\n outputPerMillionTokens: 75,\n },\n 'claude-sonnet-4-5-20250929': {\n inputPerMillionTokens: 3,\n outputPerMillionTokens: 15,\n },\n 'claude-sonnet-4-5': {\n inputPerMillionTokens: 3,\n outputPerMillionTokens: 15,\n },\n 'claude-haiku-4-5': {\n inputPerMillionTokens: 1,\n outputPerMillionTokens: 5,\n },\n 'claude-3-7-sonnet-latest': {\n inputPerMillionTokens: 3,\n outputPerMillionTokens: 15,\n },\n 'claude-3-5-haiku-latest': {\n inputPerMillionTokens: 1,\n outputPerMillionTokens: 5,\n },\n },\n};\n\n// In-memory cache for dynamic pricing (TTL: 24 hours)\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours\n\ninterface PricingCacheEntry {\n pricing: ModelPricing;\n timestamp: number;\n}\n\nconst pricingCache = new Map<string, PricingCacheEntry>();\n\n/**\n * Get static pricing for a provider/model\n */\nexport function getStaticPricing(provider: string, model: string): ModelPricing | null {\n const providerPricing = STATIC_PRICING_TABLE[provider.toLowerCase()];\n if (!providerPricing) {\n return null;\n }\n\n return providerPricing[model] || null;\n}\n\n/**\n * Fetch dynamic pricing from provider API or documentation\n */\nexport async function fetchDynamicPricing(\n provider: string,\n model: string,\n apiKey?: string\n): Promise<ModelPricing | null> {\n const normalizedProvider = provider.toLowerCase();\n\n // DeepSeek: Scrape pricing from documentation\n if (normalizedProvider === 'deepseek') {\n try {\n const response = await fetch('https://api-docs.deepseek.com/quick_start/pricing');\n if (!response.ok) {\n return null;\n }\n\n const html = await response.text();\n\n // Parse pricing from HTML (looking for pricing table or text)\n // DeepSeek pricing is typically listed as:\n // - deepseek-chat: $0.14 / $0.28 per million tokens\n // - deepseek-reasoner: $0.55 / $2.19 per million tokens\n\n // Try to extract pricing for the specific model\n const modelLower = model.toLowerCase();\n\n // For deepseek-chat, look for the first pricing entry\n if (modelLower.includes('chat')) {\n const match = html.match(/chat.*?\\$?0\\.14.*?\\$?0\\.28/i);\n if (match) {\n return {\n inputPerMillionTokens: 0.14,\n outputPerMillionTokens: 0.28,\n };\n }\n }\n\n // For deepseek-reasoner, look for reasoner pricing\n if (modelLower.includes('reasoner')) {\n const match = html.match(/reasoner.*?\\$?0\\.55.*?\\$?2\\.19/i);\n if (match) {\n return {\n inputPerMillionTokens: 0.55,\n outputPerMillionTokens: 2.19,\n };\n }\n }\n\n // Fallback to static if scraping fails\n return null;\n } catch (error) {\n // Silently fail and use static pricing\n return null;\n }\n }\n\n // Anthropic Models API (requires API key)\n if (normalizedProvider === 'anthropic' && apiKey) {\n try {\n const response = await fetch(`https://api.anthropic.com/v1/models/${model}`, {\n headers: {\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n });\n\n if (!response.ok) {\n return null;\n }\n\n const data = (await response.json()) as {\n pricing?: {\n input_price_per_million_tokens?: number;\n output_price_per_million_tokens?: number;\n };\n };\n\n if (\n data.pricing?.input_price_per_million_tokens != null &&\n data.pricing?.output_price_per_million_tokens != null\n ) {\n return {\n inputPerMillionTokens: data.pricing.input_price_per_million_tokens,\n outputPerMillionTokens: data.pricing.output_price_per_million_tokens,\n };\n }\n } catch (error) {\n // Silently fail and use static pricing\n return null;\n }\n }\n\n return null;\n}\n\n/**\n * Get pricing for a model (hybrid: API first, fallback to static)\n * Caches dynamic pricing for 24 hours\n */\nexport async function getModelPricing(\n provider: string,\n model: string,\n apiKey?: string\n): Promise<ModelPricing | null> {\n const cacheKey = `${provider}:${model}`;\n\n // Check cache first\n const cached = pricingCache.get(cacheKey);\n if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) {\n return cached.pricing;\n }\n\n // Try to fetch dynamic pricing\n const dynamicPricing = await fetchDynamicPricing(provider, model, apiKey);\n if (dynamicPricing) {\n // Cache the result\n pricingCache.set(cacheKey, {\n pricing: dynamicPricing,\n timestamp: Date.now(),\n });\n return dynamicPricing;\n }\n\n // Fallback to static pricing\n const staticPricing = getStaticPricing(provider, model);\n if (staticPricing) {\n // Cache static pricing too (to avoid repeated lookups)\n pricingCache.set(cacheKey, {\n pricing: staticPricing,\n timestamp: Date.now(),\n });\n }\n\n return staticPricing;\n}\n\n/**\n * Clear pricing cache (useful for testing or forcing refresh)\n */\nexport function clearPricingCache(): void {\n pricingCache.clear();\n}\n","/**\n * Tool format converters\n * Handles conversion between LLMTool interface and provider-specific formats\n */\n\nimport { LLMTool } from '../ILLMProvider.js';\nimport { ToolCall } from '../../types/index.js';\n\n/**\n * Convert LLMTool to OpenAI function calling format\n * Used by: DeepSeek, OpenAI, Qwen (OpenAI-compatible providers)\n */\nexport function toOpenAITools(tools: LLMTool[]): unknown[] {\n return tools.map((tool) => ({\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.schema, // Already JSON Schema\n },\n }));\n}\n\n/**\n * Convert LLMTool to Anthropic tool format\n * Used by: Anthropic Claude API\n */\nexport function toAnthropicTools(tools: LLMTool[]): unknown[] {\n return tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n input_schema: {\n type: 'object',\n ...tool.schema, // Merge with existing schema\n },\n }));\n}\n\n/**\n * Parse tool calls from OpenAI response\n */\nexport function parseOpenAIToolCalls(response: {\n choices?: Array<{\n message?: {\n tool_calls?: Array<{\n id: string;\n type: string;\n function: {\n name: string;\n arguments: string;\n };\n }>;\n };\n }>;\n}): ToolCall[] {\n const toolCalls = response.choices?.[0]?.message?.tool_calls || [];\n\n return toolCalls.map((tc) => {\n let parsedArgs: Record<string, unknown>;\n try {\n parsedArgs = JSON.parse(tc.function.arguments);\n } catch {\n parsedArgs = {};\n }\n\n return {\n id: tc.id,\n name: tc.function.name,\n arguments: parsedArgs,\n };\n });\n}\n\n/**\n * Parse tool calls from Anthropic response\n */\nexport function parseAnthropicToolCalls(response: {\n content?: Array<\n | { type: 'text'; text: string }\n | {\n type: 'tool_use';\n id: string;\n name: string;\n input: Record<string, unknown>;\n }\n >;\n}): ToolCall[] {\n const content = response.content || [];\n\n return content\n .filter(\n (block): block is Extract<typeof block, { type: 'tool_use' }> => block.type === 'tool_use'\n )\n .map((block) => ({\n id: block.id,\n name: block.name,\n arguments: block.input,\n }));\n}\n\n/**\n * Map OpenAI finish reason to standard format\n */\nexport function mapOpenAIFinishReason(reason: string): 'stop' | 'tool_calls' | 'length' | 'error' {\n switch (reason) {\n case 'stop':\n return 'stop';\n case 'tool_calls':\n return 'tool_calls';\n case 'length':\n return 'length';\n case 'content_filter':\n case 'insufficient_system_resource':\n return 'error';\n default:\n return 'error';\n }\n}\n\n/**\n * Map Anthropic stop reason to standard format\n */\nexport function mapAnthropicFinishReason(\n reason: string\n): 'stop' | 'tool_calls' | 'length' | 'error' {\n switch (reason) {\n case 'end_turn':\n return 'stop';\n case 'tool_use':\n return 'tool_calls';\n case 'max_tokens':\n return 'length';\n case 'stop_sequence':\n return 'stop';\n default:\n return 'error';\n }\n}\n","/**\n * Server-Sent Events (SSE) stream parsers\n * Handles different streaming formats from various providers\n */\n\nimport { ChatChunk } from '../../types/index.js';\n\n/**\n * Parse OpenAI-format SSE stream\n * Used by: DeepSeek, OpenAI, Qwen\n *\n * Format:\n * data: {\"choices\":[{\"delta\":{\"content\":\"hello\"}}]}\n * data: [DONE]\n */\nexport async function* parseOpenAIStream(stream: AsyncIterable<string>): AsyncGenerator<ChatChunk> {\n let buffer = '';\n\n for await (const chunk of stream) {\n buffer += chunk;\n\n // Split by newlines to get individual SSE messages\n const lines = buffer.split('\\n');\n\n // Keep the last incomplete line in buffer\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Skip empty lines\n if (!trimmed) continue;\n\n // Check for [DONE] marker\n if (trimmed === 'data: [DONE]') {\n yield { content: '', done: true };\n return;\n }\n\n // Parse data: lines\n if (trimmed.startsWith('data: ')) {\n const jsonStr = trimmed.substring(6); // Remove 'data: ' prefix\n try {\n const data = JSON.parse(jsonStr) as {\n choices?: Array<{\n delta?: {\n content?: string;\n role?: string;\n };\n finish_reason?: string | null;\n }>;\n };\n\n const delta = data.choices?.[0]?.delta;\n const content = delta?.content || '';\n const finishReason = data.choices?.[0]?.finish_reason;\n\n if (content) {\n yield { content, done: false };\n }\n\n if (finishReason) {\n yield { content: '', done: true };\n return;\n }\n } catch (error) {\n // Skip malformed JSON\n continue;\n }\n }\n }\n }\n\n // Flush any remaining buffer\n if (buffer.trim()) {\n yield { content: '', done: true };\n }\n}\n\n/**\n * Parse Anthropic-format SSE stream\n * Used by: Anthropic Claude API\n *\n * Format:\n * event: message_start\n * data: {\"type\":\"message_start\"}\n *\n * event: content_block_delta\n * data: {\"delta\":{\"text\":\"hello\"}}\n *\n * event: message_stop\n * data: {}\n */\nexport async function* parseAnthropicStream(\n stream: AsyncIterable<string>\n): AsyncGenerator<ChatChunk> {\n let buffer = '';\n let currentEvent = '';\n\n for await (const chunk of stream) {\n buffer += chunk;\n\n // Split by double newlines to get individual SSE events\n const events = buffer.split('\\n\\n');\n\n // Keep the last incomplete event in buffer\n buffer = events.pop() || '';\n\n for (const event of events) {\n const lines = event.split('\\n');\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (trimmed.startsWith('event: ')) {\n currentEvent = trimmed.substring(7);\n } else if (trimmed.startsWith('data: ')) {\n const jsonStr = trimmed.substring(6);\n\n try {\n const data = JSON.parse(jsonStr);\n\n // Handle content_block_delta events\n if (currentEvent === 'content_block_delta') {\n const content = data.delta?.text || '';\n if (content) {\n yield { content, done: false };\n }\n }\n\n // Handle content_block_start events\n if (currentEvent === 'content_block_start') {\n const content = data.content_block?.text || '';\n if (content) {\n yield { content, done: false };\n }\n }\n\n // Handle message_delta events (may contain usage info)\n if (currentEvent === 'message_delta') {\n // No content in message_delta, just metadata\n continue;\n }\n\n // Handle message_stop event\n if (currentEvent === 'message_stop') {\n yield { content: '', done: true };\n return;\n }\n\n // Handle error events\n if (currentEvent === 'error') {\n throw new Error(data.error?.message || 'Anthropic streaming error');\n }\n } catch (error) {\n // Skip malformed JSON or propagate errors\n if (currentEvent === 'error') {\n throw error;\n }\n continue;\n }\n }\n }\n }\n }\n\n // Flush any remaining buffer\n if (buffer.trim()) {\n yield { content: '', done: true };\n }\n}\n","/**\n * Anthropic Claude LLM Provider\n * Uses Claude's Messages API with Anthropic-specific format\n */\n\nimport { encode } from 'gpt-tokenizer';\nimport { BaseLLMProvider } from './BaseLLMProvider.js';\nimport { ILLMProvider, LLMTool } from './ILLMProvider.js';\nimport { Message, ChatResponse, ChatChunk, LLMConfig } from '../types/index.js';\nimport { APIClient } from './utils/apiClient.js';\nimport { getStaticPricing } from './pricing/pricingData.js';\nimport {\n toAnthropicTools,\n parseAnthropicToolCalls,\n mapAnthropicFinishReason,\n} from './utils/toolFormatters.js';\nimport { parseAnthropicStream } from './utils/streamParsers.js';\nimport { ConfigurationError } from '../utils/errors.js';\n\nexport class AnthropicProvider extends BaseLLMProvider implements ILLMProvider {\n private apiClient: APIClient;\n\n constructor(config: LLMConfig) {\n super(config);\n\n const apiKey = config.apiKey || process.env.ANTHROPIC_API_KEY;\n if (!apiKey) {\n throw new ConfigurationError(\n 'ANTHROPIC_API_KEY not found in config or environment variables. ' +\n 'Please set ANTHROPIC_API_KEY in your .env file or pass it via config.'\n );\n }\n const baseURL = config.baseURL || 'https://api.anthropic.com';\n\n this.apiClient = new APIClient({\n baseURL,\n headers: {\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n 'Content-Type': 'application/json',\n },\n timeout: 60000,\n });\n }\n\n async chat(messages: Message[], tools?: LLMTool[]): Promise<ChatResponse> {\n return this.withRetry(async () => {\n const { system, messages: userMessages } = this.formatAnthropicMessages(messages);\n\n const requestBody: AnthropicChatRequest = {\n model: this.config.model,\n messages: userMessages,\n max_tokens: this.config.maxTokens,\n temperature: this.config.temperature,\n };\n\n // Add system message if present\n if (system) {\n requestBody.system = system;\n }\n\n // Add tools if present\n if (tools && tools.length > 0) {\n requestBody.tools = toAnthropicTools(tools);\n }\n\n const response = await this.apiClient.post<AnthropicChatResponse>(\n '/v1/messages',\n requestBody\n );\n\n return this.parseResponse(response);\n });\n }\n\n async *streamChat(messages: Message[], tools?: LLMTool[]): AsyncGenerator<ChatChunk> {\n const { system, messages: userMessages } = this.formatAnthropicMessages(messages);\n\n const requestBody: AnthropicChatRequest = {\n model: this.config.model,\n messages: userMessages,\n max_tokens: this.config.maxTokens,\n temperature: this.config.temperature,\n stream: true,\n };\n\n if (system) {\n requestBody.system = system;\n }\n\n if (tools && tools.length > 0) {\n requestBody.tools = toAnthropicTools(tools);\n }\n\n const stream = this.apiClient.stream('/v1/messages', requestBody);\n\n for await (const chunk of parseAnthropicStream(stream)) {\n yield chunk;\n }\n }\n\n countTokens(text: string): number {\n return encode(text).length;\n }\n\n calculateCost(inputTokens: number, outputTokens: number): number {\n const pricing = getStaticPricing('anthropic', this.config.model);\n if (!pricing) {\n return 0; // Unknown model, return 0 cost\n }\n\n return (\n (inputTokens / 1_000_000) * pricing.inputPerMillionTokens +\n (outputTokens / 1_000_000) * pricing.outputPerMillionTokens\n );\n }\n\n /**\n * Format messages for Anthropic API\n * Extracts system messages into separate parameter\n */\n private formatAnthropicMessages(messages: Message[]): {\n system?: string;\n messages: Array<{ role: string; content: string }>;\n } {\n const systemMessages = messages.filter((m) => m.role === 'system');\n const userMessages = messages.filter((m) => m.role !== 'system');\n\n const system =\n systemMessages.length > 0 ? systemMessages.map((m) => m.content).join('\\n\\n') : undefined;\n\n return {\n system,\n messages: userMessages.map((msg) => ({\n role: msg.role === 'assistant' ? 'assistant' : 'user',\n content: msg.content,\n })),\n };\n }\n\n /**\n * Parse Anthropic API response\n */\n private parseResponse(response: AnthropicChatResponse): ChatResponse {\n const content = response.content || [];\n const usage = response.usage;\n\n // Extract text content from content blocks\n const textContent = content\n .filter((block) => block.type === 'text')\n .map((block) => (block as { type: 'text'; text: string }).text)\n .join('');\n\n return {\n content: textContent,\n toolCalls: parseAnthropicToolCalls(response),\n finishReason: mapAnthropicFinishReason(response.stop_reason),\n usage: {\n inputTokens: usage.input_tokens,\n outputTokens: usage.output_tokens,\n totalTokens: usage.input_tokens + usage.output_tokens,\n },\n };\n }\n}\n\n/**\n * Anthropic API request type\n */\ninterface AnthropicChatRequest {\n model: string;\n messages: Array<{\n role: string;\n content: string;\n }>;\n max_tokens: number;\n temperature?: number;\n system?: string;\n tools?: unknown[];\n stream?: boolean;\n}\n\n/**\n * Anthropic API response type\n */\ninterface AnthropicChatResponse {\n id: string;\n type: string;\n role: string;\n content: Array<\n | { type: 'text'; text: string }\n | {\n type: 'tool_use';\n id: string;\n name: string;\n input: Record<string, unknown>;\n }\n >;\n model: string;\n stop_reason: string;\n stop_sequence?: string | null;\n usage: {\n input_tokens: number;\n output_tokens: number;\n };\n}\n","/**\n * Factory for creating LLM provider instances\n */\n\nimport { ILLMProvider } from './ILLMProvider.js';\nimport { LLMConfig } from '../types/index.js';\nimport { DeepSeekProvider } from './DeepSeekProvider.js';\nimport { AnthropicProvider } from './AnthropicProvider.js';\n\nexport class ProviderFactory {\n static create(config: LLMConfig): ILLMProvider {\n switch (config.provider.toLowerCase()) {\n case 'deepseek':\n return new DeepSeekProvider(config);\n case 'anthropic':\n return new AnthropicProvider(config);\n case 'openai':\n throw new Error(\n 'OpenAI provider coming soon - see roadmap Phase 3. ' +\n 'In the meantime, you can use DeepSeek which is OpenAI-compatible.'\n );\n case 'google':\n case 'gemini':\n throw new Error('Google/Gemini provider coming soon - see roadmap Phase 3.');\n case 'qwen':\n throw new Error(\n 'Qwen provider coming soon - see roadmap Phase 3. ' +\n 'In the meantime, you can use DeepSeek which is similar.'\n );\n case 'ollama':\n throw new Error('Ollama provider coming soon - see roadmap Phase 3.');\n default:\n throw new Error(`Unsupported provider: ${config.provider}`);\n }\n }\n}\n","/**\n * Init command handler\n * Initializes Mimir in the current project\n */\n\nimport { IFileSystem } from '../../platform/IFileSystem.js';\nimport { ConfigLoader } from '../../config/ConfigLoader.js';\nimport { MimirInitializer } from '../../core/MimirInitializer.js';\nimport { logger } from '../../utils/logger.js';\n\nexport interface InitOptions {\n interactive?: boolean;\n quiet?: boolean;\n}\n\nexport class InitCommand {\n private initializer: MimirInitializer;\n\n constructor(_fs: IFileSystem, _configLoader: ConfigLoader) {\n this.initializer = new MimirInitializer(_fs, _configLoader);\n }\n\n async execute(projectRoot?: string, options: InitOptions = {}): Promise<void> {\n const root = projectRoot || process.cwd();\n\n if (!options.quiet) {\n logger.info('Initializing Mimir workspace', { projectRoot: root });\n }\n\n // Check if already initialized\n if (await this.initializer.isWorkspaceInitialized(root)) {\n if (!options.quiet) {\n logger.info('Mimir workspace is already initialized in this directory.');\n logger.info('Run \"mimir\" to start an interactive chat session.');\n }\n return;\n }\n\n // Run full initialization\n const result = await this.initializer.initializeWorkspace(root);\n\n // Print summary (unless quiet mode)\n if (!options.quiet) {\n this.initializer.printSummary(result, root);\n }\n\n // Exit with error if initialization failed\n if (!result.success) {\n process.exit(1);\n }\n }\n}\n"],"mappings":"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","names":["path","fs","path","z","fs","yaml","path","fs","path","yaml","path","os","fs","React","useState","Box","Box","Text","jsx","Box","Text","Box","Text","chalk","os","jsx","jsxs","chalk","Box","Text","useMemo","Box","Text","chalk","chalk","jsx","jsxs","chalk","fg","useMemo","Box","Text","jsx","jsxs","useState","Box","configLoader","React","React","render","useEffect","useState","useMemo","useCallback","useRef","useEffect","Box","Text","Box","Text","jsx","jsxs","Box","Text","Box","Text","jsx","jsxs","cost","Box","Text","React","useState","useEffect","Box","Text","React","useMemo","Box","Text","chalk","useState","jsx","jsxs","chalk","useMemo","safeSelectedIndex","startIndex","endIndex","moreAbove","moreBelow","moreAboveCount","moreBelowCount","actualHeight","React","maxWidth","Box","Text","jsx","jsxs","React","useState","useEffect","Box","Text","useState","useEffect","Box","Text","jsx","jsxs","cost","Text","useState","useEffect","Box","handlers","useEffect","useState","os","jsx","useState","useEffect","useEffect","useEffect","useInput","useInput","jsx","jsxs","useState","useRef","useEffect","useMemo","useCallback","Box","Text","jsx","useEffect","fs","z","yaml","path","os","z","fs","path","os","yaml","z","z","helpText","themes","existsSync","readFileSync","path","dirname","fs","configLoader","encode","encode","path","yaml","configLoader","firstRunDetector","setupCommand","fs","rerender","React","render","fs"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/platform/FileSystemAdapter.ts","../src/platform/ProcessExecutorAdapter.ts","../src/config/schemas.ts","../src/utils/logger.ts","../src/config/AllowlistLoader.ts","../src/config/ConfigLoader.ts","../src/cli/utils/firstRunDetector.ts","../src/cli/commands/SetupCommand.ts","../src/cli/components/SetupWizard.tsx","../src/cli/components/WizardLayout.tsx","../src/cli/components/WizardHead.tsx","../src/cli/theme-colors.ts","../src/cli/components/logo.ts","../src/cli/components/SecurityWarning.tsx","../src/utils/keyboardFormatter.ts","../src/cli/components/ThemeSelector.tsx","../src/config/themes/theme-schema.ts","../src/config/themes/definitions/mimir.json","../src/config/themes/definitions/dark.json","../src/config/themes/definitions/light.json","../src/config/themes/definitions/dark-colorblind.json","../src/config/themes/definitions/light-colorblind.json","../src/config/themes/definitions/dark-ansi.json","../src/config/themes/definitions/light-ansi.json","../src/config/themes/index.ts","../src/cli/utils/syntaxHighlight.ts","../src/cli/commands/ChatCommand.ts","../src/cli/components/ChatApp.tsx","../src/cli/components/ChatInterface.tsx","../src/cli/components/MimirHeader.tsx","../src/cli/components/MessageList.tsx","../src/cli/components/InputBox.tsx","../src/core/SlashCommandParser.ts","../src/cli/components/CommandAutocomplete.tsx","../src/cli/hooks/useTerminalSize.ts","../src/cli/components/Footer.tsx","../src/cli/components/tips.ts","../src/cli/keyboard/KeyboardEventBus.ts","../src/cli/keyboard/KeyboardContext.tsx","../src/utils/KeyBindings.ts","../src/cli/keyboard/useKeyboardAction.ts","../src/cli/keyboard/useKeyboardInput.ts","../src/core/SlashCommand.ts","../src/core/CustomCommandLoader.ts","../src/cli/utils/signalHandler.ts","../src/cli/commands/slashCommands/NewCommand.ts","../src/cli/commands/slashCommands/ModelCommand.ts","../src/cli/commands/slashCommands/ModeCommand.ts","../src/cli/commands/slashCommands/HelpCommand.ts","../src/cli/commands/slashCommands/ThemeCommand.ts","../src/storage/Database.ts","../src/storage/seed.ts","../src/core/MimirInitializer.ts","../src/providers/DeepSeekProvider.ts","../src/utils/errors.ts","../src/providers/BaseLLMProvider.ts","../src/providers/utils/apiClient.ts","../src/providers/pricing/pricingData.ts","../src/providers/utils/toolFormatters.ts","../src/providers/utils/streamParsers.ts","../src/providers/AnthropicProvider.ts","../src/providers/ProviderFactory.ts","../src/cli/commands/InitCommand.ts","../src/cli/commands/UninstallCommand.ts"],"sourcesContent":["/**\n * Mimir CLI entry point\n *\n * Note: Shebang is NOT included in source code.\n * - npm adds it automatically based on package.json bin field\n * - pkg adds it automatically when creating binaries\n */\n\nimport { Command } from 'commander';\nimport { FileSystemAdapter } from './platform/FileSystemAdapter.js';\nimport { ProcessExecutorAdapter } from './platform/ProcessExecutorAdapter.js';\nimport { ConfigLoader } from './config/ConfigLoader.js';\nimport { FirstRunDetector } from './cli/utils/firstRunDetector.js';\nimport { SetupCommand } from './cli/commands/SetupCommand.js';\nimport { ChatCommand } from './cli/commands/ChatCommand.js';\nimport { InitCommand } from './cli/commands/InitCommand.js';\nimport { UninstallCommand } from './cli/commands/UninstallCommand.js';\nimport { logger } from './utils/logger.js';\n\n// Initialize dependencies\nconst fs = new FileSystemAdapter();\nconst executor = new ProcessExecutorAdapter();\nconst configLoader = new ConfigLoader(fs);\nconst firstRunDetector = new FirstRunDetector(fs);\nconst setupCommand = new SetupCommand(configLoader);\nconst chatCommand = new ChatCommand(configLoader, firstRunDetector, setupCommand, fs);\nconst initCommand = new InitCommand(fs, configLoader);\nconst uninstallCommand = new UninstallCommand(fs, executor);\n\nconst program = new Command();\n\nprogram.name('mimir').description('Platform-agnostic, BYOK AI coding agent CLI').version('0.1.0');\n\n// Setup wizard\nprogram\n .command('setup')\n .description('Run setup wizard')\n .action(async () => {\n await setupCommand.execute();\n process.exit(0);\n });\n\n// Main interactive chat command\nprogram\n .command('chat', { isDefault: true })\n .description('Start interactive chat session')\n .action(async () => {\n await chatCommand.execute();\n process.exit(0);\n });\n\n// Initialize project\nprogram\n .command('init')\n .description('Initialize Mimir in current project')\n .option('--no-interactive', 'Run without interactive prompts (for automated setup)')\n .option('-q, --quiet', 'Suppress output')\n .action(async (options: { interactive?: boolean; quiet?: boolean }) => {\n await initCommand.execute(undefined, options);\n process.exit(0);\n });\n\n// Uninstall\nprogram\n .command('uninstall')\n .description('Uninstall Mimir from your system')\n .option('-y, --yes', 'Skip confirmation prompts')\n .option('--keep-config', 'Keep configuration directory (~/.mimir)')\n .option('--remove-config', 'Remove configuration directory (~/.mimir)')\n .option('-q, --quiet', 'Suppress output (implies --yes)')\n .action(\n async (options: {\n yes?: boolean;\n keepConfig?: boolean;\n removeConfig?: boolean;\n quiet?: boolean;\n }) => {\n await uninstallCommand.execute(options);\n process.exit(0);\n }\n );\n\n// History management\nconst history = program.command('history').description('Manage conversation history');\n\nhistory\n .command('list')\n .description('List recent conversations')\n .action(() => {\n logger.warn('Listing conversations... (not implemented yet)');\n });\n\nhistory\n .command('resume <id>')\n .description('Resume a conversation')\n .action((id: string) => {\n logger.warn(`Resuming conversation ${id}... (not implemented yet)`);\n });\n\nhistory\n .command('export <id>')\n .description('Export conversation to file')\n .action((id: string) => {\n logger.warn(`Exporting conversation ${id}... (not implemented yet)`);\n });\n\nhistory\n .command('clear')\n .description('Clear conversation history')\n .action(() => {\n logger.warn('Clearing history... (not implemented yet)');\n });\n\n// Cost analytics\nconst cost = program.command('cost').description('View cost analytics');\n\ncost\n .command('today')\n .description(\"Show today's spending\")\n .action(() => {\n logger.warn(\"Fetching today's costs... (not implemented yet)\");\n });\n\ncost\n .command('week')\n .description('Show weekly spending')\n .action(() => {\n logger.warn('Fetching weekly costs... (not implemented yet)');\n });\n\ncost\n .command('month')\n .description('Show monthly spending')\n .action(() => {\n logger.warn('Fetching monthly costs... (not implemented yet)');\n });\n\ncost\n .command('compare')\n .description('Compare provider costs')\n .action(() => {\n logger.warn('Comparing providers... (not implemented yet)');\n });\n\n// Diagnostics\nprogram\n .command('doctor')\n .description('Run diagnostics')\n .action(() => {\n logger.warn('Running diagnostics... (not implemented yet)');\n });\n\n// Permissions management\nconst permissions = program.command('permissions').description('Manage command permissions');\n\npermissions\n .command('list')\n .description('List allowed commands')\n .action(() => {\n logger.warn('Listing permissions... (not implemented yet)');\n });\n\npermissions\n .command('add <pattern>')\n .description('Add command to allowlist')\n .action((pattern: string) => {\n logger.warn(`Adding ${pattern} to allowlist... (not implemented yet)`);\n });\n\npermissions\n .command('remove <pattern>')\n .description('Remove command from allowlist')\n .action((pattern: string) => {\n logger.warn(`Removing ${pattern} from allowlist... (not implemented yet)`);\n });\n\nprogram.parse();\n","/**\n * FileSystemAdapter - Cross-platform file system implementation\n * Uses Node.js fs/promises + fast-glob for file operations\n */\n\nimport { IFileSystem, Stats } from './IFileSystem.js';\nimport fs from 'fs/promises';\nimport fg from 'fast-glob';\n\nexport class FileSystemAdapter implements IFileSystem {\n async readFile(path: string, encoding: BufferEncoding = 'utf-8'): Promise<string> {\n return fs.readFile(path, encoding);\n }\n\n async writeFile(\n path: string,\n content: string,\n encoding: BufferEncoding = 'utf-8'\n ): Promise<void> {\n await fs.writeFile(path, content, encoding);\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n await fs.access(path);\n return true;\n } catch {\n return false;\n }\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n await fs.mkdir(path, options);\n }\n\n async readdir(path: string): Promise<string[]> {\n return fs.readdir(path);\n }\n\n async stat(path: string): Promise<Stats> {\n const stats = await fs.stat(path);\n return {\n isFile: () => stats.isFile(),\n isDirectory: () => stats.isDirectory(),\n size: stats.size,\n mtime: stats.mtime,\n };\n }\n\n async unlink(path: string): Promise<void> {\n await fs.unlink(path);\n }\n\n async rmdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n await fs.rmdir(path, options);\n }\n\n async copyFile(src: string, dest: string): Promise<void> {\n await fs.copyFile(src, dest);\n }\n\n async glob(pattern: string, options?: { cwd?: string; ignore?: string[] }): Promise<string[]> {\n return fg(pattern, {\n cwd: options?.cwd,\n ignore: options?.ignore,\n });\n }\n}\n","/**\n * ProcessExecutorAdapter - Cross-platform process execution implementation\n * Uses execa for reliable cross-platform command execution\n */\n\nimport { IProcessExecutor, ExecOptions, ExecResult } from './IProcessExecutor.js';\nimport { execa, execaCommand } from 'execa';\nimport { ChildProcess } from 'child_process';\n\nexport class ProcessExecutorAdapter implements IProcessExecutor {\n /**\n * Execute command and wait for completion\n */\n async execute(\n command: string,\n args: string[] = [],\n options: ExecOptions = {}\n ): Promise<ExecResult> {\n try {\n const result = await execa(command, args, {\n cwd: options.cwd,\n env: options.env,\n timeout: options.timeout,\n shell: options.shell,\n input: options.input,\n reject: false, // Don't throw on non-zero exit codes\n });\n\n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode ?? (result.failed ? 1 : 0),\n command: result.command,\n timedOut: result.timedOut ?? false,\n };\n } catch (error: any) {\n // Handle execution errors (spawn failures, etc.)\n // For ENOENT errors (command not found), use exit code 127 (standard shell convention)\n // For other errors, use exitCode from error or default to 1\n const exitCode = error.code === 'ENOENT' ? 127 : error.exitCode || 1;\n\n return {\n stdout: error.stdout || '',\n stderr: error.stderr || error.message || String(error),\n exitCode,\n command: error.command || `${command} ${args.join(' ')}`,\n timedOut: error.timedOut ?? false,\n };\n }\n }\n\n /**\n * Spawn process (doesn't wait for completion)\n */\n spawn(command: string, args: string[] = [], options: ExecOptions = {}): ChildProcess {\n const subprocess = execa(command, args, {\n cwd: options.cwd,\n env: options.env,\n timeout: options.timeout,\n shell: options.shell,\n stdin: options.input ? 'pipe' : 'inherit',\n stdout: 'pipe',\n stderr: 'pipe',\n });\n\n // Write input if provided\n if (options.input && subprocess.stdin) {\n subprocess.stdin.write(options.input);\n subprocess.stdin.end();\n }\n\n return subprocess as unknown as ChildProcess;\n }\n\n /**\n * Execute command in shell\n */\n async executeShell(command: string, options: ExecOptions = {}): Promise<ExecResult> {\n try {\n const result = await execaCommand(command, {\n cwd: options.cwd,\n env: options.env,\n timeout: options.timeout,\n shell: true,\n input: options.input,\n reject: false, // Don't throw on non-zero exit codes\n });\n\n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode ?? (result.failed ? 1 : 0),\n command: result.command,\n timedOut: result.timedOut ?? false,\n };\n } catch (error: any) {\n // Handle execution errors (spawn failures, etc.)\n // For ENOENT errors (command not found), use exit code 127 (standard shell convention)\n // For other errors, use exitCode from error or default to 1\n const exitCode = error.code === 'ENOENT' ? 127 : error.exitCode || 1;\n\n return {\n stdout: error.stdout || '',\n stderr: error.stderr || error.message || String(error),\n exitCode,\n command: error.command || command,\n timedOut: error.timedOut ?? false,\n };\n }\n }\n}\n","/**\n * Configuration schemas with Zod validation\n */\n\nimport { z } from 'zod';\n\n// Theme options matching Claude Code + Mimir Nordic theme\nexport const ThemeSchema = z.enum([\n 'mimir',\n 'dark',\n 'light',\n 'dark-colorblind',\n 'light-colorblind',\n 'dark-ansi',\n 'light-ansi',\n]);\n\nexport const UIConfigSchema = z.object({\n theme: ThemeSchema.default('mimir'),\n syntaxHighlighting: z.boolean().default(true),\n showLineNumbers: z.boolean().default(true),\n compactMode: z.boolean().default(false),\n // Autocomplete behavior\n autocompleteAutoShow: z.boolean().default(true), // Automatically show autocomplete when suggestions available\n autocompleteExecuteOnSelect: z.boolean().default(true), // Execute command immediately if no more parameters needed\n});\n\nexport const LLMConfigSchema = z.object({\n provider: z.enum(['deepseek', 'anthropic', 'openai', 'google', 'gemini', 'qwen', 'ollama']),\n model: z.string(),\n apiKey: z.string().optional(),\n baseURL: z.string().optional(),\n temperature: z.number().min(0).max(2).default(0.7),\n maxTokens: z.number().default(4096),\n});\n\nexport const PermissionsConfigSchema = z.object({\n autoAccept: z.boolean().default(false),\n acceptRiskLevel: z.enum(['low', 'medium', 'high', 'critical']).default('medium'),\n alwaysAcceptCommands: z\n .array(z.string())\n .nullable()\n .default([])\n .transform((val) => val ?? []),\n});\n\n// Helper to accept string or array of strings for shortcuts\nconst shortcutSchema = z\n .union([z.string(), z.array(z.string()).min(1)])\n .transform((val) => (Array.isArray(val) ? val : [val]));\n\nexport const KeyBindingsConfigSchema = z.object({\n // Core actions - Ctrl+C and Escape share the same 'interrupt' logic\n interrupt: shortcutSchema.default(['Ctrl+C', 'Escape']),\n accept: shortcutSchema.default(['Enter']),\n\n // Mode and navigation\n modeSwitch: shortcutSchema.default(['Shift+Tab']),\n editCommand: shortcutSchema.default(['Ctrl+E']),\n\n // Autocomplete/tooltips\n showTooltip: shortcutSchema.default(['Ctrl+Space', 'Tab']),\n navigateUp: shortcutSchema.default(['ArrowUp']),\n navigateDown: shortcutSchema.default(['ArrowDown']),\n\n // Utility\n help: shortcutSchema.default(['?']),\n clearScreen: shortcutSchema.default(['Ctrl+L']),\n undo: shortcutSchema.default(['Ctrl+Z']),\n redo: shortcutSchema.default(['Ctrl+Y']), // Auto-converted to Cmd+Shift+Z on Mac\n\n // Legacy/deprecated - kept for backwards compatibility\n reject: shortcutSchema.default([]).optional(),\n});\n\nexport const DockerConfigSchema = z.object({\n enabled: z.boolean().default(true),\n baseImage: z.string().default('alpine:latest'),\n cpuLimit: z.number().optional(),\n memoryLimit: z.string().optional(),\n});\n\nexport const MonitoringConfigSchema = z.object({\n metricsRetentionDays: z.number().min(1).max(365).default(90),\n enableHealthChecks: z.boolean().default(true),\n healthCheckIntervalSeconds: z.number().min(10).max(3600).default(300),\n slowOperationThresholdMs: z.number().min(100).default(5000),\n batchWriteIntervalSeconds: z.number().min(1).max(60).default(10),\n});\n\nexport const BudgetConfigSchema = z.object({\n enabled: z.boolean().default(false),\n dailyLimit: z.number().min(0).optional(), // USD\n weeklyLimit: z.number().min(0).optional(),\n monthlyLimit: z.number().min(0).optional(),\n warningThreshold: z.number().min(0).max(1).default(0.8), // 80%\n});\n\nexport const RateLimitConfigSchema = z.object({\n enabled: z.boolean().default(true),\n commandsPerMinute: z.number().min(1).default(60),\n toolExecutionsPerMinute: z.number().min(1).default(30),\n llmCallsPerMinute: z.number().min(1).default(20),\n maxFileSizeMB: z.number().min(1).default(100),\n});\n\nexport const ConfigSchema = z.object({\n llm: LLMConfigSchema,\n permissions: PermissionsConfigSchema,\n keyBindings: KeyBindingsConfigSchema,\n docker: DockerConfigSchema,\n ui: UIConfigSchema,\n monitoring: MonitoringConfigSchema,\n budget: BudgetConfigSchema,\n rateLimit: RateLimitConfigSchema,\n});\n\nexport type Theme = z.infer<typeof ThemeSchema>;\nexport type UIConfig = z.infer<typeof UIConfigSchema>;\nexport type LLMConfig = z.infer<typeof LLMConfigSchema>;\nexport type PermissionsConfig = z.infer<typeof PermissionsConfigSchema>;\nexport type KeyBindingsConfig = z.infer<typeof KeyBindingsConfigSchema>;\nexport type DockerConfig = z.infer<typeof DockerConfigSchema>;\nexport type MonitoringConfig = z.infer<typeof MonitoringConfigSchema>;\nexport type BudgetConfig = z.infer<typeof BudgetConfigSchema>;\nexport type RateLimitConfig = z.infer<typeof RateLimitConfigSchema>;\nexport type Config = z.infer<typeof ConfigSchema>;\n","/**\n * Logging utility using winston\n */\n\nimport winston from 'winston';\nimport DailyRotateFile from 'winston-daily-rotate-file';\nimport fs from 'fs';\nimport path from 'path';\n\nexport type LogLevel = 'error' | 'warn' | 'info' | 'debug';\n\nexport class Logger {\n private logger: winston.Logger;\n private fileLoggingEnabled = false;\n private consoleTransport: winston.transport;\n\n constructor(logDir = '.mimir/logs') {\n // Resolve to absolute path for clarity\n const absoluteLogDir = path.resolve(process.cwd(), logDir);\n\n // Attempt to create log directory (synchronous to work in constructor)\n // Gracefully degrade to console-only logging if this fails\n try {\n if (!fs.existsSync(absoluteLogDir)) {\n fs.mkdirSync(absoluteLogDir, { recursive: true });\n }\n this.fileLoggingEnabled = true;\n } catch (error) {\n // Degrade gracefully - warn but don't crash\n console.warn(\n `[Logger] Warning: Failed to create log directory at ${absoluteLogDir}. File logging disabled. Error: ${error}`\n );\n this.fileLoggingEnabled = false;\n }\n\n // Build transports array conditionally\n // Create console transport (can be disabled later for Ink UI)\n this.consoleTransport = new winston.transports.Console({\n format: winston.format.combine(winston.format.colorize(), winston.format.simple()),\n });\n\n const transports: winston.transport[] = [this.consoleTransport];\n\n // Only add file transports if directory creation succeeded\n if (this.fileLoggingEnabled) {\n transports.push(\n // Error logs with daily rotation\n new DailyRotateFile({\n dirname: absoluteLogDir,\n filename: '%DATE%-error.log',\n datePattern: 'YYYYMMDD',\n level: 'error',\n maxSize: '10m', // Rotate when file reaches 10MB\n maxFiles: '30d', // Keep logs for 30 days\n zippedArchive: true, // Compress old logs\n }),\n // Combined logs with daily rotation\n new DailyRotateFile({\n dirname: absoluteLogDir,\n filename: '%DATE%.log',\n datePattern: 'YYYYMMDD',\n maxSize: '10m', // Rotate when file reaches 10MB\n maxFiles: '30d', // Keep logs for 30 days\n zippedArchive: true, // Compress old logs\n })\n );\n }\n\n this.logger = winston.createLogger({\n level: process.env.LOG_LEVEL || 'info',\n format: winston.format.combine(\n winston.format.timestamp(),\n winston.format.errors({ stack: true }),\n winston.format.json()\n ),\n transports,\n });\n }\n\n error(message: string, meta?: Record<string, unknown>): void {\n this.logger.error(message, meta);\n }\n\n warn(message: string, meta?: Record<string, unknown>): void {\n this.logger.warn(message, meta);\n }\n\n info(message: string, meta?: Record<string, unknown>): void {\n this.logger.info(message, meta);\n }\n\n debug(message: string, meta?: Record<string, unknown>): void {\n this.logger.debug(message, meta);\n }\n\n /**\n * Disable console logging (useful when Ink UI is active)\n */\n disableConsole(): void {\n this.logger.remove(this.consoleTransport);\n }\n\n /**\n * Enable console logging\n */\n enableConsole(): void {\n if (!this.logger.transports.includes(this.consoleTransport)) {\n this.logger.add(this.consoleTransport);\n }\n }\n}\n\n// Singleton instance\nexport const logger = new Logger();\n","/**\n * Allowlist loader for team-shared command permissions\n * Loads from .mimir/allowlist.yml\n */\n\nimport { IFileSystem } from '../platform/IFileSystem.js';\nimport { logger } from '../utils/logger.js';\nimport yaml from 'yaml';\nimport path from 'path';\nimport { z } from 'zod';\n\n/**\n * Allowlist schema\n */\nexport const AllowlistSchema = z.object({\n // Command patterns that are always allowed\n commands: z.array(z.string()).default([]),\n\n // File patterns that can be modified without confirmation\n files: z.array(z.string()).default([]),\n\n // Network destinations that are allowed\n urls: z.array(z.string()).default([]),\n\n // Environment variables that can be accessed\n envVars: z.array(z.string()).default([]),\n\n // Specific bash commands that are safe\n bashCommands: z.array(z.string()).default([]),\n});\n\nexport type Allowlist = z.infer<typeof AllowlistSchema>;\n\nexport class AllowlistLoader {\n constructor(private fs: IFileSystem) {}\n\n /**\n * Load allowlist from project .mimir/allowlist.yml\n */\n async loadProjectAllowlist(projectRoot: string): Promise<Allowlist | null> {\n const allowlistPath = path.join(projectRoot, '.mimir', 'allowlist.yml');\n return await this.loadAllowlistFile(allowlistPath, 'project');\n }\n\n /**\n * Load allowlist from global ~/.mimir/allowlist.yml\n */\n async loadGlobalAllowlist(): Promise<Allowlist | null> {\n const homeDir = process.env.HOME || process.env.USERPROFILE || '~';\n const allowlistPath = path.join(homeDir, '.mimir', 'allowlist.yml');\n return await this.loadAllowlistFile(allowlistPath, 'global');\n }\n\n /**\n * Load and parse allowlist file\n */\n private async loadAllowlistFile(\n filePath: string,\n scope: 'global' | 'project'\n ): Promise<Allowlist | null> {\n try {\n if (!(await this.fs.exists(filePath))) {\n logger.debug(`No ${scope} allowlist found`, { path: filePath });\n return null;\n }\n\n const content = await this.fs.readFile(filePath);\n const parsed = yaml.parse(content) as unknown;\n\n // Validate schema\n const allowlist = AllowlistSchema.parse(parsed);\n\n logger.info(`Loaded ${scope} allowlist`, {\n path: filePath,\n commands: allowlist.commands.length,\n files: allowlist.files.length,\n urls: allowlist.urls.length,\n });\n\n return allowlist;\n } catch (error) {\n logger.error(`Failed to load ${scope} allowlist`, {\n path: filePath,\n error,\n });\n return null;\n }\n }\n\n /**\n * Merge multiple allowlists (global + project)\n * Project allowlist takes precedence\n */\n merge(global: Allowlist | null, project: Allowlist | null): Allowlist {\n const merged: Allowlist = {\n commands: [],\n files: [],\n urls: [],\n envVars: [],\n bashCommands: [],\n };\n\n // Merge global\n if (global) {\n merged.commands.push(...global.commands);\n merged.files.push(...global.files);\n merged.urls.push(...global.urls);\n merged.envVars.push(...global.envVars);\n merged.bashCommands.push(...global.bashCommands);\n }\n\n // Merge project (deduplicates)\n if (project) {\n // Use Set to deduplicate\n merged.commands = [...new Set([...merged.commands, ...project.commands])];\n merged.files = [...new Set([...merged.files, ...project.files])];\n merged.urls = [...new Set([...merged.urls, ...project.urls])];\n merged.envVars = [...new Set([...merged.envVars, ...project.envVars])];\n merged.bashCommands = [...new Set([...merged.bashCommands, ...project.bashCommands])];\n }\n\n return merged;\n }\n\n /**\n * Create example allowlist file\n */\n async createExample(filePath: string, scope: 'global' | 'project'): Promise<void> {\n const exampleContent = scope === 'global' ? this.getGlobalExample() : this.getProjectExample();\n\n try {\n const dir = path.dirname(filePath);\n if (!(await this.fs.exists(dir))) {\n await this.fs.mkdir(dir, { recursive: true });\n }\n\n await this.fs.writeFile(filePath, exampleContent);\n logger.info(`Created example ${scope} allowlist`, { path: filePath });\n } catch (error) {\n logger.error(`Failed to create example allowlist`, {\n path: filePath,\n error,\n });\n throw error;\n }\n }\n\n /**\n * Get example global allowlist\n */\n private getGlobalExample(): string {\n return `# Global Allowlist\n# Commands, files, and operations that are safe across all projects\n\n# Commands that don't require permission prompt\ncommands:\n - '/status' # Git status\n - '/diff' # Git diff\n - '/help' # Show help\n - '/version' # Show version\n - '/doctor' # System diagnostics\n\n# Safe bash commands\nbashCommands:\n - 'git status'\n - 'git diff'\n - 'git log'\n - 'ls'\n - 'pwd'\n - 'echo *'\n - 'cat *.md'\n\n# Files that can be modified without confirmation (use globs)\nfiles:\n - '**/*.md' # Documentation files\n - '**/*.txt' # Text files\n - '**/README.*' # README files\n\n# URLs that can be accessed without confirmation\nurls:\n - 'https://api.github.com/**'\n - 'https://registry.npmjs.org/**'\n\n# Environment variables that can be read\nenvVars:\n - 'NODE_ENV'\n - 'PATH'\n - 'USER'\n - 'HOME'\n`;\n }\n\n /**\n * Get example project allowlist\n */\n private getProjectExample(): string {\n return `# Project Allowlist\n# Team-shared permissions for this project\n# Commit this file to version control for consistent team experience\n\n# Custom slash commands that are safe to run\ncommands:\n - '/test' # Run test suite\n - '/lint' # Run linter\n - '/build' # Build project\n - '/test-coverage' # Run tests with coverage\n\n# Safe bash commands specific to this project\nbashCommands:\n - 'yarn test'\n - 'yarn lint'\n - 'yarn build'\n - 'npm run test'\n - 'npm run lint'\n\n# Files that can be auto-formatted or modified\nfiles:\n - 'src/**/*.ts' # TypeScript source files\n - 'src/**/*.tsx' # React TypeScript files\n - 'tests/**/*.ts' # Test files\n - '*.json' # JSON config files\n - '.prettierrc.*' # Prettier config\n - '.eslintrc.*' # ESLint config\n\n# API endpoints used by this project\nurls:\n - 'https://api.example.com/**'\n - 'https://staging.example.com/**'\n\n# Environment variables specific to this project\nenvVars:\n - 'API_KEY'\n - 'DATABASE_URL'\n - 'REDIS_URL'\n`;\n }\n}\n","/**\n * Configuration loader with hierarchy support\n * Priority: CLI flags > env vars > project config > global config > defaults\n */\n\nimport { Config, ConfigSchema } from './schemas.js';\nimport { IFileSystem } from '../platform/IFileSystem.js';\nimport { AllowlistLoader, Allowlist } from './AllowlistLoader.js';\nimport yaml from 'yaml';\nimport path from 'path';\nimport os from 'os';\nimport dotenv from 'dotenv';\nimport { logger } from '../utils/logger.js';\n\nexport interface ConfigLoadOptions {\n projectRoot?: string;\n cliFlags?: Partial<Config>;\n}\n\nexport interface ConfigLoadResult {\n config: Config;\n allowlist: Allowlist;\n}\n\nexport class ConfigLoader {\n private allowlistLoader: AllowlistLoader;\n\n constructor(private fs: IFileSystem) {\n this.allowlistLoader = new AllowlistLoader(fs);\n }\n\n /**\n * Load configuration with full hierarchy:\n * 1. Default config\n * 2. Global (~/.mimir/config.yml)\n * 3. Project (.mimir/config.yml)\n * 4. Environment variables (.env)\n * 5. CLI flags\n *\n * Also loads allowlist from:\n * 1. Global (~/.mimir/allowlist.yml)\n * 2. Project (.mimir/allowlist.yml)\n */\n async load(options: ConfigLoadOptions = {}): Promise<ConfigLoadResult> {\n // 1. Start with defaults\n let config = this.getDefaults();\n\n // 2. Load global config\n const globalConfig = await this.loadGlobalConfig();\n if (globalConfig) {\n config = this.merge(config, globalConfig);\n }\n\n // 3. Load project config\n if (options.projectRoot) {\n const projectConfig = await this.loadProjectConfig(options.projectRoot);\n if (projectConfig) {\n config = this.merge(config, projectConfig);\n }\n }\n\n // 4. Load .env file\n const envConfig = this.loadEnvConfig(options.projectRoot);\n if (envConfig) {\n config = this.merge(config, envConfig);\n }\n\n // 5. Apply CLI flags\n if (options.cliFlags) {\n config = this.merge(config, options.cliFlags);\n }\n\n // Validate final config\n const validatedConfig = ConfigSchema.parse(config);\n\n // Load allowlists\n const globalAllowlist = await this.allowlistLoader.loadGlobalAllowlist();\n const projectAllowlist = options.projectRoot\n ? await this.allowlistLoader.loadProjectAllowlist(options.projectRoot)\n : null;\n\n const mergedAllowlist = this.allowlistLoader.merge(globalAllowlist, projectAllowlist);\n\n // Merge allowlist commands with config.yml alwaysAcceptCommands\n if (mergedAllowlist.commands.length > 0) {\n validatedConfig.permissions.alwaysAcceptCommands = [\n ...new Set([\n ...validatedConfig.permissions.alwaysAcceptCommands,\n ...mergedAllowlist.commands,\n ]),\n ];\n }\n\n return {\n config: validatedConfig,\n allowlist: mergedAllowlist,\n };\n }\n\n private getDefaults(): Config {\n // Platform-specific defaults\n const isWindows = process.platform === 'win32';\n\n return {\n llm: {\n provider: 'deepseek',\n model: 'deepseek-chat',\n temperature: 0.7,\n maxTokens: 4096,\n },\n permissions: {\n autoAccept: false,\n acceptRiskLevel: 'medium',\n alwaysAcceptCommands: [],\n },\n keyBindings: {\n interrupt: ['Ctrl+C', 'Escape'],\n accept: ['Enter'],\n modeSwitch: ['Shift+Tab'],\n editCommand: ['Ctrl+E'],\n // Windows: Ctrl+Space is intercepted by terminal - use Tab only\n // macOS/Linux: Both work\n showTooltip: isWindows ? ['Tab'] : ['Ctrl+Space', 'Tab'],\n navigateUp: ['ArrowUp'],\n navigateDown: ['ArrowDown'],\n help: ['?'],\n clearScreen: ['Ctrl+L'],\n undo: ['Ctrl+Z'],\n redo: ['Ctrl+Y'],\n },\n docker: {\n enabled: true,\n baseImage: 'alpine:latest',\n },\n ui: {\n theme: 'mimir',\n syntaxHighlighting: true,\n showLineNumbers: true,\n compactMode: false,\n autocompleteAutoShow: true,\n autocompleteExecuteOnSelect: true,\n },\n monitoring: {\n metricsRetentionDays: 90,\n enableHealthChecks: true,\n healthCheckIntervalSeconds: 300,\n slowOperationThresholdMs: 5000,\n batchWriteIntervalSeconds: 10,\n },\n budget: {\n enabled: false,\n warningThreshold: 0.8,\n },\n rateLimit: {\n enabled: true,\n commandsPerMinute: 60,\n toolExecutionsPerMinute: 30,\n llmCallsPerMinute: 20,\n maxFileSizeMB: 100,\n },\n };\n }\n\n private async loadGlobalConfig(): Promise<Partial<Config> | null> {\n try {\n const configPath = path.join(os.homedir(), '.mimir', 'config.yml');\n if (!(await this.fs.exists(configPath))) {\n return null;\n }\n const content = await this.fs.readFile(configPath);\n return yaml.parse(content) as Partial<Config>;\n } catch (error) {\n logger.warn('Failed to load global config', { error });\n return null;\n }\n }\n\n private async loadProjectConfig(projectRoot: string): Promise<Partial<Config> | null> {\n try {\n const configPath = path.join(projectRoot, '.mimir', 'config.yml');\n if (!(await this.fs.exists(configPath))) {\n return null;\n }\n const content = await this.fs.readFile(configPath);\n return yaml.parse(content) as Partial<Config>;\n } catch (error) {\n logger.warn('Failed to load project config', { error });\n return null;\n }\n }\n\n private loadEnvConfig(projectRoot?: string): Partial<Config> | null {\n try {\n // Load .env from project root if provided, otherwise cwd\n const envPath = projectRoot ? path.join(projectRoot, '.env') : '.env';\n dotenv.config({ path: envPath });\n\n const envConfig: Record<string, unknown> = {};\n\n // Map environment variables to config structure\n if (\n process.env.DEEPSEEK_API_KEY ||\n process.env.ANTHROPIC_API_KEY ||\n process.env.OPENAI_API_KEY\n ) {\n const provider = process.env.LLM_PROVIDER?.toUpperCase();\n const apiKey = provider ? process.env[`${provider}_API_KEY`] : undefined;\n const baseURL = provider ? process.env[`${provider}_BASE_URL`] : undefined;\n\n if (apiKey || baseURL) {\n envConfig.llm = {\n ...(apiKey && { apiKey }),\n ...(baseURL && { baseURL }),\n };\n }\n }\n\n if (process.env.DOCKER_ENABLED) {\n envConfig.docker = {\n enabled: process.env.DOCKER_ENABLED === 'true',\n };\n }\n\n if (process.env.MIMIR_THEME) {\n envConfig.ui = {\n theme: process.env.MIMIR_THEME,\n };\n }\n\n return Object.keys(envConfig).length > 0 ? (envConfig as Partial<Config>) : null;\n } catch (error) {\n logger.warn('Failed to load .env config', { error });\n return null;\n }\n }\n\n private merge(base: Config, override: Partial<Config>): Config {\n return {\n llm: { ...base.llm, ...override.llm },\n permissions: { ...base.permissions, ...override.permissions },\n keyBindings: { ...base.keyBindings, ...override.keyBindings },\n docker: { ...base.docker, ...override.docker },\n ui: { ...base.ui, ...override.ui },\n monitoring: { ...base.monitoring, ...override.monitoring },\n budget: { ...base.budget, ...override.budget },\n rateLimit: { ...base.rateLimit, ...override.rateLimit },\n };\n }\n\n async save(\n config: Partial<Config>,\n scope: 'global' | 'project',\n projectRoot?: string\n ): Promise<void> {\n const configPath =\n scope === 'global'\n ? path.join(os.homedir(), '.mimir', 'config.yml')\n : path.join(projectRoot || process.cwd(), '.mimir', 'config.yml');\n\n const configDir = path.dirname(configPath);\n\n // Ensure directory exists\n if (!(await this.fs.exists(configDir))) {\n await this.fs.mkdir(configDir, { recursive: true });\n }\n\n const yamlContent = yaml.stringify(config);\n await this.fs.writeFile(configPath, yamlContent);\n logger.info(`Config saved to ${configPath}`);\n }\n\n validate(config: unknown): Config {\n return ConfigSchema.parse(config);\n }\n}\n","/**\n * First-run detection utility\n * Checks if this is the first time Mimir is being run (no global config exists)\n */\n\nimport { IFileSystem } from '../../platform/IFileSystem.js';\nimport path from 'path';\nimport os from 'os';\n\nexport class FirstRunDetector {\n constructor(private fs: IFileSystem) {}\n\n async isFirstRun(): Promise<boolean> {\n const globalConfigPath = this.getGlobalConfigPath();\n const exists = await this.fs.exists(globalConfigPath);\n return !exists;\n }\n\n getGlobalConfigPath(): string {\n const homeDir = os.homedir();\n return path.join(homeDir, '.mimir', 'config.yml');\n }\n\n async getGlobalConfigDir(): Promise<string> {\n const homeDir = os.homedir();\n return path.join(homeDir, '.mimir');\n }\n}\n","/**\n * Setup command handler\n * Runs setup wizard and saves configuration\n */\n\nimport React from 'react';\nimport { render } from 'ink';\nimport { SetupWizard } from '../components/SetupWizard.js';\nimport { ConfigLoader } from '../../config/ConfigLoader.js';\nimport { Theme } from '../../config/schemas.js';\nimport { logger } from '../../utils/logger.js';\n\nexport class SetupCommand {\n constructor(private configLoader: ConfigLoader) {}\n\n async execute(): Promise<void> {\n // Enter alternate screen buffer for wizard\n process.stdout.write('\\x1b[?1049h');\n\n // Load current configuration to get keyboard bindings\n const { config } = await this.configLoader.load();\n\n return new Promise((resolve, reject) => {\n const { waitUntilExit, clear } = render(\n React.createElement(SetupWizard, {\n keyBindings: config.keyBindings,\n onComplete: async (theme: Theme): Promise<void> => {\n try {\n // Save configuration to global config\n await this.configLoader.save(\n {\n ui: {\n theme,\n syntaxHighlighting: true,\n showLineNumbers: true,\n compactMode: false,\n autocompleteAutoShow: true,\n autocompleteExecuteOnSelect: true,\n },\n },\n 'global'\n );\n\n logger.info('Setup completed successfully');\n // Exit alternate screen buffer\n process.stdout.write('\\x1b[?1049l');\n setTimeout(() => resolve(), 500); // Brief delay to show completion message\n } catch (error) {\n logger.error('Setup failed', { error });\n // Exit alternate screen buffer on error\n process.stdout.write('\\x1b[?1049l');\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n },\n onCancel: (): void => {\n logger.info('Setup cancelled by user');\n // Exit alternate screen buffer on cancel\n process.stdout.write('\\x1b[?1049l');\n resolve();\n },\n }),\n {\n // Prevent console patching to avoid layout shifts\n patchConsole: false,\n }\n );\n\n // Handle process interruption (Ctrl+C)\n const cleanup = (): void => {\n process.stdout.write('\\x1b[?1049l');\n clear();\n process.exit(0);\n };\n\n process.on('SIGINT', cleanup);\n process.on('SIGTERM', cleanup);\n\n void waitUntilExit().then(() => {\n // Remove cleanup handlers\n process.off('SIGINT', cleanup);\n process.off('SIGTERM', cleanup);\n });\n });\n }\n}\n","/**\n * Setup wizard component\n * Orchestrates first-run setup flow: security warning → theme selection\n */\n\nimport React, { useState } from 'react';\nimport { Box } from 'ink';\nimport { WizardLayout } from './WizardLayout.js';\nimport { SecurityWarning } from './SecurityWarning.js';\nimport { ThemeSelector } from './ThemeSelector.js';\nimport { Theme, KeyBindingsConfig } from '../../config/schemas.js';\n\nexport interface SetupWizardProps {\n onComplete: (theme: Theme) => void | Promise<void>;\n onCancel: () => void;\n keyBindings: KeyBindingsConfig;\n}\n\ntype WizardStep = 'security' | 'theme';\n\nexport const SetupWizard: React.FC<SetupWizardProps> = ({ onComplete, onCancel, keyBindings }) => {\n const [step, setStep] = useState<WizardStep>('security');\n\n const handleSecurityAccept = () => {\n setStep('theme');\n };\n\n const handleThemeSelect = (theme: Theme) => {\n void onComplete(theme);\n };\n\n return (\n <Box flexDirection=\"column\">\n {step === 'security' && (\n <WizardLayout title=\"Welcome to Mimir Code\">\n <SecurityWarning\n onAccept={handleSecurityAccept}\n onCancel={onCancel}\n keyBindings={keyBindings}\n />\n </WizardLayout>\n )}\n {step === 'theme' && (\n <WizardLayout title=\"\">\n <ThemeSelector\n onSelect={handleThemeSelect}\n onCancel={onCancel}\n keyBindings={keyBindings}\n />\n </WizardLayout>\n )}\n </Box>\n );\n};\n","/**\n * Wizard layout component\n * Provides consistent layout with header for wizard steps\n */\n\nimport React from 'react';\nimport { Box, Text } from 'ink';\nimport { WizardHead } from './WizardHead.js';\nimport { MimirColors } from '../theme-colors.js';\n\nexport interface WizardLayoutProps {\n title: string;\n children: React.ReactNode;\n}\n\nexport const WizardLayout: React.FC<WizardLayoutProps> = ({ title, children }) => {\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1}>\n <WizardHead />\n {title && (\n <Box marginBottom={1}>\n <Text color={MimirColors.snowStorm3}>{title}</Text>\n </Box>\n )}\n {children}\n </Box>\n );\n};\n","/**\n * Wizard head ASCII art component\n * Simple wizard icon for use in setup wizard\n */\n\nimport React from 'react';\nimport { Box, Text } from 'ink';\nimport chalk from 'chalk';\nimport { MimirColors } from '../theme-colors.js';\nimport { MIMIR_LOGO } from './logo.js';\n\nexport const WizardHead: React.FC = () => {\n const nordFrost = chalk.hex(MimirColors.frost3);\n\n return (\n <Box flexDirection=\"column\" marginBottom={1} alignItems=\"center\">\n {MIMIR_LOGO.map((line, index) => (\n <Text key={index}>{nordFrost.bold(line)}</Text>\n ))}\n </Box>\n );\n};\n","/**\n * Mimir theme color constants\n * Nordic/cold blue palette for use across the entire CLI\n */\n\nexport const MimirColors = {\n // Polar Night (dark backgrounds)\n polarNight1: '#2E3440',\n polarNight2: '#3B4252',\n polarNight3: '#434C5E',\n polarNight4: '#4C566A',\n\n // Snow Storm (light foregrounds)\n snowStorm1: '#D8DEE9',\n snowStorm2: '#E5E9F0',\n snowStorm3: '#ECEFF4',\n\n // Frost (blues/cyans)\n frost1: '#8FBCBB', // Cyan\n frost2: '#88C0D0', // Bright Cyan\n frost3: '#81A1C1', // Blue\n frost4: '#5E81AC', // Dark Blue\n\n // Aurora (accent colors)\n auroraRed: '#BF616A',\n auroraOrange: '#D08770',\n auroraYellow: '#EBCB8B',\n auroraGreen: '#A3BE8C',\n auroraPurple: '#B48EAD',\n} as const;\n\nexport type MimirColor = (typeof MimirColors)[keyof typeof MimirColors];\n","/**\n * Mimir wizard ASCII art logo\n * Easily editable - each line is a separate string\n */\n\nexport const MIMIR_LOGO = ['▗█▗█▖', '█████', '▜▆█▆▛', ' ▆▅▆ '];\n","/**\n * Security warning component\n * Displays security disclosure on first run\n */\n\nimport React, { useMemo } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport figures from 'figures';\nimport chalk from 'chalk';\nimport { MimirColors } from '../theme-colors.js';\nimport { KeyBindingsConfig } from '../../config/schemas.js';\nimport { formatKeyboardShortcut } from '../../utils/keyboardFormatter.js';\n\nexport interface SecurityWarningProps {\n onAccept: () => void;\n onCancel: () => void;\n keyBindings: KeyBindingsConfig;\n}\n\nexport const SecurityWarning: React.FC<SecurityWarningProps> = ({\n onAccept,\n onCancel,\n keyBindings,\n}) => {\n useInput((_input, key) => {\n if (key.return) {\n onAccept();\n } else if (key.escape) {\n onCancel();\n }\n });\n\n const nordRed = chalk.hex(MimirColors.auroraRed);\n const nordGreen = chalk.hex(MimirColors.auroraGreen);\n\n // Format shortcuts for display\n const acceptShortcut = useMemo(\n () => formatKeyboardShortcut(keyBindings.accept),\n [keyBindings.accept]\n );\n const cancelShortcut = useMemo(\n () => formatKeyboardShortcut(keyBindings.interrupt),\n [keyBindings.interrupt]\n );\n\n return (\n <Box flexDirection=\"column\">\n <Box marginBottom={1}>\n <Text color=\"yellow\" bold>\n {figures.warning} Security Warning\n </Text>\n </Box>\n\n <Box marginBottom={1}>\n <Text>Mimir Code can execute commands and modify files on your system.</Text>\n </Box>\n\n <Box marginBottom={1}>\n <Text dimColor>You'll approve commands before execution via the permission system.</Text>\n </Box>\n\n <Box>\n <Text>\n Press {nordGreen(acceptShortcut)} to continue or {nordRed(cancelShortcut)} to cancel\n </Text>\n </Box>\n </Box>\n );\n};\n","/**\n * Keyboard shortcut formatting utility\n * Converts keyboard shortcuts to user-friendly display format with icons\n */\n\nimport os from 'os';\n\n/**\n * Icon mappings for keyboard keys\n */\nconst KEY_ICONS: Record<string, string> = {\n // Arrow keys\n ArrowUp: '↑',\n ArrowDown: '↓',\n ArrowLeft: '←',\n ArrowRight: '→',\n Up: '↑',\n Down: '↓',\n Left: '←',\n Right: '→',\n\n // Special keys\n Enter: '↵',\n Return: '↵',\n Backspace: '⌫',\n Delete: '⌦',\n Del: '⌦',\n Space: '␣',\n\n // Modifiers\n Shift: '⇧',\n Control: '⌃',\n Ctrl: '⌃',\n Command: '⌘',\n Cmd: '⌘',\n Meta: '⌘',\n};\n\n/**\n * Platform-specific modifier names\n */\nconst PLATFORM_MODIFIERS: Record<string, Record<string, string>> = {\n darwin: {\n Ctrl: 'Cmd',\n Control: 'Command',\n },\n win32: {\n Cmd: 'Ctrl',\n Command: 'Control',\n },\n linux: {\n Cmd: 'Ctrl',\n Command: 'Control',\n },\n};\n\nexport interface KeyboardFormatterOptions {\n /**\n * Use icons instead of text (default: true)\n * When true: ArrowUp → ↑, Enter → ↵, Ctrl → ⌃\n * When false: ArrowUp → Arrow Up, Enter → Enter, Ctrl → Ctrl\n */\n useIcons?: boolean;\n\n /**\n * Use icons for modifiers (default: false)\n * When true: Ctrl+C → ⌃C\n * When false: Ctrl+C → Ctrl+C\n */\n useModifierIcons?: boolean;\n\n /**\n * Platform override (default: current platform)\n * Used to convert Ctrl/Cmd based on platform\n */\n platform?: NodeJS.Platform;\n\n /**\n * Separator for multiple shortcuts (default: ', ')\n * Example: 'Ctrl+C, Escape' vs 'Ctrl+C / Escape'\n */\n separator?: string;\n\n /**\n * Show only first shortcut when multiple are provided (default: false)\n */\n showFirstOnly?: boolean;\n}\n\n/**\n * Normalize key name for consistent formatting\n * Handles case variations and aliases\n */\nfunction normalizeKeyName(key: string): string {\n return key\n .replace(/Control/gi, 'Ctrl')\n .replace(/Command/gi, 'Cmd')\n .replace(/Delete/gi, 'Del')\n .replace(/Escape/gi, 'Esc')\n .split('+')\n .map((part) => part.trim())\n .map((part) => {\n const lower = part.toLowerCase();\n\n // Handle arrow keys with proper casing (case-insensitive input)\n if (lower === 'arrowup' || lower === 'up') return 'ArrowUp';\n if (lower === 'arrowdown' || lower === 'down') return 'ArrowDown';\n if (lower === 'arrowleft' || lower === 'left') return 'ArrowLeft';\n if (lower === 'arrowright' || lower === 'right') return 'ArrowRight';\n\n // Standard case: capitalize first letter\n const normalized = part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();\n\n // Map common aliases\n if (normalized === 'Meta') return 'Cmd';\n if (normalized === 'Option') return 'Alt';\n\n return normalized;\n })\n .join('+');\n}\n\n/**\n * Apply platform-specific modifier conversions\n */\nfunction applyPlatformModifiers(key: string, platform: NodeJS.Platform): string {\n const modifiers = PLATFORM_MODIFIERS[platform] || PLATFORM_MODIFIERS.linux;\n if (!modifiers) return key;\n\n let result = key;\n\n for (const [from, to] of Object.entries(modifiers)) {\n // Replace modifier keys, being careful with word boundaries\n result = result.replace(new RegExp(`\\\\b${from}\\\\b`, 'g'), to);\n }\n\n return result;\n}\n\n/**\n * Format a single keyboard shortcut with icons\n */\nfunction formatSingleShortcut(\n shortcut: string,\n options: Required<KeyboardFormatterOptions>\n): string {\n const { useIcons, useModifierIcons, platform } = options;\n\n // Normalize and apply platform modifiers\n let normalized = normalizeKeyName(shortcut);\n normalized = applyPlatformModifiers(normalized, platform);\n\n // Split into parts (e.g., \"Ctrl+Shift+C\" → [\"Ctrl\", \"Shift\", \"C\"])\n const parts = normalized.split('+').map((p) => p.trim());\n\n // Format each part\n const formatted = parts.map((part, index) => {\n const isModifier = index < parts.length - 1; // All parts except the last are modifiers\n const icon = KEY_ICONS[part];\n\n if (useIcons && icon) {\n // Use icon if available\n if (isModifier && !useModifierIcons) {\n // For modifiers, respect useModifierIcons option\n return part;\n }\n return icon;\n }\n\n // No icon - format as readable text\n if (part.startsWith('Arrow')) {\n // ArrowUp → Up (when not using icons)\n return part.replace('Arrow', '');\n }\n\n return part;\n });\n\n // Join with '+' for modifier combinations, or directly for single keys\n if (formatted.length === 1) {\n return formatted[0] ?? '';\n }\n\n // Join modifiers with '+' or '' depending on whether we're using modifier icons\n if (useModifierIcons && formatted.every((f) => f.length === 1)) {\n // All single chars (icons) - no separator needed (e.g., ⌘⇧C)\n return formatted.join('');\n }\n\n return formatted.join('+');\n}\n\n/**\n * Format keyboard shortcut(s) for display\n *\n * @param shortcuts - Single shortcut string or array of shortcuts\n * @param options - Formatting options\n * @returns Formatted shortcut string\n *\n * @example\n * ```typescript\n * // Single shortcut with icons\n * formatKeyboardShortcut('ArrowUp');\n * // → '↑'\n *\n * // Multiple shortcuts\n * formatKeyboardShortcut(['Ctrl+C', 'Escape']);\n * // → 'Ctrl+C, Esc'\n *\n * // With modifier icons\n * formatKeyboardShortcut('Ctrl+Shift+C', { useModifierIcons: true });\n * // → '⌃⇧C'\n *\n * // Without icons\n * formatKeyboardShortcut('Enter', { useIcons: false });\n * // → 'Enter'\n *\n * // Navigation keys for footer\n * formatKeyboardShortcut(['ArrowUp', 'ArrowDown'], { separator: '/' });\n * // → '↑/↓'\n * ```\n */\nexport function formatKeyboardShortcut(\n shortcuts: string | string[],\n options: KeyboardFormatterOptions = {}\n): string {\n const opts: Required<KeyboardFormatterOptions> = {\n useIcons: options.useIcons ?? true,\n useModifierIcons: options.useModifierIcons ?? false,\n platform: options.platform ?? os.platform(),\n separator: options.separator ?? ', ',\n showFirstOnly: options.showFirstOnly ?? false,\n };\n\n // Handle array of shortcuts\n if (Array.isArray(shortcuts)) {\n if (shortcuts.length === 0) return '';\n if (opts.showFirstOnly) {\n const first = shortcuts[0];\n if (!first) return '';\n return formatSingleShortcut(first, opts);\n }\n return shortcuts.map((s) => formatSingleShortcut(s, opts)).join(opts.separator);\n }\n\n // Single shortcut\n return formatSingleShortcut(shortcuts, opts);\n}\n\n/**\n * Helper for navigation arrows (↑↓)\n * Common pattern in UI footers\n */\nexport function formatNavigationArrows(\n upShortcut: string | string[],\n downShortcut: string | string[],\n options: KeyboardFormatterOptions = {}\n): string {\n const up = formatKeyboardShortcut(upShortcut, { ...options, showFirstOnly: true });\n const down = formatKeyboardShortcut(downShortcut, { ...options, showFirstOnly: true });\n return `${up}${down}`;\n}\n\n/**\n * Helper for building UI footer text with shortcuts\n *\n * @example\n * ```typescript\n * buildFooterText([\n * { shortcut: ['ArrowUp', 'ArrowDown'], label: 'navigate' },\n * { shortcut: 'Enter', label: 'select' },\n * { shortcut: ['Ctrl+C', 'Escape'], label: 'cancel' },\n * ]);\n * // → '↑↓ navigate | Enter select | Ctrl+C, Esc cancel'\n * ```\n */\nexport function buildFooterText(\n items: Array<{ shortcut: string | string[]; label: string }>,\n options: KeyboardFormatterOptions = {}\n): string {\n return items\n .map(({ shortcut, label }) => {\n const formatted = formatKeyboardShortcut(shortcut, options);\n return `${formatted} ${label}`;\n })\n .join(' | ');\n}\n","/**\n * Theme selector component with code preview\n * Allows user to choose from available themes with live preview\n */\n\nimport React, { useState, useMemo } from 'react';\nimport { Box, Text } from 'ink';\nimport SelectInput from 'ink-select-input';\nimport chalk from 'chalk';\nimport { Theme, KeyBindingsConfig } from '../../config/schemas.js';\nimport { getTheme, getAllThemes, getThemeMetadata } from '../../config/themes/index.js';\nimport { getPreviewWithDiff } from '../utils/syntaxHighlight.js';\nimport { buildFooterText } from '../../utils/keyboardFormatter.js';\n\nexport interface ThemeSelectorProps {\n onSelect: (theme: Theme) => void;\n onCancel: () => void;\n keyBindings: KeyBindingsConfig;\n}\n\nexport const ThemeSelector: React.FC<ThemeSelectorProps> = ({\n onSelect,\n onCancel: _onCancel,\n keyBindings,\n}) => {\n const [highlightedIndex, setHighlightedIndex] = useState(0);\n\n // Get all available themes dynamically\n const availableThemes = getAllThemes();\n const items = availableThemes.map((themeKey) => {\n const metadata = getThemeMetadata(themeKey);\n return {\n label: metadata.name,\n value: themeKey,\n };\n });\n\n const currentThemeKey = availableThemes[highlightedIndex];\n if (!currentThemeKey) return null;\n const themeColors = getTheme(currentThemeKey);\n const preview = getPreviewWithDiff();\n\n const bg = chalk.bgHex('#1e1e1e');\n const fg = chalk.hex('#eceff4');\n\n // Build footer text from keyboard shortcuts\n const footerText = useMemo(() => {\n const navUp = keyBindings.navigateUp[0] ?? 'ArrowUp';\n const navDown = keyBindings.navigateDown[0] ?? 'ArrowDown';\n return buildFooterText([\n { shortcut: [navUp, navDown], label: 'navigate' },\n { shortcut: keyBindings.accept ?? 'Enter', label: 'select' },\n { shortcut: keyBindings.interrupt ?? 'Escape', label: 'cancel' },\n ]);\n }, [keyBindings]);\n\n return (\n <Box flexDirection=\"column\">\n <Text>{bg(fg.bold(' Select your theme: '))}</Text>\n <Text>{bg(' ')}</Text>\n\n <Box flexDirection=\"column\">\n <SelectInput\n items={items}\n onSelect={(item) => onSelect(item.value)}\n onHighlight={(item) => {\n const index = availableThemes.findIndex((t) => t === item.value);\n if (index !== -1) setHighlightedIndex(index);\n }}\n />\n </Box>\n\n <Text>{bg(' ')}</Text>\n <Text>{bg(fg(' Preview: '))}</Text>\n {preview.map((item, idx) => (\n <Text key={idx}>\n {item.type === 'remove' && bg(themeColors.colors.diffRemoveLine(`- ${item.line}`))}\n {item.type === 'add' && bg(themeColors.colors.diffAddLine(`+ ${item.line}`))}\n {item.type === 'normal' &&\n bg(\n fg(\n ` ${themeColors.colors.keyword(item.line.match(/return/)?.[0] || '')}${item.line.replace(/return/, '')}`\n )\n )}\n </Text>\n ))}\n <Text>{bg(' ')}</Text>\n\n <Text>{bg(chalk.dim(` ${footerText} `))}</Text>\n </Box>\n );\n};\n","/**\n * Theme JSON schema and parser\n * Converts JSON theme definitions to chalk-based themes\n */\n\nimport chalk from 'chalk';\nimport type { ThemeDefinition, ThemeColors } from './index.js';\n\nexport interface ThemeColorJSON {\n fg?: string; // Foreground color (hex)\n bg?: string; // Background color (hex)\n bold?: boolean;\n dim?: boolean;\n italic?: boolean;\n underline?: boolean;\n}\n\nexport interface ThemeJSON {\n name: string;\n supportsFullColor: boolean;\n colors: {\n // UI Elements\n headerBg: ThemeColorJSON;\n headerText: ThemeColorJSON;\n footerBg: ThemeColorJSON;\n footerText: ThemeColorJSON;\n inputPrompt: ThemeColorJSON;\n inputText: ThemeColorJSON;\n autocompleteBg: ThemeColorJSON;\n\n // Autocomplete specific\n autocompleteText: ThemeColorJSON;\n autocompleteSelectedBg: ThemeColorJSON;\n autocompleteSelectedText: ThemeColorJSON;\n autocompleteHeaderText: ThemeColorJSON;\n autocompleteFooterText: ThemeColorJSON;\n autocompleteMoreIndicator: ThemeColorJSON;\n\n // Mode indicators\n modePlan: ThemeColorJSON;\n modeAct: ThemeColorJSON;\n modeDiscuss: ThemeColorJSON;\n\n // Message roles\n userMessage: ThemeColorJSON;\n assistantMessage: ThemeColorJSON;\n systemMessage: ThemeColorJSON;\n\n // Syntax highlighting\n keyword: ThemeColorJSON;\n string: ThemeColorJSON;\n number: ThemeColorJSON;\n comment: ThemeColorJSON;\n function: ThemeColorJSON;\n variable: ThemeColorJSON;\n\n // Status indicators\n success: ThemeColorJSON;\n warning: ThemeColorJSON;\n error: ThemeColorJSON;\n info: ThemeColorJSON;\n\n // Diff colors\n diffAddLine: ThemeColorJSON;\n diffRemoveLine: ThemeColorJSON;\n };\n}\n\n/**\n * Parse a JSON theme color definition into a chalk instance\n */\nfunction parseColor(color: ThemeColorJSON): typeof chalk {\n let result = chalk;\n\n if (color.bg) {\n result = result.bgHex(color.bg);\n }\n if (color.fg) {\n result = result.hex(color.fg);\n }\n if (color.bold) {\n result = result.bold;\n }\n if (color.dim) {\n result = result.dim;\n }\n if (color.italic) {\n result = result.italic;\n }\n if (color.underline) {\n result = result.underline;\n }\n\n return result;\n}\n\n/**\n * Convert a JSON theme definition to a ThemeDefinition\n */\nexport function parseThemeJSON(json: ThemeJSON): ThemeDefinition {\n const colors: ThemeColors = {\n headerBg: parseColor(json.colors.headerBg),\n headerText: parseColor(json.colors.headerText),\n footerBg: parseColor(json.colors.footerBg),\n footerText: parseColor(json.colors.footerText),\n inputPrompt: parseColor(json.colors.inputPrompt),\n inputText: parseColor(json.colors.inputText),\n autocompleteBg: parseColor(json.colors.autocompleteBg),\n\n autocompleteText: parseColor(json.colors.autocompleteText),\n autocompleteSelectedBg: parseColor(json.colors.autocompleteSelectedBg),\n autocompleteSelectedText: parseColor(json.colors.autocompleteSelectedText),\n autocompleteHeaderText: parseColor(json.colors.autocompleteHeaderText),\n autocompleteFooterText: parseColor(json.colors.autocompleteFooterText),\n autocompleteMoreIndicator: parseColor(json.colors.autocompleteMoreIndicator),\n\n modePlan: parseColor(json.colors.modePlan),\n modeAct: parseColor(json.colors.modeAct),\n modeDiscuss: parseColor(json.colors.modeDiscuss),\n\n userMessage: parseColor(json.colors.userMessage),\n assistantMessage: parseColor(json.colors.assistantMessage),\n systemMessage: parseColor(json.colors.systemMessage),\n\n keyword: parseColor(json.colors.keyword),\n string: parseColor(json.colors.string),\n number: parseColor(json.colors.number),\n comment: parseColor(json.colors.comment),\n function: parseColor(json.colors.function),\n variable: parseColor(json.colors.variable),\n\n success: parseColor(json.colors.success),\n warning: parseColor(json.colors.warning),\n error: parseColor(json.colors.error),\n info: parseColor(json.colors.info),\n\n diffAddLine: parseColor(json.colors.diffAddLine),\n diffRemoveLine: parseColor(json.colors.diffRemoveLine),\n };\n\n return {\n name: json.name,\n colors,\n supportsFullColor: json.supportsFullColor,\n rawColors: {\n autocompleteBg: json.colors.autocompleteBg.bg,\n autocompleteSelectedBg: json.colors.autocompleteSelectedBg.bg,\n },\n };\n}\n","{\n \"name\": \"Mimir\",\n \"supportsFullColor\": true,\n \"colors\": {\n \"headerBg\": { \"bg\": \"#2E3440\", \"fg\": \"#ECEFF4\" },\n \"headerText\": { \"fg\": \"#D8DEE9\" },\n \"footerBg\": { \"bg\": \"#3B4252\" },\n \"footerText\": { \"fg\": \"#4C566A\" },\n \"inputPrompt\": { \"fg\": \"#88C0D0\" },\n \"inputText\": { \"fg\": \"#ECEFF4\" },\n \"autocompleteBg\": { \"bg\": \"#3B4252\" },\n\n \"autocompleteText\": { \"fg\": \"#ECEFF4\" },\n \"autocompleteSelectedBg\": { \"bg\": \"#88C0D0\", \"fg\": \"#2E3440\" },\n \"autocompleteSelectedText\": { \"fg\": \"#2E3440\" },\n \"autocompleteHeaderText\": { \"fg\": \"#88C0D0\", \"bold\": true },\n \"autocompleteFooterText\": { \"fg\": \"#616E88\" },\n \"autocompleteMoreIndicator\": { \"fg\": \"#616E88\" },\n\n \"modePlan\": { \"fg\": \"#5E81AC\" },\n \"modeAct\": { \"fg\": \"#A3BE8C\" },\n \"modeDiscuss\": { \"fg\": \"#B48EAD\" },\n\n \"userMessage\": { \"fg\": \"#8FBCBB\" },\n \"assistantMessage\": { \"fg\": \"#81A1C1\" },\n \"systemMessage\": { \"fg\": \"#5E81AC\" },\n\n \"keyword\": { \"fg\": \"#81A1C1\" },\n \"string\": { \"fg\": \"#A3BE8C\" },\n \"number\": { \"fg\": \"#B48EAD\" },\n \"comment\": { \"fg\": \"#616E88\" },\n \"function\": { \"fg\": \"#88C0D0\" },\n \"variable\": { \"fg\": \"#D8DEE9\" },\n\n \"success\": { \"fg\": \"#A3BE8C\" },\n \"warning\": { \"fg\": \"#EBCB8B\" },\n \"error\": { \"fg\": \"#BF616A\" },\n \"info\": { \"fg\": \"#88C0D0\" },\n\n \"diffAddLine\": { \"bg\": \"#A3BE8C\", \"fg\": \"#FFFFFF\" },\n \"diffRemoveLine\": { \"bg\": \"#D08770\", \"fg\": \"#FFFFFF\" }\n }\n}\n","{\n \"name\": \"Dark\",\n \"supportsFullColor\": true,\n \"colors\": {\n \"headerBg\": { \"bg\": \"#1a1a1a\", \"fg\": \"#ffffff\" },\n \"headerText\": { \"fg\": \"#e0e0e0\" },\n \"footerBg\": { \"bg\": \"#2d2d2d\" },\n \"footerText\": { \"fg\": \"#888888\" },\n \"inputPrompt\": { \"fg\": \"#00d4ff\" },\n \"inputText\": { \"fg\": \"#ffffff\" },\n \"autocompleteBg\": { \"bg\": \"#2d2d2d\" },\n\n \"autocompleteText\": { \"fg\": \"#ffffff\" },\n \"autocompleteSelectedBg\": { \"bg\": \"#00d4ff\", \"fg\": \"#000000\" },\n \"autocompleteSelectedText\": { \"fg\": \"#000000\" },\n \"autocompleteHeaderText\": { \"fg\": \"#00d4ff\", \"bold\": true },\n \"autocompleteFooterText\": { \"fg\": \"#666666\" },\n \"autocompleteMoreIndicator\": { \"fg\": \"#666666\" },\n\n \"modePlan\": { \"fg\": \"#2196F3\" },\n \"modeAct\": { \"fg\": \"#4CAF50\" },\n \"modeDiscuss\": { \"fg\": \"#C792EA\" },\n\n \"userMessage\": { \"fg\": \"#4CAF50\" },\n \"assistantMessage\": { \"fg\": \"#2196F3\" },\n \"systemMessage\": { \"fg\": \"#FF9800\" },\n\n \"keyword\": { \"fg\": \"#C792EA\" },\n \"string\": { \"fg\": \"#C3E88D\" },\n \"number\": { \"fg\": \"#F78C6C\" },\n \"comment\": { \"fg\": \"#546E7A\" },\n \"function\": { \"fg\": \"#82AAFF\" },\n \"variable\": { \"fg\": \"#EEFFFF\" },\n\n \"success\": { \"fg\": \"#4CAF50\" },\n \"warning\": { \"fg\": \"#FFC107\" },\n \"error\": { \"fg\": \"#F44336\" },\n \"info\": { \"fg\": \"#2196F3\" },\n\n \"diffAddLine\": { \"bg\": \"#22863a\", \"fg\": \"#ffffff\" },\n \"diffRemoveLine\": { \"bg\": \"#cb2431\", \"fg\": \"#ffffff\" }\n }\n}\n","{\n \"name\": \"Light\",\n \"supportsFullColor\": true,\n \"colors\": {\n \"headerBg\": { \"bg\": \"#f5f5f5\", \"fg\": \"#000000\" },\n \"headerText\": { \"fg\": \"#424242\" },\n \"footerBg\": { \"bg\": \"#e0e0e0\" },\n \"footerText\": { \"fg\": \"#757575\" },\n \"inputPrompt\": { \"fg\": \"#0288D1\" },\n \"inputText\": { \"fg\": \"#212121\" },\n \"autocompleteBg\": { \"bg\": \"#e0e0e0\" },\n\n \"autocompleteText\": { \"fg\": \"#212121\" },\n \"autocompleteSelectedBg\": { \"bg\": \"#0288D1\", \"fg\": \"#ffffff\" },\n \"autocompleteSelectedText\": { \"fg\": \"#ffffff\" },\n \"autocompleteHeaderText\": { \"fg\": \"#0288D1\", \"bold\": true },\n \"autocompleteFooterText\": { \"fg\": \"#9E9E9E\" },\n \"autocompleteMoreIndicator\": { \"fg\": \"#9E9E9E\" },\n\n \"modePlan\": { \"fg\": \"#1565C0\" },\n \"modeAct\": { \"fg\": \"#2E7D32\" },\n \"modeDiscuss\": { \"fg\": \"#7B1FA2\" },\n\n \"userMessage\": { \"fg\": \"#2E7D32\" },\n \"assistantMessage\": { \"fg\": \"#1565C0\" },\n \"systemMessage\": { \"fg\": \"#EF6C00\" },\n\n \"keyword\": { \"fg\": \"#7B1FA2\" },\n \"string\": { \"fg\": \"#558B2F\" },\n \"number\": { \"fg\": \"#D84315\" },\n \"comment\": { \"fg\": \"#9E9E9E\" },\n \"function\": { \"fg\": \"#1976D2\" },\n \"variable\": { \"fg\": \"#424242\" },\n\n \"success\": { \"fg\": \"#2E7D32\" },\n \"warning\": { \"fg\": \"#F57C00\" },\n \"error\": { \"fg\": \"#C62828\" },\n \"info\": { \"fg\": \"#1565C0\" },\n\n \"diffAddLine\": { \"bg\": \"#d1f4d1\", \"fg\": \"#000000\" },\n \"diffRemoveLine\": { \"bg\": \"#ffeef0\", \"fg\": \"#000000\" }\n }\n}\n","{\n \"name\": \"Dark Colorblind\",\n \"supportsFullColor\": true,\n \"colors\": {\n \"headerBg\": { \"bg\": \"#1a1a1a\", \"fg\": \"#ffffff\" },\n \"headerText\": { \"fg\": \"#e0e0e0\" },\n \"footerBg\": { \"bg\": \"#2d2d2d\" },\n \"footerText\": { \"fg\": \"#888888\" },\n \"inputPrompt\": { \"fg\": \"#64B5F6\" },\n \"inputText\": { \"fg\": \"#ffffff\" },\n \"autocompleteBg\": { \"bg\": \"#2d2d2d\" },\n\n \"autocompleteText\": { \"fg\": \"#ffffff\" },\n \"autocompleteSelectedBg\": { \"bg\": \"#64B5F6\", \"fg\": \"#000000\" },\n \"autocompleteSelectedText\": { \"fg\": \"#000000\" },\n \"autocompleteHeaderText\": { \"fg\": \"#64B5F6\", \"bold\": true },\n \"autocompleteFooterText\": { \"fg\": \"#757575\" },\n \"autocompleteMoreIndicator\": { \"fg\": \"#757575\" },\n\n \"modePlan\": { \"fg\": \"#64B5F6\" },\n \"modeAct\": { \"fg\": \"#81C784\" },\n \"modeDiscuss\": { \"fg\": \"#9575CD\" },\n\n \"userMessage\": { \"fg\": \"#64B5F6\" },\n \"assistantMessage\": { \"fg\": \"#FFB74D\" },\n \"systemMessage\": { \"fg\": \"#9575CD\" },\n\n \"keyword\": { \"fg\": \"#E1BEE7\" },\n \"string\": { \"fg\": \"#FFE082\" },\n \"number\": { \"fg\": \"#FFAB91\" },\n \"comment\": { \"fg\": \"#757575\" },\n \"function\": { \"fg\": \"#90CAF9\" },\n \"variable\": { \"fg\": \"#E0E0E0\" },\n\n \"success\": { \"fg\": \"#81C784\" },\n \"warning\": { \"fg\": \"#FFB74D\" },\n \"error\": { \"fg\": \"#E57373\" },\n \"info\": { \"fg\": \"#64B5F6\" },\n\n \"diffAddLine\": { \"bg\": \"#1976D2\", \"fg\": \"#ffffff\" },\n \"diffRemoveLine\": { \"bg\": \"#EF6C00\", \"fg\": \"#ffffff\" }\n }\n}\n","{\n \"name\": \"Light Colorblind\",\n \"supportsFullColor\": true,\n \"colors\": {\n \"headerBg\": { \"bg\": \"#f5f5f5\", \"fg\": \"#000000\" },\n \"headerText\": { \"fg\": \"#424242\" },\n \"footerBg\": { \"bg\": \"#e0e0e0\" },\n \"footerText\": { \"fg\": \"#757575\" },\n \"inputPrompt\": { \"fg\": \"#1976D2\" },\n \"inputText\": { \"fg\": \"#212121\" },\n \"autocompleteBg\": { \"bg\": \"#e0e0e0\" },\n\n \"autocompleteText\": { \"fg\": \"#212121\" },\n \"autocompleteSelectedBg\": { \"bg\": \"#1976D2\", \"fg\": \"#ffffff\" },\n \"autocompleteSelectedText\": { \"fg\": \"#ffffff\" },\n \"autocompleteHeaderText\": { \"fg\": \"#1976D2\", \"bold\": true },\n \"autocompleteFooterText\": { \"fg\": \"#9E9E9E\" },\n \"autocompleteMoreIndicator\": { \"fg\": \"#9E9E9E\" },\n\n \"modePlan\": { \"fg\": \"#1976D2\" },\n \"modeAct\": { \"fg\": \"#388E3C\" },\n \"modeDiscuss\": { \"fg\": \"#7B1FA2\" },\n\n \"userMessage\": { \"fg\": \"#1976D2\" },\n \"assistantMessage\": { \"fg\": \"#F57C00\" },\n \"systemMessage\": { \"fg\": \"#7B1FA2\" },\n\n \"keyword\": { \"fg\": \"#8E24AA\" },\n \"string\": { \"fg\": \"#F9A825\" },\n \"number\": { \"fg\": \"#D84315\" },\n \"comment\": { \"fg\": \"#9E9E9E\" },\n \"function\": { \"fg\": \"#1565C0\" },\n \"variable\": { \"fg\": \"#424242\" },\n\n \"success\": { \"fg\": \"#388E3C\" },\n \"warning\": { \"fg\": \"#F57C00\" },\n \"error\": { \"fg\": \"#D32F2F\" },\n \"info\": { \"fg\": \"#1976D2\" },\n\n \"diffAddLine\": { \"bg\": \"#BBDEFB\", \"fg\": \"#000000\" },\n \"diffRemoveLine\": { \"bg\": \"#FFE0B2\", \"fg\": \"#000000\" }\n }\n}\n","{\n \"name\": \"Dark ANSI\",\n \"supportsFullColor\": false,\n \"colors\": {\n \"headerBg\": { \"bg\": \"#000000\", \"fg\": \"#FFFFFF\" },\n \"headerText\": { \"fg\": \"#FFFFFF\" },\n \"footerBg\": { \"bg\": \"#000000\" },\n \"footerText\": { \"fg\": \"#808080\" },\n \"inputPrompt\": { \"fg\": \"#00FFFF\" },\n \"inputText\": { \"fg\": \"#FFFFFF\" },\n \"autocompleteBg\": { \"bg\": \"#000000\" },\n\n \"autocompleteText\": { \"fg\": \"#FFFFFF\" },\n \"autocompleteSelectedBg\": { \"bg\": \"#00FFFF\", \"fg\": \"#000000\" },\n \"autocompleteSelectedText\": { \"fg\": \"#000000\" },\n \"autocompleteHeaderText\": { \"fg\": \"#00FFFF\", \"bold\": true },\n \"autocompleteFooterText\": { \"fg\": \"#808080\" },\n \"autocompleteMoreIndicator\": { \"fg\": \"#808080\" },\n\n \"modePlan\": { \"fg\": \"#0000FF\" },\n \"modeAct\": { \"fg\": \"#00FF00\" },\n \"modeDiscuss\": { \"fg\": \"#FF00FF\" },\n\n \"userMessage\": { \"fg\": \"#00FF00\" },\n \"assistantMessage\": { \"fg\": \"#0000FF\" },\n \"systemMessage\": { \"fg\": \"#FFFF00\" },\n\n \"keyword\": { \"fg\": \"#FF00FF\" },\n \"string\": { \"fg\": \"#00FF00\" },\n \"number\": { \"fg\": \"#FF0000\" },\n \"comment\": { \"fg\": \"#808080\" },\n \"function\": { \"fg\": \"#0000FF\" },\n \"variable\": { \"fg\": \"#FFFFFF\" },\n\n \"success\": { \"fg\": \"#00FF00\" },\n \"warning\": { \"fg\": \"#FFFF00\" },\n \"error\": { \"fg\": \"#FF0000\" },\n \"info\": { \"fg\": \"#0000FF\" },\n\n \"diffAddLine\": { \"bg\": \"#008000\", \"fg\": \"#FFFFFF\" },\n \"diffRemoveLine\": { \"bg\": \"#800000\", \"fg\": \"#FFFFFF\" }\n }\n}\n","{\n \"name\": \"Light ANSI\",\n \"supportsFullColor\": false,\n \"colors\": {\n \"headerBg\": { \"bg\": \"#FFFFFF\", \"fg\": \"#000000\" },\n \"headerText\": { \"fg\": \"#000000\" },\n \"footerBg\": { \"bg\": \"#FFFFFF\" },\n \"footerText\": { \"fg\": \"#808080\" },\n \"inputPrompt\": { \"fg\": \"#0000FF\" },\n \"inputText\": { \"fg\": \"#000000\" },\n \"autocompleteBg\": { \"bg\": \"#FFFFFF\" },\n\n \"autocompleteText\": { \"fg\": \"#000000\" },\n \"autocompleteSelectedBg\": { \"bg\": \"#0000FF\", \"fg\": \"#FFFFFF\" },\n \"autocompleteSelectedText\": { \"fg\": \"#FFFFFF\" },\n \"autocompleteHeaderText\": { \"fg\": \"#0000FF\", \"bold\": true },\n \"autocompleteFooterText\": { \"fg\": \"#808080\" },\n \"autocompleteMoreIndicator\": { \"fg\": \"#808080\" },\n\n \"modePlan\": { \"fg\": \"#0000FF\" },\n \"modeAct\": { \"fg\": \"#00FF00\" },\n \"modeDiscuss\": { \"fg\": \"#FF00FF\" },\n\n \"userMessage\": { \"fg\": \"#00FF00\" },\n \"assistantMessage\": { \"fg\": \"#0000FF\" },\n \"systemMessage\": { \"fg\": \"#FFFF00\" },\n\n \"keyword\": { \"fg\": \"#FF00FF\" },\n \"string\": { \"fg\": \"#00FF00\" },\n \"number\": { \"fg\": \"#FF0000\" },\n \"comment\": { \"fg\": \"#808080\" },\n \"function\": { \"fg\": \"#0000FF\" },\n \"variable\": { \"fg\": \"#000000\" },\n\n \"success\": { \"fg\": \"#00FF00\" },\n \"warning\": { \"fg\": \"#FFFF00\" },\n \"error\": { \"fg\": \"#FF0000\" },\n \"info\": { \"fg\": \"#0000FF\" },\n\n \"diffAddLine\": { \"bg\": \"#90EE90\", \"fg\": \"#000000\" },\n \"diffRemoveLine\": { \"bg\": \"#FFB6C1\", \"fg\": \"#000000\" }\n }\n}\n","/**\n * Theme registry and definitions\n */\n\nimport { Theme } from '../schemas.js';\nimport chalk from 'chalk';\n\nexport interface ThemeColors {\n // UI Elements\n headerBg: typeof chalk;\n headerText: typeof chalk;\n footerBg: typeof chalk;\n footerText: typeof chalk;\n inputPrompt: typeof chalk;\n inputText: typeof chalk;\n autocompleteBg: typeof chalk;\n\n // Autocomplete specific\n autocompleteText: typeof chalk;\n autocompleteSelectedBg: typeof chalk;\n autocompleteSelectedText: typeof chalk;\n autocompleteHeaderText: typeof chalk;\n autocompleteFooterText: typeof chalk;\n autocompleteMoreIndicator: typeof chalk;\n\n // Mode indicators\n modePlan: typeof chalk;\n modeAct: typeof chalk;\n modeDiscuss: typeof chalk;\n\n // Message roles\n userMessage: typeof chalk;\n assistantMessage: typeof chalk;\n systemMessage: typeof chalk;\n\n // Syntax highlighting\n keyword: typeof chalk;\n string: typeof chalk;\n number: typeof chalk;\n comment: typeof chalk;\n function: typeof chalk;\n variable: typeof chalk;\n\n // Status indicators\n success: typeof chalk;\n warning: typeof chalk;\n error: typeof chalk;\n info: typeof chalk;\n\n // Diff colors\n diffAddLine: typeof chalk;\n diffRemoveLine: typeof chalk;\n}\n\nexport interface ThemeDefinition {\n name: string;\n colors: ThemeColors;\n supportsFullColor: boolean; // true for 24-bit, false for ANSI-only\n rawColors: {\n autocompleteBg?: string; // Raw hex color for components that need it\n autocompleteSelectedBg?: string; // Raw hex color for selected autocomplete item\n };\n}\n\n// Theme registry\nconst themes = new Map<Theme, ThemeDefinition>();\n\nexport function registerTheme(theme: Theme, definition: ThemeDefinition): void {\n themes.set(theme, definition);\n}\n\nexport function getTheme(theme: Theme): ThemeDefinition {\n const definition = themes.get(theme);\n if (!definition) {\n throw new Error(`Theme ${theme} not found`);\n }\n return definition;\n}\n\nexport function getAllThemes(): Theme[] {\n return Array.from(themes.keys());\n}\n\nexport function getThemeMetadata(theme: Theme): { name: string } {\n const definition = getTheme(theme);\n return {\n name: definition.name,\n };\n}\n\n// Initialize all themes from JSON dynamically\nimport { parseThemeJSON, ThemeJSON } from './theme-schema.js';\nimport mimirJSON from './definitions/mimir.json' assert { type: 'json' };\nimport darkJSON from './definitions/dark.json' assert { type: 'json' };\nimport lightJSON from './definitions/light.json' assert { type: 'json' };\nimport darkColorblindJSON from './definitions/dark-colorblind.json' assert { type: 'json' };\nimport lightColorblindJSON from './definitions/light-colorblind.json' assert { type: 'json' };\nimport darkAnsiJSON from './definitions/dark-ansi.json' assert { type: 'json' };\nimport lightAnsiJSON from './definitions/light-ansi.json' assert { type: 'json' };\n\n// Map of theme key to JSON\nconst themeDefinitions: Record<string, ThemeJSON> = {\n mimir: mimirJSON as ThemeJSON,\n dark: darkJSON as ThemeJSON,\n light: lightJSON as ThemeJSON,\n 'dark-colorblind': darkColorblindJSON as ThemeJSON,\n 'light-colorblind': lightColorblindJSON as ThemeJSON,\n 'dark-ansi': darkAnsiJSON as ThemeJSON,\n 'light-ansi': lightAnsiJSON as ThemeJSON,\n};\n\n// Register all themes\nObject.entries(themeDefinitions).forEach(([key, json]) => {\n registerTheme(key as Theme, parseThemeJSON(json));\n});\n","/**\n * Syntax highlighting utility\n * Highlights code snippets using theme colors\n */\n\nimport { ThemeColors } from '../../config/themes/index.js';\n\nexport interface HighlightedToken {\n text: string;\n color: typeof import('chalk');\n}\n\n/**\n * Simple regex-based syntax highlighter for TypeScript/JavaScript\n */\nexport function highlightCode(code: string, themeColors: ThemeColors): string {\n let result = code;\n\n // Keywords\n const keywords =\n /\\b(const|let|var|function|class|interface|type|export|import|from|return|if|else|for|while|async|await|new|this|extends|implements)\\b/g;\n result = result.replace(keywords, (match) => themeColors.keyword(match));\n\n // Strings (both single and double quotes)\n const strings = /(['\"`])(?:(?=(\\\\?))\\2.)*?\\1/g;\n result = result.replace(strings, (match) => themeColors.string(match));\n\n // Numbers\n const numbers = /\\b\\d+(\\.\\d+)?\\b/g;\n result = result.replace(numbers, (match) => themeColors.number(match));\n\n // Comments\n const comments = /\\/\\/.*$/gm;\n result = result.replace(comments, (match) => themeColors.comment(match));\n\n // Function calls\n const functionCalls = /\\b([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*\\(/g;\n result = result.replace(functionCalls, (_match, name) => themeColors.function(name) + '(');\n\n return result;\n}\n\n/**\n * Get sample code for theme preview (hacker news meme with inline diff)\n */\nexport function getPreviewWithDiff(): Array<{ type: 'add' | 'remove' | 'normal'; line: string }> {\n return [\n { type: 'remove', line: 'function getRandomNumber() {' },\n { type: 'add', line: 'function getRandomNumber(): number {' },\n { type: 'normal', line: ' return 4;' },\n { type: 'normal', line: '}' },\n ];\n}\n","/**\n * Chat command handler\n * Main interactive chat session\n */\n\nimport React from 'react';\nimport { render } from 'ink';\nimport { ChatApp } from '../components/ChatApp.js';\nimport { ConfigLoader } from '../../config/ConfigLoader.js';\nimport { Config, Theme as ThemeType } from '../../config/schemas.js';\nimport { FirstRunDetector } from '../utils/firstRunDetector.js';\nimport { SetupCommand } from './SetupCommand.js';\nimport { IFileSystem } from '../../platform/IFileSystem.js';\nimport { Message } from '../../types/index.js';\nimport { logger } from '../../utils/logger.js';\nimport { SlashCommandRegistry } from '../../core/SlashCommand.js';\nimport { CustomCommandLoader } from '../../core/CustomCommandLoader.js';\nimport { SlashCommandParser } from '../../core/SlashCommandParser.js';\nimport { installSignalHandlers } from '../utils/signalHandler.js';\nimport {\n NewCommand,\n ModelCommand,\n ModeCommand,\n HelpCommand,\n ThemeCommand,\n} from './slashCommands/index.js';\nimport { MimirInitializer } from '../../core/MimirInitializer.js';\nimport { ProviderFactory } from '../../providers/ProviderFactory.js';\nimport { ILLMProvider } from '../../providers/ILLMProvider.js';\nimport { ConfigurationError } from '../../utils/errors.js';\nimport path from 'path';\nimport yaml from 'yaml';\n\nexport class ChatCommand {\n private commandRegistry: SlashCommandRegistry;\n\n constructor(\n private configLoader: ConfigLoader,\n private firstRunDetector: FirstRunDetector,\n private setupCommand: SetupCommand,\n private fs: IFileSystem\n ) {\n this.commandRegistry = new SlashCommandRegistry();\n }\n\n private async initializeCommands(projectRoot: string): Promise<void> {\n // Register built-in commands\n this.commandRegistry.register(new NewCommand());\n this.commandRegistry.register(new ModelCommand());\n this.commandRegistry.register(new ModeCommand());\n this.commandRegistry.register(new ThemeCommand());\n this.commandRegistry.register(new HelpCommand(this.commandRegistry));\n\n // Load custom commands\n const customLoader = new CustomCommandLoader(this.fs);\n const customCommands = await customLoader.loadAll(projectRoot);\n\n // Register custom commands, skip if conflicts with built-in\n customCommands.forEach((cmd) => {\n if (this.commandRegistry.has(cmd.name)) {\n logger.warn('Custom command conflicts with built-in, skipping', {\n name: cmd.name,\n });\n return;\n }\n this.commandRegistry.register(cmd);\n });\n\n logger.info('Slash commands initialized', {\n total: this.commandRegistry.getAll().length,\n });\n }\n\n /**\n * Initialize LLM provider with config\n * Returns provider instance or error message\n */\n private initializeProvider(config: Config): { provider?: ILLMProvider; error?: string } {\n try {\n const provider = ProviderFactory.create(config.llm);\n return { provider };\n } catch (error) {\n if (error instanceof ConfigurationError) {\n return { error: error.message };\n }\n return { error: `Failed to initialize provider: ${(error as Error).message}` };\n }\n }\n\n /**\n * Save config changes to project config file\n */\n private async saveConfig(projectRoot: string, config: Config): Promise<void> {\n try {\n const configPath = path.join(projectRoot, '.mimir', 'config.yml');\n const yamlContent = yaml.stringify(config);\n await this.fs.writeFile(configPath, yamlContent);\n logger.info('Config saved', { path: configPath });\n } catch (error) {\n logger.error('Failed to save config', { error });\n throw new Error(`Failed to save config: ${(error as Error).message}`);\n }\n }\n\n /**\n * Process user message through LLM provider\n */\n private async processMessage(\n provider: ILLMProvider,\n messages: Message[],\n userInput: string\n ): Promise<Message> {\n const startTime = Date.now();\n\n try {\n // Add user message to history\n const userMessage: Message = {\n role: 'user',\n content: userInput,\n };\n messages.push(userMessage);\n\n // Call LLM\n const response = await provider.chat(messages);\n const duration = Date.now() - startTime;\n\n // Create assistant message with metadata\n const assistantMessage: Message = {\n role: 'assistant',\n content: response.content,\n metadata: {\n timestamp: Date.now(),\n duration,\n usage: response.usage,\n cost: provider.calculateCost(response.usage.inputTokens, response.usage.outputTokens),\n model: provider.getModelName(),\n provider: provider.getProviderName(),\n },\n };\n\n messages.push(assistantMessage);\n return assistantMessage;\n } catch (error) {\n const duration = Date.now() - startTime;\n logger.error('LLM call failed', { error });\n\n // Return error message\n const errorMessage: Message = {\n role: 'assistant',\n content: `❌ Error: ${(error as Error).message}`,\n metadata: {\n timestamp: Date.now(),\n duration,\n model: provider.getModelName(),\n provider: provider.getProviderName(),\n },\n };\n\n messages.push(errorMessage);\n return errorMessage;\n }\n }\n\n async execute(workspaceRoot?: string): Promise<void> {\n // Use provided workspace root or fall back to process.cwd()\n // In production, this should be passed from CLI entry point\n const cwd = workspaceRoot ?? process.cwd();\n\n // Check if first run\n if (await this.firstRunDetector.isFirstRun()) {\n logger.info('First run detected, launching setup wizard');\n await this.setupCommand.execute();\n // Wizard exits alternate screen buffer on completion, returning to main buffer\n }\n\n // Auto-initialize workspace if .mimir doesn't exist\n const initializer = new MimirInitializer(this.fs, this.configLoader);\n if (!(await initializer.isWorkspaceInitialized(cwd))) {\n logger.info('Workspace not initialized. Running setup...');\n const result = await initializer.initializeWorkspace(cwd);\n\n if (!result.success) {\n const errorMsg = 'Failed to initialize workspace: ' + result.errors.join(', ');\n logger.error(errorMsg);\n throw new Error('Workspace initialization failed');\n }\n\n logger.info('Workspace initialized successfully');\n }\n\n // Enter alternate screen buffer to prevent layout shifts\n // This ensures the app renders in a separate buffer and doesn't push content down\n process.stdout.write('\\x1b[?1049h');\n\n // Load configuration\n const { config } = await this.configLoader.load({\n projectRoot: cwd,\n });\n\n // Initialize slash commands\n await this.initializeCommands(cwd);\n\n // Initialize LLM provider\n let providerResult = this.initializeProvider(config);\n\n // Initialize chat state\n const state = {\n messages: [] as Message[],\n currentMode: 'discuss' as 'plan' | 'act' | 'discuss',\n totalCost: 0,\n provider: providerResult.provider,\n config,\n };\n\n // Show welcome message or error if provider not configured\n if (!state.provider && providerResult.error) {\n state.messages.push({\n role: 'assistant',\n content: `⚠️ ${providerResult.error}\\n\\nTo use the chat, you need to:\\n1. Set up an API key as an environment variable (e.g., DEEPSEEK_API_KEY or ANTHROPIC_API_KEY)\\n2. Or use /model <provider> <model> to switch to a configured provider\\n\\nAvailable providers: deepseek, anthropic`,\n });\n }\n\n return new Promise((resolve) => {\n // Render function to update UI\n const renderUI = (rerender: (element: React.ReactElement) => void): void => {\n const element = React.createElement(ChatApp, {\n fs: this.fs,\n projectRoot: process.cwd(),\n config: state.config,\n messages: state.messages,\n currentMode: state.currentMode,\n totalCost: state.totalCost,\n commandRegistry: this.commandRegistry,\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n onUserInput: async (input: string) => {\n // Parse for slash command\n const parseResult = SlashCommandParser.parse(input);\n\n if (parseResult.isCommand && parseResult.commandName) {\n // Execute slash command\n const result = await this.commandRegistry.execute(\n parseResult.commandName,\n parseResult.args || [],\n {\n currentMode: state.currentMode,\n currentProvider: state.config.llm.provider,\n currentModel: state.config.llm.model,\n messageCount: state.messages.length,\n requestModeSwitch: (mode): void => {\n state.currentMode = mode;\n logger.info('Mode switched via command', { mode });\n // Force rerender to update mode colors (MimirHeader logo, etc.)\n renderUI(rerender);\n },\n requestModelSwitch: async (provider, model): Promise<void> => {\n logger.info('Model switch requested', { provider, model });\n\n // Validate provider type\n const validProviders = [\n 'deepseek',\n 'anthropic',\n 'openai',\n 'google',\n 'gemini',\n 'qwen',\n 'ollama',\n ] as const;\n if (!validProviders.includes(provider as (typeof validProviders)[number])) {\n state.messages.push({\n role: 'assistant',\n content: `❌ Invalid provider: ${provider}. Valid providers: ${validProviders.join(', ')}`,\n });\n return;\n }\n\n // Update config\n state.config.llm.provider = provider as (typeof validProviders)[number];\n\n // Set model - use provided model or default for provider\n if (model) {\n state.config.llm.model = model;\n } else {\n // Set default model for provider\n switch (provider.toLowerCase()) {\n case 'deepseek':\n state.config.llm.model = 'deepseek-chat';\n break;\n case 'anthropic':\n state.config.llm.model = 'claude-sonnet-4-5-20250929';\n break;\n case 'openai':\n state.config.llm.model = 'gpt-4';\n break;\n case 'google':\n case 'gemini':\n state.config.llm.model = 'gemini-pro';\n break;\n default:\n state.config.llm.model = provider; // fallback\n }\n }\n\n // Save config\n try {\n await this.saveConfig(cwd, state.config);\n\n // Reinitialize provider\n const newProviderResult = this.initializeProvider(state.config);\n if (newProviderResult.provider) {\n state.provider = newProviderResult.provider;\n state.messages.push({\n role: 'assistant',\n content: `✓ Switched to ${provider}${model ? `/${model}` : ''}`,\n });\n } else {\n state.messages.push({\n role: 'assistant',\n content: `❌ Failed to switch: ${newProviderResult.error}`,\n });\n }\n } catch (error) {\n state.messages.push({\n role: 'assistant',\n content: `❌ Failed to save config: ${(error as Error).message}`,\n });\n }\n },\n requestNewChat: (): void => {\n state.messages = [];\n state.totalCost = 0;\n logger.info('New chat started');\n },\n requestThemeChange: async (theme): Promise<void> => {\n // Create new config object with updated theme to trigger React rerender\n state.config = {\n ...state.config,\n ui: {\n ...state.config.ui,\n theme: theme as ThemeType,\n },\n };\n\n try {\n await this.saveConfig(cwd, state.config);\n logger.info('Theme changed and saved', { theme });\n\n // Force immediate rerender with new theme\n renderUI(rerender);\n } catch (error) {\n logger.error('Failed to save theme change', { error });\n }\n },\n sendPrompt: (prompt) => {\n // For custom commands - add as user message\n state.messages.push({\n role: 'user',\n content: prompt,\n });\n // TODO: Process through agent\n state.messages.push({\n role: 'assistant',\n content: `Received prompt from command: ${prompt}`,\n });\n },\n }\n );\n\n if (!result.success) {\n // Show error message\n state.messages.push({\n role: 'assistant',\n content: `Error: ${result.error}`,\n });\n }\n\n // Re-render\n renderUI(rerender);\n return;\n }\n\n // Normal message handling\n logger.info('User input received', { input });\n\n // Check if provider is available\n if (!state.provider) {\n state.messages.push({\n role: 'user',\n content: input,\n });\n state.messages.push({\n role: 'assistant',\n content:\n '❌ No LLM provider configured. Please use /model <provider> <model> to set up a provider.',\n });\n renderUI(rerender);\n return;\n }\n\n // Process through LLM\n await this.processMessage(state.provider, state.messages, input);\n\n // Update total cost\n const lastMessage = state.messages[state.messages.length - 1];\n if (lastMessage?.metadata?.cost) {\n state.totalCost += lastMessage.metadata.cost;\n }\n\n // Re-render with updated messages\n renderUI(rerender);\n },\n onModeSwitch: (mode: 'plan' | 'act' | 'discuss'): void => {\n state.currentMode = mode;\n logger.info('Mode switched', { mode });\n // Force rerender to sync mode changes (e.g., from Shift+Tab)\n renderUI(rerender);\n },\n onExit: (): void => {\n logger.info('Chat session ended');\n resolve();\n },\n });\n\n rerender(element);\n };\n\n // Disable console logging while Ink UI is active to prevent log pollution\n logger.disableConsole();\n\n // NOTE: Do NOT manually call process.stdin.setRawMode()!\n // Ink manages raw mode internally via its stdin handling.\n // Manual manipulation causes UV_HANDLE_CLOSING crashes on exit.\n\n const { waitUntilExit, rerender, clear } = render(\n React.createElement(ChatApp, {\n fs: this.fs,\n projectRoot: process.cwd(),\n config: state.config,\n messages: state.messages,\n currentMode: state.currentMode,\n totalCost: state.totalCost,\n commandRegistry: this.commandRegistry,\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n onUserInput: async (input: string) => {\n // Parse for slash command\n const parseResult = SlashCommandParser.parse(input);\n\n if (parseResult.isCommand && parseResult.commandName) {\n // Execute slash command\n const result = await this.commandRegistry.execute(\n parseResult.commandName,\n parseResult.args || [],\n {\n currentMode: state.currentMode,\n currentProvider: state.config.llm.provider,\n currentModel: state.config.llm.model,\n messageCount: state.messages.length,\n requestModeSwitch: (mode): void => {\n state.currentMode = mode;\n logger.info('Mode switched via command', { mode });\n // Force rerender to update mode colors (MimirHeader logo, etc.)\n renderUI(rerender);\n },\n requestModelSwitch: async (provider, model): Promise<void> => {\n logger.info('Model switch requested', { provider, model });\n\n // Validate provider type\n const validProviders = [\n 'deepseek',\n 'anthropic',\n 'openai',\n 'google',\n 'gemini',\n 'qwen',\n 'ollama',\n ] as const;\n if (!validProviders.includes(provider as (typeof validProviders)[number])) {\n state.messages.push({\n role: 'assistant',\n content: `❌ Invalid provider: ${provider}. Valid providers: ${validProviders.join(', ')}`,\n });\n return;\n }\n\n // Update config\n state.config.llm.provider = provider as (typeof validProviders)[number];\n\n // Set model - use provided model or default for provider\n if (model) {\n state.config.llm.model = model;\n } else {\n // Set default model for provider\n switch (provider.toLowerCase()) {\n case 'deepseek':\n state.config.llm.model = 'deepseek-chat';\n break;\n case 'anthropic':\n state.config.llm.model = 'claude-sonnet-4-5-20250929';\n break;\n case 'openai':\n state.config.llm.model = 'gpt-4';\n break;\n case 'google':\n case 'gemini':\n state.config.llm.model = 'gemini-pro';\n break;\n default:\n state.config.llm.model = provider; // fallback\n }\n }\n\n // Save config\n try {\n await this.saveConfig(cwd, state.config);\n\n // Reinitialize provider\n const newProviderResult = this.initializeProvider(state.config);\n if (newProviderResult.provider) {\n state.provider = newProviderResult.provider;\n state.messages.push({\n role: 'assistant',\n content: `✓ Switched to ${provider}${model ? `/${model}` : ''}`,\n });\n } else {\n state.messages.push({\n role: 'assistant',\n content: `❌ Failed to switch: ${newProviderResult.error}`,\n });\n }\n } catch (error) {\n state.messages.push({\n role: 'assistant',\n content: `❌ Failed to save config: ${(error as Error).message}`,\n });\n }\n },\n requestNewChat: (): void => {\n state.messages = [];\n state.totalCost = 0;\n logger.info('New chat started');\n },\n requestThemeChange: async (theme): Promise<void> => {\n // Create new config object with updated theme to trigger React rerender\n state.config = {\n ...state.config,\n ui: {\n ...state.config.ui,\n theme: theme as ThemeType,\n },\n };\n\n try {\n await this.saveConfig(cwd, state.config);\n logger.info('Theme changed and saved', { theme });\n\n // Force immediate rerender with new theme\n renderUI(rerender);\n } catch (error) {\n logger.error('Failed to save theme change', { error });\n }\n },\n sendPrompt: (prompt): void => {\n // For custom commands - add as user message\n state.messages.push({\n role: 'user',\n content: prompt,\n });\n // TODO: Process through agent\n state.messages.push({\n role: 'assistant',\n content: `Received prompt from command: ${prompt}`,\n });\n },\n }\n );\n\n if (!result.success) {\n // Show error message\n state.messages.push({\n role: 'assistant',\n content: `Error: ${result.error}`,\n });\n }\n\n // Re-render\n renderUI(rerender);\n return;\n }\n\n // Normal message handling\n logger.info('User input received', { input });\n\n // Check if provider is available\n if (!state.provider) {\n state.messages.push({\n role: 'user',\n content: input,\n });\n state.messages.push({\n role: 'assistant',\n content:\n '❌ No LLM provider configured. Please use /model <provider> <model> to set up a provider.',\n });\n renderUI(rerender);\n return;\n }\n\n // Process through LLM\n await this.processMessage(state.provider, state.messages, input);\n\n // Update total cost\n const lastMessage = state.messages[state.messages.length - 1];\n if (lastMessage?.metadata?.cost) {\n state.totalCost += lastMessage.metadata.cost;\n }\n\n renderUI(rerender);\n },\n onModeSwitch: (mode: 'plan' | 'act' | 'discuss'): void => {\n state.currentMode = mode;\n logger.info('Mode switched', { mode });\n // Force rerender to sync mode changes (e.g., from Shift+Tab)\n renderUI(rerender);\n },\n onExit: (): void => {\n logger.info('Chat session ended');\n // Exit alternate screen buffer before resolving\n process.stdout.write('\\x1b[?1049l');\n resolve();\n },\n }),\n {\n // Prevent console patching to avoid layout shifts from console.log\n patchConsole: false,\n // CRITICAL: Disable Ink's default Ctrl+C exit behavior\n // We handle Ctrl+C manually through our keyboard system\n exitOnCtrlC: false,\n }\n );\n\n // Handle process termination with SignalHandler\n const signalHandler = installSignalHandlers({\n keyBindings: config.keyBindings,\n onCleanup: async () => {\n // Re-enable console logging for cleanup messages\n logger.enableConsole();\n // NOTE: Do NOT call setRawMode here - Ink handles cleanup\n // Manually restoring raw mode causes UV_HANDLE_CLOSING crashes\n // Exit alternate screen buffer\n process.stdout.write('\\x1b[?1049l');\n // Clear Ink render\n clear();\n logger.info('Chat interface cleanup completed');\n },\n emergencyExitCount: 3,\n cleanupTimeout: 5000,\n });\n\n waitUntilExit()\n .then(() => {\n // Re-enable console logging after UI exits\n logger.enableConsole();\n logger.info('Chat interface exited');\n // NOTE: Do NOT call setRawMode here - Ink handles cleanup\n // Exit alternate screen buffer on normal exit\n process.stdout.write('\\x1b[?1049l');\n // Remove signal handlers\n signalHandler.uninstall();\n resolve();\n })\n .catch((error) => {\n logger.error('Error during UI cleanup', { error });\n // Re-enable console and exit alternate screen even on error\n logger.enableConsole();\n process.stdout.write('\\x1b[?1049l');\n signalHandler.uninstall();\n resolve();\n });\n });\n }\n}\n","/**\n * Top-level chat app component\n * Wraps ChatInterface with KeyboardProvider and sets up keyboard input capture\n */\n\nimport React, { useEffect } from 'react';\nimport { useStdin } from 'ink';\nimport { ChatInterface, ChatInterfaceProps } from './ChatInterface.js';\nimport { KeyboardProvider, useKeyboardInput } from '../keyboard/index.js';\nimport { IFileSystem } from '../../platform/IFileSystem.js';\nimport { logger } from '../../utils/logger.js';\n\nexport interface ChatAppProps extends ChatInterfaceProps {\n fs: IFileSystem;\n projectRoot?: string;\n}\n\n/**\n * Inner component that uses keyboard hooks\n * Must be inside KeyboardProvider\n */\nfunction ChatInterfaceWithKeyboard(props: ChatInterfaceProps): React.JSX.Element {\n const { stdin: _stdin, setRawMode, isRawModeSupported } = useStdin();\n\n // Enable raw mode using Ink's API (not process.stdin directly)\n useEffect(() => {\n if (isRawModeSupported) {\n setRawMode(true);\n logger.debug('Raw mode enabled via Ink useStdin', {\n isRawModeSupported,\n platform: process.platform,\n });\n } else {\n logger.warn('Raw mode not supported in this environment', {\n platform: process.platform,\n isTTY: process.stdin.isTTY,\n });\n }\n\n // Cleanup: Ink handles restoring raw mode automatically\n // DO NOT manually call setRawMode(false) here - causes UV_HANDLE_CLOSING\n return () => {\n // Intentionally empty - Ink handles cleanup\n };\n }, [setRawMode, isRawModeSupported]);\n\n // Capture keyboard input at top level\n useKeyboardInput({ isActive: true });\n\n return <ChatInterface {...props} />;\n}\n\n/**\n * Top-level chat app with keyboard handling\n */\nexport function ChatApp({ fs, projectRoot, ...chatProps }: ChatAppProps): JSX.Element {\n return (\n <KeyboardProvider\n bindingsConfig={chatProps.config.keyBindings}\n fs={fs}\n projectRoot={projectRoot}\n >\n <ChatInterfaceWithKeyboard {...chatProps} />\n </KeyboardProvider>\n );\n}\n","/**\n * Main chat interface component\n * Composes Header, MessageList, InputBox, and Footer\n */\n\nimport React, { useState, useMemo, useCallback, useRef, useEffect } from 'react';\nimport { Box, Text } from 'ink';\nimport { MimirHeader } from './MimirHeader.js';\nimport { MessageList } from './MessageList.js';\nimport { InputBox } from './InputBox.js';\nimport { Footer } from './Footer.js';\nimport { Message } from '../../types/index.js';\nimport { Config } from '../../config/schemas.js';\nimport { useTerminalSize } from '../hooks/useTerminalSize.js';\nimport { SlashCommandRegistry } from '../../core/SlashCommand.js';\nimport { useKeyboard, useKeyboardAction } from '../keyboard/index.js';\n\nexport interface ChatInterfaceProps {\n config: Config;\n messages: Message[];\n onUserInput: (input: string) => void;\n onExit: () => void;\n currentMode: 'plan' | 'act' | 'discuss';\n onModeSwitch?: (mode: 'plan' | 'act' | 'discuss') => void;\n totalCost: number;\n version?: string;\n workspace?: string;\n isAgentRunning?: boolean;\n commandRegistry?: SlashCommandRegistry;\n}\n\nexport const ChatInterface: React.FC<ChatInterfaceProps> = ({\n config,\n messages,\n onUserInput,\n onExit,\n currentMode,\n onModeSwitch,\n totalCost,\n version = '0.1.0',\n workspace = process.cwd(),\n isAgentRunning = false,\n commandRegistry,\n}) => {\n const [input, setInput] = useState('');\n const [mode, setMode] = useState<'plan' | 'act' | 'discuss'>(currentMode);\n const [interruptPressCount, setInterruptPressCount] = useState(0);\n const [isAutocompleteShowing, setIsAutocompleteShowing] = useState(false);\n const [autocompleteSelectedIndex, setAutocompleteSelectedIndex] = useState(0);\n const [autocompleteItemCount, setAutocompleteItemCount] = useState(0);\n const [manuallyClosedAutocomplete, setManuallyClosedAutocomplete] = useState(false);\n const acceptSelectionRef = useRef<(() => void) | null>(null);\n const interruptTimerRef = useRef<NodeJS.Timeout | null>(null);\n const { width: terminalWidth, height: terminalHeight } = useTerminalSize();\n const { updateContext } = useKeyboard();\n\n // Sync mode with currentMode prop\n useEffect(() => {\n setMode(currentMode);\n }, [currentMode]);\n\n // Update keyboard context when state changes\n useEffect(() => {\n updateContext({\n isAutocompleteVisible: isAutocompleteShowing,\n isAgentRunning,\n isInputFocused: true,\n });\n }, [isAutocompleteShowing, isAgentRunning, updateContext]);\n\n // Memoize divider width - only recalculate when terminal width changes\n // This ensures Ink only updates the divider line on resize, not entire UI\n const dividerWidth = useMemo(() => {\n return Math.max(1, terminalWidth);\n }, [terminalWidth]);\n\n // Reset interrupt count after 2 seconds of no interrupt presses\n useEffect(() => {\n if (interruptPressCount > 0) {\n if (interruptTimerRef.current) {\n clearTimeout(interruptTimerRef.current);\n }\n interruptTimerRef.current = setTimeout(() => {\n setInterruptPressCount(0);\n }, 2000);\n }\n return () => {\n if (interruptTimerRef.current) {\n clearTimeout(interruptTimerRef.current);\n }\n };\n }, [interruptPressCount]);\n\n // Track actual autocomplete height for dynamic message area sizing\n const [actualAutocompleteHeight, setActualAutocompleteHeight] = useState(0);\n\n // Auto-show autocomplete when suggestions available (unless manually closed)\n const handleAutocompleteStateChange = useCallback(\n (state: {\n itemCount: number;\n isParameterMode: boolean;\n shouldShow: boolean;\n actualHeight?: number;\n }) => {\n setAutocompleteItemCount(state.itemCount);\n\n // Update actual height if provided\n if (state.actualHeight !== undefined) {\n setActualAutocompleteHeight(state.actualHeight);\n }\n\n // Auto-show autocomplete if:\n // 1. Config flag is enabled (autocompleteAutoShow)\n // 2. Should show (has suggestions)\n // 3. User hasn't manually closed it\n // 4. Item count > 0\n if (\n config.ui.autocompleteAutoShow &&\n state.shouldShow &&\n !manuallyClosedAutocomplete &&\n state.itemCount > 0\n ) {\n setIsAutocompleteShowing((prev) => {\n // Only reset selected index when first showing autocomplete\n if (!prev) {\n setAutocompleteSelectedIndex(0);\n }\n return true;\n });\n } else if (!state.shouldShow) {\n // Hide if no suggestions\n setIsAutocompleteShowing(false);\n setActualAutocompleteHeight(0);\n }\n },\n [manuallyClosedAutocomplete, config.ui.autocompleteAutoShow]\n );\n\n // Reset manual close flag when input changes\n const handleInputChange = useCallback((newValue: string) => {\n setInput(newValue);\n // Reset manual close flag to allow autocomplete to show again\n setManuallyClosedAutocomplete(false);\n // Reset selected index when typing (not when navigating)\n setAutocompleteSelectedIndex(0);\n }, []);\n\n // KEYBOARD ACTIONS - Using centralized keyboard system\n\n // Navigate up in autocomplete (priority: 10 - child handler)\n useKeyboardAction(\n 'navigateUp',\n (event) => {\n if (!event.context.isAutocompleteVisible || autocompleteItemCount === 0) {\n return false; // Not handled, let others try\n }\n\n setAutocompleteSelectedIndex((prev) => (prev > 0 ? prev - 1 : autocompleteItemCount - 1));\n return true; // Handled, stop propagation\n },\n { priority: 10 }\n );\n\n // Navigate down in autocomplete (priority: 10 - child handler)\n useKeyboardAction(\n 'navigateDown',\n (event) => {\n if (!event.context.isAutocompleteVisible || autocompleteItemCount === 0) {\n return false; // Not handled\n }\n\n setAutocompleteSelectedIndex((prev) => (prev < autocompleteItemCount - 1 ? prev + 1 : 0));\n return true; // Handled\n },\n { priority: 10 }\n );\n\n // Accept autocomplete selection (Tab/Enter) (priority: 10 - child handler)\n useKeyboardAction(\n 'accept',\n (event) => {\n if (!event.context.isAutocompleteVisible || autocompleteItemCount === 0) {\n return false; // Not handled\n }\n\n if (acceptSelectionRef.current) {\n acceptSelectionRef.current();\n }\n setAutocompleteSelectedIndex(0);\n return true; // Handled\n },\n { priority: 10 }\n );\n\n // Show tooltip/autocomplete (Tab/Ctrl+Space) (priority: 0 - normal handler)\n useKeyboardAction(\n 'showTooltip',\n (event) => {\n if (event.context.isAutocompleteVisible && autocompleteItemCount > 0) {\n // Autocomplete is showing - Tab should select item (same as Enter)\n if (acceptSelectionRef.current) {\n acceptSelectionRef.current();\n }\n setAutocompleteSelectedIndex(0);\n return true; // Handled\n }\n\n // Not showing or no items - show autocomplete\n setIsAutocompleteShowing(true);\n setManuallyClosedAutocomplete(false);\n setAutocompleteSelectedIndex(0);\n return true; // Handled\n },\n { priority: 0 }\n );\n\n // Interrupt (Ctrl+C and Escape) - Shared logic for both keys\n // Priority 10 ensures autocomplete close is handled before exit\n useKeyboardAction(\n 'interrupt',\n (event) => {\n // If autocomplete showing, close it first (priority handling)\n if (event.context.isAutocompleteVisible) {\n setIsAutocompleteShowing(false);\n setManuallyClosedAutocomplete(true);\n setAutocompleteSelectedIndex(0);\n return true; // Handled, don't exit app\n }\n\n // Handle interrupt/exit logic\n const newCount = interruptPressCount + 1;\n setInterruptPressCount(newCount);\n\n if (event.context.isAgentRunning) {\n if (newCount === 1) {\n // First press: interrupt agent (TODO: implement agent interruption)\n // For now, just count it\n } else if (newCount >= 2) {\n // Second press: exit\n onExit();\n }\n } else {\n if (newCount >= 2) {\n // Not running and second press: exit\n onExit();\n }\n }\n\n return true; // Handled\n },\n { priority: 10 }\n );\n\n // Mode switch (Shift+Tab) (priority: 0 - normal handler)\n useKeyboardAction(\n 'modeSwitch',\n (event) => {\n if (event.context.isAutocompleteVisible) {\n return false; // Don't switch modes while autocomplete showing\n }\n\n const modes: Array<'plan' | 'act' | 'discuss'> = ['plan', 'act', 'discuss'];\n const currentIndex = modes.indexOf(mode);\n const nextIndex = (currentIndex + 1) % modes.length;\n const nextMode = modes[nextIndex];\n if (nextMode) {\n setMode(nextMode);\n if (onModeSwitch) {\n onModeSwitch(nextMode);\n }\n }\n return true; // Handled\n },\n { priority: 0 }\n );\n\n // Memoize submit handler to prevent InputBox from re-rendering unnecessarily\n // Accepts optional value parameter from autocomplete to avoid stale state issues\n const handleSubmit = useCallback(\n (value?: string) => {\n const submittedValue = value !== undefined ? value : input;\n if (submittedValue.trim()) {\n onUserInput(submittedValue);\n setInput('');\n }\n },\n [input, onUserInput]\n );\n\n // Memoize divider content - only recalculate when width changes\n const dividerContent = useMemo(() => '─'.repeat(dividerWidth), [dividerWidth]);\n\n // Create context for slash command parameter autocomplete\n const commandContext = useMemo(\n () => ({\n currentMode: mode,\n currentProvider: config.llm.provider,\n currentModel: config.llm.model,\n messageCount: messages.length,\n }),\n [mode, config.llm.provider, config.llm.model, messages.length]\n );\n\n // Layout structure (from top to bottom):\n // MimirHeader (4) + Divider (1) + MessageList (flex) + InputBox + Divider (1) + Footer (1)\n // InputBox contains: Input (1) + Autocomplete (0-N when visible)\n //\n // Fixed UI lines: Header (4) + Divider (1) + Input (1) + Divider (1) + Footer (1) = 8\n // Variable: MessageList + Autocomplete\n\n const fixedUIHeight = 8;\n const minMessageLines = 3;\n\n // Calculate space for autocomplete dynamically:\n // Total available = terminalHeight - fixedUI - minMessages\n // Autocomplete structure: Header (1) + moreAbove (0-1) + items (N) + moreBelow (0-1) + Footer (1)\n const autocompleteOverhead = 4; // header + footer + max 2 pagination indicators\n const availableForAutocomplete = terminalHeight - fixedUIHeight - minMessageLines;\n const availableForAutocompleteItems = Math.max(\n 0,\n availableForAutocomplete - autocompleteOverhead\n );\n\n // maxVisible clamped between 5-10 items\n const maxVisibleItems = Math.max(5, Math.min(10, availableForAutocompleteItems));\n\n // Use actualAutocompleteHeight if available, otherwise reserve space based on maxVisibleItems\n // This prevents overflow during the initial render before height is calculated\n // Add generous buffer for potential parameter tooltips (worst case: up to 12 extra lines for params + padding)\n const parameterTooltipBuffer = 12;\n const estimatedAutocompleteHeight = isAutocompleteShowing\n ? actualAutocompleteHeight || maxVisibleItems + autocompleteOverhead + parameterTooltipBuffer\n : 0;\n\n const messageAreaHeight = Math.max(\n minMessageLines,\n terminalHeight - fixedUIHeight - estimatedAutocompleteHeight\n );\n\n return (\n <Box flexDirection=\"column\" height={terminalHeight}>\n {/* Fixed header */}\n <MimirHeader\n version={version}\n provider={config.llm.provider}\n model={config.llm.model}\n workspace={workspace}\n theme={config.ui.theme}\n mode={mode}\n />\n\n <Box>\n <Text dimColor>{dividerContent}</Text>\n </Box>\n\n {/* Scrollable message area - shrinks when autocomplete appears */}\n <Box height={messageAreaHeight}>\n <MessageList\n messages={messages}\n theme={config.ui.theme}\n syntaxHighlighting={config.ui.syntaxHighlighting}\n />\n </Box>\n\n {/* Fixed bottom section: Input + Autocomplete (below input) + Footer */}\n {/* Autocomplete grows downward from input when visible, pushing footer down */}\n <InputBox\n value={input}\n onChange={handleInputChange}\n onSubmit={handleSubmit}\n theme={config.ui.theme}\n commandRegistry={commandRegistry}\n context={commandContext}\n onAutocompleteChange={setIsAutocompleteShowing}\n forceShowAutocomplete={isAutocompleteShowing}\n onAutocompleteStateChange={handleAutocompleteStateChange}\n autocompleteIndex={autocompleteSelectedIndex}\n onAcceptSelectionRef={acceptSelectionRef}\n maxVisible={maxVisibleItems}\n keyBindings={config.keyBindings}\n autocompleteExecuteOnSelect={config.ui.autocompleteExecuteOnSelect}\n />\n\n <Box>\n <Text dimColor>{dividerContent}</Text>\n </Box>\n\n <Footer\n theme={config.ui.theme}\n shortcuts={config.keyBindings}\n mode={mode}\n cost={totalCost}\n interruptPressCount={interruptPressCount}\n isAgentRunning={isAgentRunning}\n />\n </Box>\n );\n};\n","/**\n * Mimir header component with wizard ASCII art\n * Layout inspired by Claude Code with wizard head on left, info on right\n */\n\nimport React from 'react';\nimport { Box, Text } from 'ink';\nimport { Theme } from '../../config/schemas.js';\nimport { getTheme } from '../../config/themes/index.js';\nimport { MIMIR_LOGO } from './logo.js';\n\nexport interface MimirHeaderProps {\n version: string;\n provider: string;\n model: string;\n workspace: string;\n theme: Theme;\n mode: 'plan' | 'act' | 'discuss';\n}\n\nexport const MimirHeader: React.FC<MimirHeaderProps> = ({\n version,\n provider,\n model,\n workspace,\n theme,\n mode,\n}) => {\n const themeDefinition = getTheme(theme);\n\n // Logo color changes based on current mode\n const logoColor =\n mode === 'plan'\n ? themeDefinition.colors.modePlan\n : mode === 'act'\n ? themeDefinition.colors.modeAct\n : themeDefinition.colors.modeDiscuss;\n\n const versionColor = themeDefinition.colors.warning;\n const providerColor = themeDefinition.colors.success;\n const dimText = themeDefinition.colors.comment;\n\n const infoLines = [\n versionColor(`Mimir Code v${version}`),\n providerColor(`${provider} · ${model}`),\n dimText(workspace),\n themeDefinition.colors.info(`Theme: ${themeDefinition.name}`),\n ];\n\n // Fixed width for logo column to ensure consistent alignment\n const LOGO_WIDTH = 7;\n\n return (\n <Box flexDirection=\"column\" height={MIMIR_LOGO.length} flexShrink={0}>\n {MIMIR_LOGO.map((logoLine, index) => (\n <Box key={index}>\n <Box width={LOGO_WIDTH}>\n <Text>{logoColor.bold(logoLine)}</Text>\n </Box>\n {infoLines[index] && <Text>{infoLines[index]}</Text>}\n </Box>\n ))}\n </Box>\n );\n};\n","/**\n * Message list component\n * Displays conversation messages with role-based colors and thinking indicators\n * Uses Static component to prevent re-rendering of existing messages\n */\n\nimport React from 'react';\nimport { Box, Text, Static } from 'ink';\nimport { Message } from '../../types/index.js';\nimport { Theme } from '../../config/schemas.js';\nimport { getTheme } from '../../config/themes/index.js';\n\nexport interface MessageListProps {\n messages: Message[];\n theme: Theme;\n syntaxHighlighting: boolean;\n}\n\nexport const MessageList: React.FC<MessageListProps> = ({\n messages,\n theme,\n syntaxHighlighting: _syntaxHighlighting,\n}) => {\n const themeDefinition = getTheme(theme);\n const { userMessage, assistantMessage, systemMessage } = themeDefinition.colors;\n\n const getRoleChalk = (role: Message['role']) => {\n switch (role) {\n case 'user':\n return userMessage;\n case 'assistant':\n return assistantMessage;\n case 'system':\n return systemMessage;\n default:\n return assistantMessage;\n }\n };\n\n const formatDuration = (ms: number): string => {\n if (ms < 1000) return `${Math.round(ms)}ms`;\n return `${(ms / 1000).toFixed(1)}s`;\n };\n\n const formatCost = (cost: number): string => {\n if (cost === 0) return '$0.00';\n if (cost < 0.0001) return `$${cost.toExponential(2)}`;\n return `$${cost.toFixed(4)}`;\n };\n\n const renderThinkingIndicator = (message: Message) => {\n if (!message.metadata) return null;\n\n const { duration, usage, cost, model, provider } = message.metadata;\n\n const parts: string[] = [];\n\n // Model/Provider\n if (provider && model) {\n parts.push(`${provider}/${model}`);\n } else if (model) {\n parts.push(model);\n }\n\n // Duration\n if (duration != null) {\n parts.push(formatDuration(duration));\n }\n\n // Tokens\n if (usage) {\n parts.push(`${usage.inputTokens}→${usage.outputTokens} tokens`);\n }\n\n // Cost\n if (cost != null) {\n parts.push(formatCost(cost));\n }\n\n if (parts.length === 0) return null;\n\n return (\n <Box marginTop={0}>\n <Text dimColor italic>\n ({parts.join(' • ')})\n </Text>\n </Box>\n );\n };\n\n const renderMessage = (message: Message, index: number) => (\n <Box key={index} flexDirection=\"column\" marginBottom={1}>\n <Text>{getRoleChalk(message.role).bold(`[${message.role.toUpperCase()}]:`)}</Text>\n <Text>{message.content}</Text>\n {message.role === 'assistant' && renderThinkingIndicator(message)}\n </Box>\n );\n\n return (\n <Box flexDirection=\"column\" paddingX={1} paddingY={1} flexGrow={1}>\n {messages.length === 0 && <Text dimColor>No messages yet. Start typing below...</Text>}\n {messages.length > 0 && (\n <Static items={messages}>{(message, index) => renderMessage(message, index)}</Static>\n )}\n </Box>\n );\n};\n","/**\n * Input box component\n * User input field with prompt and autocomplete support\n *\n * Keyboard behavior (based on terminal CLI best practices):\n * - **Tab**: Show/trigger autocomplete (traditional shell pattern, works on all platforms)\n * - **Ctrl+Space**: Alternative autocomplete trigger (macOS/Linux only - Windows terminal intercepts it)\n * - **Escape**: Close autocomplete (or pass to parent if not showing)\n * - **Ctrl+C**: Close autocomplete FIRST (or pass to parent for exit if not showing)\n * - **Up/Down**: Navigate autocomplete items\n * - **Enter**: Accept selected item (or execute command if not showing)\n *\n * Note: On Windows, Ctrl+Space is intercepted by PowerShell/Windows Terminal and never\n * reaches the application. Tab is the recommended universal shortcut for autocomplete.\n *\n * Parameter detection (bash COMP_WORDS pattern):\n * - `/command param ` (trailing space) → shows NEXT parameter if exists\n * - `/command param` (no space) → shows completions for CURRENT parameter\n * - No autocomplete shown if no more parameters available\n *\n * Architecture:\n * - Global keyboard event bus with action-based routing\n * - Keyboard events managed via KeyboardContext\n * - Pre-allocated space to prevent layout shifts\n * - Autocomplete positioned below input line (standard terminal pattern)\n */\n\nimport React, { useState, useCallback, useEffect } from 'react';\nimport { Box, Text } from 'ink';\nimport TextInput from 'ink-text-input';\nimport { Theme, KeyBindingsConfig } from '../../config/schemas.js';\nimport { getTheme } from '../../config/themes/index.js';\nimport { SlashCommandRegistry, SlashCommandContext } from '../../core/SlashCommand.js';\nimport { SlashCommandParser } from '../../core/SlashCommandParser.js';\nimport { CommandAutocomplete } from './CommandAutocomplete.js';\nimport { ISlashCommand } from '../../core/SlashCommand.js';\n\nexport interface InputBoxProps {\n value: string;\n onChange: (value: string) => void;\n onSubmit: (value?: string) => void;\n theme: Theme;\n commandRegistry?: SlashCommandRegistry;\n // Context for parameter autocomplete\n context?: SlashCommandContext;\n // Callback when autocomplete visibility changes\n onAutocompleteChange?: (isShowing: boolean) => void;\n // Externally controlled autocomplete visibility (from parent keyboard handler)\n forceShowAutocomplete?: boolean;\n // Callback to report autocomplete state (item count for navigation, actual height for layout)\n onAutocompleteStateChange?: (state: {\n itemCount: number;\n isParameterMode: boolean;\n shouldShow: boolean;\n actualHeight?: number;\n }) => void;\n // Maximum number of visible items in autocomplete (dynamically calculated from terminal height)\n maxVisible?: number;\n // Selected autocomplete index (controlled from parent)\n autocompleteIndex?: number;\n // Ref to expose accept selection function to parent\n onAcceptSelectionRef?: React.MutableRefObject<(() => void) | null>;\n // Keyboard bindings for autocomplete footer\n keyBindings: KeyBindingsConfig;\n // Execute command immediately if no more parameters needed\n autocompleteExecuteOnSelect?: boolean;\n}\n\nexport const InputBox: React.FC<InputBoxProps> = React.memo(\n ({\n value,\n onChange,\n onSubmit,\n theme,\n commandRegistry,\n context,\n onAutocompleteChange,\n forceShowAutocomplete,\n onAutocompleteStateChange,\n autocompleteIndex,\n onAcceptSelectionRef,\n maxVisible = 5,\n keyBindings,\n autocompleteExecuteOnSelect = true,\n }) => {\n const themeDefinition = getTheme(theme);\n const [filteredCommands, setFilteredCommands] = useState<ISlashCommand[]>([]);\n const [parameterSuggestions, setParameterSuggestions] = useState<string[]>([]);\n const [parameterName, setParameterName] = useState<string>('');\n const [isParameterMode, setIsParameterMode] = useState(false);\n const [inputKey, setInputKey] = useState(0);\n const [autocompleteHeight, setAutocompleteHeight] = useState(0);\n\n // Use controlled autocomplete state from parent, with local fallback\n const showAutocomplete = forceShowAutocomplete !== undefined ? forceShowAutocomplete : false;\n const selectedIndex = autocompleteIndex !== undefined ? autocompleteIndex : 0;\n\n // Notify parent when autocomplete visibility changes\n useEffect(() => {\n if (onAutocompleteChange) {\n onAutocompleteChange(showAutocomplete);\n }\n }, [showAutocomplete, onAutocompleteChange]);\n\n // Calculate autocomplete suggestions based on current input\n // Based on bash COMP_WORDS pattern - detect parameter boundaries with space\n const calculateSuggestions = useCallback(() => {\n if (!commandRegistry) {\n return { show: false, isParam: false, commands: [], params: [], paramName: '' };\n }\n\n const trimmed = value.trim();\n\n // Not a slash command at all\n if (!trimmed.startsWith('/')) {\n return { show: false, isParam: false, commands: [], params: [], paramName: '' };\n }\n\n const parsed = SlashCommandParser.parse(value);\n\n // Check for parameter mode - when there's a space after command\n if (parsed.isCommand && parsed.commandName && value.includes(' ')) {\n const command = commandRegistry.get(parsed.commandName);\n\n // Only show parameter autocomplete if command has parameter suggestions\n if (command?.getParameterSuggestions && context) {\n const currentInput = parsed.rawArgs || '';\n\n // Split into word boundaries (like bash COMP_WORDS)\n // Filter out empty strings\n const parts = currentInput.split(/\\s+/).filter((a) => a.length > 0);\n\n // Detect if we're at a parameter boundary (trailing space after last param)\n // Pattern: \"/command param \" vs \"/command param\"\n // Check original value for trailing space (handles \"/theme \" where rawArgs is empty)\n const endsWithSpace = /\\s$/.test(value);\n\n let paramIndex: number;\n let partialValue: string;\n\n if (endsWithSpace) {\n // Trailing space = finished with current param, ready for NEXT parameter\n // e.g., \"/model deepseek \" -> parts=['deepseek'], paramIndex=1\n // Only show autocomplete if the NEXT parameter exists\n paramIndex = parts.length;\n partialValue = '';\n\n // Check if next parameter exists\n // Pass already-typed args so commands can provide context-aware suggestions\n const nextParamSuggestions = command.getParameterSuggestions(\n paramIndex,\n context,\n parts\n );\n if (nextParamSuggestions.length === 0) {\n // No next parameter - don't show autocomplete\n return { show: false, isParam: false, commands: [], params: [], paramName: '' };\n }\n\n return {\n show: true,\n isParam: true,\n commands: [],\n params: nextParamSuggestions,\n paramName: command.parameters?.[paramIndex]?.name || 'parameter',\n };\n } else if (parts.length === 0) {\n // No arguments yet \" \" after command - first parameter\n paramIndex = 0;\n partialValue = '';\n } else {\n // No trailing space = still typing current parameter\n // e.g., \"/model dee\" -> parts=['dee'], paramIndex=0\n paramIndex = parts.length - 1;\n partialValue = parts[parts.length - 1]?.toLowerCase() || '';\n }\n\n // Pass completed args (all but the last partial one) for context-aware suggestions\n const completedArgs = paramIndex > 0 ? parts.slice(0, paramIndex) : [];\n const allSuggestions = command.getParameterSuggestions(\n paramIndex,\n context,\n completedArgs\n );\n\n // Filter suggestions based on partial value\n const filteredSuggestions = partialValue\n ? allSuggestions.filter((s) => s.toLowerCase().startsWith(partialValue))\n : allSuggestions;\n\n if (filteredSuggestions.length > 0) {\n return {\n show: true,\n isParam: true,\n commands: [],\n params: filteredSuggestions,\n paramName: command.parameters?.[paramIndex]?.name || 'parameter',\n };\n }\n }\n\n // No parameter suggestions available\n return { show: false, isParam: false, commands: [], params: [], paramName: '' };\n }\n\n // Command autocomplete mode - only if no space yet (still typing command name)\n const partialName = SlashCommandParser.getPartialCommandName(value);\n\n if (partialName === null) {\n return { show: false, isParam: false, commands: [], params: [], paramName: '' };\n }\n\n // Only show command autocomplete if there's no space (still typing command name)\n const hasSpace = value.includes(' ');\n if (hasSpace) {\n return { show: false, isParam: false, commands: [], params: [], paramName: '' };\n }\n\n const matches = commandRegistry.search(partialName);\n\n return {\n show: matches.length > 0,\n isParam: false,\n commands: matches,\n params: [],\n paramName: '',\n };\n }, [value, commandRegistry, context]);\n\n // Update autocomplete suggestions when input changes\n useEffect(() => {\n const suggestions = calculateSuggestions();\n\n setIsParameterMode(suggestions.isParam);\n setFilteredCommands(suggestions.commands);\n setParameterSuggestions(suggestions.params);\n setParameterName(suggestions.paramName);\n\n // Notify parent about autocomplete state (item count for navigation)\n const itemCount = suggestions.isParam\n ? suggestions.params.length\n : suggestions.commands.length;\n\n if (onAutocompleteStateChange) {\n onAutocompleteStateChange({\n itemCount,\n isParameterMode: suggestions.isParam,\n shouldShow: suggestions.show && itemCount > 0,\n });\n }\n }, [calculateSuggestions, onAutocompleteStateChange]);\n\n // Callback to receive actual rendered height from CommandAutocomplete\n const handleHeightCalculated = useCallback((height: number) => {\n setAutocompleteHeight(height);\n }, []);\n\n // Reset height when autocomplete is hidden\n useEffect(() => {\n if (!showAutocomplete) {\n setAutocompleteHeight(0);\n }\n }, [showAutocomplete]);\n\n // Report autocomplete state changes to parent\n useEffect(() => {\n const itemCount = isParameterMode ? parameterSuggestions.length : filteredCommands.length;\n\n if (onAutocompleteStateChange) {\n onAutocompleteStateChange({\n itemCount,\n isParameterMode,\n shouldShow: showAutocomplete && itemCount > 0,\n actualHeight: showAutocomplete ? autocompleteHeight : 0,\n });\n }\n }, [\n autocompleteHeight,\n isParameterMode,\n parameterSuggestions.length,\n filteredCommands.length,\n showAutocomplete,\n onAutocompleteStateChange,\n ]);\n\n // Accept autocomplete selection (called by parent when Tab/Enter pressed)\n const acceptSelection = useCallback(() => {\n const itemCount = isParameterMode ? parameterSuggestions.length : filteredCommands.length;\n if (itemCount === 0) return;\n\n if (isParameterMode) {\n // Select parameter suggestion\n const selected = parameterSuggestions[selectedIndex];\n if (selected) {\n const parsed = SlashCommandParser.parse(value);\n const currentInput = parsed.rawArgs || '';\n\n // Split into word boundaries\n const parts = currentInput.split(/\\s+/).filter((a) => a.length > 0);\n const endsWithSpace = currentInput.length > 0 && /\\s$/.test(currentInput);\n\n let completedArgs: string[];\n if (endsWithSpace || parts.length === 0) {\n // Adding new argument\n completedArgs = [...parts, selected];\n } else {\n // Replacing last partial argument\n completedArgs = [...parts.slice(0, -1), selected];\n }\n\n const commandName = parsed.commandName;\n if (!commandName) return;\n\n const baseCommand = `/${commandName}`;\n const newValue = `${baseCommand} ${completedArgs.join(' ')} `;\n\n // Check if there are more parameters expected\n const command = commandRegistry?.get(commandName);\n const hasMoreParams =\n command?.getParameterSuggestions && context\n ? command.getParameterSuggestions(completedArgs.length, context, completedArgs)\n .length > 0\n : false;\n\n if (!hasMoreParams && autocompleteExecuteOnSelect) {\n // No more parameters - auto-execute (if enabled)\n setInputKey((prev) => prev + 1);\n const finalValue = newValue.trim();\n onChange(finalValue);\n // Pass value directly to onSubmit to avoid stale state issues\n setTimeout(() => {\n onSubmit(finalValue);\n }, 0);\n } else {\n // More parameters expected or auto-execute disabled - add trailing space and continue\n setInputKey((prev) => prev + 1);\n onChange(newValue);\n }\n }\n } else {\n // Select command\n const selectedCommand = filteredCommands[selectedIndex];\n if (selectedCommand) {\n const newValue = `/${selectedCommand.name} `;\n\n // Check if command has parameters\n const hasParams =\n selectedCommand.getParameterSuggestions && context\n ? selectedCommand.getParameterSuggestions(0, context, []).length > 0\n : false;\n\n if (!hasParams && autocompleteExecuteOnSelect) {\n // No parameters - auto-execute (if enabled)\n setInputKey((prev) => prev + 1);\n const finalValue = newValue.trim();\n onChange(finalValue);\n // Pass value directly to onSubmit to avoid stale state issues\n setTimeout(() => {\n onSubmit(finalValue);\n }, 0);\n } else {\n // Has parameters or auto-execute disabled - add trailing space and continue\n setInputKey((prev) => prev + 1);\n onChange(newValue);\n }\n }\n }\n }, [\n isParameterMode,\n parameterSuggestions,\n filteredCommands,\n selectedIndex,\n value,\n onChange,\n onSubmit,\n commandRegistry,\n context,\n autocompleteExecuteOnSelect,\n ]);\n\n // Expose accept selection function to parent via ref\n useEffect(() => {\n if (onAcceptSelectionRef) {\n onAcceptSelectionRef.current = acceptSelection;\n }\n }, [onAcceptSelectionRef, acceptSelection]);\n\n const handleSubmit = useCallback(() => {\n // Only submit if autocomplete is not showing\n if (!showAutocomplete) {\n onSubmit(undefined);\n }\n }, [showAutocomplete, onSubmit]);\n\n return (\n <Box flexDirection=\"column\" flexShrink={0}>\n {/* Input line - always anchored at same position */}\n <Box paddingX={1} flexShrink={0}>\n <Text>{themeDefinition.colors.inputPrompt('> ')}</Text>\n <TextInput key={inputKey} value={value} onChange={onChange} onSubmit={handleSubmit} />\n </Box>\n\n {/* Autocomplete appears BELOW input line */}\n {showAutocomplete && (\n <CommandAutocomplete\n commands={isParameterMode ? undefined : filteredCommands}\n parameterSuggestions={isParameterMode ? parameterSuggestions : undefined}\n parameterName={isParameterMode ? parameterName : undefined}\n selectedIndex={selectedIndex}\n showParameterInfo={!isParameterMode}\n selectedCommand={isParameterMode ? undefined : filteredCommands[selectedIndex]}\n theme={theme}\n maxVisible={maxVisible}\n keyBindings={keyBindings}\n onHeightCalculated={handleHeightCalculated}\n />\n )}\n </Box>\n );\n }\n);\n\nInputBox.displayName = 'InputBox';\n","/**\n * Parser for slash commands\n * Handles detection and parsing of slash commands from user input\n */\n\n/**\n * Parse result from input string\n */\nexport interface ParseResult {\n isCommand: boolean;\n commandName?: string;\n args?: string[];\n rawArgs?: string;\n}\n\n/**\n * Parser for slash commands\n */\nexport class SlashCommandParser {\n private static readonly COMMAND_REGEX = /^\\/(\\w+)(?:\\s+(.*))?$/;\n\n /**\n * Check if input starts with /\n */\n static isCommandPrefix(input: string): boolean {\n return input.trimStart().startsWith('/');\n }\n\n /**\n * Parse slash command from input\n * Examples:\n * \"/new\" -> { isCommand: true, commandName: 'new', args: [] }\n * \"/model deepseek\" -> { isCommand: true, commandName: 'model', args: ['deepseek'] }\n * \"/custom arg1 arg2\" -> { isCommand: true, commandName: 'custom', args: ['arg1', 'arg2'], rawArgs: 'arg1 arg2' }\n */\n static parse(input: string): ParseResult {\n const trimmed = input.trim();\n\n if (!this.isCommandPrefix(trimmed)) {\n return { isCommand: false };\n }\n\n const match = this.COMMAND_REGEX.exec(trimmed);\n\n if (!match) {\n return { isCommand: false };\n }\n\n const commandName = match[1];\n const rawArgs = match[2] || '';\n const args = rawArgs ? rawArgs.trim().split(/\\s+/) : [];\n\n return {\n isCommand: true,\n commandName,\n args,\n rawArgs,\n };\n }\n\n /**\n * Get partial command name for autocomplete\n * \"/mod\" -> \"mod\"\n * \"/\" -> \"\"\n */\n static getPartialCommandName(input: string): string | null {\n const trimmed = input.trimStart();\n\n if (!trimmed.startsWith('/')) {\n return null;\n }\n\n // Extract command name (before first space)\n const spaceIndex = trimmed.indexOf(' ');\n if (spaceIndex === -1) {\n return trimmed.substring(1); // Remove /\n }\n\n return trimmed.substring(1, spaceIndex);\n }\n}\n","/**\n * Command autocomplete dropdown\n * Shows available commands or parameter suggestions\n */\n\nimport React, { useMemo } from 'react';\nimport { Box, Text } from 'ink';\nimport chalk from 'chalk';\nimport { ISlashCommand } from '../../core/SlashCommand.js';\nimport { Theme, KeyBindingsConfig } from '../../config/schemas.js';\nimport { getTheme } from '../../config/themes/index.js';\nimport { formatNavigationArrows, formatKeyboardShortcut } from '../../utils/keyboardFormatter.js';\nimport { useTerminalSize } from '../hooks/useTerminalSize.js';\n\n/**\n * Adjust hex color brightness by a factor\n * @param hex - Hex color string (e.g., '#3B4252')\n * @param factor - Adjustment factor (-1 to 1, negative for darker, positive for lighter)\n * @returns Adjusted hex color\n */\nfunction adjustHexBrightness(hex: string, factor: number): string {\n // Remove # if present\n const cleanHex = hex.replace('#', '');\n\n // Parse RGB components\n const r = parseInt(cleanHex.substring(0, 2), 16);\n const g = parseInt(cleanHex.substring(2, 4), 16);\n const b = parseInt(cleanHex.substring(4, 6), 16);\n\n // Adjust brightness\n const adjust = (value: number) => {\n const adjusted =\n factor < 0\n ? value * (1 + factor) // Darken\n : value + (255 - value) * factor; // Lighten\n return Math.max(0, Math.min(255, Math.round(adjusted)));\n };\n\n const newR = adjust(r);\n const newG = adjust(g);\n const newB = adjust(b);\n\n // Convert back to hex\n const toHex = (n: number) => n.toString(16).padStart(2, '0');\n return `#${toHex(newR)}${toHex(newG)}${toHex(newB)}`;\n}\n\nexport interface CommandAutocompleteProps {\n // For command autocomplete\n commands?: ISlashCommand[];\n // For parameter autocomplete\n parameterSuggestions?: string[];\n parameterName?: string;\n selectedIndex: number;\n maxVisible?: number;\n // Show parameter info for selected command\n showParameterInfo?: boolean;\n selectedCommand?: ISlashCommand;\n // Theme for styling\n theme: Theme;\n // Keyboard shortcuts for footer\n keyBindings: KeyBindingsConfig;\n // Callback to report actual rendered height\n onHeightCalculated?: (height: number) => void;\n}\n\nexport const CommandAutocomplete: React.FC<CommandAutocompleteProps> = ({\n commands,\n parameterSuggestions,\n parameterName,\n selectedIndex,\n maxVisible = 5,\n showParameterInfo = false,\n selectedCommand: _selectedCommand,\n theme,\n keyBindings,\n onHeightCalculated,\n}) => {\n const themeDefinition = getTheme(theme);\n const bgColorHex = themeDefinition.rawColors.autocompleteBg || '#2e3440';\n const bg = chalk.bgHex(bgColorHex);\n const autocompleteText = themeDefinition.colors.autocompleteText;\n const autocompleteSelectedBgHex = themeDefinition.rawColors.autocompleteSelectedBg || '#88c0d0';\n const autocompleteSelectedBg = chalk.bgHex(autocompleteSelectedBgHex);\n const autocompleteSelectedText = themeDefinition.colors.autocompleteSelectedText;\n const autocompleteHeaderText = themeDefinition.colors.autocompleteHeaderText;\n const autocompleteFooterText = themeDefinition.colors.autocompleteFooterText;\n const autocompleteMoreIndicator = themeDefinition.colors.autocompleteMoreIndicator;\n\n // Subtle background for parameter rows (slightly darker)\n const paramBgHex = adjustHexBrightness(bgColorHex, -0.05); // 5% darker\n const paramBg = chalk.bgHex(paramBgHex);\n\n // Get terminal width to constrain autocomplete\n const { width: terminalWidth } = useTerminalSize();\n const maxAllowedWidth = Math.max(30, terminalWidth - 4); // Leave 4 chars margin, minimum 30\n\n // Helper to truncate text with ellipsis if it exceeds max width\n const truncateText = (text: string, maxLen: number): string => {\n // Strip ANSI codes for accurate length calculation\n // eslint-disable-next-line no-control-regex\n const stripped = text.replace(/\\x1B\\[[0-9;]*m/g, '');\n if (stripped.length <= maxLen) {\n return stripped; // Always return stripped version for consistent formatting\n }\n // Truncate stripped text and add ellipsis\n return stripped.slice(0, maxLen - 3) + '...';\n };\n\n // Helper to create full-width background line\n const bgLine = (content: string, width: number, chalkFn = autocompleteText) => {\n const truncated = truncateText(content, width);\n // truncateText already strips ANSI codes, so we can use length directly\n const padding = Math.max(0, width - truncated.length);\n return bg(chalkFn(truncated + ' '.repeat(padding)));\n };\n\n // Build footer text from keyboard shortcuts with icons\n const footerText = useMemo(() => {\n const navigateKeys = formatNavigationArrows(keyBindings.navigateUp, keyBindings.navigateDown);\n // Show all accept keys (Tab, Enter, etc.)\n const acceptKeys = formatKeyboardShortcut(keyBindings.showTooltip.concat(keyBindings.accept));\n const cancelKeys = formatKeyboardShortcut(keyBindings.interrupt);\n return ` ${navigateKeys} navigate | ${acceptKeys} select | ${cancelKeys} cancel `;\n }, [keyBindings]);\n\n // Parameter autocomplete mode\n if (parameterSuggestions && parameterSuggestions.length > 0) {\n // Guard: Ensure selectedIndex is within bounds\n const safeSelectedIndex = Math.max(0, Math.min(selectedIndex, parameterSuggestions.length - 1));\n\n const { visibleSuggestions, startIndex, endIndex } = useMemo(() => {\n if (parameterSuggestions.length <= maxVisible) {\n return {\n visibleSuggestions: parameterSuggestions,\n startIndex: 0,\n endIndex: parameterSuggestions.length,\n };\n }\n\n // Calculate window to ensure selected item is ALWAYS visible\n let startIndex: number;\n let endIndex: number;\n\n if (safeSelectedIndex < Math.floor(maxVisible / 2)) {\n // Near start - show from beginning\n startIndex = 0;\n endIndex = maxVisible;\n } else if (safeSelectedIndex >= parameterSuggestions.length - Math.floor(maxVisible / 2)) {\n // Near end - show last maxVisible items\n startIndex = parameterSuggestions.length - maxVisible;\n endIndex = parameterSuggestions.length;\n } else {\n // Middle - center the selected item\n startIndex = safeSelectedIndex - Math.floor(maxVisible / 2);\n endIndex = startIndex + maxVisible;\n }\n\n // Safety bounds\n startIndex = Math.max(0, startIndex);\n endIndex = Math.min(parameterSuggestions.length, endIndex);\n\n return {\n visibleSuggestions: parameterSuggestions.slice(startIndex, endIndex),\n startIndex,\n endIndex,\n };\n }, [parameterSuggestions, safeSelectedIndex, maxVisible]);\n\n const moreAbove = startIndex > 0;\n const moreBelow = endIndex < parameterSuggestions.length;\n const moreAboveCount = startIndex;\n const moreBelowCount = parameterSuggestions.length - endIndex;\n\n // Calculate exact rendered height by counting lines we're about to render:\n // 1. Header line\n // 2. More above indicator (conditional)\n // 3. Each visible suggestion (1 line each)\n // 4. More below indicator (conditional)\n // 5. Footer line\n const actualHeight = useMemo(() => {\n let height = 0;\n height += 1; // header\n if (moreAbove) height += 1; // more above indicator\n height += visibleSuggestions.length; // all visible items\n if (moreBelow) height += 1; // more below indicator\n height += 1; // footer\n return height;\n }, [moreAbove, visibleSuggestions.length, moreBelow]);\n\n // Report height to parent\n React.useEffect(() => {\n if (onHeightCalculated) {\n onHeightCalculated(actualHeight);\n }\n }, [onHeightCalculated, actualHeight]);\n\n // Calculate max width for consistent backgrounds, clamped to terminal width\n const maxWidth = useMemo(() => {\n const header = ` ${parameterName || 'Parameter'} (${parameterSuggestions.length}) `;\n const moreText = moreAbove ? ` ▲ ${moreAboveCount} more above ` : '';\n const moreBelowText = moreBelow ? ` ▼ ${moreBelowCount} more below ` : '';\n const items = visibleSuggestions.map((s) => ` ${s}`);\n\n const lengths = [\n header.length,\n footerText.length,\n moreText.length,\n moreBelowText.length,\n ...items.map((i) => i.length),\n ];\n const idealWidth = Math.max(...lengths, 50); // Minimum 50 chars\n return Math.min(idealWidth, maxAllowedWidth); // Clamp to terminal width\n }, [\n parameterName,\n parameterSuggestions.length,\n visibleSuggestions,\n moreAbove,\n moreBelow,\n moreAboveCount,\n moreBelowCount,\n footerText,\n maxAllowedWidth,\n ]);\n\n return (\n <Box flexDirection=\"column\" flexShrink={0}>\n <Text>\n {bgLine(\n ` ${parameterName || 'Parameter'} (${parameterSuggestions.length}) `,\n maxWidth,\n autocompleteHeaderText\n )}\n </Text>\n {moreAbove && (\n <Text>\n {bgLine(` ▲ ${moreAboveCount} more above `, maxWidth, autocompleteMoreIndicator)}\n </Text>\n )}\n {visibleSuggestions.map((suggestion, idx) => {\n // Calculate actual index in original array\n const actualIndex = startIndex + idx;\n const isSelected = actualIndex === safeSelectedIndex;\n const prefix = isSelected ? '> ' : ' ';\n const content = `${prefix}${suggestion}`;\n\n return (\n <Text key={`${actualIndex}-${suggestion}`}>\n {isSelected\n ? autocompleteSelectedBg(\n autocompleteSelectedText(truncateText(content, maxWidth).padEnd(maxWidth, ' '))\n )\n : bgLine(content, maxWidth)}\n </Text>\n );\n })}\n {moreBelow && (\n <Text>\n {bgLine(` ▼ ${moreBelowCount} more below `, maxWidth, autocompleteMoreIndicator)}\n </Text>\n )}\n <Text>{bgLine(footerText, maxWidth, autocompleteFooterText)}</Text>\n </Box>\n );\n }\n\n // Command autocomplete mode\n if (!commands || commands.length === 0) {\n return null;\n }\n\n // Guard: Ensure selectedIndex is within bounds\n const safeSelectedIndex = Math.max(0, Math.min(selectedIndex, commands.length - 1));\n\n const { visibleCommands, startIndex, endIndex } = useMemo(() => {\n // Helper: count lines a command takes (1 + params if selected and showing param info)\n const countLines = (cmd: ISlashCommand | undefined, idx: number) => {\n if (!cmd) return 1; // Safety: treat undefined as 1 line\n let lines = 1; // Command itself\n if (showParameterInfo && idx === safeSelectedIndex && cmd.parameters) {\n lines += cmd.parameters.length; // Add parameter lines\n }\n return lines;\n };\n\n // Calculate total lines if we show all commands\n const totalLines = commands.reduce((sum, cmd, idx) => sum + countLines(cmd, idx), 0);\n\n // If total lines fit in maxVisible, show all\n if (totalLines <= maxVisible) {\n return {\n visibleCommands: commands,\n startIndex: 0,\n endIndex: commands.length,\n };\n }\n\n // Need to window - calculate visible range accounting for line counts\n // Strategy: Start from selected item and expand outward until we hit maxVisible lines\n let startIndex = safeSelectedIndex;\n let endIndex = safeSelectedIndex + 1;\n let lineCount = countLines(commands[safeSelectedIndex], safeSelectedIndex);\n\n // Expand downward first (items after selected)\n while (endIndex < commands.length && lineCount < maxVisible) {\n const nextLines = countLines(commands[endIndex], endIndex);\n if (lineCount + nextLines > maxVisible) break;\n lineCount += nextLines;\n endIndex++;\n }\n\n // Then expand upward (items before selected) if we have room\n while (startIndex > 0 && lineCount < maxVisible) {\n const prevLines = countLines(commands[startIndex - 1], startIndex - 1);\n if (lineCount + prevLines > maxVisible) break;\n lineCount += prevLines;\n startIndex--;\n }\n\n return {\n visibleCommands: commands.slice(startIndex, endIndex),\n startIndex,\n endIndex,\n };\n }, [commands, safeSelectedIndex, maxVisible, showParameterInfo]);\n\n const moreAbove = startIndex > 0;\n const moreBelow = endIndex < commands.length;\n const moreAboveCount = startIndex;\n const moreBelowCount = commands.length - endIndex;\n\n // Calculate parameter tooltip lines for selected command\n const safeIndex = Math.max(0, Math.min(selectedIndex, commands.length - 1));\n const selectedCmd = commands[safeIndex];\n const paramTooltipLines =\n showParameterInfo && selectedCmd?.parameters ? selectedCmd.parameters.length : 0;\n\n // Calculate exact rendered height by counting lines we're about to render:\n // 1. Header line\n // 2. More above indicator (conditional)\n // 3. Each visible command (1 line each)\n // 4. Parameter tooltips for selected command (conditional, N lines)\n // 5. More below indicator (conditional)\n // 6. Footer line\n const actualHeight = useMemo(() => {\n let height = 0;\n height += 1; // header\n if (moreAbove) height += 1; // more above indicator\n height += visibleCommands.length; // all visible command items\n height += paramTooltipLines; // parameter tooltips for selected command\n if (moreBelow) height += 1; // more below indicator\n height += 1; // footer\n return height;\n }, [moreAbove, visibleCommands.length, paramTooltipLines, moreBelow]);\n\n // Report height to parent\n React.useEffect(() => {\n if (onHeightCalculated) {\n onHeightCalculated(actualHeight);\n }\n }, [onHeightCalculated, actualHeight]);\n\n // Calculate max width for consistent backgrounds, clamped to terminal width\n const maxWidth = useMemo(() => {\n const header = ` Commands (${commands.length}) `;\n const moreText = moreAbove ? ` ▲ ${moreAboveCount} more above ` : '';\n const moreBelowText = moreBelow ? ` ▼ ${moreBelowCount} more below ` : '';\n\n const cmdLengths = visibleCommands.map((cmd) => {\n const cmdLine = ` /${cmd.name} - ${cmd.description}`;\n let maxLen = cmdLine.length;\n if (showParameterInfo && cmd.parameters) {\n cmd.parameters.forEach((param) => {\n const paramLine = ` <${param.name}>: ${param.description}`;\n maxLen = Math.max(maxLen, paramLine.length);\n });\n }\n return maxLen;\n });\n\n const lengths = [\n header.length,\n footerText.length,\n moreText.length,\n moreBelowText.length,\n ...cmdLengths,\n ];\n const idealWidth = Math.max(...lengths, 50); // Minimum 50 chars\n return Math.min(idealWidth, maxAllowedWidth); // Clamp to terminal width\n }, [\n commands.length,\n visibleCommands,\n showParameterInfo,\n moreAbove,\n moreBelow,\n moreAboveCount,\n moreBelowCount,\n footerText,\n maxAllowedWidth,\n ]);\n\n return (\n <Box flexDirection=\"column\" flexShrink={0}>\n <Text>{bgLine(` Commands (${commands.length}) `, maxWidth, autocompleteHeaderText)}</Text>\n {moreAbove && (\n <Text>\n {bgLine(` ▲ ${moreAboveCount} more above `, maxWidth, autocompleteMoreIndicator)}\n </Text>\n )}\n {(() => {\n // Calculate consistent column width for all commands (table layout)\n // Find longest command name in the visible set\n const longestCmdName = Math.max(...visibleCommands.map((c) => c.name.length));\n const cmdColumnWidth = longestCmdName + 2; // +2 for '/' and spacing\n\n // Also check parameters if showing\n let longestParamSig = 0;\n if (showParameterInfo) {\n for (const cmd of visibleCommands) {\n if (cmd.parameters) {\n for (const p of cmd.parameters) {\n const paramSig = `/${cmd.name} <${p.name}>`.length;\n longestParamSig = Math.max(longestParamSig, paramSig);\n }\n }\n }\n }\n const signatureColumnWidth = Math.max(cmdColumnWidth, longestParamSig + 2);\n\n return visibleCommands.map((command, idx) => {\n const actualIndex = startIndex + idx;\n const isSelected = actualIndex === safeSelectedIndex;\n const prefix = isSelected ? '> ' : ' ';\n\n // Build table row: [prefix][/name][padding][description]\n const cmdName = `${prefix}/${command.name}`;\n const cmdPadding = ' '.repeat(Math.max(1, signatureColumnWidth - cmdName.length + 2));\n const cmdLine = cmdName + cmdPadding + command.description;\n const cmdTruncated = truncateText(cmdLine, maxWidth);\n\n // Split at description boundary\n const descStartIdx = cmdName.length + cmdPadding.length;\n const cmdPart = cmdTruncated.substring(0, Math.min(descStartIdx, cmdTruncated.length));\n const descPart = cmdTruncated.substring(Math.min(descStartIdx, cmdTruncated.length));\n const rowPadding = ' '.repeat(Math.max(0, maxWidth - cmdTruncated.length));\n\n return (\n <React.Fragment key={`${actualIndex}-${command.name}`}>\n <Text>\n {isSelected\n ? autocompleteSelectedBg(\n autocompleteSelectedText(cmdPart) +\n autocompleteSelectedText(chalk.dim(descPart)) +\n autocompleteSelectedText(rowPadding)\n )\n : bg(\n autocompleteText(cmdPart) +\n autocompleteText(chalk.dim(descPart)) +\n autocompleteText(rowPadding)\n )}\n </Text>\n {isSelected &&\n showParameterInfo &&\n command.parameters &&\n command.parameters.length > 0 &&\n command.parameters.map((param) => {\n // Parameter row: [ <param>][padding][description] (indented by 2 spaces)\n const paramSig = ` <${param.name}>`;\n const paramPadding = ' '.repeat(\n Math.max(1, signatureColumnWidth - paramSig.length + 2)\n );\n const paramLine = paramSig + paramPadding + param.description;\n const paramTruncated = truncateText(paramLine, maxWidth);\n\n const paramDescStartIdx = paramSig.length + paramPadding.length;\n const paramSigPart = paramTruncated.substring(\n 0,\n Math.min(paramDescStartIdx, paramTruncated.length)\n );\n const paramDescPart = paramTruncated.substring(\n Math.min(paramDescStartIdx, paramTruncated.length)\n );\n const paramRowPadding = ' '.repeat(Math.max(0, maxWidth - paramTruncated.length));\n\n return (\n <Text key={`${actualIndex}-${command.name}-${param.name}`}>\n {paramBg(\n autocompleteText(chalk.dim(paramSigPart)) +\n autocompleteText(chalk.hex('#8b95a8')(paramDescPart)) +\n autocompleteText(paramRowPadding)\n )}\n </Text>\n );\n })}\n </React.Fragment>\n );\n });\n })()}\n {moreBelow && (\n <Text>\n {bgLine(` ▼ ${moreBelowCount} more below `, maxWidth, autocompleteMoreIndicator)}\n </Text>\n )}\n <Text>{bgLine(footerText, maxWidth, autocompleteFooterText)}</Text>\n </Box>\n );\n};\n","import { useEffect, useState } from 'react';\nimport { useStdout } from 'ink';\n\n/**\n * Custom hook for reactive terminal dimensions\n *\n * Unlike useStdout() which provides static dimensions,\n * this hook ensures component re-renders when terminal is resized.\n *\n * @returns {width: number, height: number} - Current terminal dimensions\n */\nexport const useTerminalSize = (): { width: number; height: number } => {\n const { stdout } = useStdout();\n\n // Initialize with current dimensions or fallback to 80x24\n const [dimensions, setDimensions] = useState({\n width: stdout?.columns || 80,\n height: stdout?.rows || 24,\n });\n\n useEffect(() => {\n if (!stdout) return;\n\n // Handler for terminal resize events (SIGWINCH)\n const handleResize = () => {\n setDimensions({\n width: stdout.columns || 80,\n height: stdout.rows || 24,\n });\n };\n\n // Listen for resize events\n // Ink automatically handles SIGWINCH and emits 'resize' on stdout\n stdout.on('resize', handleResize);\n\n // Update dimensions immediately in case they changed before listener was attached\n handleResize();\n\n // Cleanup listener on unmount\n return () => {\n stdout.off('resize', handleResize);\n };\n }, [stdout]);\n\n return dimensions;\n};\n","/**\n * Chat footer component\n * Displays mode, cost, keyboard shortcuts and help tips\n */\n\nimport React, { useState, useEffect } from 'react';\nimport { Box, Text } from 'ink';\nimport { Theme, KeyBindingsConfig } from '../../config/schemas.js';\nimport { getTheme } from '../../config/themes/index.js';\nimport { getRandomTip } from './tips.js';\nimport { formatKeyboardShortcut } from '../../utils/keyboardFormatter.js';\n\nexport interface FooterProps {\n theme: Theme;\n shortcuts: KeyBindingsConfig;\n mode: 'plan' | 'act' | 'discuss';\n cost: number;\n interruptPressCount?: number;\n isAgentRunning?: boolean;\n}\n\nexport const Footer: React.FC<FooterProps> = ({\n theme,\n shortcuts,\n mode,\n cost,\n interruptPressCount = 0,\n isAgentRunning = false,\n}) => {\n const themeDefinition = getTheme(theme);\n\n // Get mode display with icon, color, and capitalization\n const getModeDisplay = (): JSX.Element => {\n switch (mode) {\n case 'plan':\n return <Text>{themeDefinition.colors.modePlan('□ PLAN ')}</Text>;\n case 'act':\n return <Text>{themeDefinition.colors.modeAct('▶ ACT ')}</Text>;\n case 'discuss':\n return <Text>{themeDefinition.colors.modeDiscuss('◉ DISCUSS')}</Text>;\n }\n };\n\n // Random tip that rotates every 10 seconds\n const [currentTip, setCurrentTip] = useState(getRandomTip(shortcuts));\n\n useEffect(() => {\n const interval = setInterval(() => {\n setCurrentTip(getRandomTip(shortcuts));\n }, 10000); // Change tip every 10 seconds\n\n return () => clearInterval(interval);\n }, [shortcuts]);\n\n // Get message to display below shortcuts\n const getMessage = () => {\n if (interruptPressCount === 1) {\n const interruptKey = formatKeyboardShortcut(shortcuts.interrupt);\n if (isAgentRunning) {\n return (\n <Text>\n {themeDefinition.colors.warning(\n `Agent interrupted. Press ${interruptKey} again to exit`\n )}\n </Text>\n );\n } else {\n return <Text>{themeDefinition.colors.warning(`Press ${interruptKey} again to exit`)}</Text>;\n }\n }\n return <Text dimColor>{currentTip}</Text>;\n };\n\n return (\n <Box flexDirection=\"column\">\n <Box>\n <Text>\n Mode: {getModeDisplay()}\n {' | '}\n Cost: <Text>{themeDefinition.colors.warning(`$${cost.toFixed(4)}`)}</Text>\n </Text>\n </Box>\n <Box>\n <Text dimColor>\n {formatKeyboardShortcut(shortcuts.interrupt)}=Cancel |{' '}\n {formatKeyboardShortcut(shortcuts.modeSwitch)}=Mode | /help=Commands\n </Text>\n </Box>\n <Box>{getMessage()}</Box>\n </Box>\n );\n};\n","/**\n * Random tips displayed in the footer\n */\n\nimport { KeyBindingsConfig } from '../../config/schemas.js';\nimport { formatKeyboardShortcut } from '../../utils/keyboardFormatter.js';\n\n/**\n * Generate tips array with dynamic keyboard shortcuts\n */\nfunction generateTips(keyBindings: KeyBindingsConfig): string[] {\n const modeSwitchKey = formatKeyboardShortcut(keyBindings.modeSwitch, { showFirstOnly: true });\n const editKey = formatKeyboardShortcut(keyBindings.editCommand, { showFirstOnly: true });\n\n return [\n 'Tip: Use /help to see all available commands',\n `Tip: Switch modes with ${modeSwitchKey} (Plan → Act → Discuss)`,\n 'Tip: Type /plan <task> to create an execution plan',\n 'Tip: Use /discuss <topic> to enter architect/discuss mode',\n 'Tip: Your conversation history is automatically saved',\n 'Tip: Check total costs with /cost to track your spending',\n `Tip: Use ${editKey} to edit your last command (coming soon)`,\n 'Tip: The permission system keeps your code safe - review commands before they run',\n 'Tip: Docker sandboxing isolates untrusted code execution',\n 'Tip: MCP servers extend Mimir with custom tools and capabilities',\n 'Tip: Use /model <provider> to switch between LLM providers',\n 'Tip: Create checkpoints with /checkpoint to save your progress',\n 'Tip: Configuration can be customized in .mimir/config.yml',\n ];\n}\n\n/**\n * Get a random tip with dynamic keyboard shortcuts\n */\nexport function getRandomTip(keyBindings: KeyBindingsConfig): string {\n const tips = generateTips(keyBindings);\n const randomIndex = Math.floor(Math.random() * tips.length);\n return tips[randomIndex] ?? 'Tip: Use keyboard shortcuts for faster navigation';\n}\n","/**\n * Central keyboard event bus for dispatching keyboard actions\n * Supports event propagation control and priority-based handling\n */\n\nimport { EventEmitter } from 'events';\nimport { KeyBindingAction, KeyBindingsManager } from '../../utils/KeyBindings.js';\nimport { logger } from '../../utils/logger.js';\n\nexport interface KeyboardEventContext {\n /** Is autocomplete/tooltip currently showing? */\n isAutocompleteVisible: boolean;\n /** Is the agent currently running? */\n isAgentRunning: boolean;\n /** Is there text input currently focused? */\n isInputFocused: boolean;\n /** Custom context data */\n [key: string]: unknown;\n}\n\nexport interface KeyboardEvent {\n /** The semantic action triggered */\n action: KeyBindingAction;\n /** Raw key that was pressed */\n rawKey: string;\n /** Current context when event was triggered */\n context: Readonly<KeyboardEventContext>;\n /** Stop propagation to parent handlers */\n stopPropagation(): void;\n /** Was propagation stopped? */\n isPropagationStopped(): boolean;\n}\n\nexport interface KeyboardEventHandler {\n /** The action this handler responds to */\n action: KeyBindingAction;\n /** Handler function */\n handler: (event: KeyboardEvent) => void | boolean;\n /** Priority (higher = runs first). Default: 0 */\n priority?: number;\n /** Unique ID for this handler (for cleanup) */\n id: string;\n}\n\n/**\n * Central keyboard event bus\n * Manages keyboard event routing with priority and propagation control\n */\nexport class KeyboardEventBus extends EventEmitter {\n private handlers: Map<KeyBindingAction, KeyboardEventHandler[]> = new Map();\n private context: KeyboardEventContext = {\n isAutocompleteVisible: false,\n isAgentRunning: false,\n isInputFocused: true,\n };\n\n constructor(private bindingsManager: KeyBindingsManager) {\n super();\n this.setMaxListeners(50); // Allow many components to subscribe\n }\n\n /**\n * Update keyboard context\n */\n updateContext(updates: Partial<KeyboardEventContext>): void {\n this.context = { ...this.context, ...updates };\n }\n\n /**\n * Get current context (readonly)\n */\n getContext(): Readonly<KeyboardEventContext> {\n return Object.freeze({ ...this.context });\n }\n\n /**\n * Subscribe to keyboard action\n * Returns unsubscribe function\n */\n subscribe(\n action: KeyBindingAction,\n handler: (event: KeyboardEvent) => void | boolean,\n options: { priority?: number; id?: string } = {}\n ): () => void {\n const handlerObj: KeyboardEventHandler = {\n action,\n handler,\n priority: options.priority ?? 0,\n id: options.id ?? `${action}-${Date.now()}-${Math.random()}`,\n };\n\n const handlers = this.handlers.get(action) || [];\n handlers.push(handlerObj);\n\n // Sort by priority (descending)\n handlers.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));\n\n this.handlers.set(action, handlers);\n\n // Return unsubscribe function\n return () => {\n const handlers = this.handlers.get(action);\n if (handlers) {\n const index = handlers.findIndex((h) => h.id === handlerObj.id);\n if (index !== -1) {\n handlers.splice(index, 1);\n }\n }\n };\n }\n\n /**\n * Dispatch a raw key press\n * Converts to action and emits to handlers\n */\n dispatch(rawKey: string): boolean {\n const action = this.bindingsManager.getActionForKey(rawKey);\n\n if (!action) {\n return false;\n }\n\n return this.dispatchAction(action, rawKey);\n }\n\n /**\n * Dispatch a specific action\n * @returns true if event was handled, false otherwise\n */\n dispatchAction(action: KeyBindingAction, rawKey?: string): boolean {\n const handlers = this.handlers.get(action);\n\n if (!handlers || handlers.length === 0) {\n return false;\n }\n\n let propagationStopped = false;\n\n const event: KeyboardEvent = {\n action,\n rawKey: rawKey ?? action,\n context: this.getContext(),\n stopPropagation: () => {\n propagationStopped = true;\n },\n isPropagationStopped: () => propagationStopped,\n };\n\n // Execute handlers in priority order\n for (const { handler, id, priority } of handlers) {\n if (propagationStopped) {\n break;\n }\n\n try {\n const result = handler(event);\n\n // Handler can return false to continue, true to stop propagation\n if (result === false) {\n continue;\n } else if (result === true) {\n event.stopPropagation();\n }\n } catch (error) {\n logger.error(`Error in keyboard handler for ${action}`, {\n error,\n handlerId: id,\n priority,\n });\n }\n }\n\n return true;\n }\n\n /**\n * Remove all handlers for an action\n */\n clearAction(action: KeyBindingAction): void {\n this.handlers.delete(action);\n }\n\n /**\n * Remove all handlers\n */\n clearAll(): void {\n this.handlers.clear();\n }\n\n /**\n * Get all registered actions\n */\n getRegisteredActions(): KeyBindingAction[] {\n return Array.from(this.handlers.keys());\n }\n\n /**\n * Get handler count for action\n */\n getHandlerCount(action: KeyBindingAction): number {\n return this.handlers.get(action)?.length ?? 0;\n }\n}\n","/**\n * React context for keyboard event bus\n * Provides centralized keyboard handling to all components\n */\n\nimport { createContext, useContext, useEffect, useState, ReactNode } from 'react';\nimport { KeyboardEventBus, KeyboardEventContext } from './KeyboardEventBus.js';\nimport { KeyBindingsManager } from '../../utils/KeyBindings.js';\nimport { IFileSystem } from '../../platform/IFileSystem.js';\nimport { KeyBindingsConfig } from '../../config/schemas.js';\n\ninterface KeyboardContextValue {\n eventBus: KeyboardEventBus;\n bindingsManager: KeyBindingsManager;\n updateContext: (updates: Partial<KeyboardEventContext>) => void;\n getContext: () => Readonly<KeyboardEventContext>;\n}\n\nconst KeyboardContext = createContext<KeyboardContextValue | null>(null);\n\nexport interface KeyboardProviderProps {\n children: ReactNode;\n bindingsConfig: KeyBindingsConfig;\n fs: IFileSystem;\n projectRoot?: string;\n}\n\n/**\n * Provider for keyboard system\n * Must wrap the entire app to enable keyboard handling\n */\nexport function KeyboardProvider({\n children,\n bindingsConfig,\n fs: _fs,\n projectRoot: _projectRoot,\n}: KeyboardProviderProps): JSX.Element {\n const [contextValue] = useState<KeyboardContextValue>(() => {\n const bindingsManager = new KeyBindingsManager(bindingsConfig);\n const eventBus = new KeyboardEventBus(bindingsManager);\n\n return {\n eventBus,\n bindingsManager,\n updateContext: (updates) => eventBus.updateContext(updates),\n getContext: () => eventBus.getContext(),\n };\n });\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n contextValue.eventBus.clearAll();\n };\n }, [contextValue]);\n\n return <KeyboardContext.Provider value={contextValue}>{children}</KeyboardContext.Provider>;\n}\n\n/**\n * Hook to access keyboard system\n */\nexport function useKeyboard(): KeyboardContextValue {\n const context = useContext(KeyboardContext);\n\n if (!context) {\n throw new Error('useKeyboard must be used within KeyboardProvider');\n }\n\n return context;\n}\n","/**\n * Keyboard shortcuts with platform-specific bindings\n * Loads from .mimir/config.yml\n */\n\nimport { KeyBindingsConfig } from '../config/schemas.js';\nimport { logger } from './logger.js';\nimport os from 'os';\n\nexport interface KeyBinding {\n keys: string[]; // Now supports multiple shortcuts per action\n displayName: string; // Primary key for display\n action: string;\n description: string;\n}\n\nexport type KeyBindingAction =\n | 'interrupt' // Ctrl+C and Escape - cancel/interrupt operation\n | 'accept' // Enter - confirm action\n | 'modeSwitch' // Shift+Tab - switch modes\n | 'editCommand' // Ctrl+E - edit instruction\n | 'showTooltip' // Ctrl+Space and Tab - show autocomplete\n | 'navigateUp' // Arrow Up - navigate up in lists\n | 'navigateDown' // Arrow Down - navigate down in lists\n | 'help' // ? - show help\n | 'clearScreen' // Ctrl+L - clear screen\n | 'undo' // Ctrl+Z - undo\n | 'redo' // Ctrl+Y (Cmd+Shift+Z on Mac) - redo\n | 'reject'; // @deprecated - use 'interrupt' instead\n\nexport class KeyBindingsManager {\n private bindings: Map<KeyBindingAction, KeyBinding> = new Map();\n private platform: 'darwin' | 'win32' | 'linux';\n\n constructor(private config: KeyBindingsConfig) {\n this.platform = os.platform() as 'darwin' | 'win32' | 'linux';\n this.initializeDefaults();\n }\n\n /**\n * Initialize default platform-specific bindings\n */\n private initializeDefaults(): void {\n const isMac = this.platform === 'darwin';\n const modKey = isMac ? 'Cmd' : 'Ctrl';\n\n // Helper to convert config keys to platform-specific\n const toPlatform = (keys: string[]): string[] => {\n return keys.map((key) => key.replace(/Ctrl/g, modKey));\n };\n\n // Core bindings from config\n this.addBinding('interrupt', {\n keys: toPlatform(this.config.interrupt),\n displayName: toPlatform(this.config.interrupt)[0] ?? 'Ctrl+C',\n action: 'interrupt',\n description: 'Cancel/interrupt current operation',\n });\n\n this.addBinding('accept', {\n keys: this.config.accept,\n displayName: this.config.accept[0] ?? 'Enter',\n action: 'accept',\n description: 'Accept/confirm action',\n });\n\n // Note: 'reject' action is deprecated - use 'interrupt' instead\n // Only add if explicitly configured for backwards compatibility\n if (this.config.reject && this.config.reject.length > 0) {\n this.addBinding('reject', {\n keys: this.config.reject,\n displayName: this.config.reject[0] ?? 'Escape',\n action: 'reject',\n description: 'Reject/cancel prompt (deprecated)',\n });\n }\n\n this.addBinding('modeSwitch', {\n keys: this.config.modeSwitch,\n displayName: this.config.modeSwitch[0] ?? 'Shift+Tab',\n action: 'modeSwitch',\n description: 'Switch between modes',\n });\n\n this.addBinding('editCommand', {\n keys: toPlatform(this.config.editCommand),\n displayName: toPlatform(this.config.editCommand)[0] ?? `${modKey}+E`,\n action: 'editCommand',\n description: 'Edit alternative instruction',\n });\n\n this.addBinding('showTooltip', {\n keys: toPlatform(this.config.showTooltip),\n displayName: toPlatform(this.config.showTooltip)[0] ?? `${modKey}+Space`,\n action: 'showTooltip',\n description: 'Show autocomplete/tooltip',\n });\n\n this.addBinding('navigateUp', {\n keys: this.config.navigateUp,\n displayName: this.config.navigateUp[0] ?? 'ArrowUp',\n action: 'navigateUp',\n description: 'Navigate up in list',\n });\n\n this.addBinding('navigateDown', {\n keys: this.config.navigateDown,\n displayName: this.config.navigateDown[0] ?? 'ArrowDown',\n action: 'navigateDown',\n description: 'Navigate down in list',\n });\n\n this.addBinding('help', {\n keys: this.config.help,\n displayName: this.config.help[0] ?? '?',\n action: 'help',\n description: 'Show help overlay',\n });\n\n this.addBinding('clearScreen', {\n keys: toPlatform(this.config.clearScreen),\n displayName: toPlatform(this.config.clearScreen)[0] ?? `${modKey}+L`,\n action: 'clearScreen',\n description: 'Clear screen',\n });\n\n this.addBinding('undo', {\n keys: toPlatform(this.config.undo),\n displayName: toPlatform(this.config.undo)[0] ?? `${modKey}+Z`,\n action: 'undo',\n description: 'Undo last action',\n });\n\n // Redo has platform-specific default\n const redoKeys = isMac ? [`${modKey}+Shift+Z`] : toPlatform(this.config.redo);\n\n this.addBinding('redo', {\n keys: redoKeys,\n displayName: redoKeys[0] ?? `${modKey}+Y`,\n action: 'redo',\n description: 'Redo last undone action',\n });\n }\n\n /**\n * Add or override a key binding\n */\n private addBinding(action: KeyBindingAction, binding: KeyBinding): void {\n this.bindings.set(action, binding);\n }\n\n /**\n * Get binding for action\n */\n getBinding(action: KeyBindingAction): KeyBinding | undefined {\n return this.bindings.get(action);\n }\n\n /**\n * Get all bindings\n */\n getAllBindings(): Map<KeyBindingAction, KeyBinding> {\n return new Map(this.bindings);\n }\n\n /**\n * Get help text for all shortcuts\n */\n getHelpText(): string {\n const lines = ['Keyboard Shortcuts:', ''];\n\n for (const [, binding] of this.bindings) {\n // Format multiple keys as \"Ctrl+C, Escape\"\n const keysDisplay = binding.keys.join(', ');\n lines.push(` ${keysDisplay.padEnd(20)} ${binding.description}`);\n }\n\n return lines.join('\\n');\n }\n\n /**\n * Normalize key string for comparison\n * Handles: Ctrl/Control, Cmd/Command, variations in case\n */\n static normalizeKey(key: string): string {\n return key\n .replace(/Control/gi, 'Ctrl')\n .replace(/Command/gi, 'Cmd')\n .replace(/Delete/gi, 'Del')\n .replace(/Escape/gi, 'Esc')\n .split('+')\n .map((part) => part.trim())\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())\n .join('+');\n }\n\n /**\n * Check if pressed key matches any binding for the action\n */\n matches(pressedKey: string, action: KeyBindingAction): boolean {\n const binding = this.bindings.get(action);\n if (!binding || !binding.keys) return false;\n\n const normalizedPressed = KeyBindingsManager.normalizeKey(pressedKey);\n\n // Check if pressed key matches any of the bound keys\n return binding.keys.some((key) => {\n const normalizedBinding = KeyBindingsManager.normalizeKey(key);\n return normalizedPressed === normalizedBinding;\n });\n }\n\n /**\n * Get action for a pressed key (reverse lookup)\n */\n getActionForKey(pressedKey: string): KeyBindingAction | null {\n const normalizedPressed = KeyBindingsManager.normalizeKey(pressedKey);\n\n for (const [action, binding] of this.bindings) {\n // Defensive check: skip if binding is somehow undefined\n if (!binding || !binding.keys) {\n logger.warn(`Invalid binding for action: ${action}`, { binding });\n continue;\n }\n\n if (binding.keys.some((key) => KeyBindingsManager.normalizeKey(key) === normalizedPressed)) {\n return action;\n }\n }\n\n return null;\n }\n\n /**\n * Get platform-specific modifier key name\n */\n static getModifierKey(platform?: NodeJS.Platform): string {\n const p = platform || os.platform();\n return p === 'darwin' ? 'Cmd' : 'Ctrl';\n }\n\n /**\n * Convert config binding to platform-specific display\n */\n static toPlatformBinding(binding: string, platform?: NodeJS.Platform): string {\n const modKey = KeyBindingsManager.getModifierKey(platform);\n return binding.replace(/Ctrl|Cmd/gi, modKey);\n }\n}\n","/**\n * React hook for subscribing to keyboard actions\n * Components use this to handle specific keyboard shortcuts\n */\n\nimport { useEffect, useRef } from 'react';\nimport { KeyBindingAction } from '../../utils/KeyBindings.js';\nimport { KeyboardEvent } from './KeyboardEventBus.js';\nimport { useKeyboard } from './KeyboardContext.js';\n\nexport interface UseKeyboardActionOptions {\n /**\n * Priority for this handler (higher = runs first)\n * Use this for nested components where child should handle before parent\n * Default: 0\n */\n priority?: number;\n\n /**\n * Enable/disable this handler\n * Default: true\n */\n enabled?: boolean;\n\n /**\n * Unique ID for this handler (for debugging)\n * Default: auto-generated\n */\n id?: string;\n}\n\n/**\n * Subscribe to a keyboard action\n * Handler can return true to stop propagation to parent handlers\n *\n * @example\n * // Handle Escape in a tooltip (child component)\n * useKeyboardAction('reject', (event) => {\n * if (!isTooltipVisible) return false; // Let parent handle it\n * hideTooltip();\n * return true; // Stop propagation - we handled it\n * }, { priority: 10 }); // Higher priority than parent\n *\n * // Handle Escape in main interface (parent component)\n * useKeyboardAction('reject', (event) => {\n * showExitConfirmation();\n * return true;\n * }, { priority: 0 });\n */\nexport function useKeyboardAction(\n action: KeyBindingAction,\n handler: (event: KeyboardEvent) => void | boolean,\n options: UseKeyboardActionOptions = {}\n): void {\n const { eventBus } = useKeyboard();\n const { priority = 0, enabled = true, id } = options;\n\n // Use ref to avoid recreating handler on every render\n const handlerRef = useRef(handler);\n useEffect(() => {\n handlerRef.current = handler;\n }, [handler]);\n\n useEffect(() => {\n if (!enabled) return;\n\n // Wrap handler to use latest version from ref\n const wrappedHandler = (event: KeyboardEvent) => {\n return handlerRef.current(event);\n };\n\n const unsubscribe = eventBus.subscribe(action, wrappedHandler, {\n priority,\n id,\n });\n\n return unsubscribe;\n }, [eventBus, action, priority, enabled, id]);\n}\n\n/**\n * Subscribe to multiple keyboard actions with the same handler\n */\nexport function useKeyboardActions(\n actions: KeyBindingAction[],\n handler: (event: KeyboardEvent) => void | boolean,\n options: UseKeyboardActionOptions = {}\n): void {\n const { eventBus } = useKeyboard();\n const { priority = 0, enabled = true } = options;\n\n const handlerRef = useRef(handler);\n useEffect(() => {\n handlerRef.current = handler;\n }, [handler]);\n\n useEffect(() => {\n if (!enabled) return;\n\n const wrappedHandler = (event: KeyboardEvent) => {\n return handlerRef.current(event);\n };\n\n const unsubscribers = actions.map((action) =>\n eventBus.subscribe(action, wrappedHandler, {\n priority,\n id: options.id ? `${options.id}-${action}` : undefined,\n })\n );\n\n return () => {\n unsubscribers.forEach((unsub) => unsub());\n };\n }, [eventBus, actions.join(','), priority, enabled, options.id]);\n}\n","/**\n * Top-level keyboard input capture\n * Wraps Ink's useInput and dispatches to KeyboardEventBus\n */\n\nimport { useInput } from 'ink';\nimport { useKeyboard } from './KeyboardContext.js';\n\n/**\n * Ink Key object type\n * Based on Ink's useInput hook callback signature\n */\ninterface InkKey {\n return?: boolean;\n escape?: boolean;\n tab?: boolean;\n shift?: boolean;\n backspace?: boolean;\n delete?: boolean;\n upArrow?: boolean;\n downArrow?: boolean;\n leftArrow?: boolean;\n rightArrow?: boolean;\n pageUp?: boolean;\n pageDown?: boolean;\n ctrl?: boolean;\n meta?: boolean;\n}\n\n/**\n * ASCII control character mapping (0x00-0x1F)\n * Maps character codes to Ctrl+ key combinations\n */\nconst CONTROL_CHAR_MAP: Record<number, string> = {\n 0x00: 'Space',\n 0x01: 'A',\n 0x02: 'B',\n 0x03: 'C',\n 0x04: 'D',\n 0x05: 'E',\n 0x06: 'F',\n 0x07: 'G',\n 0x08: 'H',\n 0x09: 'I',\n 0x0a: 'J',\n 0x0b: 'K',\n 0x0c: 'L',\n 0x0d: 'M',\n 0x0e: 'N',\n 0x0f: 'O',\n 0x10: 'P',\n 0x11: 'Q',\n 0x12: 'R',\n 0x13: 'S',\n 0x14: 'T',\n 0x15: 'U',\n 0x16: 'V',\n 0x17: 'W',\n 0x18: 'X',\n 0x19: 'Y',\n 0x1a: 'Z',\n 0x1b: '[',\n 0x1c: '\\\\',\n 0x1d: ']',\n 0x1e: '^',\n 0x1f: '_',\n};\n\n/**\n * Convert Ink key event to normalized key string\n */\nfunction inkKeyToString(input: string, key: InkKey): string {\n // Special keys\n if (key.return) return 'Enter';\n if (key.escape) return 'Escape';\n if (key.tab) return key.shift ? 'Shift+Tab' : 'Tab';\n if (key.backspace) return 'Backspace';\n if (key.delete) return 'Delete';\n if (key.upArrow) return 'ArrowUp';\n if (key.downArrow) return 'ArrowDown';\n if (key.leftArrow) return 'ArrowLeft';\n if (key.rightArrow) return 'ArrowRight';\n if (key.pageUp) return 'PageUp';\n if (key.pageDown) return 'PageDown';\n\n const charCode = input.length > 0 ? input.charCodeAt(0) : -1;\n\n // Ctrl combinations\n if (key.ctrl) {\n // Control characters (0x00-0x1F)\n if (charCode >= 0x00 && charCode <= 0x1f) {\n const letter = CONTROL_CHAR_MAP[charCode];\n if (letter) {\n return `Ctrl+${letter}`;\n }\n }\n\n // Printable characters\n if (input.length === 1) {\n return `Ctrl+${input.toUpperCase()}`;\n }\n\n return `Ctrl`;\n }\n\n // Meta/Cmd combinations (macOS)\n if (key.meta) {\n if (key.shift && input.length === 1) {\n return `Cmd+Shift+${input.toUpperCase()}`;\n }\n if (input.length === 1) {\n return `Cmd+${input.toUpperCase()}`;\n }\n return `Cmd`;\n }\n\n // Shift combinations\n if (key.shift && input.length === 1) {\n return input;\n }\n\n return input;\n}\n\nexport interface UseKeyboardInputOptions {\n isActive?: boolean;\n}\n\n/**\n * Capture keyboard input and dispatch to event bus\n */\nexport function useKeyboardInput(options: UseKeyboardInputOptions = {}): void {\n const { isActive = true } = options;\n const { eventBus, bindingsManager } = useKeyboard();\n\n useInput(\n (input, key) => {\n if (!isActive) return;\n\n const keyString = inkKeyToString(input, key);\n const action = bindingsManager.getActionForKey(keyString);\n\n if (action) {\n eventBus.dispatchAction(action, keyString);\n }\n },\n { isActive }\n );\n}\n","/**\n * Slash command interface and registry\n * Provides foundation for built-in and custom slash commands in chat interface\n */\n\nimport { z } from 'zod';\n\n/**\n * Result of executing a slash command\n */\nexport interface SlashCommandResult {\n success: boolean;\n // For built-in commands that manipulate state\n action?: 'new_chat' | 'switch_mode' | 'switch_model' | 'send_prompt' | 'open_theme_selector';\n data?: unknown;\n error?: string;\n // For custom commands that inject prompts\n prompt?: string;\n}\n\n/**\n * Context provided to slash commands during execution\n */\nexport interface SlashCommandContext {\n // Current chat state (read-only for commands)\n currentMode: 'plan' | 'act' | 'discuss';\n currentProvider: string;\n currentModel: string;\n messageCount: number;\n // Callbacks for commands to request actions\n requestModeSwitch?: (mode: 'plan' | 'act' | 'discuss') => void;\n requestModelSwitch?: (provider: string, model?: string) => void | Promise<void>;\n requestNewChat?: () => void;\n requestThemeChange?: (theme: string) => void | Promise<void>;\n // For custom commands - send prompt to agent\n sendPrompt?: (prompt: string) => void;\n}\n\n/**\n * Parameter definition for commands\n */\nexport interface CommandParameter {\n name: string;\n description: string;\n required: boolean;\n // For autocomplete - provide suggestions\n suggestions?: string[];\n}\n\n/**\n * Slash command interface\n */\nexport interface ISlashCommand {\n name: string;\n description: string;\n usage: string;\n aliases?: string[];\n // Parameter definitions for help and autocomplete\n parameters?: CommandParameter[];\n // Zod schema for argument validation (optional)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n argsSchema?: z.ZodSchema<any>;\n // Execute the command with parsed arguments\n execute(args: string[], context: SlashCommandContext): Promise<SlashCommandResult>;\n // Get parameter suggestions for autocomplete (optional)\n // currentArgs: already-typed arguments (e.g., for \"/model deepseek \", currentArgs = [\"deepseek\"])\n getParameterSuggestions?: (\n paramIndex: number,\n context: SlashCommandContext,\n currentArgs?: string[]\n ) => string[];\n}\n\n/**\n * Registry for slash commands\n */\nexport class SlashCommandRegistry {\n private commands: Map<string, ISlashCommand> = new Map();\n private aliases: Map<string, string> = new Map();\n\n register(command: ISlashCommand): void {\n this.commands.set(command.name, command);\n\n // Register aliases\n if (command.aliases) {\n command.aliases.forEach((alias) => {\n this.aliases.set(alias, command.name);\n });\n }\n }\n\n unregister(commandName: string): void {\n const command = this.commands.get(commandName);\n if (command?.aliases) {\n command.aliases.forEach((alias) => this.aliases.delete(alias));\n }\n this.commands.delete(commandName);\n }\n\n get(nameOrAlias: string): ISlashCommand | undefined {\n // Check if it's an alias first\n const actualName = this.aliases.get(nameOrAlias) ?? nameOrAlias;\n return this.commands.get(actualName);\n }\n\n getAll(): ISlashCommand[] {\n return Array.from(this.commands.values());\n }\n\n has(nameOrAlias: string): boolean {\n return this.aliases.has(nameOrAlias) || this.commands.has(nameOrAlias);\n }\n\n async execute(\n nameOrAlias: string,\n args: string[],\n context: SlashCommandContext\n ): Promise<SlashCommandResult> {\n const command = this.get(nameOrAlias);\n\n if (!command) {\n return {\n success: false,\n error: `Command not found: /${nameOrAlias}`,\n };\n }\n\n try {\n // Validate args if schema provided\n if (command.argsSchema) {\n command.argsSchema.parse(args);\n }\n\n return await command.execute(args, context);\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n // For autocomplete\n search(prefix: string): ISlashCommand[] {\n const results: ISlashCommand[] = [];\n const lowerPrefix = prefix.toLowerCase();\n\n for (const command of this.commands.values()) {\n if (command.name.toLowerCase().startsWith(lowerPrefix)) {\n results.push(command);\n } else if (command.aliases?.some((a) => a.toLowerCase().startsWith(lowerPrefix))) {\n results.push(command);\n }\n }\n\n // Sort results alphabetically by name for consistent, predictable ordering\n return results.sort((a, b) => a.name.localeCompare(b.name));\n }\n}\n","/**\n * Custom command loader\n * Loads custom slash commands from YAML files in .mimir/commands/\n */\n\nimport { z } from 'zod';\nimport yaml from 'yaml';\nimport path from 'path';\nimport os from 'os';\nimport { IFileSystem } from '../platform/IFileSystem.js';\nimport { ISlashCommand, SlashCommandContext, SlashCommandResult } from './SlashCommand.js';\nimport { logger } from '../utils/logger.js';\n\n/**\n * Schema for custom command YAML files\n */\nconst CustomCommandSchema = z.object({\n name: z\n .string()\n .regex(/^[a-z][a-z0-9-]*$/, 'Command name must be lowercase alphanumeric with hyphens'),\n description: z.string(),\n usage: z.string(),\n aliases: z.array(z.string()).optional(),\n prompt: z.string(),\n});\n\ntype CustomCommandDefinition = z.infer<typeof CustomCommandSchema>;\n\n/**\n * Custom command loaded from YAML file\n */\nclass CustomCommand implements ISlashCommand {\n constructor(private definition: CustomCommandDefinition) {}\n\n get name(): string {\n return this.definition.name;\n }\n\n get description(): string {\n return this.definition.description;\n }\n\n get usage(): string {\n return this.definition.usage;\n }\n\n get aliases(): string[] | undefined {\n return this.definition.aliases;\n }\n\n async execute(args: string[], context: SlashCommandContext): Promise<SlashCommandResult> {\n // Substitute placeholders in prompt\n let prompt = this.definition.prompt;\n\n // $1, $2, $3... for individual args\n args.forEach((arg, index) => {\n const placeholder = `$${index + 1}`;\n prompt = prompt.replace(new RegExp(`\\\\${placeholder}`, 'g'), arg);\n });\n\n // $ARGUMENTS for all args joined\n const allArgs = args.join(' ');\n prompt = prompt.replace(/\\$ARGUMENTS/g, allArgs);\n\n // Send prompt to agent via context\n if (context.sendPrompt) {\n context.sendPrompt(prompt);\n return {\n success: true,\n action: 'send_prompt',\n prompt,\n };\n }\n\n return {\n success: false,\n error: 'Context does not support sending prompts',\n };\n }\n}\n\n/**\n * Loads custom commands from .yml files\n */\nexport class CustomCommandLoader {\n constructor(private fs: IFileSystem) {}\n\n /**\n * Load custom commands from both global and project directories\n */\n async loadAll(projectRoot?: string): Promise<ISlashCommand[]> {\n const commandMap = new Map<string, ISlashCommand>();\n\n // Load global commands first\n const globalCommands = await this.loadFromDirectory(\n path.join(os.homedir(), '.mimir', 'commands')\n );\n globalCommands.forEach((cmd) => commandMap.set(cmd.name, cmd));\n\n // Project commands override global\n if (projectRoot) {\n const projectCommands = await this.loadFromDirectory(\n path.join(projectRoot, '.mimir', 'commands')\n );\n projectCommands.forEach((cmd) => {\n if (commandMap.has(cmd.name)) {\n logger.info('Project command overrides global', { name: cmd.name });\n }\n commandMap.set(cmd.name, cmd);\n });\n }\n\n return Array.from(commandMap.values());\n }\n\n /**\n * Load commands from a specific directory\n */\n private async loadFromDirectory(dirPath: string): Promise<ISlashCommand[]> {\n const commands: ISlashCommand[] = [];\n\n try {\n if (!(await this.fs.exists(dirPath))) {\n return commands;\n }\n\n const files = await this.fs.glob('*.yml', { cwd: dirPath });\n\n for (const file of files) {\n const fullPath = path.join(dirPath, file);\n const command = await this.loadCommand(fullPath);\n if (command) {\n commands.push(command);\n }\n }\n\n logger.info('Loaded custom commands', {\n directory: dirPath,\n count: commands.length,\n });\n } catch (error) {\n logger.warn('Failed to load commands from directory', {\n directory: dirPath,\n error,\n });\n }\n\n return commands;\n }\n\n /**\n * Load a single command from YAML file\n */\n private async loadCommand(filePath: string): Promise<ISlashCommand | null> {\n try {\n const content = await this.fs.readFile(filePath);\n const data = yaml.parse(content) as unknown;\n const definition = CustomCommandSchema.parse(data);\n\n return new CustomCommand(definition);\n } catch (error) {\n logger.warn('Failed to load custom command', {\n file: filePath,\n error,\n });\n return null;\n }\n }\n\n /**\n * Validate custom command file without loading\n */\n async validate(filePath: string): Promise<{ valid: boolean; error?: string }> {\n try {\n const content = await this.fs.readFile(filePath);\n const data = yaml.parse(content) as unknown;\n CustomCommandSchema.parse(data);\n return { valid: true };\n } catch (error) {\n return {\n valid: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n}\n","/**\n * Graceful signal handling (SIGINT, SIGTERM)\n * Handles Ctrl+C and termination signals at the application level\n */\n\nimport { logger } from '../../utils/logger.js';\nimport { KeyBindingsConfig } from '../../config/schemas.js';\nimport { formatKeyboardShortcut } from '../../utils/keyboardFormatter.js';\n\nexport interface SignalHandlerOptions {\n /**\n * Callback to run before exit\n * For cleanup: close DB, stop containers, etc.\n */\n onCleanup?: () => Promise<void> | void;\n\n /**\n * Number of Ctrl+C presses before emergency exit\n * Default: 3\n */\n emergencyExitCount?: number;\n\n /**\n * Timeout in ms for cleanup\n * If cleanup takes longer, force exit\n * Default: 5000 (5 seconds)\n */\n cleanupTimeout?: number;\n\n /**\n * Time window in ms for counting rapid presses\n * Default: 2000 (2 seconds)\n */\n rapidPressWindow?: number;\n\n /**\n * Keyboard bindings configuration for displaying interrupt key\n * Optional - if not provided, defaults to \"Ctrl+C\"\n */\n keyBindings?: KeyBindingsConfig;\n}\n\nexport class SignalHandler {\n private sigintCount = 0;\n private cleanupTimeout: NodeJS.Timeout | null = null;\n private rapidPressTimeout: NodeJS.Timeout | null = null;\n private isCleaningUp = false;\n private cleanupPromise: Promise<void> | null = null;\n\n private readonly emergencyExitCount: number;\n private readonly cleanupTimeoutMs: number;\n private readonly rapidPressWindowMs: number;\n private readonly onCleanup?: () => Promise<void> | void;\n private readonly interruptKeyDisplay: string;\n\n constructor(options: SignalHandlerOptions = {}) {\n this.emergencyExitCount = options.emergencyExitCount ?? 3;\n this.cleanupTimeoutMs = options.cleanupTimeout ?? 5000;\n this.rapidPressWindowMs = options.rapidPressWindow ?? 2000;\n this.onCleanup = options.onCleanup;\n\n // Format interrupt key for display (defaults to Ctrl+C if no bindings provided)\n this.interruptKeyDisplay = options.keyBindings\n ? formatKeyboardShortcut(options.keyBindings.interrupt, { showFirstOnly: true })\n : 'Ctrl+C';\n }\n\n /**\n * Install signal handlers\n * Call this once at app startup\n */\n install(): void {\n // Handle SIGINT (Ctrl+C)\n process.on('SIGINT', () => void this.handleSigint());\n\n // Handle SIGTERM (kill command)\n process.on('SIGTERM', () => void this.handleSigterm());\n\n // Handle SIGBREAK (Ctrl+Break on Windows)\n // On Windows, this is sometimes triggered instead of SIGINT\n if (process.platform === 'win32') {\n process.on('SIGBREAK', () => void this.handleSigint());\n }\n\n logger.debug('Signal handlers installed', {\n platform: process.platform,\n emergencyExitCount: this.emergencyExitCount,\n cleanupTimeout: this.cleanupTimeoutMs,\n });\n }\n\n /**\n * Handle SIGINT (Ctrl+C)\n * Allows multiple presses for emergency exit\n */\n private async handleSigint(): Promise<void> {\n this.sigintCount++;\n\n // Reset counter after rapid press window\n if (this.rapidPressTimeout) {\n clearTimeout(this.rapidPressTimeout);\n }\n this.rapidPressTimeout = setTimeout(() => {\n this.sigintCount = 0;\n }, this.rapidPressWindowMs);\n\n logger.debug(`SIGINT received (${this.sigintCount}/${this.emergencyExitCount})`);\n\n // Emergency exit on Nth press\n if (this.sigintCount >= this.emergencyExitCount) {\n logger.warn('Emergency exit triggered');\n this.emergencyExit();\n return;\n }\n\n // First press: start graceful cleanup\n if (this.sigintCount === 1) {\n await this.gracefulExit('SIGINT');\n } else {\n // Subsequent presses: warn user\n console.error(\n `\\nPress ${this.interruptKeyDisplay} ${this.emergencyExitCount - this.sigintCount} more time(s) to force exit`\n );\n }\n }\n\n /**\n * Handle SIGTERM (kill command)\n * Always does graceful cleanup\n */\n private async handleSigterm(): Promise<void> {\n logger.debug('SIGTERM received');\n await this.gracefulExit('SIGTERM');\n }\n\n /**\n * Perform graceful exit with cleanup\n */\n private async gracefulExit(signal: string): Promise<void> {\n if (this.isCleaningUp) {\n logger.debug('Cleanup already in progress');\n // Wait for existing cleanup to finish\n if (this.cleanupPromise) {\n await this.cleanupPromise;\n }\n return;\n }\n\n this.isCleaningUp = true;\n\n logger.info(`Graceful shutdown initiated (${signal})`);\n\n // Set cleanup timeout\n this.cleanupTimeout = setTimeout(() => {\n logger.warn('Cleanup timeout exceeded, forcing exit');\n this.forceExit(1);\n }, this.cleanupTimeoutMs);\n\n // Run cleanup\n this.cleanupPromise = this.runCleanup();\n\n try {\n await this.cleanupPromise;\n logger.info('Cleanup completed successfully');\n this.exit(0);\n } catch (error) {\n logger.error('Error during cleanup', { error });\n this.exit(1);\n } finally {\n if (this.cleanupTimeout) {\n clearTimeout(this.cleanupTimeout);\n }\n }\n }\n\n /**\n * Run user-provided cleanup function\n */\n private async runCleanup(): Promise<void> {\n if (!this.onCleanup) {\n return;\n }\n\n try {\n await this.onCleanup();\n } catch (error) {\n logger.error('Cleanup function threw error', { error });\n throw error;\n }\n }\n\n /**\n * Emergency exit without cleanup\n */\n private emergencyExit(): void {\n console.error('\\n\\nEmergency exit - no cleanup performed');\n this.forceExit(130); // Standard exit code for Ctrl+C\n }\n\n /**\n * Normal exit after cleanup\n */\n private exit(code: number): void {\n // Clear alternate screen buffer if in use\n process.stdout.write('\\x1b[?1049l');\n\n process.exit(code);\n }\n\n /**\n * Force exit immediately\n */\n private forceExit(code: number): void {\n process.stdout.write('\\x1b[?1049l');\n process.exit(code);\n }\n\n /**\n * Remove signal handlers\n * For testing or if you need to uninstall\n */\n uninstall(): void {\n process.removeAllListeners('SIGINT');\n process.removeAllListeners('SIGTERM');\n\n // Remove SIGBREAK listener on Windows\n if (process.platform === 'win32') {\n process.removeAllListeners('SIGBREAK');\n }\n\n if (this.rapidPressTimeout) {\n clearTimeout(this.rapidPressTimeout);\n }\n if (this.cleanupTimeout) {\n clearTimeout(this.cleanupTimeout);\n }\n\n logger.debug('Signal handlers removed');\n }\n}\n\n/**\n * Install signal handlers with cleanup callback\n * Returns SignalHandler instance for manual control if needed\n */\nexport function installSignalHandlers(options: SignalHandlerOptions = {}): SignalHandler {\n const handler = new SignalHandler(options);\n handler.install();\n return handler;\n}\n","/**\n * /new command\n * Starts a new chat conversation\n */\n\nimport {\n ISlashCommand,\n SlashCommandContext,\n SlashCommandResult,\n} from '../../../core/SlashCommand.js';\n\nexport class NewCommand implements ISlashCommand {\n name = 'new';\n description = 'Start a new chat conversation';\n usage = '/new';\n aliases = ['n', 'clear'];\n\n async execute(_args: string[], context: SlashCommandContext): Promise<SlashCommandResult> {\n if (context.requestNewChat) {\n context.requestNewChat();\n return {\n success: true,\n action: 'new_chat',\n };\n }\n\n return {\n success: false,\n error: 'New chat not supported in this context',\n };\n }\n}\n","/**\n * /model command\n * Switch LLM provider/model\n */\n\nimport { z } from 'zod';\nimport {\n ISlashCommand,\n SlashCommandContext,\n SlashCommandResult,\n CommandParameter,\n} from '../../../core/SlashCommand.js';\n\nexport class ModelCommand implements ISlashCommand {\n name = 'model';\n description = 'Switch LLM provider/model';\n usage = '/model <provider> [model]';\n aliases = ['provider', 'm'];\n\n parameters: CommandParameter[] = [\n {\n name: 'provider',\n description: 'The LLM provider to use',\n required: true,\n suggestions: ['deepseek', 'anthropic', 'openai', 'google', 'gemini', 'qwen', 'ollama'],\n },\n {\n name: 'model',\n description: 'Optional specific model name',\n required: false,\n },\n ];\n\n argsSchema = z.tuple([\n z.enum(['deepseek', 'anthropic', 'openai', 'google', 'gemini', 'qwen', 'ollama']),\n z.string().optional(),\n ]);\n\n getParameterSuggestions(\n paramIndex: number,\n context: SlashCommandContext,\n currentArgs?: string[]\n ): string[] {\n if (paramIndex === 0) {\n return ['deepseek', 'anthropic', 'openai', 'google', 'gemini', 'qwen', 'ollama'];\n }\n\n // Model suggestions based on provider\n // Use the provider the user is currently typing (currentArgs[0]), not the configured provider\n if (paramIndex === 1) {\n const provider = currentArgs?.[0]?.toLowerCase() || context.currentProvider.toLowerCase();\n switch (provider) {\n case 'deepseek':\n return ['deepseek-chat', 'deepseek-reasoner'];\n case 'anthropic':\n return ['claude-sonnet-4-5-20250929', 'claude-opus-4-5-20251101', 'claude-haiku-4-5'];\n case 'openai':\n return ['gpt-4', 'gpt-4-turbo', 'gpt-3.5-turbo'];\n case 'google':\n case 'gemini':\n return ['gemini-pro', 'gemini-ultra'];\n default:\n return [];\n }\n }\n\n return [];\n }\n\n async execute(args: string[], context: SlashCommandContext): Promise<SlashCommandResult> {\n if (args.length === 0) {\n return {\n success: false,\n error: 'Usage: /model <provider> [model]',\n };\n }\n\n const provider = args[0];\n const model = args[1] ?? undefined;\n\n if (context.requestModelSwitch && provider) {\n void context.requestModelSwitch(provider, model);\n return {\n success: true,\n action: 'switch_model',\n data: { provider, model },\n };\n }\n\n return {\n success: false,\n error: 'Model switching not supported in this context',\n };\n }\n}\n","/**\n * /mode command\n * Switch chat mode (plan/act/discuss)\n */\n\nimport { z } from 'zod';\nimport {\n ISlashCommand,\n SlashCommandContext,\n SlashCommandResult,\n CommandParameter,\n} from '../../../core/SlashCommand.js';\n\nexport class ModeCommand implements ISlashCommand {\n name = 'mode';\n description = 'Switch chat mode (plan/act/discuss)';\n usage = '/mode <plan|act|discuss>';\n\n parameters: CommandParameter[] = [\n {\n name: 'mode',\n description: 'The mode to switch to',\n required: true,\n suggestions: ['plan', 'act', 'discuss'],\n },\n ];\n\n argsSchema = z.tuple([z.enum(['plan', 'act', 'discuss'])]);\n\n getParameterSuggestions(\n paramIndex: number,\n _context: SlashCommandContext,\n _currentArgs?: string[]\n ): string[] {\n if (paramIndex === 0) {\n return ['plan', 'act', 'discuss'];\n }\n return [];\n }\n\n async execute(args: string[], context: SlashCommandContext): Promise<SlashCommandResult> {\n if (args.length === 0) {\n return {\n success: false,\n error: 'Usage: /mode <plan|act|discuss>',\n };\n }\n\n const mode = args[0] as 'plan' | 'act' | 'discuss';\n\n if (context.requestModeSwitch) {\n context.requestModeSwitch(mode);\n return {\n success: true,\n action: 'switch_mode',\n data: { mode },\n };\n }\n\n return {\n success: false,\n error: 'Mode switching not supported in this context',\n };\n }\n}\n","/**\n * /help command\n * Show available slash commands\n */\n\nimport {\n ISlashCommand,\n SlashCommandContext,\n SlashCommandResult,\n} from '../../../core/SlashCommand.js';\nimport { SlashCommandRegistry } from '../../../core/SlashCommand.js';\n\nexport class HelpCommand implements ISlashCommand {\n name = 'help';\n description = 'Show available slash commands';\n usage = '/help [command]';\n aliases = ['?', 'h'];\n\n constructor(private registry: SlashCommandRegistry) {}\n\n async execute(args: string[], context: SlashCommandContext): Promise<SlashCommandResult> {\n // Show help for specific command\n if (args.length > 0) {\n const commandName = args[0];\n if (!commandName) {\n return {\n success: false,\n error: 'Command name is required',\n };\n }\n const command = this.registry.get(commandName);\n\n if (!command) {\n return {\n success: false,\n error: `Command not found: /${commandName}`,\n };\n }\n\n const helpText = [\n `Command: /${command.name}`,\n `Description: ${command.description}`,\n `Usage: ${command.usage}`,\n command.aliases?.length ? `Aliases: ${command.aliases.map((a) => `/${a}`).join(', ')}` : '',\n ]\n .filter(Boolean)\n .join('\\n');\n\n if (context.sendPrompt) {\n context.sendPrompt(helpText);\n }\n\n return {\n success: true,\n data: { helpText },\n };\n }\n\n // Show all commands\n const allCommands = this.registry.getAll();\n const helpText = [\n 'Available Commands:',\n '',\n ...allCommands.map((cmd) => ` /${cmd.name.padEnd(15)} - ${cmd.description}`),\n '',\n 'Type /help <command> for more details',\n ].join('\\n');\n\n if (context.sendPrompt) {\n context.sendPrompt(helpText);\n }\n\n return {\n success: true,\n data: { helpText },\n };\n }\n}\n","/**\n * /theme command\n * Lists available themes or changes to specified theme\n */\n\nimport {\n ISlashCommand,\n SlashCommandContext,\n SlashCommandResult,\n CommandParameter,\n} from '../../../core/SlashCommand.js';\nimport { getAllThemes, getThemeMetadata } from '../../../config/themes/index.js';\n\nexport class ThemeCommand implements ISlashCommand {\n name = 'theme';\n description = 'Show available themes or change to specified theme';\n usage = '/theme [theme-name]';\n aliases = ['t'];\n\n parameters: CommandParameter[] = [\n {\n name: 'theme',\n description: 'Theme to switch to (leave empty to list all)',\n required: false,\n suggestions: getAllThemes(),\n },\n ];\n\n getParameterSuggestions(\n paramIndex: number,\n _context: SlashCommandContext,\n _currentArgs?: string[]\n ): string[] {\n if (paramIndex === 0) {\n return getAllThemes();\n }\n return [];\n }\n\n async execute(args: string[], context: SlashCommandContext): Promise<SlashCommandResult> {\n // If no arguments, list available themes\n if (args.length === 0) {\n const themes = getAllThemes();\n const themeList = themes\n .map((t, i) => {\n const meta = getThemeMetadata(t);\n return ` ${i + 1}. ${t} - ${meta.name}`;\n })\n .join('\\n');\n\n const message = `Available themes:\\n${themeList}\\n\\nUse /theme <name> to switch (e.g., /theme dark)`;\n\n return {\n success: true,\n action: 'send_prompt',\n prompt: message,\n };\n }\n\n // Change to specified theme\n const themeName = args[0]?.toLowerCase();\n if (!themeName) {\n return {\n success: false,\n error: 'Theme name is required',\n };\n }\n\n const themes = getAllThemes();\n type ThemeName =\n | 'mimir'\n | 'dark'\n | 'light'\n | 'dark-colorblind'\n | 'light-colorblind'\n | 'dark-ansi'\n | 'light-ansi';\n\n if (!themes.includes(themeName as ThemeName)) {\n return {\n success: false,\n error: `Theme '${themeName}' not found. Available: ${themes.join(', ')}`,\n };\n }\n\n // Request theme change\n if (context.requestThemeChange) {\n await context.requestThemeChange(themeName as ThemeName);\n return {\n success: true,\n action: 'send_prompt',\n prompt: `Theme changed to '${themeName}'`,\n };\n }\n\n return {\n success: false,\n error: 'Theme change not available in this context',\n };\n }\n}\n","/**\n * Database Manager using sql.js\n * Handles automatic initialization, migrations, and seeding\n */\n\nimport initSqlJs, { Database as SqlJsDatabase } from 'sql.js';\nimport { defaultPricing } from './seed.js';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { readFileSync, existsSync } from 'fs';\nimport type { IFileSystem } from '../platform/IFileSystem.js';\n\nexport interface DatabaseConfig {\n path: string;\n verbose?: boolean;\n fileSystem?: IFileSystem;\n}\n\ninterface RunResult {\n changes: number;\n lastInsertRowid: number;\n}\n\n/**\n * Locate sql.js WASM file\n * Tries multiple locations in order:\n * 1. resources/ directory (for standalone binaries)\n * 2. node_modules/sql.js/dist/ (for development)\n */\nfunction locateWasmFile(): ArrayBuffer {\n const wasmFileName = 'sql-wasm.wasm';\n\n // Determine the binary directory\n // For Bun compiled binaries, process.argv[0] is the executable path\n // For Node.js, use process.execPath\n const executablePath = process.argv[0] || process.execPath;\n const binaryDir = dirname(executablePath);\n\n // Location 1: resources directory (for production binaries)\n // Standalone binaries will have: /path/to/mimir (executable) + /path/to/resources/sql-wasm.wasm\n const resourcesPaths = [\n // Next to the binary (same directory) - most common for our installers\n join(binaryDir, 'resources', wasmFileName),\n // For development/testing\n join(process.cwd(), 'resources', wasmFileName),\n // Parent directory of binary (for some install layouts)\n join(binaryDir, '..', 'resources', wasmFileName),\n ];\n\n for (const resourcePath of resourcesPaths) {\n if (existsSync(resourcePath)) {\n const buffer = readFileSync(resourcePath);\n // Convert Node.js Buffer to ArrayBuffer\n return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);\n }\n }\n\n // Location 2: node_modules (for development only)\n const currentDir = dirname(fileURLToPath(import.meta.url));\n const nodeModulesPaths = [\n join(currentDir, '..', '..', 'node_modules', 'sql.js', 'dist', wasmFileName),\n join(process.cwd(), 'node_modules', 'sql.js', 'dist', wasmFileName),\n ];\n\n for (const modulePath of nodeModulesPaths) {\n if (existsSync(modulePath)) {\n const buffer = readFileSync(modulePath);\n // Convert Node.js Buffer to ArrayBuffer\n return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);\n }\n }\n\n // Enhanced error message with diagnostic information\n const diagnostics = [\n `process.argv[0]: ${process.argv[0]}`,\n `process.execPath: ${process.execPath}`,\n `executablePath: ${executablePath}`,\n `binaryDir: ${binaryDir}`,\n `currentDir: ${currentDir}`,\n `process.cwd(): ${process.cwd()}`,\n ];\n\n throw new Error(\n `Could not locate ${wasmFileName}.\\n\\nDiagnostics:\\n${diagnostics.join('\\n')}\\n\\nTried:\\n` +\n [...resourcesPaths, ...nodeModulesPaths].map((p) => ` - ${p}`).join('\\n')\n );\n}\n\n/**\n * DatabaseManager with automatic initialization and migrations\n */\nexport class DatabaseManager {\n private db!: SqlJsDatabase;\n private config: DatabaseConfig;\n private SQL: any;\n private nodeFs: typeof import('fs') | null = null;\n\n private constructor(config: DatabaseConfig, SQL: any) {\n this.config = config;\n this.SQL = SQL;\n }\n\n /**\n * Create DatabaseManager instance with proper directory setup\n */\n static async create(config: DatabaseConfig): Promise<DatabaseManager> {\n // Ensure database directory exists\n const dbDir = dirname(config.path);\n\n if (config.fileSystem) {\n const dirExists = await config.fileSystem.exists(dbDir);\n if (!dirExists) {\n await config.fileSystem.mkdir(dbDir, { recursive: true });\n }\n } else {\n const { existsSync, mkdirSync } = await import('fs');\n if (!existsSync(dbDir)) {\n mkdirSync(dbDir, { recursive: true });\n }\n }\n\n // Initialize sql.js with WASM binary from file system\n const wasmBinary = locateWasmFile();\n const SQL = await initSqlJs({\n wasmBinary,\n });\n const manager = new DatabaseManager(config, SQL);\n\n // Load Node.js fs module for sync operations\n manager.nodeFs = await import('fs');\n\n // Load or create database\n await manager.loadDatabase();\n\n // Initialize schema and seed data\n manager.initialize();\n\n // Save database after initialization (creates tables and seeds data)\n await manager.save();\n\n return manager;\n }\n\n /**\n * Load database from file or create new\n */\n private async loadDatabase(): Promise<void> {\n try {\n if (this.config.fileSystem) {\n const exists = await this.config.fileSystem.exists(this.config.path);\n if (exists) {\n const buffer = await this.config.fileSystem.readFile(\n this.config.path,\n 'binary' as BufferEncoding\n );\n const uint8Array = new Uint8Array(Buffer.from(buffer as any, 'binary'));\n this.db = new this.SQL.Database(uint8Array);\n if (this.config.verbose) {\n console.log('Loaded existing database from', this.config.path);\n }\n } else {\n this.db = new this.SQL.Database();\n if (this.config.verbose) {\n console.log('Created new database');\n }\n }\n } else {\n const { existsSync, readFileSync } = await import('fs');\n if (existsSync(this.config.path)) {\n const buffer = readFileSync(this.config.path);\n this.db = new this.SQL.Database(buffer);\n } else {\n this.db = new this.SQL.Database();\n }\n }\n } catch (error) {\n this.db = new this.SQL.Database();\n if (this.config.verbose) {\n console.log('Created new database after error:', error);\n }\n }\n }\n\n /**\n * Save database to disk (async version)\n */\n async save(): Promise<void> {\n const data = this.db.export();\n const buffer = Buffer.from(data);\n\n if (this.config.fileSystem) {\n await this.config.fileSystem.writeFile(\n this.config.path,\n buffer.toString('binary'),\n 'binary' as BufferEncoding\n );\n } else {\n const { writeFileSync } = await import('fs');\n writeFileSync(this.config.path, buffer);\n }\n }\n\n /**\n * Save database to disk (sync version for auto-save)\n * Uses sync fs operations to avoid async in execute/transaction\n */\n private saveSync(): void {\n const data = this.db.export();\n const buffer = Buffer.from(data);\n\n // Use pre-loaded Node.js fs module for sync operations\n if (this.nodeFs) {\n this.nodeFs.writeFileSync(this.config.path, buffer);\n }\n }\n\n /**\n * Initialize database with migrations and seed data\n */\n private initialize(): void {\n try {\n this.createTablesManually();\n this.seedDatabase();\n } catch (error) {\n console.error('Database initialization failed:', error);\n throw error;\n }\n }\n\n /**\n * Manually create tables from schema\n */\n private createTablesManually(): void {\n const createTablesSQL = `\n CREATE TABLE IF NOT EXISTS migrations (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n version TEXT NOT NULL UNIQUE,\n applied_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now'))\n );\n\n CREATE TABLE IF NOT EXISTS conversations (\n id TEXT PRIMARY KEY,\n title TEXT,\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n total_tokens INTEGER DEFAULT 0,\n total_cost REAL DEFAULT 0.0,\n provider TEXT,\n model TEXT,\n status TEXT DEFAULT 'active' CHECK(status IN ('active', 'archived', 'deleted'))\n );\n\n CREATE INDEX IF NOT EXISTS idx_conversations_created_at ON conversations(created_at DESC);\n CREATE INDEX IF NOT EXISTS idx_conversations_status ON conversations(status);\n\n CREATE TABLE IF NOT EXISTS messages (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n role TEXT NOT NULL CHECK(role IN ('system', 'user', 'assistant')),\n content TEXT NOT NULL,\n timestamp INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n input_tokens INTEGER DEFAULT 0,\n output_tokens INTEGER DEFAULT 0,\n cost REAL DEFAULT 0.0,\n metadata TEXT,\n FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_messages_conversation_id ON messages(conversation_id);\n CREATE INDEX IF NOT EXISTS idx_messages_timestamp ON messages(timestamp);\n\n CREATE TABLE IF NOT EXISTS tool_calls (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n message_id TEXT,\n tool_name TEXT NOT NULL,\n arguments TEXT NOT NULL,\n result TEXT,\n status TEXT DEFAULT 'pending' CHECK(status IN ('pending', 'running', 'success', 'failed')),\n error TEXT,\n started_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n completed_at INTEGER,\n duration_ms INTEGER,\n FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE,\n FOREIGN KEY (message_id) REFERENCES messages(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_tool_calls_conversation_id ON tool_calls(conversation_id);\n CREATE INDEX IF NOT EXISTS idx_tool_calls_status ON tool_calls(status);\n CREATE INDEX IF NOT EXISTS idx_tool_calls_started_at ON tool_calls(started_at DESC);\n\n CREATE TABLE IF NOT EXISTS permissions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n conversation_id TEXT,\n command TEXT NOT NULL,\n risk_level TEXT NOT NULL CHECK(risk_level IN ('low', 'medium', 'high', 'critical')),\n decision TEXT NOT NULL CHECK(decision IN ('allow', 'deny', 'always', 'never')),\n user_confirmed INTEGER DEFAULT 0,\n timestamp INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n context TEXT,\n FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE SET NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_permissions_conversation_id ON permissions(conversation_id);\n CREATE INDEX IF NOT EXISTS idx_permissions_timestamp ON permissions(timestamp DESC);\n CREATE INDEX IF NOT EXISTS idx_permissions_decision ON permissions(decision);\n\n CREATE TABLE IF NOT EXISTS checkpoints (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n description TEXT,\n files_snapshot TEXT NOT NULL,\n git_diff TEXT,\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_checkpoints_conversation_id ON checkpoints(conversation_id);\n CREATE INDEX IF NOT EXISTS idx_checkpoints_created_at ON checkpoints(created_at DESC);\n\n CREATE TABLE IF NOT EXISTS cost_summary (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n date TEXT NOT NULL,\n provider TEXT NOT NULL,\n model TEXT NOT NULL,\n total_tokens INTEGER DEFAULT 0,\n input_tokens INTEGER DEFAULT 0,\n output_tokens INTEGER DEFAULT 0,\n total_cost REAL DEFAULT 0.0,\n request_count INTEGER DEFAULT 0,\n UNIQUE(date, provider, model)\n );\n\n CREATE INDEX IF NOT EXISTS idx_cost_summary_date ON cost_summary(date DESC);\n CREATE INDEX IF NOT EXISTS idx_cost_summary_provider ON cost_summary(provider);\n\n CREATE TABLE IF NOT EXISTS session_state (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n agent_state TEXT NOT NULL,\n iteration INTEGER DEFAULT 0,\n created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_session_state_conversation_id ON session_state(conversation_id);\n\n CREATE TABLE IF NOT EXISTS metrics (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n operation TEXT NOT NULL,\n duration_ms INTEGER NOT NULL,\n conversation_id TEXT,\n session_id TEXT,\n provider TEXT,\n model TEXT,\n input_tokens INTEGER,\n output_tokens INTEGER,\n total_tokens INTEGER,\n cost REAL,\n tool_name TEXT,\n tool_args TEXT,\n tool_result_size INTEGER,\n query_type TEXT,\n table_name TEXT,\n rows_affected INTEGER,\n success INTEGER DEFAULT 1,\n error TEXT,\n memory_mb REAL,\n cpu_percent REAL,\n metadata TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_metrics_timestamp ON metrics(timestamp DESC);\n CREATE INDEX IF NOT EXISTS idx_metrics_operation ON metrics(operation);\n CREATE INDEX IF NOT EXISTS idx_metrics_conversation_id ON metrics(conversation_id);\n CREATE INDEX IF NOT EXISTS idx_metrics_provider ON metrics(provider);\n CREATE INDEX IF NOT EXISTS idx_metrics_success ON metrics(success);\n\n CREATE TABLE IF NOT EXISTS pricing (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n provider TEXT NOT NULL,\n model TEXT NOT NULL,\n input_price_per_1m REAL NOT NULL,\n output_price_per_1m REAL NOT NULL,\n effective_from INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),\n effective_until INTEGER,\n currency TEXT DEFAULT 'USD',\n notes TEXT,\n UNIQUE(provider, model, effective_from)\n );\n\n CREATE INDEX IF NOT EXISTS idx_pricing_provider_model ON pricing(provider, model);\n CREATE INDEX IF NOT EXISTS idx_pricing_effective ON pricing(effective_from DESC);\n `;\n\n const statements = createTablesSQL.split(';').filter((s) => s.trim());\n for (const statement of statements) {\n try {\n this.db.run(statement);\n } catch (error) {\n if (this.config.verbose) {\n console.log('Table creation warning:', error);\n }\n }\n }\n\n if (this.config.verbose) {\n console.log('Database tables created successfully');\n }\n }\n\n /**\n * Seed database with initial data\n */\n private seedDatabase(): void {\n const pricingCount = this.db.exec(\n \"SELECT COUNT(*) as count FROM sqlite_master WHERE type='table' AND name='pricing'\"\n );\n\n if (pricingCount.length === 0 || pricingCount[0]?.values[0]?.[0] === 0) {\n this.createTablesManually();\n }\n\n const existingPricing = this.db.exec('SELECT COUNT(*) as count FROM pricing');\n const count = existingPricing.length > 0 ? existingPricing[0]?.values[0]?.[0] : 0;\n\n if (count === 0) {\n for (const price of defaultPricing) {\n const stmt = this.db.prepare(\n `INSERT INTO pricing (provider, model, input_price_per_1m, output_price_per_1m, effective_from, currency)\n VALUES (?, ?, ?, ?, ?, ?)`\n );\n // sql.js doesn't accept undefined - convert to null or use defaults\n const effectiveFrom = price.effectiveFrom\n ? typeof price.effectiveFrom === 'number'\n ? price.effectiveFrom\n : Math.floor(price.effectiveFrom.getTime() / 1000)\n : Math.floor(Date.now() / 1000);\n\n stmt.run([\n price.provider,\n price.model,\n price.inputPricePer1M,\n price.outputPricePer1M,\n effectiveFrom,\n price.currency ?? 'USD',\n ]);\n stmt.free();\n }\n\n if (this.config.verbose) {\n console.log(`Seeded ${defaultPricing.length} pricing entries`);\n }\n }\n\n try {\n const migrationExists = this.db.exec(\n \"SELECT COUNT(*) as count FROM migrations WHERE version = '1.0.0'\"\n );\n const migCount = migrationExists.length > 0 ? migrationExists[0]?.values[0]?.[0] : 0;\n\n if (migCount === 0) {\n this.db.run(\"INSERT INTO migrations (version) VALUES ('1.0.0')\");\n }\n } catch (error) {\n // Migration table might not exist yet\n }\n }\n\n /**\n * Execute a raw SQL query (auto-saves for write operations)\n */\n execute(sql: string, params?: unknown[]): RunResult {\n const stmt = this.db.prepare(sql);\n stmt.bind((params || []) as (string | number | null | Uint8Array)[]);\n stmt.step();\n const info = this.db.getRowsModified();\n stmt.free();\n\n // Auto-save for write operations (INSERT, UPDATE, DELETE)\n const isWrite = /^\\s*(INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)/i.test(sql);\n if (isWrite && info > 0) {\n // Save synchronously (sql.js export is sync, fs write would be async but we'll handle that)\n this.saveSync();\n }\n\n return {\n changes: info,\n lastInsertRowid: 0, // sql.js doesn't provide this easily\n };\n }\n\n /**\n * Query a raw SQL statement\n */\n query<T = unknown>(sql: string, params?: unknown[]): T[] {\n const stmt = this.db.prepare(sql);\n stmt.bind((params || []) as (string | number | null | Uint8Array)[]);\n const results: T[] = [];\n\n while (stmt.step()) {\n const row = stmt.getAsObject();\n results.push(row as T);\n }\n stmt.free();\n return results;\n }\n\n /**\n * Execute a query and return a single row\n */\n queryOne<T>(sql: string, params?: unknown[]): T | null {\n try {\n const stmt = this.db.prepare(sql);\n stmt.bind((params || []) as (string | number | null | Uint8Array)[]);\n if (stmt.step()) {\n const row = stmt.getAsObject();\n stmt.free();\n return row as T;\n }\n stmt.free();\n return null;\n } catch (error) {\n console.error('Query failed:', error);\n return null;\n }\n }\n\n /**\n * Run a transaction (auto-saves after commit)\n */\n transaction<T>(fn: (db: DatabaseManager) => T): T {\n this.db.run('BEGIN TRANSACTION');\n try {\n const result = fn(this);\n this.db.run('COMMIT');\n // Save after successful commit\n this.saveSync();\n return result;\n } catch (error) {\n this.db.run('ROLLBACK');\n throw error;\n }\n }\n\n /**\n * Close database connection\n */\n close(): void {\n this.db.close();\n }\n\n /**\n * Vacuum database to optimize storage\n */\n vacuum(): void {\n this.db.run('VACUUM');\n }\n\n /**\n * Get database statistics\n */\n getStats(): {\n pageCount: number;\n pageSize: number;\n sizeBytes: number;\n walMode: boolean;\n } {\n const pageCount = this.queryOne<{ page_count: number }>('PRAGMA page_count');\n const pageSize = this.queryOne<{ page_size: number }>('PRAGMA page_size');\n\n return {\n pageCount: pageCount?.page_count || 0,\n pageSize: pageSize?.page_size || 0,\n sizeBytes: (pageCount?.page_count || 0) * (pageSize?.page_size || 0),\n walMode: false, // sql.js doesn't support WAL mode\n };\n }\n\n /**\n * Perform a database health check\n */\n async healthCheck(): Promise<boolean> {\n try {\n const result = this.queryOne<{ integrity_check: string }>('PRAGMA integrity_check');\n return result?.integrity_check === 'ok';\n } catch (error) {\n console.error('Health check failed:', error);\n return false;\n }\n }\n}\n\n// Singleton instance for the application\nlet dbInstance: DatabaseManager | null = null;\n\n/**\n * Get or create database manager instance (async)\n */\nexport async function getDatabaseManagerAsync(config?: DatabaseConfig): Promise<DatabaseManager> {\n if (!dbInstance && config) {\n dbInstance = await DatabaseManager.create(config);\n }\n if (!dbInstance) {\n throw new Error('DatabaseManager not initialized. Call with config first.');\n }\n return dbInstance;\n}\n\n/**\n * Close database connection\n */\nexport function closeDatabaseManager(): void {\n if (dbInstance) {\n dbInstance.close();\n dbInstance = null;\n }\n}\n","/**\n * Database seed data for initial setup\n */\n\nimport { NewPricing } from './schema.js';\n\n/**\n * Default pricing data for LLM providers (as of January 2025)\n */\nexport const defaultPricing: NewPricing[] = [\n // DeepSeek\n {\n provider: 'deepseek',\n model: 'deepseek-chat',\n inputPricePer1M: 0.14,\n outputPricePer1M: 0.28,\n notes: 'DeepSeek-V3 pricing',\n },\n {\n provider: 'deepseek',\n model: 'deepseek-coder',\n inputPricePer1M: 0.14,\n outputPricePer1M: 0.28,\n notes: 'DeepSeek Coder pricing',\n },\n\n // Anthropic Claude\n {\n provider: 'anthropic',\n model: 'claude-3-5-sonnet-20241022',\n inputPricePer1M: 3.0,\n outputPricePer1M: 15.0,\n notes: 'Claude 3.5 Sonnet',\n },\n {\n provider: 'anthropic',\n model: 'claude-3-5-haiku-20241022',\n inputPricePer1M: 0.8,\n outputPricePer1M: 4.0,\n notes: 'Claude 3.5 Haiku',\n },\n {\n provider: 'anthropic',\n model: 'claude-3-opus-20240229',\n inputPricePer1M: 15.0,\n outputPricePer1M: 75.0,\n notes: 'Claude 3 Opus',\n },\n\n // OpenAI\n {\n provider: 'openai',\n model: 'gpt-4-turbo',\n inputPricePer1M: 10.0,\n outputPricePer1M: 30.0,\n notes: 'GPT-4 Turbo',\n },\n {\n provider: 'openai',\n model: 'gpt-4o',\n inputPricePer1M: 2.5,\n outputPricePer1M: 10.0,\n notes: 'GPT-4o',\n },\n {\n provider: 'openai',\n model: 'gpt-4o-mini',\n inputPricePer1M: 0.15,\n outputPricePer1M: 0.6,\n notes: 'GPT-4o Mini',\n },\n {\n provider: 'openai',\n model: 'gpt-3.5-turbo',\n inputPricePer1M: 0.5,\n outputPricePer1M: 1.5,\n notes: 'GPT-3.5 Turbo',\n },\n\n // Google Gemini\n {\n provider: 'google',\n model: 'gemini-2.0-flash-exp',\n inputPricePer1M: 0.0,\n outputPricePer1M: 0.0,\n notes: 'Free during preview',\n },\n {\n provider: 'google',\n model: 'gemini-1.5-pro',\n inputPricePer1M: 1.25,\n outputPricePer1M: 5.0,\n notes: 'Gemini 1.5 Pro',\n },\n {\n provider: 'google',\n model: 'gemini-1.5-flash',\n inputPricePer1M: 0.075,\n outputPricePer1M: 0.3,\n notes: 'Gemini 1.5 Flash',\n },\n\n // Qwen\n {\n provider: 'qwen',\n model: 'qwen-max',\n inputPricePer1M: 0.4,\n outputPricePer1M: 1.2,\n notes: 'Qwen Max estimated pricing',\n },\n {\n provider: 'qwen',\n model: 'qwen-plus',\n inputPricePer1M: 0.2,\n outputPricePer1M: 0.6,\n notes: 'Qwen Plus estimated pricing',\n },\n\n // Ollama (local models)\n {\n provider: 'ollama',\n model: 'llama3',\n inputPricePer1M: 0.0,\n outputPricePer1M: 0.0,\n notes: 'Local model - no API costs',\n },\n {\n provider: 'ollama',\n model: 'mistral',\n inputPricePer1M: 0.0,\n outputPricePer1M: 0.0,\n notes: 'Local model - no API costs',\n },\n {\n provider: 'ollama',\n model: 'codellama',\n inputPricePer1M: 0.0,\n outputPricePer1M: 0.0,\n notes: 'Local model - no API costs',\n },\n];\n","/**\n * Centralized initialization service for Mimir\n * Handles workspace setup, database creation, and configuration\n */\n\nimport { IFileSystem } from '../platform/IFileSystem.js';\nimport { ConfigLoader } from '../config/ConfigLoader.js';\nimport { getDatabaseManagerAsync, closeDatabaseManager } from '../storage/Database.js';\nimport { logger } from '../utils/logger.js';\nimport path, { dirname } from 'path';\n\nexport interface InitializationResult {\n success: boolean;\n created: string[];\n errors: string[];\n dbInitialized: boolean;\n configCreated: boolean;\n}\n\nexport class MimirInitializer {\n constructor(\n private fs: IFileSystem,\n private configLoader: ConfigLoader\n ) {}\n\n /**\n * Initialize workspace with full Mimir setup\n * Creates directories, database, config, and gitignore\n */\n async initializeWorkspace(workspaceRoot: string): Promise<InitializationResult> {\n const result: InitializationResult = {\n success: true,\n created: [],\n errors: [],\n dbInitialized: false,\n configCreated: false,\n };\n\n try {\n const mimirDir = path.join(workspaceRoot, '.mimir');\n\n // 1. Create .mimir directory\n if (!(await this.fs.exists(mimirDir))) {\n await this.fs.mkdir(mimirDir, { recursive: true });\n result.created.push('.mimir/');\n logger.info('Created .mimir directory', { path: mimirDir });\n }\n\n // 2. Create subdirectories\n const subdirs = [\n { name: 'logs', purpose: 'Application logs' },\n { name: 'commands', purpose: 'Custom slash commands' },\n { name: 'checkpoints', purpose: 'Undo/restore checkpoints' },\n { name: 'themes', purpose: 'UI theme definitions' },\n ];\n\n for (const { name, purpose } of subdirs) {\n const subdir = path.join(mimirDir, name);\n if (!(await this.fs.exists(subdir))) {\n await this.fs.mkdir(subdir, { recursive: true });\n result.created.push(`.mimir/${name}/`);\n logger.info(`Created ${name} directory`, { path: subdir, purpose });\n }\n }\n\n // 3. Create .gitignore for .mimir directory\n await this.createMimirGitignore(mimirDir, result);\n\n // 4. Copy default themes\n await this.copyDefaultThemes(mimirDir, result);\n\n // 5. Copy example commands\n await this.copyExampleCommands(mimirDir, result);\n\n // 6. Initialize SQLite database\n await this.initializeDatabase(mimirDir, result);\n\n // 7. Create config.yml if it doesn't exist\n await this.createConfigIfNeeded(mimirDir, result);\n\n // 8. Create README in .mimir folder\n await this.createReadme(mimirDir, result);\n } catch (error) {\n result.success = false;\n result.errors.push(\n `Initialization failed: ${error instanceof Error ? error.message : String(error)}`\n );\n logger.error('Workspace initialization failed', { error });\n }\n\n return result;\n }\n\n /**\n * Check if workspace is initialized\n */\n async isWorkspaceInitialized(workspaceRoot: string): Promise<boolean> {\n const mimirDir = path.join(workspaceRoot, '.mimir');\n const dbPath = path.join(mimirDir, 'mimir.db');\n\n // Check if both .mimir directory and database exist\n return (await this.fs.exists(mimirDir)) && (await this.fs.exists(dbPath));\n }\n\n /**\n * Create .gitignore inside .mimir directory\n */\n private async createMimirGitignore(\n mimirDir: string,\n result: InitializationResult\n ): Promise<void> {\n const gitignorePath = path.join(mimirDir, '.gitignore');\n\n if (await this.fs.exists(gitignorePath)) {\n return; // Already exists\n }\n\n const gitignoreContent = `# Mimir workspace-specific ignores\n# Ignore sensitive data and logs\n\n# Databases and backups\n*.db\n*.db-shm\n*.db-wal\n*.db.backup\n\n# Logs\nlogs/\n*.log\n\n# Checkpoints (may contain code snapshots)\ncheckpoints/\n\n# Temporary files\n*.tmp\n*.temp\n\n# Keep config.yml tracked (share with team)\n!config.yml\n!config.example.yml\n\n# Keep custom commands tracked\n!commands/\n`;\n\n try {\n await this.fs.writeFile(gitignorePath, gitignoreContent);\n result.created.push('.mimir/.gitignore');\n logger.info('Created .mimir/.gitignore');\n } catch (error) {\n result.errors.push(\n `Failed to create .gitignore: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * Copy default theme files to .mimir/themes/ directory\n */\n private async copyDefaultThemes(mimirDir: string, result: InitializationResult): Promise<void> {\n const themesDir = path.join(mimirDir, 'themes');\n\n // Default themes to copy\n const defaultThemes = [\n 'mimir.json',\n 'dark.json',\n 'light.json',\n 'dark-colorblind.json',\n 'light-colorblind.json',\n ];\n\n try {\n // Get the source themes directory (from installed package)\n // For Bun compiled binaries: use process.argv[0] to get binary location\n // Resources are in: ~/.local/bin/resources/themes/\n const executablePath = process.argv[0] || process.execPath;\n const binaryDir = dirname(executablePath);\n\n // Try multiple locations for theme files\n const possibleSourceDirs = [\n path.join(binaryDir, 'resources', 'themes'), // Compiled binary: ~/.local/bin/resources/themes/\n path.join(binaryDir, '../cli/themes'), // Development: dist/core/../cli/themes\n path.join(binaryDir, '../../src/cli/themes'), // Development: dist/core/../../src/cli/themes\n ];\n\n for (const themeFile of defaultThemes) {\n const destPath = path.join(themesDir, themeFile);\n\n // Skip if theme already exists (idempotency)\n if (await this.fs.exists(destPath)) {\n continue;\n }\n\n // Try each possible source directory\n let copied = false;\n for (const sourceDir of possibleSourceDirs) {\n try {\n const sourcePath = path.join(sourceDir, themeFile);\n const themeContent = await this.fs.readFile(sourcePath, 'utf-8');\n\n // Write to workspace themes directory\n await this.fs.writeFile(destPath, themeContent);\n result.created.push(`.mimir/themes/${themeFile}`);\n logger.info('Copied default theme', { theme: themeFile, from: sourceDir });\n copied = true;\n break;\n } catch (error) {\n // Try next location\n continue;\n }\n }\n\n if (!copied) {\n logger.warn(`Failed to copy theme ${themeFile}, will use built-in fallback`, {\n triedLocations: possibleSourceDirs,\n });\n }\n }\n } catch (error) {\n result.errors.push(\n `Failed to copy default themes: ${error instanceof Error ? error.message : String(error)}`\n );\n logger.error('Failed to copy themes', { error });\n }\n }\n\n /**\n * Copy example command files to .mimir/commands/ directory\n */\n private async copyExampleCommands(mimirDir: string, result: InitializationResult): Promise<void> {\n const commandsDir = path.join(mimirDir, 'commands');\n\n // Example command to copy\n const exampleCommands = ['update-docs.yml'];\n\n try {\n // Get the source commands directory (from installed package)\n // For Bun compiled binaries: use process.argv[0] to get binary location\n // Resources are in: ~/.local/bin/resources/commands/\n const executablePath = process.argv[0] || process.execPath;\n const binaryDir = dirname(executablePath);\n\n // Try multiple locations for command files\n const possibleSourceDirs = [\n path.join(binaryDir, 'resources', 'commands'), // Compiled binary: ~/.local/bin/resources/commands/\n path.join(binaryDir, '../../scripts/templates/commands'), // Development: dist/core/../../scripts/templates/commands\n path.join(binaryDir, '../../../scripts/templates/commands'), // Alternative dev path\n ];\n\n for (const commandFile of exampleCommands) {\n const destPath = path.join(commandsDir, commandFile);\n\n // Skip if command already exists (idempotency)\n if (await this.fs.exists(destPath)) {\n continue;\n }\n\n // Try each possible source directory\n let copied = false;\n for (const sourceDir of possibleSourceDirs) {\n try {\n const sourcePath = path.join(sourceDir, commandFile);\n const commandContent = await this.fs.readFile(sourcePath, 'utf-8');\n\n // Write to workspace commands directory\n await this.fs.writeFile(destPath, commandContent);\n result.created.push(`.mimir/commands/${commandFile}`);\n logger.info('Copied example command', { command: commandFile, from: sourceDir });\n copied = true;\n break;\n } catch (error) {\n // Try next location\n continue;\n }\n }\n\n if (!copied) {\n logger.warn(`Failed to copy command ${commandFile}, continuing`, {\n triedLocations: possibleSourceDirs,\n });\n }\n }\n } catch (error) {\n result.errors.push(\n `Failed to copy example commands: ${error instanceof Error ? error.message : String(error)}`\n );\n logger.error('Failed to copy commands', { error });\n }\n }\n\n /**\n * Initialize SQLite database with Drizzle ORM\n */\n private async initializeDatabase(mimirDir: string, result: InitializationResult): Promise<void> {\n const dbPath = path.join(mimirDir, 'mimir.db');\n\n // Check if database already exists (idempotency)\n if (await this.fs.exists(dbPath)) {\n logger.info('Database already exists, skipping initialization', { path: dbPath });\n return;\n }\n\n try {\n // DatabaseManager auto-creates tables and seeds pricing\n // Use async factory with IFileSystem abstraction\n const db = await getDatabaseManagerAsync({\n path: dbPath,\n verbose: false,\n fileSystem: this.fs,\n });\n\n // Perform a write operation to ensure database file is created\n // better-sqlite3 may delay file creation until first write\n db.execute('SELECT 1');\n\n // Close database connection and clear singleton (flushes to disk)\n closeDatabaseManager();\n\n // Now verify database was created (after close flushes it)\n if (await this.fs.exists(dbPath)) {\n result.created.push('.mimir/mimir.db');\n result.dbInitialized = true;\n logger.info('Database initialized', { path: dbPath });\n } else {\n result.errors.push('Database file was not created on disk');\n }\n } catch (error) {\n result.errors.push(\n `Database initialization failed: ${error instanceof Error ? error.message : String(error)}`\n );\n logger.error('Failed to initialize database', { error });\n }\n }\n\n /**\n * Format array for YAML - creates inline array syntax [item1, item2]\n */\n private formatYamlArray(arr: string[]): string {\n if (!arr || arr.length === 0) return '[]';\n if (arr.length === 1) {\n // Quote special YAML characters: ?, *, &, !, |, >, @, `\n const val = arr[0];\n if (!val) return '[]';\n if (/^[?*&!|>@`]/.test(val) || val === '?' || val === '*') {\n return `\"${val}\"`;\n }\n return val;\n }\n // For arrays, quote each item if needed\n const quoted = arr.map((item) => {\n if (/^[?*&!|>@`]/.test(item) || item === '?' || item === '*') {\n return `\"${item}\"`;\n }\n return item;\n });\n return `[${quoted.join(', ')}]`;\n }\n\n /**\n * Create config.yml if it doesn't exist\n */\n private async createConfigIfNeeded(\n mimirDir: string,\n result: InitializationResult\n ): Promise<void> {\n const configPath = path.join(mimirDir, 'config.yml');\n\n if (await this.fs.exists(configPath)) {\n return; // Config already exists\n }\n\n try {\n // Get default config from ConfigLoader (platform-specific)\n const { config: defaults } = await this.configLoader.load();\n\n // Create user-friendly config with comments\n const configContent = `# Mimir Configuration\n# This file can be committed to version control for team sharing\n# Store API keys in .env or environment variables instead\n\n# LLM Provider Configuration\nllm:\n provider: ${defaults.llm.provider} # deepseek | anthropic | openai | google | gemini | qwen | ollama\n model: ${defaults.llm.model}\n # apiKey: \\${DEEPSEEK_API_KEY} # Use environment variable (recommended)\n # baseURL: https://api.deepseek.com # Optional: override API endpoint\n temperature: ${defaults.llm.temperature}\n maxTokens: ${defaults.llm.maxTokens}\n\n# Permission System\npermissions:\n autoAccept: ${defaults.permissions.autoAccept} # DANGEROUS: Auto-approve all commands\n acceptRiskLevel: ${defaults.permissions.acceptRiskLevel} # low | medium | high | critical\n alwaysAcceptCommands: ${this.formatYamlArray(defaults.permissions.alwaysAcceptCommands)}\n\n# Keyboard Shortcuts (supports both single string and array)\n# Examples:\n# accept: Enter (single shortcut)\n# interrupt: [Ctrl+C, Escape] (multiple shortcuts)\n#\n# Note: On Windows, Ctrl+Space is intercepted by the terminal and won't work.\n# Tab is the recommended shortcut for autocomplete on all platforms.\nkeyBindings:\n interrupt: ${this.formatYamlArray(defaults.keyBindings.interrupt)}\n accept: ${this.formatYamlArray(defaults.keyBindings.accept)}\n modeSwitch: ${this.formatYamlArray(defaults.keyBindings.modeSwitch)}\n editCommand: ${this.formatYamlArray(defaults.keyBindings.editCommand)}\n showTooltip: ${this.formatYamlArray(defaults.keyBindings.showTooltip)} # Tab recommended (Ctrl+Space doesn't work on Windows)\n navigateUp: ${this.formatYamlArray(defaults.keyBindings.navigateUp)}\n navigateDown: ${this.formatYamlArray(defaults.keyBindings.navigateDown)}\n help: ${this.formatYamlArray(defaults.keyBindings.help)}\n clearScreen: ${this.formatYamlArray(defaults.keyBindings.clearScreen)}\n undo: ${this.formatYamlArray(defaults.keyBindings.undo)}\n redo: ${this.formatYamlArray(defaults.keyBindings.redo)}\n\n# Docker Sandbox (for running untrusted code)\ndocker:\n enabled: ${defaults.docker.enabled}\n baseImage: ${defaults.docker.baseImage}\n\n# User Interface\nui:\n theme: ${defaults.ui.theme} # mimir | dark | light | dark-colorblind | light-colorblind\n syntaxHighlighting: ${defaults.ui.syntaxHighlighting}\n showLineNumbers: ${defaults.ui.showLineNumbers}\n compactMode: ${defaults.ui.compactMode}\n autocompleteAutoShow: ${defaults.ui.autocompleteAutoShow} # Auto-show autocomplete when suggestions available\n autocompleteExecuteOnSelect: ${defaults.ui.autocompleteExecuteOnSelect} # Execute command if no more params needed\n\n# Monitoring & Metrics\nmonitoring:\n metricsRetentionDays: ${defaults.monitoring.metricsRetentionDays} # Keep metrics for N days\n enableHealthChecks: ${defaults.monitoring.enableHealthChecks}\n healthCheckIntervalSeconds: ${defaults.monitoring.healthCheckIntervalSeconds}\n slowOperationThresholdMs: ${defaults.monitoring.slowOperationThresholdMs}\n batchWriteIntervalSeconds: ${defaults.monitoring.batchWriteIntervalSeconds}\n\n# Budget Limits (prevents runaway costs)\nbudget:\n enabled: ${defaults.budget.enabled}\n # dailyLimit: 10.00 # USD per day (optional)\n # weeklyLimit: 50.00 # USD per week (optional)\n # monthlyLimit: 100.00 # USD per month (optional)\n warningThreshold: ${defaults.budget.warningThreshold} # Warn at 80% of limit\n\n# Rate Limiting (prevents excessive operations)\nrateLimit:\n enabled: ${defaults.rateLimit.enabled}\n commandsPerMinute: ${defaults.rateLimit.commandsPerMinute}\n toolExecutionsPerMinute: ${defaults.rateLimit.toolExecutionsPerMinute}\n llmCallsPerMinute: ${defaults.rateLimit.llmCallsPerMinute}\n maxFileSizeMB: ${defaults.rateLimit.maxFileSizeMB}\n`;\n\n await this.fs.writeFile(configPath, configContent);\n result.created.push('.mimir/config.yml');\n result.configCreated = true;\n logger.info('Created config.yml', { path: configPath });\n } catch (error) {\n result.errors.push(\n `Failed to create config.yml: ${error instanceof Error ? error.message : String(error)}`\n );\n logger.error('Failed to create config', { error });\n }\n }\n\n /**\n * Create README in .mimir directory\n */\n private async createReadme(mimirDir: string, result: InitializationResult): Promise<void> {\n const readmePath = path.join(mimirDir, 'README.md');\n\n if (await this.fs.exists(readmePath)) {\n return; // README already exists\n }\n\n const readmeContent = `# Mimir Workspace\n\nThis directory contains Mimir's workspace-specific data and configuration.\n\n## Directory Structure\n\n\\`\\`\\`\n.mimir/\n├── config.yml # Workspace configuration (tracked in git)\n├── mimir.db # Conversation history and metrics (ignored)\n├── logs/ # Application logs (ignored)\n├── commands/ # Custom slash commands (tracked)\n├── themes/ # UI theme definitions (tracked)\n├── checkpoints/ # Undo/restore checkpoints (ignored)\n├── .gitignore # Ignores sensitive data\n└── README.md # This file\n\\`\\`\\`\n\n## Files You Should Track in Git\n\n✅ **config.yml** - Team configuration (shared settings, allowlists)\n✅ **commands/** - Custom slash commands for your team\n✅ **themes/** - Custom UI themes for your team\n❌ **mimir.db** - Local conversation history (private)\n❌ **logs/** - Application logs (private)\n❌ **checkpoints/** - Code snapshots (private)\n\n## Configuration\n\nEdit \\`config.yml\\` to customize Mimir's behavior for this workspace:\n- LLM provider and model settings\n- Permission system (command allowlists)\n- Rate limiting and budget controls\n- UI preferences (including themes)\n\n**API Keys:** Store in \\`.env\\` file in project root, not in config.yml!\n\n## Database\n\n\\`mimir.db\\` is a SQLite database containing:\n- Conversation history\n- Message tokens and costs\n- Tool execution records\n- Performance metrics\n- Permission audit trail\n\nUse \\`mimir history\\` commands to manage conversations.\n\n## Custom Commands\n\nCustom slash commands extend Mimir's capabilities with team-specific workflows.\n\n### Example Commands Provided\n\nSix example commands are pre-installed in \\`commands/\\`:\n- **\\`/security\\`** - Analyze git diffs for security vulnerabilities\n- **\\`/refactor\\`** - Suggest code refactoring improvements\n- **\\`/test\\`** - Generate comprehensive test cases\n- **\\`/docs\\`** - Generate or improve documentation\n- **\\`/review\\`** - Perform comprehensive code review\n- **\\`/perf\\`** - Analyze performance issues and optimizations\n\n### Creating Custom Commands\n\nCommands are defined in YAML files in \\`commands/\\` directory:\n\n\\`\\`\\`yaml\n# .mimir/commands/deploy.yml\nname: deploy\ndescription: Deploy application to specified environment\nusage: /deploy [environment]\naliases: [d]\nprompt: |\n Deploy the application to $1 environment.\n\n Steps:\n 1. Run tests to ensure code quality\n 2. Build production bundle\n 3. Deploy to $1 environment\n 4. Run smoke tests\n 5. Monitor for errors\n\n Environment: $1 (or production if not specified)\n\\`\\`\\`\n\n**Placeholders:**\n- \\`$1\\`, \\`$2\\`, \\`$3\\` - Individual arguments\n- \\`$ARGUMENTS\\` - All arguments joined together\n\n**Usage:**\n\\`\\`\\`bash\n/deploy staging # Deploys to staging\n/security src/auth.ts # Security analysis of auth file\n/test src/utils.ts # Generate tests for utils\n\\`\\`\\`\n\n### Command Customization\n\nModify the example commands to match your workflow:\n- Add team-specific context to prompts\n- Customize analysis criteria\n- Add project-specific checks\n- Create domain-specific commands (e.g., \\`/api-design\\`, \\`/schema-migration\\`)\n\nCommands in this directory are tracked in git and shared with your team.\n\n## Custom Themes\n\nCustomize Mimir's appearance by creating theme files in \\`themes/\\` directory:\n\\`\\`\\`bash\n.mimir/themes/mimir.json # Default theme (provided)\n.mimir/themes/dark.json # Dark theme (provided)\n.mimir/themes/company-theme.json # Your custom theme\n\\`\\`\\`\n\nSelect theme in \\`config.yml\\`:\n\\`\\`\\`yaml\nui:\n theme: company-theme # Loads from themes/company-theme.json\n\\`\\`\\`\n\nSee the theme documentation for creating custom themes.\n\n---\n\n**Generated by Mimir v0.1.0**\n`;\n\n try {\n await this.fs.writeFile(readmePath, readmeContent);\n result.created.push('.mimir/README.md');\n logger.info('Created README.md');\n } catch (error) {\n result.errors.push(\n `Failed to create README: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * Print initialization summary\n */\n printSummary(result: InitializationResult, workspaceRoot: string): void {\n /* eslint-disable no-console */\n console.log('\\n🚀 Mimir Workspace Initialized!\\n');\n\n if (result.created.length > 0) {\n console.log('Created:');\n result.created.forEach((item) => console.log(` ✓ ${item}`));\n }\n\n if (result.dbInitialized) {\n console.log('\\n📊 Database:');\n console.log(' ✓ SQLite database created and seeded with pricing data');\n }\n\n if (result.configCreated) {\n console.log('\\n⚙️ Configuration:');\n console.log(' ✓ config.yml created with default settings');\n console.log(' 💡 Edit .mimir/config.yml to customize settings');\n console.log(' 💡 Store API keys in .env file, not in config.yml');\n }\n\n if (result.errors.length > 0) {\n console.log('\\n⚠️ Warnings:');\n result.errors.forEach((error) => console.log(` ! ${error}`));\n }\n\n console.log('\\n📁 Workspace structure:');\n console.log(` ${path.join(workspaceRoot, '.mimir')}`);\n console.log(' ├── config.yml (tracked in git)');\n console.log(' ├── mimir.db (ignored)');\n console.log(' ├── logs/ (ignored)');\n console.log(' ├── commands/ (tracked - 6 example commands provided)');\n console.log(' ├── themes/ (tracked - custom UI themes)');\n console.log(' └── checkpoints/ (ignored)');\n\n console.log('\\n💡 Custom Commands:');\n console.log(' Six example slash commands are ready to use:');\n console.log(' • /security - Analyze git diffs for security vulnerabilities');\n console.log(' • /refactor - Suggest code refactoring improvements');\n console.log(' • /test - Generate comprehensive test cases');\n console.log(' • /docs - Generate or improve documentation');\n console.log(' • /review - Perform comprehensive code review');\n console.log(' • /perf - Analyze performance issues');\n console.log('\\n Edit .mimir/commands/*.yml to customize or create your own!');\n\n console.log('\\n✨ Ready to use! Run \"mimir\" to start an interactive chat session.\\n');\n /* eslint-enable no-console */\n }\n}\n","/**\n * DeepSeek LLM Provider\n * OpenAI-compatible API with cost-effective pricing\n */\n\nimport { encode } from 'gpt-tokenizer';\nimport { BaseLLMProvider } from './BaseLLMProvider.js';\nimport { ILLMProvider, LLMTool } from './ILLMProvider.js';\nimport { Message, ChatResponse, ChatChunk, LLMConfig } from '../types/index.js';\nimport { APIClient } from './utils/apiClient.js';\nimport { getStaticPricing } from './pricing/pricingData.js';\nimport {\n toOpenAITools,\n parseOpenAIToolCalls,\n mapOpenAIFinishReason,\n} from './utils/toolFormatters.js';\nimport { parseOpenAIStream } from './utils/streamParsers.js';\nimport { ConfigurationError } from '../utils/errors.js';\n\nexport class DeepSeekProvider extends BaseLLMProvider implements ILLMProvider {\n private apiClient: APIClient;\n\n constructor(config: LLMConfig) {\n super(config);\n\n const apiKey = config.apiKey || process.env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n throw new ConfigurationError(\n 'DEEPSEEK_API_KEY not found in config or environment variables. ' +\n 'Please set DEEPSEEK_API_KEY in your .env file or pass it via config.'\n );\n }\n\n const baseURL = config.baseURL || 'https://api.deepseek.com';\n\n this.apiClient = new APIClient({\n baseURL,\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n timeout: 60000,\n });\n }\n\n async chat(messages: Message[], tools?: LLMTool[]): Promise<ChatResponse> {\n return this.withRetry(async () => {\n const requestBody = {\n model: this.config.model,\n messages: this.formatMessages(messages),\n tools: tools ? toOpenAITools(tools) : undefined,\n temperature: this.config.temperature,\n max_tokens: this.config.maxTokens,\n };\n\n const response = await this.apiClient.post<DeepSeekChatResponse>(\n '/chat/completions',\n requestBody\n );\n\n return this.parseResponse(response);\n });\n }\n\n async *streamChat(messages: Message[], tools?: LLMTool[]): AsyncGenerator<ChatChunk> {\n const requestBody = {\n model: this.config.model,\n messages: this.formatMessages(messages),\n tools: tools ? toOpenAITools(tools) : undefined,\n temperature: this.config.temperature,\n max_tokens: this.config.maxTokens,\n stream: true,\n };\n\n const stream = this.apiClient.stream('/chat/completions', requestBody);\n\n for await (const chunk of parseOpenAIStream(stream)) {\n yield chunk;\n }\n }\n\n countTokens(text: string): number {\n return encode(text).length;\n }\n\n calculateCost(inputTokens: number, outputTokens: number): number {\n const pricing = getStaticPricing('deepseek', this.config.model);\n if (!pricing) {\n return 0; // Unknown model, return 0 cost\n }\n\n return (\n (inputTokens / 1_000_000) * pricing.inputPerMillionTokens +\n (outputTokens / 1_000_000) * pricing.outputPerMillionTokens\n );\n }\n\n /**\n * Format messages for OpenAI-compatible API\n */\n private formatMessages(\n messages: Message[]\n ): Array<{ role: string; content: string; name?: string }> {\n return messages.map((msg) => ({\n role: msg.role,\n content: msg.content,\n name: msg.name,\n }));\n }\n\n /**\n * Parse DeepSeek API response\n */\n private parseResponse(response: DeepSeekChatResponse): ChatResponse {\n const choice = response.choices[0];\n const message = choice?.message;\n const usage = response.usage;\n\n if (!choice || !message) {\n throw new Error('Invalid response from DeepSeek API: missing choice or message');\n }\n\n return {\n content: message.content || '',\n toolCalls: parseOpenAIToolCalls(response),\n finishReason: mapOpenAIFinishReason(choice.finish_reason),\n usage: {\n inputTokens: usage.prompt_tokens,\n outputTokens: usage.completion_tokens,\n totalTokens: usage.total_tokens,\n },\n };\n }\n}\n\n/**\n * DeepSeek API response type\n */\ninterface DeepSeekChatResponse {\n id: string;\n object: string;\n created: number;\n model: string;\n choices: Array<{\n index: number;\n message: {\n role: string;\n content: string | null;\n tool_calls?: Array<{\n id: string;\n type: string;\n function: {\n name: string;\n arguments: string;\n };\n }>;\n };\n finish_reason: string;\n }>;\n usage: {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n prompt_cache_hit_tokens?: number;\n prompt_cache_miss_tokens?: number;\n };\n}\n","/**\n * Custom error classes\n */\n\nexport class MimirError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'MimirError';\n }\n}\n\nexport class ConfigurationError extends MimirError {\n constructor(message: string) {\n super(message);\n this.name = 'ConfigurationError';\n }\n}\n\nexport class ProviderError extends MimirError {\n constructor(\n message: string,\n public readonly provider?: string\n ) {\n super(message);\n this.name = 'ProviderError';\n }\n}\n\nexport class ToolExecutionError extends MimirError {\n constructor(\n message: string,\n public readonly toolName?: string\n ) {\n super(message);\n this.name = 'ToolExecutionError';\n }\n}\n\nexport class PermissionDeniedError extends MimirError {\n constructor(\n message: string,\n public readonly command?: string\n ) {\n super(message);\n this.name = 'PermissionDeniedError';\n }\n}\n\nexport class DockerError extends MimirError {\n constructor(message: string) {\n super(message);\n this.name = 'DockerError';\n }\n}\n\nexport class NetworkError extends MimirError {\n constructor(\n message: string,\n public readonly statusCode?: number\n ) {\n super(message);\n this.name = 'NetworkError';\n }\n}\n\nexport class RateLimitError extends MimirError {\n constructor(\n message: string,\n public readonly retryAfter?: number\n ) {\n super(message);\n this.name = 'RateLimitError';\n }\n}\n","/**\n * Base LLM Provider implementation\n * Contains common logic for retry, error handling, etc.\n */\n\nimport { ILLMProvider, LLMTool } from './ILLMProvider.js';\nimport { Message, ChatResponse, ChatChunk, LLMConfig } from '../types/index.js';\nimport { NetworkError } from '../utils/errors.js';\n\nexport interface RetryConfig {\n maxRetries: number;\n retryDelay: number;\n backoffMultiplier: number;\n}\n\nexport abstract class BaseLLMProvider implements ILLMProvider {\n protected config: LLMConfig;\n protected retryConfig: RetryConfig;\n\n constructor(config: LLMConfig, retryConfig?: RetryConfig) {\n this.config = config;\n this.retryConfig = retryConfig ?? {\n maxRetries: 3,\n retryDelay: 1000,\n backoffMultiplier: 2,\n };\n }\n\n abstract chat(messages: Message[], tools?: LLMTool[]): Promise<ChatResponse>;\n abstract streamChat(messages: Message[], tools?: LLMTool[]): AsyncGenerator<ChatChunk>;\n abstract countTokens(text: string): number;\n abstract calculateCost(inputTokens: number, outputTokens: number): number;\n\n getProviderName(): string {\n return this.config.provider;\n }\n\n getModelName(): string {\n return this.config.model;\n }\n\n /**\n * Retry wrapper for API calls\n * Only retries on NetworkError (5xx server errors)\n * Does NOT retry on auth errors, rate limits, or client errors\n */\n protected async withRetry<T>(fn: () => Promise<T>): Promise<T> {\n let lastError: Error | undefined;\n let delay = this.retryConfig.retryDelay;\n\n for (let attempt = 0; attempt <= this.retryConfig.maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error as Error;\n\n // Only retry on NetworkError (transient server issues)\n // Don't retry on auth errors, rate limits, or client errors\n const shouldRetry = error instanceof NetworkError && attempt < this.retryConfig.maxRetries;\n\n if (shouldRetry) {\n await this.sleep(delay);\n delay *= this.retryConfig.backoffMultiplier;\n } else {\n // For non-retryable errors, throw immediately\n throw lastError;\n }\n }\n }\n\n throw lastError;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","/**\n * HTTP API client wrapper around axios\n * Handles request/response, error mapping, and streaming\n */\n\nimport axios, { AxiosInstance, AxiosError, AxiosResponse } from 'axios';\nimport { ProviderError, NetworkError, RateLimitError } from '../../utils/errors.js';\n\nexport interface APIClientConfig {\n baseURL: string;\n headers: Record<string, string>;\n timeout?: number;\n}\n\nexport class APIClient {\n private axiosInstance: AxiosInstance;\n private providerName: string;\n\n constructor(config: APIClientConfig) {\n this.axiosInstance = axios.create({\n baseURL: config.baseURL,\n headers: config.headers,\n timeout: config.timeout || 60000, // 60 seconds default\n });\n\n // Extract provider name from base URL for error messages\n this.providerName = this.extractProviderName(config.baseURL);\n }\n\n /**\n * POST request with JSON payload\n */\n async post<T>(endpoint: string, data: unknown): Promise<T> {\n try {\n const response: AxiosResponse<T> = await this.axiosInstance.post(endpoint, data);\n return response.data;\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n /**\n * GET request\n */\n async get<T>(endpoint: string): Promise<T> {\n try {\n const response: AxiosResponse<T> = await this.axiosInstance.get(endpoint);\n return response.data;\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n /**\n * Stream request for Server-Sent Events (SSE)\n * Returns async iterable of string chunks\n */\n async *stream(endpoint: string, data: unknown): AsyncGenerator<string, void, unknown> {\n try {\n const response = await this.axiosInstance.post(endpoint, data, {\n responseType: 'stream',\n headers: {\n Accept: 'text/event-stream',\n },\n });\n\n const stream = response.data;\n\n // Read stream chunks\n for await (const chunk of stream) {\n const chunkStr = chunk.toString('utf-8');\n yield chunkStr;\n }\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n /**\n * Map axios errors to custom error types\n */\n private mapError(error: unknown): Error {\n if (!axios.isAxiosError(error)) {\n return error as Error;\n }\n\n const axiosError = error as AxiosError;\n const status = axiosError.response?.status;\n const errorData = axiosError.response?.data as {\n error?: { message?: string };\n message?: string;\n };\n const message = errorData?.error?.message || errorData?.message || axiosError.message;\n\n // Rate limit error (429)\n if (status === 429) {\n const retryAfter = parseInt((axiosError.response?.headers['retry-after'] as string) || '60');\n return new RateLimitError(`${this.providerName} rate limit exceeded: ${message}`, retryAfter);\n }\n\n // Auth errors (401, 403)\n if (status === 401 || status === 403) {\n return new ProviderError(\n `${this.providerName} authentication failed: ${message}`,\n this.providerName\n );\n }\n\n // Server errors (5xx)\n if (status && status >= 500) {\n return new NetworkError(`${this.providerName} server error: ${message}`, status);\n }\n\n // Client errors (4xx)\n if (status && status >= 400) {\n return new ProviderError(`${this.providerName} request error: ${message}`, this.providerName);\n }\n\n // Network/timeout errors\n if (axiosError.code === 'ECONNABORTED' || axiosError.code === 'ETIMEDOUT') {\n return new NetworkError(`${this.providerName} request timeout: ${message}`);\n }\n\n // Generic provider error\n return new ProviderError(`${this.providerName} error: ${message}`, this.providerName);\n }\n\n /**\n * Extract provider name from base URL\n */\n private extractProviderName(baseURL: string): string {\n try {\n const url = new URL(baseURL);\n const hostname = url.hostname;\n\n if (hostname.includes('deepseek')) return 'DeepSeek';\n if (hostname.includes('anthropic')) return 'Anthropic';\n if (hostname.includes('openai')) return 'OpenAI';\n if (hostname.includes('google')) return 'Google';\n\n return hostname;\n } catch {\n return 'Unknown Provider';\n }\n }\n}\n","/**\n * Pricing data for LLM providers\n * Hybrid approach: Fetch from API first, fallback to static table\n */\n\nexport interface ModelPricing {\n inputPerMillionTokens: number;\n outputPerMillionTokens: number;\n}\n\n// Static fallback pricing (updated as of 2025-12-25)\nconst STATIC_PRICING_TABLE: Record<string, Record<string, ModelPricing>> = {\n deepseek: {\n 'deepseek-chat': {\n inputPerMillionTokens: 0.14,\n outputPerMillionTokens: 0.28,\n },\n 'deepseek-reasoner': {\n inputPerMillionTokens: 0.55,\n outputPerMillionTokens: 2.19,\n },\n },\n anthropic: {\n 'claude-opus-4-5-20251101': {\n inputPerMillionTokens: 15,\n outputPerMillionTokens: 75,\n },\n 'claude-opus-4-5': {\n inputPerMillionTokens: 15,\n outputPerMillionTokens: 75,\n },\n 'claude-sonnet-4-5-20250929': {\n inputPerMillionTokens: 3,\n outputPerMillionTokens: 15,\n },\n 'claude-sonnet-4-5': {\n inputPerMillionTokens: 3,\n outputPerMillionTokens: 15,\n },\n 'claude-haiku-4-5': {\n inputPerMillionTokens: 1,\n outputPerMillionTokens: 5,\n },\n 'claude-3-7-sonnet-latest': {\n inputPerMillionTokens: 3,\n outputPerMillionTokens: 15,\n },\n 'claude-3-5-haiku-latest': {\n inputPerMillionTokens: 1,\n outputPerMillionTokens: 5,\n },\n },\n};\n\n// In-memory cache for dynamic pricing (TTL: 24 hours)\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours\n\ninterface PricingCacheEntry {\n pricing: ModelPricing;\n timestamp: number;\n}\n\nconst pricingCache = new Map<string, PricingCacheEntry>();\n\n/**\n * Get static pricing for a provider/model\n */\nexport function getStaticPricing(provider: string, model: string): ModelPricing | null {\n const providerPricing = STATIC_PRICING_TABLE[provider.toLowerCase()];\n if (!providerPricing) {\n return null;\n }\n\n return providerPricing[model] || null;\n}\n\n/**\n * Fetch dynamic pricing from provider API or documentation\n */\nexport async function fetchDynamicPricing(\n provider: string,\n model: string,\n apiKey?: string\n): Promise<ModelPricing | null> {\n const normalizedProvider = provider.toLowerCase();\n\n // DeepSeek: Scrape pricing from documentation\n if (normalizedProvider === 'deepseek') {\n try {\n const response = await fetch('https://api-docs.deepseek.com/quick_start/pricing');\n if (!response.ok) {\n return null;\n }\n\n const html = await response.text();\n\n // Parse pricing from HTML (looking for pricing table or text)\n // DeepSeek pricing is typically listed as:\n // - deepseek-chat: $0.14 / $0.28 per million tokens\n // - deepseek-reasoner: $0.55 / $2.19 per million tokens\n\n // Try to extract pricing for the specific model\n const modelLower = model.toLowerCase();\n\n // For deepseek-chat, look for the first pricing entry\n if (modelLower.includes('chat')) {\n const match = html.match(/chat.*?\\$?0\\.14.*?\\$?0\\.28/i);\n if (match) {\n return {\n inputPerMillionTokens: 0.14,\n outputPerMillionTokens: 0.28,\n };\n }\n }\n\n // For deepseek-reasoner, look for reasoner pricing\n if (modelLower.includes('reasoner')) {\n const match = html.match(/reasoner.*?\\$?0\\.55.*?\\$?2\\.19/i);\n if (match) {\n return {\n inputPerMillionTokens: 0.55,\n outputPerMillionTokens: 2.19,\n };\n }\n }\n\n // Fallback to static if scraping fails\n return null;\n } catch (error) {\n // Silently fail and use static pricing\n return null;\n }\n }\n\n // Anthropic Models API (requires API key)\n if (normalizedProvider === 'anthropic' && apiKey) {\n try {\n const response = await fetch(`https://api.anthropic.com/v1/models/${model}`, {\n headers: {\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n });\n\n if (!response.ok) {\n return null;\n }\n\n const data = (await response.json()) as {\n pricing?: {\n input_price_per_million_tokens?: number;\n output_price_per_million_tokens?: number;\n };\n };\n\n if (\n data.pricing?.input_price_per_million_tokens != null &&\n data.pricing?.output_price_per_million_tokens != null\n ) {\n return {\n inputPerMillionTokens: data.pricing.input_price_per_million_tokens,\n outputPerMillionTokens: data.pricing.output_price_per_million_tokens,\n };\n }\n } catch (error) {\n // Silently fail and use static pricing\n return null;\n }\n }\n\n return null;\n}\n\n/**\n * Get pricing for a model (hybrid: API first, fallback to static)\n * Caches dynamic pricing for 24 hours\n */\nexport async function getModelPricing(\n provider: string,\n model: string,\n apiKey?: string\n): Promise<ModelPricing | null> {\n const cacheKey = `${provider}:${model}`;\n\n // Check cache first\n const cached = pricingCache.get(cacheKey);\n if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) {\n return cached.pricing;\n }\n\n // Try to fetch dynamic pricing\n const dynamicPricing = await fetchDynamicPricing(provider, model, apiKey);\n if (dynamicPricing) {\n // Cache the result\n pricingCache.set(cacheKey, {\n pricing: dynamicPricing,\n timestamp: Date.now(),\n });\n return dynamicPricing;\n }\n\n // Fallback to static pricing\n const staticPricing = getStaticPricing(provider, model);\n if (staticPricing) {\n // Cache static pricing too (to avoid repeated lookups)\n pricingCache.set(cacheKey, {\n pricing: staticPricing,\n timestamp: Date.now(),\n });\n }\n\n return staticPricing;\n}\n\n/**\n * Clear pricing cache (useful for testing or forcing refresh)\n */\nexport function clearPricingCache(): void {\n pricingCache.clear();\n}\n","/**\n * Tool format converters\n * Handles conversion between LLMTool interface and provider-specific formats\n */\n\nimport { LLMTool } from '../ILLMProvider.js';\nimport { ToolCall } from '../../types/index.js';\n\n/**\n * Convert LLMTool to OpenAI function calling format\n * Used by: DeepSeek, OpenAI, Qwen (OpenAI-compatible providers)\n */\nexport function toOpenAITools(tools: LLMTool[]): unknown[] {\n return tools.map((tool) => ({\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.schema, // Already JSON Schema\n },\n }));\n}\n\n/**\n * Convert LLMTool to Anthropic tool format\n * Used by: Anthropic Claude API\n */\nexport function toAnthropicTools(tools: LLMTool[]): unknown[] {\n return tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n input_schema: {\n type: 'object',\n ...tool.schema, // Merge with existing schema\n },\n }));\n}\n\n/**\n * Parse tool calls from OpenAI response\n */\nexport function parseOpenAIToolCalls(response: {\n choices?: Array<{\n message?: {\n tool_calls?: Array<{\n id: string;\n type: string;\n function: {\n name: string;\n arguments: string;\n };\n }>;\n };\n }>;\n}): ToolCall[] {\n const toolCalls = response.choices?.[0]?.message?.tool_calls || [];\n\n return toolCalls.map((tc) => {\n let parsedArgs: Record<string, unknown>;\n try {\n parsedArgs = JSON.parse(tc.function.arguments);\n } catch {\n parsedArgs = {};\n }\n\n return {\n id: tc.id,\n name: tc.function.name,\n arguments: parsedArgs,\n };\n });\n}\n\n/**\n * Parse tool calls from Anthropic response\n */\nexport function parseAnthropicToolCalls(response: {\n content?: Array<\n | { type: 'text'; text: string }\n | {\n type: 'tool_use';\n id: string;\n name: string;\n input: Record<string, unknown>;\n }\n >;\n}): ToolCall[] {\n const content = response.content || [];\n\n return content\n .filter(\n (block): block is Extract<typeof block, { type: 'tool_use' }> => block.type === 'tool_use'\n )\n .map((block) => ({\n id: block.id,\n name: block.name,\n arguments: block.input,\n }));\n}\n\n/**\n * Map OpenAI finish reason to standard format\n */\nexport function mapOpenAIFinishReason(reason: string): 'stop' | 'tool_calls' | 'length' | 'error' {\n switch (reason) {\n case 'stop':\n return 'stop';\n case 'tool_calls':\n return 'tool_calls';\n case 'length':\n return 'length';\n case 'content_filter':\n case 'insufficient_system_resource':\n return 'error';\n default:\n return 'error';\n }\n}\n\n/**\n * Map Anthropic stop reason to standard format\n */\nexport function mapAnthropicFinishReason(\n reason: string\n): 'stop' | 'tool_calls' | 'length' | 'error' {\n switch (reason) {\n case 'end_turn':\n return 'stop';\n case 'tool_use':\n return 'tool_calls';\n case 'max_tokens':\n return 'length';\n case 'stop_sequence':\n return 'stop';\n default:\n return 'error';\n }\n}\n","/**\n * Server-Sent Events (SSE) stream parsers\n * Handles different streaming formats from various providers\n */\n\nimport { ChatChunk } from '../../types/index.js';\n\n/**\n * Parse OpenAI-format SSE stream\n * Used by: DeepSeek, OpenAI, Qwen\n *\n * Format:\n * data: {\"choices\":[{\"delta\":{\"content\":\"hello\"}}]}\n * data: [DONE]\n */\nexport async function* parseOpenAIStream(stream: AsyncIterable<string>): AsyncGenerator<ChatChunk> {\n let buffer = '';\n\n for await (const chunk of stream) {\n buffer += chunk;\n\n // Split by newlines to get individual SSE messages\n const lines = buffer.split('\\n');\n\n // Keep the last incomplete line in buffer\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Skip empty lines\n if (!trimmed) continue;\n\n // Check for [DONE] marker\n if (trimmed === 'data: [DONE]') {\n yield { content: '', done: true };\n return;\n }\n\n // Parse data: lines\n if (trimmed.startsWith('data: ')) {\n const jsonStr = trimmed.substring(6); // Remove 'data: ' prefix\n try {\n const data = JSON.parse(jsonStr) as {\n choices?: Array<{\n delta?: {\n content?: string;\n role?: string;\n };\n finish_reason?: string | null;\n }>;\n };\n\n const delta = data.choices?.[0]?.delta;\n const content = delta?.content || '';\n const finishReason = data.choices?.[0]?.finish_reason;\n\n if (content) {\n yield { content, done: false };\n }\n\n if (finishReason) {\n yield { content: '', done: true };\n return;\n }\n } catch (error) {\n // Skip malformed JSON\n continue;\n }\n }\n }\n }\n\n // Flush any remaining buffer\n if (buffer.trim()) {\n yield { content: '', done: true };\n }\n}\n\n/**\n * Parse Anthropic-format SSE stream\n * Used by: Anthropic Claude API\n *\n * Format:\n * event: message_start\n * data: {\"type\":\"message_start\"}\n *\n * event: content_block_delta\n * data: {\"delta\":{\"text\":\"hello\"}}\n *\n * event: message_stop\n * data: {}\n */\nexport async function* parseAnthropicStream(\n stream: AsyncIterable<string>\n): AsyncGenerator<ChatChunk> {\n let buffer = '';\n let currentEvent = '';\n\n for await (const chunk of stream) {\n buffer += chunk;\n\n // Split by double newlines to get individual SSE events\n const events = buffer.split('\\n\\n');\n\n // Keep the last incomplete event in buffer\n buffer = events.pop() || '';\n\n for (const event of events) {\n const lines = event.split('\\n');\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (trimmed.startsWith('event: ')) {\n currentEvent = trimmed.substring(7);\n } else if (trimmed.startsWith('data: ')) {\n const jsonStr = trimmed.substring(6);\n\n try {\n const data = JSON.parse(jsonStr);\n\n // Handle content_block_delta events\n if (currentEvent === 'content_block_delta') {\n const content = data.delta?.text || '';\n if (content) {\n yield { content, done: false };\n }\n }\n\n // Handle content_block_start events\n if (currentEvent === 'content_block_start') {\n const content = data.content_block?.text || '';\n if (content) {\n yield { content, done: false };\n }\n }\n\n // Handle message_delta events (may contain usage info)\n if (currentEvent === 'message_delta') {\n // No content in message_delta, just metadata\n continue;\n }\n\n // Handle message_stop event\n if (currentEvent === 'message_stop') {\n yield { content: '', done: true };\n return;\n }\n\n // Handle error events\n if (currentEvent === 'error') {\n throw new Error(data.error?.message || 'Anthropic streaming error');\n }\n } catch (error) {\n // Skip malformed JSON or propagate errors\n if (currentEvent === 'error') {\n throw error;\n }\n continue;\n }\n }\n }\n }\n }\n\n // Flush any remaining buffer\n if (buffer.trim()) {\n yield { content: '', done: true };\n }\n}\n","/**\n * Anthropic Claude LLM Provider\n * Uses Claude's Messages API with Anthropic-specific format\n */\n\nimport { encode } from 'gpt-tokenizer';\nimport { BaseLLMProvider } from './BaseLLMProvider.js';\nimport { ILLMProvider, LLMTool } from './ILLMProvider.js';\nimport { Message, ChatResponse, ChatChunk, LLMConfig } from '../types/index.js';\nimport { APIClient } from './utils/apiClient.js';\nimport { getStaticPricing } from './pricing/pricingData.js';\nimport {\n toAnthropicTools,\n parseAnthropicToolCalls,\n mapAnthropicFinishReason,\n} from './utils/toolFormatters.js';\nimport { parseAnthropicStream } from './utils/streamParsers.js';\nimport { ConfigurationError } from '../utils/errors.js';\n\nexport class AnthropicProvider extends BaseLLMProvider implements ILLMProvider {\n private apiClient: APIClient;\n\n constructor(config: LLMConfig) {\n super(config);\n\n const apiKey = config.apiKey || process.env.ANTHROPIC_API_KEY;\n if (!apiKey) {\n throw new ConfigurationError(\n 'ANTHROPIC_API_KEY not found in config or environment variables. ' +\n 'Please set ANTHROPIC_API_KEY in your .env file or pass it via config.'\n );\n }\n const baseURL = config.baseURL || 'https://api.anthropic.com';\n\n this.apiClient = new APIClient({\n baseURL,\n headers: {\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n 'Content-Type': 'application/json',\n },\n timeout: 60000,\n });\n }\n\n async chat(messages: Message[], tools?: LLMTool[]): Promise<ChatResponse> {\n return this.withRetry(async () => {\n const { system, messages: userMessages } = this.formatAnthropicMessages(messages);\n\n const requestBody: AnthropicChatRequest = {\n model: this.config.model,\n messages: userMessages,\n max_tokens: this.config.maxTokens,\n temperature: this.config.temperature,\n };\n\n // Add system message if present\n if (system) {\n requestBody.system = system;\n }\n\n // Add tools if present\n if (tools && tools.length > 0) {\n requestBody.tools = toAnthropicTools(tools);\n }\n\n const response = await this.apiClient.post<AnthropicChatResponse>(\n '/v1/messages',\n requestBody\n );\n\n return this.parseResponse(response);\n });\n }\n\n async *streamChat(messages: Message[], tools?: LLMTool[]): AsyncGenerator<ChatChunk> {\n const { system, messages: userMessages } = this.formatAnthropicMessages(messages);\n\n const requestBody: AnthropicChatRequest = {\n model: this.config.model,\n messages: userMessages,\n max_tokens: this.config.maxTokens,\n temperature: this.config.temperature,\n stream: true,\n };\n\n if (system) {\n requestBody.system = system;\n }\n\n if (tools && tools.length > 0) {\n requestBody.tools = toAnthropicTools(tools);\n }\n\n const stream = this.apiClient.stream('/v1/messages', requestBody);\n\n for await (const chunk of parseAnthropicStream(stream)) {\n yield chunk;\n }\n }\n\n countTokens(text: string): number {\n return encode(text).length;\n }\n\n calculateCost(inputTokens: number, outputTokens: number): number {\n const pricing = getStaticPricing('anthropic', this.config.model);\n if (!pricing) {\n return 0; // Unknown model, return 0 cost\n }\n\n return (\n (inputTokens / 1_000_000) * pricing.inputPerMillionTokens +\n (outputTokens / 1_000_000) * pricing.outputPerMillionTokens\n );\n }\n\n /**\n * Format messages for Anthropic API\n * Extracts system messages into separate parameter\n */\n private formatAnthropicMessages(messages: Message[]): {\n system?: string;\n messages: Array<{ role: string; content: string }>;\n } {\n const systemMessages = messages.filter((m) => m.role === 'system');\n const userMessages = messages.filter((m) => m.role !== 'system');\n\n const system =\n systemMessages.length > 0 ? systemMessages.map((m) => m.content).join('\\n\\n') : undefined;\n\n return {\n system,\n messages: userMessages.map((msg) => ({\n role: msg.role === 'assistant' ? 'assistant' : 'user',\n content: msg.content,\n })),\n };\n }\n\n /**\n * Parse Anthropic API response\n */\n private parseResponse(response: AnthropicChatResponse): ChatResponse {\n const content = response.content || [];\n const usage = response.usage;\n\n // Extract text content from content blocks\n const textContent = content\n .filter((block) => block.type === 'text')\n .map((block) => (block as { type: 'text'; text: string }).text)\n .join('');\n\n return {\n content: textContent,\n toolCalls: parseAnthropicToolCalls(response),\n finishReason: mapAnthropicFinishReason(response.stop_reason),\n usage: {\n inputTokens: usage.input_tokens,\n outputTokens: usage.output_tokens,\n totalTokens: usage.input_tokens + usage.output_tokens,\n },\n };\n }\n}\n\n/**\n * Anthropic API request type\n */\ninterface AnthropicChatRequest {\n model: string;\n messages: Array<{\n role: string;\n content: string;\n }>;\n max_tokens: number;\n temperature?: number;\n system?: string;\n tools?: unknown[];\n stream?: boolean;\n}\n\n/**\n * Anthropic API response type\n */\ninterface AnthropicChatResponse {\n id: string;\n type: string;\n role: string;\n content: Array<\n | { type: 'text'; text: string }\n | {\n type: 'tool_use';\n id: string;\n name: string;\n input: Record<string, unknown>;\n }\n >;\n model: string;\n stop_reason: string;\n stop_sequence?: string | null;\n usage: {\n input_tokens: number;\n output_tokens: number;\n };\n}\n","/**\n * Factory for creating LLM provider instances\n */\n\nimport { ILLMProvider } from './ILLMProvider.js';\nimport { LLMConfig } from '../types/index.js';\nimport { DeepSeekProvider } from './DeepSeekProvider.js';\nimport { AnthropicProvider } from './AnthropicProvider.js';\n\nexport class ProviderFactory {\n static create(config: LLMConfig): ILLMProvider {\n switch (config.provider.toLowerCase()) {\n case 'deepseek':\n return new DeepSeekProvider(config);\n case 'anthropic':\n return new AnthropicProvider(config);\n case 'openai':\n throw new Error(\n 'OpenAI provider coming soon - see roadmap Phase 3. ' +\n 'In the meantime, you can use DeepSeek which is OpenAI-compatible.'\n );\n case 'google':\n case 'gemini':\n throw new Error('Google/Gemini provider coming soon - see roadmap Phase 3.');\n case 'qwen':\n throw new Error(\n 'Qwen provider coming soon - see roadmap Phase 3. ' +\n 'In the meantime, you can use DeepSeek which is similar.'\n );\n case 'ollama':\n throw new Error('Ollama provider coming soon - see roadmap Phase 3.');\n default:\n throw new Error(`Unsupported provider: ${config.provider}`);\n }\n }\n}\n","/**\n * Init command handler\n * Initializes Mimir in the current project\n */\n\nimport { IFileSystem } from '../../platform/IFileSystem.js';\nimport { ConfigLoader } from '../../config/ConfigLoader.js';\nimport { MimirInitializer } from '../../core/MimirInitializer.js';\nimport { logger } from '../../utils/logger.js';\n\nexport interface InitOptions {\n interactive?: boolean;\n quiet?: boolean;\n}\n\nexport class InitCommand {\n private initializer: MimirInitializer;\n\n constructor(_fs: IFileSystem, _configLoader: ConfigLoader) {\n this.initializer = new MimirInitializer(_fs, _configLoader);\n }\n\n async execute(projectRoot?: string, options: InitOptions = {}): Promise<void> {\n const root = projectRoot || process.cwd();\n\n if (!options.quiet) {\n logger.info('Initializing Mimir workspace', { projectRoot: root });\n }\n\n // Check if already initialized\n if (await this.initializer.isWorkspaceInitialized(root)) {\n if (!options.quiet) {\n logger.info('Mimir workspace is already initialized in this directory.');\n logger.info('Run \"mimir\" to start an interactive chat session.');\n }\n return;\n }\n\n // Run full initialization\n const result = await this.initializer.initializeWorkspace(root);\n\n // Print summary (unless quiet mode)\n if (!options.quiet) {\n this.initializer.printSummary(result, root);\n }\n\n // Exit with error if initialization failed\n if (!result.success) {\n process.exit(1);\n }\n }\n}\n","/**\n * Uninstall command handler\n * Removes Mimir installation and optionally user configuration\n */\n\nimport { IFileSystem } from '../../platform/IFileSystem.js';\nimport { IProcessExecutor } from '../../platform/IProcessExecutor.js';\nimport { logger } from '../../utils/logger.js';\nimport path from 'path';\nimport os from 'os';\nimport React from 'react';\nimport { render, Box, Text } from 'ink';\nimport Spinner from 'ink-spinner';\nimport TextInput from 'ink-text-input';\n\ninterface UninstallResult {\n success: boolean;\n removed: string[];\n errors: string[];\n keepConfig: boolean;\n}\n\nexport interface UninstallOptions {\n yes?: boolean; // Auto-confirm without prompting\n keepConfig?: boolean; // Keep configuration (overrides prompt)\n removeConfig?: boolean; // Remove configuration (overrides prompt)\n quiet?: boolean; // Suppress output (implies yes)\n}\n\nexport class UninstallCommand {\n constructor(\n private fs: IFileSystem,\n private executor?: IProcessExecutor\n ) {}\n\n async execute(options: UninstallOptions = {}): Promise<void> {\n try {\n // If quiet mode, auto-confirm and suppress prompts\n const autoConfirm = options.yes || options.quiet;\n\n // 1. Show warning and get confirmation\n let confirmed = autoConfirm;\n if (!autoConfirm) {\n confirmed = await this.promptConfirmation();\n }\n\n if (!confirmed) {\n if (!options.quiet) {\n logger.info('Uninstall cancelled.');\n }\n return;\n }\n\n // 2. Determine whether to keep config\n let keepConfig: boolean;\n if (options.removeConfig !== undefined) {\n keepConfig = !options.removeConfig;\n } else if (options.keepConfig !== undefined) {\n keepConfig = options.keepConfig;\n } else if (autoConfirm) {\n // Default to keeping config in auto-confirm mode (safer)\n keepConfig = true;\n } else {\n keepConfig = await this.promptKeepConfig();\n }\n\n // 3. Detect installation type and uninstall\n const result = await this.uninstall(keepConfig, options.quiet);\n\n // 4. Show results\n if (!options.quiet) {\n this.printSummary(result);\n }\n\n if (!result.success) {\n process.exit(1);\n }\n } catch (error) {\n if (!options.quiet) {\n logger.error('Uninstall failed', { error });\n }\n process.exit(1);\n }\n }\n\n private async promptConfirmation(): Promise<boolean> {\n return new Promise((resolve) => {\n const ConfirmPrompt = () => {\n const [input, setInput] = React.useState('');\n const [submitted, setSubmitted] = React.useState(false);\n\n React.useEffect(() => {\n if (submitted) {\n const answer = input.toLowerCase();\n resolve(answer === 'y' || answer === 'yes');\n }\n }, [submitted, input]);\n\n if (submitted) {\n return null;\n }\n\n return React.createElement(\n Box,\n { flexDirection: 'column', marginY: 1 },\n React.createElement(\n Box,\n { marginBottom: 1 },\n React.createElement(\n Text,\n { bold: true, color: 'yellow' },\n '⚠️ WARNING: This will uninstall Mimir from your system.'\n )\n ),\n React.createElement(\n Box,\n null,\n React.createElement(Text, null, 'Are you sure you want to continue? (y/N): '),\n React.createElement(TextInput, {\n value: input,\n onChange: setInput,\n onSubmit: () => setSubmitted(true),\n })\n )\n );\n };\n\n render(React.createElement(ConfirmPrompt));\n });\n }\n\n private async promptKeepConfig(): Promise<boolean> {\n return new Promise((resolve) => {\n const ConfigPrompt = () => {\n const [input, setInput] = React.useState('');\n const [submitted, setSubmitted] = React.useState(false);\n\n React.useEffect(() => {\n if (submitted) {\n const answer = input.toLowerCase();\n // Default to keeping config (safer)\n resolve(answer !== 'n' && answer !== 'no');\n }\n }, [submitted, input]);\n\n if (submitted) {\n return null;\n }\n\n return React.createElement(\n Box,\n { flexDirection: 'column', marginY: 1 },\n React.createElement(\n Box,\n { marginBottom: 1 },\n React.createElement(\n Text,\n null,\n 'Do you want to keep your Mimir configuration and data in ~/.mimir?'\n )\n ),\n React.createElement(\n Box,\n null,\n React.createElement(Text, null, 'Keep configuration? (Y/n): '),\n React.createElement(TextInput, {\n value: input,\n onChange: setInput,\n onSubmit: () => setSubmitted(true),\n })\n )\n );\n };\n\n render(React.createElement(ConfigPrompt));\n });\n }\n\n private async uninstall(keepConfig: boolean, quiet = false): Promise<UninstallResult> {\n const result: UninstallResult = {\n success: true,\n removed: [],\n errors: [],\n keepConfig,\n };\n\n let clear: (() => void) | undefined;\n\n if (!quiet) {\n const UninstallProgress = () =>\n React.createElement(\n Box,\n null,\n React.createElement(\n Text,\n { color: 'cyan' },\n React.createElement(Spinner, { type: 'dots' }),\n ' Uninstalling Mimir...'\n )\n );\n\n const rendered = render(React.createElement(UninstallProgress));\n clear = rendered.clear;\n }\n\n try {\n const homeDir = os.homedir();\n\n // 1. Detect installation type\n const installType = await this.detectInstallType();\n if (!quiet) {\n logger.info(`Detected installation type: ${installType}`);\n }\n\n // 2. Remove binary installation (if applicable)\n if (installType === 'binary') {\n await this.removeBinaryInstallation(homeDir, result, quiet);\n }\n\n // 3. For npm installations, run npm uninstall\n if (installType === 'npm') {\n await this.removeNpmInstallation(result, quiet);\n }\n\n // 4. Remove global config if requested\n if (!keepConfig) {\n await this.removeGlobalConfig(homeDir, result, quiet);\n } else if (!quiet) {\n logger.info('Keeping global configuration at ~/.mimir');\n }\n } catch (error) {\n result.success = false;\n result.errors.push(\n `Uninstall failed: ${error instanceof Error ? error.message : String(error)}`\n );\n if (!quiet) {\n logger.error('Uninstall error', { error });\n }\n } finally {\n if (clear) {\n clear();\n }\n }\n\n return result;\n }\n\n private async detectInstallType(): Promise<'npm' | 'binary' | 'unknown'> {\n try {\n // Check if this script is running from npm global modules\n const scriptPath = process.argv[1];\n\n if (!scriptPath) {\n logger.debug('No script path found in process.argv[1]');\n return 'unknown';\n }\n\n logger.debug(`Detecting install type from script path: ${scriptPath}`);\n\n // Normalize path for comparison (handle Windows backslashes)\n const normalizedPath = path.normalize(scriptPath).toLowerCase();\n\n // npm installations are typically in node_modules\n if (normalizedPath.includes('node_modules')) {\n logger.debug('Detected npm installation (node_modules in path)');\n return 'npm';\n }\n\n // Binary installations are typically in ~/.mimir/bin or ~/.local/bin\n const homeDir = os.homedir();\n const mimirBinPath = path.normalize(path.join(homeDir, '.mimir', 'bin')).toLowerCase();\n const localBinPath = path.normalize(path.join(homeDir, '.local', 'bin')).toLowerCase();\n\n if (normalizedPath.includes(mimirBinPath)) {\n logger.debug('Detected binary installation (.mimir/bin in path)');\n return 'binary';\n }\n\n if (normalizedPath.includes(localBinPath)) {\n logger.debug('Detected binary installation (.local/bin in path)');\n return 'binary';\n }\n\n // Check if the binary files exist (fallback detection)\n const binaryPaths = [\n // Unix binary locations\n path.join(homeDir, '.local', 'bin', 'mimir'),\n path.join(homeDir, '.mimir', 'bin', 'mimir'),\n // Windows binary locations (.exe, .cmd variants)\n path.join(homeDir, '.local', 'bin', 'mimir.exe'),\n path.join(homeDir, '.local', 'bin', 'mimir.cmd'),\n path.join(homeDir, '.mimir', 'bin', 'mimir.exe'),\n path.join(homeDir, '.mimir', 'bin', 'mimir.cmd'),\n ];\n\n for (const binPath of binaryPaths) {\n if (await this.fs.exists(binPath)) {\n logger.debug(`Detected binary installation (found file at ${binPath})`);\n return 'binary';\n }\n }\n\n logger.debug('Could not detect installation type - defaulting to unknown');\n return 'unknown';\n } catch (error) {\n logger.debug('Error detecting installation type', { error });\n return 'unknown';\n }\n }\n\n private async removeNpmInstallation(result: UninstallResult, quiet = false): Promise<void> {\n if (!this.executor) {\n if (!quiet) {\n logger.warn('Cannot automatically uninstall npm package.');\n logger.info('Please run manually: npm uninstall -g @codedir/mimir-code');\n }\n return;\n }\n\n try {\n if (!quiet) {\n logger.info('Removing npm global package...');\n }\n\n const npmResult = await this.executor.execute(\n 'npm',\n ['uninstall', '-g', '@codedir/mimir-code'],\n {\n cwd: process.cwd(),\n }\n );\n\n if (npmResult.exitCode === 0) {\n result.removed.push('npm global package (@codedir/mimir-code)');\n if (!quiet) {\n logger.info('Successfully uninstalled npm package');\n }\n } else {\n throw new Error(`npm uninstall failed: ${npmResult.stderr}`);\n }\n } catch (error) {\n if (!quiet) {\n logger.error('Failed to uninstall npm package', { error });\n logger.info('Please run manually: npm uninstall -g @codedir/mimir-code');\n }\n result.errors.push(\n `npm uninstall failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n private async removeBinaryInstallation(\n homeDir: string,\n result: UninstallResult,\n quiet = false\n ): Promise<void> {\n const isWindows = process.platform === 'win32';\n const localBinPath = path.join(homeDir, '.local', 'bin', 'mimir');\n const mimirBinDir = path.join(homeDir, '.mimir', 'bin');\n\n if (isWindows) {\n // Windows: Spawn deferred cleanup process\n await this.spawnWindowsCleanup(localBinPath, mimirBinDir, quiet);\n\n // Remove from PATH\n await this.removeFromWindowsPath(quiet);\n\n result.removed.push('Binary (scheduled for deletion after exit)');\n result.removed.push('PATH entry');\n\n if (!quiet) {\n logger.info('✓ Scheduled binary deletion');\n logger.info('✓ Removed from PATH');\n logger.warn('⚠ Cleanup will complete in ~3 seconds');\n }\n } else {\n // Unix: Delete directly (file can be unlinked while running)\n if (await this.fs.exists(localBinPath)) {\n await this.fs.unlink(localBinPath);\n result.removed.push('~/.local/bin/mimir');\n if (!quiet) {\n logger.info('Removed binary from ~/.local/bin');\n }\n }\n\n if (await this.fs.exists(mimirBinDir)) {\n await this.fs.rmdir(mimirBinDir, { recursive: true });\n result.removed.push('~/.mimir/bin/');\n if (!quiet) {\n logger.info('Removed binary directory');\n }\n }\n\n if (!quiet) {\n logger.info('✓ Binary uninstalled');\n logger.warn('⚠ Current terminal still has mimir cached');\n logger.info(' Run: hash -r (to clear shell cache)');\n }\n }\n }\n\n private async spawnWindowsCleanup(\n binPath: string,\n binDir: string,\n quiet: boolean\n ): Promise<void> {\n if (!this.executor) {\n if (!quiet) {\n logger.warn('Cannot spawn cleanup process - no executor available');\n }\n return;\n }\n\n try {\n // Create cleanup batch script\n const cleanupScript = `@echo off\nREM Wait for parent process to exit\ntimeout /t 3 /nobreak >nul 2>&1\n\nREM Delete binary if it exists\nif exist \"${binPath}\" (\n del /f /q \"${binPath}\" >nul 2>&1\n)\nif exist \"${binPath}.exe\" (\n del /f /q \"${binPath}.exe\" >nul 2>&1\n)\nif exist \"${binPath}.cmd\" (\n del /f /q \"${binPath}.cmd\" >nul 2>&1\n)\n\nREM Delete binary directory\nif exist \"${binDir}\" (\n rmdir /s /q \"${binDir}\" >nul 2>&1\n)\n\nREM Delete this cleanup script\ndel /f /q \"%~f0\" >nul 2>&1\n`;\n\n const tempDir = os.tmpdir();\n const cleanupPath = path.join(tempDir, `mimir-cleanup-${Date.now()}.bat`);\n\n await this.fs.writeFile(cleanupPath, cleanupScript);\n\n // Spawn detached background process\n const { spawn } = await import('child_process');\n const child = spawn('cmd', ['/c', cleanupPath], {\n detached: true,\n stdio: 'ignore',\n windowsHide: true,\n });\n child.unref();\n\n if (!quiet) {\n logger.info('Spawned background cleanup process');\n }\n } catch (error) {\n if (!quiet) {\n logger.error('Failed to spawn cleanup process', { error });\n }\n }\n }\n\n private async removeFromWindowsPath(quiet: boolean): Promise<void> {\n if (!this.executor) return;\n\n try {\n // Get current user PATH\n const result = await this.executor.execute(\n 'powershell',\n ['-NoProfile', '-Command', '[Environment]::GetEnvironmentVariable(\"Path\", \"User\")'],\n { cwd: process.cwd() }\n );\n\n if (result.exitCode !== 0) {\n throw new Error('Failed to read PATH');\n }\n\n const currentPath = result.stdout.trim();\n const pathEntries = currentPath.split(';').filter(Boolean);\n\n // Remove only mimir-related entries\n const filteredEntries = pathEntries.filter((entry) => {\n const normalizedEntry = path.normalize(entry.trim()).toLowerCase();\n return !normalizedEntry.includes('mimir');\n });\n\n // Only update if we actually removed something\n if (filteredEntries.length < pathEntries.length) {\n const newPath = filteredEntries.join(';');\n\n await this.executor.execute(\n 'powershell',\n [\n '-NoProfile',\n '-Command',\n `[Environment]::SetEnvironmentVariable(\"Path\", \"${newPath}\", \"User\")`,\n ],\n { cwd: process.cwd() }\n );\n\n const removedCount = pathEntries.length - filteredEntries.length;\n if (!quiet) {\n logger.info(`Removed ${removedCount} PATH entry/entries containing 'mimir'`);\n }\n }\n } catch (error) {\n if (!quiet) {\n logger.warn('Failed to remove from PATH', { error });\n logger.info('You may need to manually remove from PATH');\n }\n }\n }\n\n private async removeGlobalConfig(\n homeDir: string,\n result: UninstallResult,\n quiet = false\n ): Promise<void> {\n const mimirDir = path.join(homeDir, '.mimir');\n\n if (await this.fs.exists(mimirDir)) {\n // Remove the directory\n await this.fs.rmdir(mimirDir, { recursive: true });\n result.removed.push('~/.mimir/');\n if (!quiet) {\n logger.info('Removed configuration directory: ~/.mimir');\n logger.info('All Mimir data has been deleted.');\n }\n }\n }\n\n /* eslint-disable no-console */\n printSummary(result: UninstallResult): void {\n console.log('');\n console.log('═══════════════════════════════════════════════════════');\n\n if (result.success) {\n console.log('✅ Mimir has been uninstalled');\n } else {\n console.log('❌ Uninstall completed with errors');\n }\n\n console.log('═══════════════════════════════════════════════════════');\n\n if (result.removed.length > 0) {\n console.log('');\n console.log('Removed:');\n result.removed.forEach((item) => console.log(` - ${item}`));\n }\n\n if (result.keepConfig) {\n console.log('');\n console.log('Configuration preserved:');\n console.log(' - ~/.mimir/ (your settings and data)');\n console.log('');\n console.log('To remove it later, run:');\n console.log(' mimir uninstall --yes --remove-config');\n console.log(' or manually: rm -rf ~/.mimir');\n }\n\n if (result.errors.length > 0) {\n console.log('');\n console.log('Errors:');\n result.errors.forEach((error) => console.log(` - ${error}`));\n }\n\n console.log('');\n console.log('Thank you for using Mimir! 👋');\n console.log('');\n }\n /* eslint-enable no-console */\n}\n"],"mappings":";;;AAQA,SAAS,eAAe;;;ACFxB,OAAO,QAAQ;AACf,OAAO,QAAQ;AAER,IAAM,oBAAN,MAA+C;AAAA,EACpD,MAAM,SAASA,OAAc,WAA2B,SAA0B;AAChF,WAAO,GAAG,SAASA,OAAM,QAAQ;AAAA,EACnC;AAAA,EAEA,MAAM,UACJA,OACA,SACA,WAA2B,SACZ;AACf,UAAM,GAAG,UAAUA,OAAM,SAAS,QAAQ;AAAA,EAC5C;AAAA,EAEA,MAAM,OAAOA,OAAgC;AAC3C,QAAI;AACF,YAAM,GAAG,OAAOA,KAAI;AACpB,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,MAAMA,OAAc,SAAkD;AAC1E,UAAM,GAAG,MAAMA,OAAM,OAAO;AAAA,EAC9B;AAAA,EAEA,MAAM,QAAQA,OAAiC;AAC7C,WAAO,GAAG,QAAQA,KAAI;AAAA,EACxB;AAAA,EAEA,MAAM,KAAKA,OAA8B;AACvC,UAAM,QAAQ,MAAM,GAAG,KAAKA,KAAI;AAChC,WAAO;AAAA,MACL,QAAQ,MAAM,MAAM,OAAO;AAAA,MAC3B,aAAa,MAAM,MAAM,YAAY;AAAA,MACrC,MAAM,MAAM;AAAA,MACZ,OAAO,MAAM;AAAA,IACf;AAAA,EACF;AAAA,EAEA,MAAM,OAAOA,OAA6B;AACxC,UAAM,GAAG,OAAOA,KAAI;AAAA,EACtB;AAAA,EAEA,MAAM,MAAMA,OAAc,SAAkD;AAC1E,UAAM,GAAG,MAAMA,OAAM,OAAO;AAAA,EAC9B;AAAA,EAEA,MAAM,SAAS,KAAa,MAA6B;AACvD,UAAM,GAAG,SAAS,KAAK,IAAI;AAAA,EAC7B;AAAA,EAEA,MAAM,KAAK,SAAiB,SAAkE;AAC5F,WAAO,GAAG,SAAS;AAAA,MACjB,KAAK,SAAS;AAAA,MACd,QAAQ,SAAS;AAAA,IACnB,CAAC;AAAA,EACH;AACF;;;AC7DA,SAAS,OAAO,oBAAoB;AAG7B,IAAM,yBAAN,MAAyD;AAAA;AAAA;AAAA;AAAA,EAI9D,MAAM,QACJ,SACA,OAAiB,CAAC,GAClB,UAAuB,CAAC,GACH;AACrB,QAAI;AACF,YAAM,SAAS,MAAM,MAAM,SAAS,MAAM;AAAA,QACxC,KAAK,QAAQ;AAAA,QACb,KAAK,QAAQ;AAAA,QACb,SAAS,QAAQ;AAAA,QACjB,OAAO,QAAQ;AAAA,QACf,OAAO,QAAQ;AAAA,QACf,QAAQ;AAAA;AAAA,MACV,CAAC;AAED,aAAO;AAAA,QACL,QAAQ,OAAO;AAAA,QACf,QAAQ,OAAO;AAAA,QACf,UAAU,OAAO,aAAa,OAAO,SAAS,IAAI;AAAA,QAClD,SAAS,OAAO;AAAA,QAChB,UAAU,OAAO,YAAY;AAAA,MAC/B;AAAA,IACF,SAAS,OAAY;AAInB,YAAM,WAAW,MAAM,SAAS,WAAW,MAAM,MAAM,YAAY;AAEnE,aAAO;AAAA,QACL,QAAQ,MAAM,UAAU;AAAA,QACxB,QAAQ,MAAM,UAAU,MAAM,WAAW,OAAO,KAAK;AAAA,QACrD;AAAA,QACA,SAAS,MAAM,WAAW,GAAG,OAAO,IAAI,KAAK,KAAK,GAAG,CAAC;AAAA,QACtD,UAAU,MAAM,YAAY;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAiB,OAAiB,CAAC,GAAG,UAAuB,CAAC,GAAiB;AACnF,UAAM,aAAa,MAAM,SAAS,MAAM;AAAA,MACtC,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,MACb,SAAS,QAAQ;AAAA,MACjB,OAAO,QAAQ;AAAA,MACf,OAAO,QAAQ,QAAQ,SAAS;AAAA,MAChC,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV,CAAC;AAGD,QAAI,QAAQ,SAAS,WAAW,OAAO;AACrC,iBAAW,MAAM,MAAM,QAAQ,KAAK;AACpC,iBAAW,MAAM,IAAI;AAAA,IACvB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,SAAiB,UAAuB,CAAC,GAAwB;AAClF,QAAI;AACF,YAAM,SAAS,MAAM,aAAa,SAAS;AAAA,QACzC,KAAK,QAAQ;AAAA,QACb,KAAK,QAAQ;AAAA,QACb,SAAS,QAAQ;AAAA,QACjB,OAAO;AAAA,QACP,OAAO,QAAQ;AAAA,QACf,QAAQ;AAAA;AAAA,MACV,CAAC;AAED,aAAO;AAAA,QACL,QAAQ,OAAO;AAAA,QACf,QAAQ,OAAO;AAAA,QACf,UAAU,OAAO,aAAa,OAAO,SAAS,IAAI;AAAA,QAClD,SAAS,OAAO;AAAA,QAChB,UAAU,OAAO,YAAY;AAAA,MAC/B;AAAA,IACF,SAAS,OAAY;AAInB,YAAM,WAAW,MAAM,SAAS,WAAW,MAAM,MAAM,YAAY;AAEnE,aAAO;AAAA,QACL,QAAQ,MAAM,UAAU;AAAA,QACxB,QAAQ,MAAM,UAAU,MAAM,WAAW,OAAO,KAAK;AAAA,QACrD;AAAA,QACA,SAAS,MAAM,WAAW;AAAA,QAC1B,UAAU,MAAM,YAAY;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AACF;;;AC1GA,SAAS,SAAS;AAGX,IAAM,cAAc,EAAE,KAAK;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,iBAAiB,EAAE,OAAO;AAAA,EACrC,OAAO,YAAY,QAAQ,OAAO;AAAA,EAClC,oBAAoB,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EAC5C,iBAAiB,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACzC,aAAa,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA;AAAA,EAEtC,sBAAsB,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA;AAAA,EAC9C,6BAA6B,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA;AACvD,CAAC;AAEM,IAAM,kBAAkB,EAAE,OAAO;AAAA,EACtC,UAAU,EAAE,KAAK,CAAC,YAAY,aAAa,UAAU,UAAU,UAAU,QAAQ,QAAQ,CAAC;AAAA,EAC1F,OAAO,EAAE,OAAO;AAAA,EAChB,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG;AAAA,EACjD,WAAW,EAAE,OAAO,EAAE,QAAQ,IAAI;AACpC,CAAC;AAEM,IAAM,0BAA0B,EAAE,OAAO;AAAA,EAC9C,YAAY,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EACrC,iBAAiB,EAAE,KAAK,CAAC,OAAO,UAAU,QAAQ,UAAU,CAAC,EAAE,QAAQ,QAAQ;AAAA,EAC/E,sBAAsB,EACnB,MAAM,EAAE,OAAO,CAAC,EAChB,SAAS,EACT,QAAQ,CAAC,CAAC,EACV,UAAU,CAAC,QAAQ,OAAO,CAAC,CAAC;AACjC,CAAC;AAGD,IAAM,iBAAiB,EACpB,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,EAC9C,UAAU,CAAC,QAAS,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,GAAG,CAAE;AAEjD,IAAM,0BAA0B,EAAE,OAAO;AAAA;AAAA,EAE9C,WAAW,eAAe,QAAQ,CAAC,UAAU,QAAQ,CAAC;AAAA,EACtD,QAAQ,eAAe,QAAQ,CAAC,OAAO,CAAC;AAAA;AAAA,EAGxC,YAAY,eAAe,QAAQ,CAAC,WAAW,CAAC;AAAA,EAChD,aAAa,eAAe,QAAQ,CAAC,QAAQ,CAAC;AAAA;AAAA,EAG9C,aAAa,eAAe,QAAQ,CAAC,cAAc,KAAK,CAAC;AAAA,EACzD,YAAY,eAAe,QAAQ,CAAC,SAAS,CAAC;AAAA,EAC9C,cAAc,eAAe,QAAQ,CAAC,WAAW,CAAC;AAAA;AAAA,EAGlD,MAAM,eAAe,QAAQ,CAAC,GAAG,CAAC;AAAA,EAClC,aAAa,eAAe,QAAQ,CAAC,QAAQ,CAAC;AAAA,EAC9C,MAAM,eAAe,QAAQ,CAAC,QAAQ,CAAC;AAAA,EACvC,MAAM,eAAe,QAAQ,CAAC,QAAQ,CAAC;AAAA;AAAA;AAAA,EAGvC,QAAQ,eAAe,QAAQ,CAAC,CAAC,EAAE,SAAS;AAC9C,CAAC;AAEM,IAAM,qBAAqB,EAAE,OAAO;AAAA,EACzC,SAAS,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACjC,WAAW,EAAE,OAAO,EAAE,QAAQ,eAAe;AAAA,EAC7C,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,aAAa,EAAE,OAAO,EAAE,SAAS;AACnC,CAAC;AAEM,IAAM,yBAAyB,EAAE,OAAO;AAAA,EAC7C,sBAAsB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,EAAE;AAAA,EAC3D,oBAAoB,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EAC5C,4BAA4B,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,IAAI,EAAE,QAAQ,GAAG;AAAA,EACpE,0BAA0B,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,QAAQ,GAAI;AAAA,EAC1D,2BAA2B,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE;AACjE,CAAC;AAEM,IAAM,qBAAqB,EAAE,OAAO;AAAA,EACzC,SAAS,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EAClC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA;AAAA,EACvC,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACxC,cAAc,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACzC,kBAAkB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG;AAAA;AACxD,CAAC;AAEM,IAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,SAAS,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACjC,mBAAmB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAE;AAAA,EAC/C,yBAAyB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAE;AAAA,EACrD,mBAAmB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAE;AAAA,EAC/C,eAAe,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG;AAC9C,CAAC;AAEM,IAAM,eAAe,EAAE,OAAO;AAAA,EACnC,KAAK;AAAA,EACL,aAAa;AAAA,EACb,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,WAAW;AACb,CAAC;;;AC/GD,OAAO,aAAa;AACpB,OAAO,qBAAqB;AAC5B,OAAOC,SAAQ;AACf,OAAO,UAAU;AAIV,IAAM,SAAN,MAAa;AAAA,EACV;AAAA,EACA,qBAAqB;AAAA,EACrB;AAAA,EAER,YAAY,SAAS,eAAe;AAElC,UAAM,iBAAiB,KAAK,QAAQ,QAAQ,IAAI,GAAG,MAAM;AAIzD,QAAI;AACF,UAAI,CAACA,IAAG,WAAW,cAAc,GAAG;AAClC,QAAAA,IAAG,UAAU,gBAAgB,EAAE,WAAW,KAAK,CAAC;AAAA,MAClD;AACA,WAAK,qBAAqB;AAAA,IAC5B,SAAS,OAAO;AAEd,cAAQ;AAAA,QACN,uDAAuD,cAAc,mCAAmC,KAAK;AAAA,MAC/G;AACA,WAAK,qBAAqB;AAAA,IAC5B;AAIA,SAAK,mBAAmB,IAAI,QAAQ,WAAW,QAAQ;AAAA,MACrD,QAAQ,QAAQ,OAAO,QAAQ,QAAQ,OAAO,SAAS,GAAG,QAAQ,OAAO,OAAO,CAAC;AAAA,IACnF,CAAC;AAED,UAAM,aAAkC,CAAC,KAAK,gBAAgB;AAG9D,QAAI,KAAK,oBAAoB;AAC3B,iBAAW;AAAA;AAAA,QAET,IAAI,gBAAgB;AAAA,UAClB,SAAS;AAAA,UACT,UAAU;AAAA,UACV,aAAa;AAAA,UACb,OAAO;AAAA,UACP,SAAS;AAAA;AAAA,UACT,UAAU;AAAA;AAAA,UACV,eAAe;AAAA;AAAA,QACjB,CAAC;AAAA;AAAA,QAED,IAAI,gBAAgB;AAAA,UAClB,SAAS;AAAA,UACT,UAAU;AAAA,UACV,aAAa;AAAA,UACb,SAAS;AAAA;AAAA,UACT,UAAU;AAAA;AAAA,UACV,eAAe;AAAA;AAAA,QACjB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,SAAK,SAAS,QAAQ,aAAa;AAAA,MACjC,OAAO,QAAQ,IAAI,aAAa;AAAA,MAChC,QAAQ,QAAQ,OAAO;AAAA,QACrB,QAAQ,OAAO,UAAU;AAAA,QACzB,QAAQ,OAAO,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,QACrC,QAAQ,OAAO,KAAK;AAAA,MACtB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,SAAiB,MAAsC;AAC3D,SAAK,OAAO,MAAM,SAAS,IAAI;AAAA,EACjC;AAAA,EAEA,KAAK,SAAiB,MAAsC;AAC1D,SAAK,OAAO,KAAK,SAAS,IAAI;AAAA,EAChC;AAAA,EAEA,KAAK,SAAiB,MAAsC;AAC1D,SAAK,OAAO,KAAK,SAAS,IAAI;AAAA,EAChC;AAAA,EAEA,MAAM,SAAiB,MAAsC;AAC3D,SAAK,OAAO,MAAM,SAAS,IAAI;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAuB;AACrB,SAAK,OAAO,OAAO,KAAK,gBAAgB;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAsB;AACpB,QAAI,CAAC,KAAK,OAAO,WAAW,SAAS,KAAK,gBAAgB,GAAG;AAC3D,WAAK,OAAO,IAAI,KAAK,gBAAgB;AAAA,IACvC;AAAA,EACF;AACF;AAGO,IAAM,SAAS,IAAI,OAAO;;;AC1GjC,OAAO,UAAU;AACjB,OAAOC,WAAU;AACjB,SAAS,KAAAC,UAAS;AAKX,IAAM,kBAAkBA,GAAE,OAAO;AAAA;AAAA,EAEtC,UAAUA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA;AAAA,EAGxC,OAAOA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA;AAAA,EAGrC,MAAMA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA;AAAA,EAGpC,SAASA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA;AAAA,EAGvC,cAAcA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAIM,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAAoBC,KAAiB;AAAjB,cAAAA;AAAA,EAAkB;AAAA;AAAA;AAAA;AAAA,EAKtC,MAAM,qBAAqB,aAAgD;AACzE,UAAM,gBAAgBF,MAAK,KAAK,aAAa,UAAU,eAAe;AACtE,WAAO,MAAM,KAAK,kBAAkB,eAAe,SAAS;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,sBAAiD;AACrD,UAAM,UAAU,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe;AAC/D,UAAM,gBAAgBA,MAAK,KAAK,SAAS,UAAU,eAAe;AAClE,WAAO,MAAM,KAAK,kBAAkB,eAAe,QAAQ;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,kBACZ,UACA,OAC2B;AAC3B,QAAI;AACF,UAAI,CAAE,MAAM,KAAK,GAAG,OAAO,QAAQ,GAAI;AACrC,eAAO,MAAM,MAAM,KAAK,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC9D,eAAO;AAAA,MACT;AAEA,YAAM,UAAU,MAAM,KAAK,GAAG,SAAS,QAAQ;AAC/C,YAAM,SAAS,KAAK,MAAM,OAAO;AAGjC,YAAM,YAAY,gBAAgB,MAAM,MAAM;AAE9C,aAAO,KAAK,UAAU,KAAK,cAAc;AAAA,QACvC,MAAM;AAAA,QACN,UAAU,UAAU,SAAS;AAAA,QAC7B,OAAO,UAAU,MAAM;AAAA,QACvB,MAAM,UAAU,KAAK;AAAA,MACvB,CAAC;AAED,aAAO;AAAA,IACT,SAAS,OAAO;AACd,aAAO,MAAM,kBAAkB,KAAK,cAAc;AAAA,QAChD,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAA0B,SAAsC;AACpE,UAAM,SAAoB;AAAA,MACxB,UAAU,CAAC;AAAA,MACX,OAAO,CAAC;AAAA,MACR,MAAM,CAAC;AAAA,MACP,SAAS,CAAC;AAAA,MACV,cAAc,CAAC;AAAA,IACjB;AAGA,QAAI,QAAQ;AACV,aAAO,SAAS,KAAK,GAAG,OAAO,QAAQ;AACvC,aAAO,MAAM,KAAK,GAAG,OAAO,KAAK;AACjC,aAAO,KAAK,KAAK,GAAG,OAAO,IAAI;AAC/B,aAAO,QAAQ,KAAK,GAAG,OAAO,OAAO;AACrC,aAAO,aAAa,KAAK,GAAG,OAAO,YAAY;AAAA,IACjD;AAGA,QAAI,SAAS;AAEX,aAAO,WAAW,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,OAAO,UAAU,GAAG,QAAQ,QAAQ,CAAC,CAAC;AACxE,aAAO,QAAQ,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,OAAO,OAAO,GAAG,QAAQ,KAAK,CAAC,CAAC;AAC/D,aAAO,OAAO,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,OAAO,MAAM,GAAG,QAAQ,IAAI,CAAC,CAAC;AAC5D,aAAO,UAAU,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,OAAO,SAAS,GAAG,QAAQ,OAAO,CAAC,CAAC;AACrE,aAAO,eAAe,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,OAAO,cAAc,GAAG,QAAQ,YAAY,CAAC,CAAC;AAAA,IACtF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,UAAkB,OAA4C;AAChF,UAAM,iBAAiB,UAAU,WAAW,KAAK,iBAAiB,IAAI,KAAK,kBAAkB;AAE7F,QAAI;AACF,YAAM,MAAMA,MAAK,QAAQ,QAAQ;AACjC,UAAI,CAAE,MAAM,KAAK,GAAG,OAAO,GAAG,GAAI;AAChC,cAAM,KAAK,GAAG,MAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,MAC9C;AAEA,YAAM,KAAK,GAAG,UAAU,UAAU,cAAc;AAChD,aAAO,KAAK,mBAAmB,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAAA,IACtE,SAAS,OAAO;AACd,aAAO,MAAM,sCAAsC;AAAA,QACjD,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAA2B;AACjC,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuCT;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAA4B;AAClC,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuCT;AACF;;;ACpOA,OAAOG,WAAU;AACjB,OAAOC,WAAU;AACjB,OAAO,QAAQ;AACf,OAAO,YAAY;AAaZ,IAAM,eAAN,MAAmB;AAAA,EAGxB,YAAoBC,KAAiB;AAAjB,cAAAA;AAClB,SAAK,kBAAkB,IAAI,gBAAgBA,GAAE;AAAA,EAC/C;AAAA,EAJQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBR,MAAM,KAAK,UAA6B,CAAC,GAA8B;AAErE,QAAI,SAAS,KAAK,YAAY;AAG9B,UAAM,eAAe,MAAM,KAAK,iBAAiB;AACjD,QAAI,cAAc;AAChB,eAAS,KAAK,MAAM,QAAQ,YAAY;AAAA,IAC1C;AAGA,QAAI,QAAQ,aAAa;AACvB,YAAM,gBAAgB,MAAM,KAAK,kBAAkB,QAAQ,WAAW;AACtE,UAAI,eAAe;AACjB,iBAAS,KAAK,MAAM,QAAQ,aAAa;AAAA,MAC3C;AAAA,IACF;AAGA,UAAM,YAAY,KAAK,cAAc,QAAQ,WAAW;AACxD,QAAI,WAAW;AACb,eAAS,KAAK,MAAM,QAAQ,SAAS;AAAA,IACvC;AAGA,QAAI,QAAQ,UAAU;AACpB,eAAS,KAAK,MAAM,QAAQ,QAAQ,QAAQ;AAAA,IAC9C;AAGA,UAAM,kBAAkB,aAAa,MAAM,MAAM;AAGjD,UAAM,kBAAkB,MAAM,KAAK,gBAAgB,oBAAoB;AACvE,UAAM,mBAAmB,QAAQ,cAC7B,MAAM,KAAK,gBAAgB,qBAAqB,QAAQ,WAAW,IACnE;AAEJ,UAAM,kBAAkB,KAAK,gBAAgB,MAAM,iBAAiB,gBAAgB;AAGpF,QAAI,gBAAgB,SAAS,SAAS,GAAG;AACvC,sBAAgB,YAAY,uBAAuB;AAAA,QACjD,GAAG,oBAAI,IAAI;AAAA,UACT,GAAG,gBAAgB,YAAY;AAAA,UAC/B,GAAG,gBAAgB;AAAA,QACrB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,WAAW;AAAA,IACb;AAAA,EACF;AAAA,EAEQ,cAAsB;AAE5B,UAAM,YAAY,QAAQ,aAAa;AAEvC,WAAO;AAAA,MACL,KAAK;AAAA,QACH,UAAU;AAAA,QACV,OAAO;AAAA,QACP,aAAa;AAAA,QACb,WAAW;AAAA,MACb;AAAA,MACA,aAAa;AAAA,QACX,YAAY;AAAA,QACZ,iBAAiB;AAAA,QACjB,sBAAsB,CAAC;AAAA,MACzB;AAAA,MACA,aAAa;AAAA,QACX,WAAW,CAAC,UAAU,QAAQ;AAAA,QAC9B,QAAQ,CAAC,OAAO;AAAA,QAChB,YAAY,CAAC,WAAW;AAAA,QACxB,aAAa,CAAC,QAAQ;AAAA;AAAA;AAAA,QAGtB,aAAa,YAAY,CAAC,KAAK,IAAI,CAAC,cAAc,KAAK;AAAA,QACvD,YAAY,CAAC,SAAS;AAAA,QACtB,cAAc,CAAC,WAAW;AAAA,QAC1B,MAAM,CAAC,GAAG;AAAA,QACV,aAAa,CAAC,QAAQ;AAAA,QACtB,MAAM,CAAC,QAAQ;AAAA,QACf,MAAM,CAAC,QAAQ;AAAA,MACjB;AAAA,MACA,QAAQ;AAAA,QACN,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,MACA,IAAI;AAAA,QACF,OAAO;AAAA,QACP,oBAAoB;AAAA,QACpB,iBAAiB;AAAA,QACjB,aAAa;AAAA,QACb,sBAAsB;AAAA,QACtB,6BAA6B;AAAA,MAC/B;AAAA,MACA,YAAY;AAAA,QACV,sBAAsB;AAAA,QACtB,oBAAoB;AAAA,QACpB,4BAA4B;AAAA,QAC5B,0BAA0B;AAAA,QAC1B,2BAA2B;AAAA,MAC7B;AAAA,MACA,QAAQ;AAAA,QACN,SAAS;AAAA,QACT,kBAAkB;AAAA,MACpB;AAAA,MACA,WAAW;AAAA,QACT,SAAS;AAAA,QACT,mBAAmB;AAAA,QACnB,yBAAyB;AAAA,QACzB,mBAAmB;AAAA,QACnB,eAAe;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,mBAAoD;AAChE,QAAI;AACF,YAAM,aAAaC,MAAK,KAAK,GAAG,QAAQ,GAAG,UAAU,YAAY;AACjE,UAAI,CAAE,MAAM,KAAK,GAAG,OAAO,UAAU,GAAI;AACvC,eAAO;AAAA,MACT;AACA,YAAM,UAAU,MAAM,KAAK,GAAG,SAAS,UAAU;AACjD,aAAOC,MAAK,MAAM,OAAO;AAAA,IAC3B,SAAS,OAAO;AACd,aAAO,KAAK,gCAAgC,EAAE,MAAM,CAAC;AACrD,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,kBAAkB,aAAsD;AACpF,QAAI;AACF,YAAM,aAAaD,MAAK,KAAK,aAAa,UAAU,YAAY;AAChE,UAAI,CAAE,MAAM,KAAK,GAAG,OAAO,UAAU,GAAI;AACvC,eAAO;AAAA,MACT;AACA,YAAM,UAAU,MAAM,KAAK,GAAG,SAAS,UAAU;AACjD,aAAOC,MAAK,MAAM,OAAO;AAAA,IAC3B,SAAS,OAAO;AACd,aAAO,KAAK,iCAAiC,EAAE,MAAM,CAAC;AACtD,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,cAAc,aAA8C;AAClE,QAAI;AAEF,YAAM,UAAU,cAAcD,MAAK,KAAK,aAAa,MAAM,IAAI;AAC/D,aAAO,OAAO,EAAE,MAAM,QAAQ,CAAC;AAE/B,YAAM,YAAqC,CAAC;AAG5C,UACE,QAAQ,IAAI,oBACZ,QAAQ,IAAI,qBACZ,QAAQ,IAAI,gBACZ;AACA,cAAM,WAAW,QAAQ,IAAI,cAAc,YAAY;AACvD,cAAM,SAAS,WAAW,QAAQ,IAAI,GAAG,QAAQ,UAAU,IAAI;AAC/D,cAAM,UAAU,WAAW,QAAQ,IAAI,GAAG,QAAQ,WAAW,IAAI;AAEjE,YAAI,UAAU,SAAS;AACrB,oBAAU,MAAM;AAAA,YACd,GAAI,UAAU,EAAE,OAAO;AAAA,YACvB,GAAI,WAAW,EAAE,QAAQ;AAAA,UAC3B;AAAA,QACF;AAAA,MACF;AAEA,UAAI,QAAQ,IAAI,gBAAgB;AAC9B,kBAAU,SAAS;AAAA,UACjB,SAAS,QAAQ,IAAI,mBAAmB;AAAA,QAC1C;AAAA,MACF;AAEA,UAAI,QAAQ,IAAI,aAAa;AAC3B,kBAAU,KAAK;AAAA,UACb,OAAO,QAAQ,IAAI;AAAA,QACrB;AAAA,MACF;AAEA,aAAO,OAAO,KAAK,SAAS,EAAE,SAAS,IAAK,YAAgC;AAAA,IAC9E,SAAS,OAAO;AACd,aAAO,KAAK,8BAA8B,EAAE,MAAM,CAAC;AACnD,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,MAAM,MAAc,UAAmC;AAC7D,WAAO;AAAA,MACL,KAAK,EAAE,GAAG,KAAK,KAAK,GAAG,SAAS,IAAI;AAAA,MACpC,aAAa,EAAE,GAAG,KAAK,aAAa,GAAG,SAAS,YAAY;AAAA,MAC5D,aAAa,EAAE,GAAG,KAAK,aAAa,GAAG,SAAS,YAAY;AAAA,MAC5D,QAAQ,EAAE,GAAG,KAAK,QAAQ,GAAG,SAAS,OAAO;AAAA,MAC7C,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,SAAS,GAAG;AAAA,MACjC,YAAY,EAAE,GAAG,KAAK,YAAY,GAAG,SAAS,WAAW;AAAA,MACzD,QAAQ,EAAE,GAAG,KAAK,QAAQ,GAAG,SAAS,OAAO;AAAA,MAC7C,WAAW,EAAE,GAAG,KAAK,WAAW,GAAG,SAAS,UAAU;AAAA,IACxD;AAAA,EACF;AAAA,EAEA,MAAM,KACJ,QACA,OACA,aACe;AACf,UAAM,aACJ,UAAU,WACNA,MAAK,KAAK,GAAG,QAAQ,GAAG,UAAU,YAAY,IAC9CA,MAAK,KAAK,eAAe,QAAQ,IAAI,GAAG,UAAU,YAAY;AAEpE,UAAM,YAAYA,MAAK,QAAQ,UAAU;AAGzC,QAAI,CAAE,MAAM,KAAK,GAAG,OAAO,SAAS,GAAI;AACtC,YAAM,KAAK,GAAG,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,IACpD;AAEA,UAAM,cAAcC,MAAK,UAAU,MAAM;AACzC,UAAM,KAAK,GAAG,UAAU,YAAY,WAAW;AAC/C,WAAO,KAAK,mBAAmB,UAAU,EAAE;AAAA,EAC7C;AAAA,EAEA,SAAS,QAAyB;AAChC,WAAO,aAAa,MAAM,MAAM;AAAA,EAClC;AACF;;;AC5QA,OAAOC,WAAU;AACjB,OAAOC,SAAQ;AAER,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAAoBC,KAAiB;AAAjB,cAAAA;AAAA,EAAkB;AAAA,EAEtC,MAAM,aAA+B;AACnC,UAAM,mBAAmB,KAAK,oBAAoB;AAClD,UAAM,SAAS,MAAM,KAAK,GAAG,OAAO,gBAAgB;AACpD,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,sBAA8B;AAC5B,UAAM,UAAUD,IAAG,QAAQ;AAC3B,WAAOD,MAAK,KAAK,SAAS,UAAU,YAAY;AAAA,EAClD;AAAA,EAEA,MAAM,qBAAsC;AAC1C,UAAM,UAAUC,IAAG,QAAQ;AAC3B,WAAOD,MAAK,KAAK,SAAS,QAAQ;AAAA,EACpC;AACF;;;ACtBA,OAAOG,YAAW;AAClB,SAAS,cAAc;;;ACDvB,SAAgB,YAAAC,iBAAgB;AAChC,SAAS,OAAAC,YAAW;;;ACApB,SAAS,OAAAC,MAAK,QAAAC,aAAY;;;ACA1B,SAAS,KAAK,YAAY;AAC1B,OAAO,WAAW;;;ACFX,IAAM,cAAc;AAAA;AAAA,EAEzB,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA;AAAA,EAGb,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,YAAY;AAAA;AAAA,EAGZ,QAAQ;AAAA;AAAA,EACR,QAAQ;AAAA;AAAA,EACR,QAAQ;AAAA;AAAA,EACR,QAAQ;AAAA;AAAA;AAAA,EAGR,WAAW;AAAA,EACX,cAAc;AAAA,EACd,cAAc;AAAA,EACd,aAAa;AAAA,EACb,cAAc;AAChB;;;ACxBO,IAAM,aAAa,CAAC,kCAAS,kCAAS,kCAAS,sBAAO;;;AFYrD;AAND,IAAM,aAAuB,MAAM;AACxC,QAAM,YAAY,MAAM,IAAI,YAAY,MAAM;AAE9C,SACE,oBAAC,OAAI,eAAc,UAAS,cAAc,GAAG,YAAW,UACrD,qBAAW,IAAI,CAAC,MAAM,UACrB,oBAAC,QAAkB,oBAAU,KAAK,IAAI,KAA3B,KAA6B,CACzC,GACH;AAEJ;;;ADJI,SACE,OAAAC,MADF;AAFG,IAAM,eAA4C,CAAC,EAAE,OAAO,SAAS,MAAM;AAChF,SACE,qBAACC,MAAA,EAAI,eAAc,UAAS,UAAU,GAAG,UAAU,GACjD;AAAA,oBAAAD,KAAC,cAAW;AAAA,IACX,SACC,gBAAAA,KAACC,MAAA,EAAI,cAAc,GACjB,0BAAAD,KAACE,OAAA,EAAK,OAAO,YAAY,YAAa,iBAAM,GAC9C;AAAA,IAED;AAAA,KACH;AAEJ;;;AItBA,SAAgB,eAAe;AAC/B,SAAS,OAAAC,MAAK,QAAAC,OAAM,gBAAgB;AACpC,OAAO,aAAa;AACpB,OAAOC,YAAW;;;ACHlB,OAAOC,SAAQ;AAKf,IAAM,YAAoC;AAAA;AAAA,EAExC,SAAS;AAAA,EACT,WAAW;AAAA,EACX,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA;AAAA,EAGP,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,OAAO;AAAA;AAAA,EAGP,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA,EACT,KAAK;AAAA,EACL,MAAM;AACR;AAKA,IAAM,qBAA6D;AAAA,EACjE,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA,OAAO;AAAA,IACL,KAAK;AAAA,IACL,SAAS;AAAA,EACX;AAAA,EACA,OAAO;AAAA,IACL,KAAK;AAAA,IACL,SAAS;AAAA,EACX;AACF;AAuCA,SAAS,iBAAiB,KAAqB;AAC7C,SAAO,IACJ,QAAQ,aAAa,MAAM,EAC3B,QAAQ,aAAa,KAAK,EAC1B,QAAQ,YAAY,KAAK,EACzB,QAAQ,YAAY,KAAK,EACzB,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,IAAI,CAAC,SAAS;AACb,UAAM,QAAQ,KAAK,YAAY;AAG/B,QAAI,UAAU,aAAa,UAAU,KAAM,QAAO;AAClD,QAAI,UAAU,eAAe,UAAU,OAAQ,QAAO;AACtD,QAAI,UAAU,eAAe,UAAU,OAAQ,QAAO;AACtD,QAAI,UAAU,gBAAgB,UAAU,QAAS,QAAO;AAGxD,UAAM,aAAa,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,EAAE,YAAY;AAG5E,QAAI,eAAe,OAAQ,QAAO;AAClC,QAAI,eAAe,SAAU,QAAO;AAEpC,WAAO;AAAA,EACT,CAAC,EACA,KAAK,GAAG;AACb;AAKA,SAAS,uBAAuB,KAAa,UAAmC;AAC9E,QAAM,YAAY,mBAAmB,QAAQ,KAAK,mBAAmB;AACrE,MAAI,CAAC,UAAW,QAAO;AAEvB,MAAI,SAAS;AAEb,aAAW,CAAC,MAAM,EAAE,KAAK,OAAO,QAAQ,SAAS,GAAG;AAElD,aAAS,OAAO,QAAQ,IAAI,OAAO,MAAM,IAAI,OAAO,GAAG,GAAG,EAAE;AAAA,EAC9D;AAEA,SAAO;AACT;AAKA,SAAS,qBACP,UACA,SACQ;AACR,QAAM,EAAE,UAAU,kBAAkB,SAAS,IAAI;AAGjD,MAAI,aAAa,iBAAiB,QAAQ;AAC1C,eAAa,uBAAuB,YAAY,QAAQ;AAGxD,QAAM,QAAQ,WAAW,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAGvD,QAAM,YAAY,MAAM,IAAI,CAAC,MAAM,UAAU;AAC3C,UAAM,aAAa,QAAQ,MAAM,SAAS;AAC1C,UAAM,OAAO,UAAU,IAAI;AAE3B,QAAI,YAAY,MAAM;AAEpB,UAAI,cAAc,CAAC,kBAAkB;AAEnC,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAGA,QAAI,KAAK,WAAW,OAAO,GAAG;AAE5B,aAAO,KAAK,QAAQ,SAAS,EAAE;AAAA,IACjC;AAEA,WAAO;AAAA,EACT,CAAC;AAGD,MAAI,UAAU,WAAW,GAAG;AAC1B,WAAO,UAAU,CAAC,KAAK;AAAA,EACzB;AAGA,MAAI,oBAAoB,UAAU,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG;AAE9D,WAAO,UAAU,KAAK,EAAE;AAAA,EAC1B;AAEA,SAAO,UAAU,KAAK,GAAG;AAC3B;AAgCO,SAAS,uBACd,WACA,UAAoC,CAAC,GAC7B;AACR,QAAM,OAA2C;AAAA,IAC/C,UAAU,QAAQ,YAAY;AAAA,IAC9B,kBAAkB,QAAQ,oBAAoB;AAAA,IAC9C,UAAU,QAAQ,YAAYA,IAAG,SAAS;AAAA,IAC1C,WAAW,QAAQ,aAAa;AAAA,IAChC,eAAe,QAAQ,iBAAiB;AAAA,EAC1C;AAGA,MAAI,MAAM,QAAQ,SAAS,GAAG;AAC5B,QAAI,UAAU,WAAW,EAAG,QAAO;AACnC,QAAI,KAAK,eAAe;AACtB,YAAM,QAAQ,UAAU,CAAC;AACzB,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO,qBAAqB,OAAO,IAAI;AAAA,IACzC;AACA,WAAO,UAAU,IAAI,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC,EAAE,KAAK,KAAK,SAAS;AAAA,EAChF;AAGA,SAAO,qBAAqB,WAAW,IAAI;AAC7C;AAMO,SAAS,uBACd,YACA,cACA,UAAoC,CAAC,GAC7B;AACR,QAAM,KAAK,uBAAuB,YAAY,EAAE,GAAG,SAAS,eAAe,KAAK,CAAC;AACjF,QAAM,OAAO,uBAAuB,cAAc,EAAE,GAAG,SAAS,eAAe,KAAK,CAAC;AACrF,SAAO,GAAG,EAAE,GAAG,IAAI;AACrB;AAeO,SAAS,gBACd,OACA,UAAoC,CAAC,GAC7B;AACR,SAAO,MACJ,IAAI,CAAC,EAAE,UAAU,MAAM,MAAM;AAC5B,UAAM,YAAY,uBAAuB,UAAU,OAAO;AAC1D,WAAO,GAAG,SAAS,IAAI,KAAK;AAAA,EAC9B,CAAC,EACA,KAAK,KAAK;AACf;;;AD/OM,gBAAAC,MACE,QAAAC,aADF;AA5BC,IAAM,kBAAkD,CAAC;AAAA,EAC9D;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,WAAS,CAAC,QAAQ,QAAQ;AACxB,QAAI,IAAI,QAAQ;AACd,eAAS;AAAA,IACX,WAAW,IAAI,QAAQ;AACrB,eAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,QAAM,UAAUC,OAAM,IAAI,YAAY,SAAS;AAC/C,QAAM,YAAYA,OAAM,IAAI,YAAY,WAAW;AAGnD,QAAM,iBAAiB;AAAA,IACrB,MAAM,uBAAuB,YAAY,MAAM;AAAA,IAC/C,CAAC,YAAY,MAAM;AAAA,EACrB;AACA,QAAM,iBAAiB;AAAA,IACrB,MAAM,uBAAuB,YAAY,SAAS;AAAA,IAClD,CAAC,YAAY,SAAS;AAAA,EACxB;AAEA,SACE,gBAAAD,MAACE,MAAA,EAAI,eAAc,UACjB;AAAA,oBAAAH,KAACG,MAAA,EAAI,cAAc,GACjB,0BAAAF,MAACG,OAAA,EAAK,OAAM,UAAS,MAAI,MACtB;AAAA,cAAQ;AAAA,MAAQ;AAAA,OACnB,GACF;AAAA,IAEA,gBAAAJ,KAACG,MAAA,EAAI,cAAc,GACjB,0BAAAH,KAACI,OAAA,EAAK,8EAAgE,GACxE;AAAA,IAEA,gBAAAJ,KAACG,MAAA,EAAI,cAAc,GACjB,0BAAAH,KAACI,OAAA,EAAK,UAAQ,MAAC,iFAAmE,GACpF;AAAA,IAEA,gBAAAJ,KAACG,MAAA,EACC,0BAAAF,MAACG,OAAA,EAAK;AAAA;AAAA,MACG,UAAU,cAAc;AAAA,MAAE;AAAA,MAAiB,QAAQ,cAAc;AAAA,MAAE;AAAA,OAC5E,GACF;AAAA,KACF;AAEJ;;;AE/DA,SAAgB,UAAU,WAAAC,gBAAe;AACzC,SAAS,OAAAC,MAAK,QAAAC,aAAY;AAC1B,OAAO,iBAAiB;AACxB,OAAOC,YAAW;;;ACHlB,OAAOC,YAAW;AAkElB,SAAS,WAAW,OAAqC;AACvD,MAAI,SAASA;AAEb,MAAI,MAAM,IAAI;AACZ,aAAS,OAAO,MAAM,MAAM,EAAE;AAAA,EAChC;AACA,MAAI,MAAM,IAAI;AACZ,aAAS,OAAO,IAAI,MAAM,EAAE;AAAA,EAC9B;AACA,MAAI,MAAM,MAAM;AACd,aAAS,OAAO;AAAA,EAClB;AACA,MAAI,MAAM,KAAK;AACb,aAAS,OAAO;AAAA,EAClB;AACA,MAAI,MAAM,QAAQ;AAChB,aAAS,OAAO;AAAA,EAClB;AACA,MAAI,MAAM,WAAW;AACnB,aAAS,OAAO;AAAA,EAClB;AAEA,SAAO;AACT;AAKO,SAAS,eAAe,MAAkC;AAC/D,QAAM,SAAsB;AAAA,IAC1B,UAAU,WAAW,KAAK,OAAO,QAAQ;AAAA,IACzC,YAAY,WAAW,KAAK,OAAO,UAAU;AAAA,IAC7C,UAAU,WAAW,KAAK,OAAO,QAAQ;AAAA,IACzC,YAAY,WAAW,KAAK,OAAO,UAAU;AAAA,IAC7C,aAAa,WAAW,KAAK,OAAO,WAAW;AAAA,IAC/C,WAAW,WAAW,KAAK,OAAO,SAAS;AAAA,IAC3C,gBAAgB,WAAW,KAAK,OAAO,cAAc;AAAA,IAErD,kBAAkB,WAAW,KAAK,OAAO,gBAAgB;AAAA,IACzD,wBAAwB,WAAW,KAAK,OAAO,sBAAsB;AAAA,IACrE,0BAA0B,WAAW,KAAK,OAAO,wBAAwB;AAAA,IACzE,wBAAwB,WAAW,KAAK,OAAO,sBAAsB;AAAA,IACrE,wBAAwB,WAAW,KAAK,OAAO,sBAAsB;AAAA,IACrE,2BAA2B,WAAW,KAAK,OAAO,yBAAyB;AAAA,IAE3E,UAAU,WAAW,KAAK,OAAO,QAAQ;AAAA,IACzC,SAAS,WAAW,KAAK,OAAO,OAAO;AAAA,IACvC,aAAa,WAAW,KAAK,OAAO,WAAW;AAAA,IAE/C,aAAa,WAAW,KAAK,OAAO,WAAW;AAAA,IAC/C,kBAAkB,WAAW,KAAK,OAAO,gBAAgB;AAAA,IACzD,eAAe,WAAW,KAAK,OAAO,aAAa;AAAA,IAEnD,SAAS,WAAW,KAAK,OAAO,OAAO;AAAA,IACvC,QAAQ,WAAW,KAAK,OAAO,MAAM;AAAA,IACrC,QAAQ,WAAW,KAAK,OAAO,MAAM;AAAA,IACrC,SAAS,WAAW,KAAK,OAAO,OAAO;AAAA,IACvC,UAAU,WAAW,KAAK,OAAO,QAAQ;AAAA,IACzC,UAAU,WAAW,KAAK,OAAO,QAAQ;AAAA,IAEzC,SAAS,WAAW,KAAK,OAAO,OAAO;AAAA,IACvC,SAAS,WAAW,KAAK,OAAO,OAAO;AAAA,IACvC,OAAO,WAAW,KAAK,OAAO,KAAK;AAAA,IACnC,MAAM,WAAW,KAAK,OAAO,IAAI;AAAA,IAEjC,aAAa,WAAW,KAAK,OAAO,WAAW;AAAA,IAC/C,gBAAgB,WAAW,KAAK,OAAO,cAAc;AAAA,EACvD;AAEA,SAAO;AAAA,IACL,MAAM,KAAK;AAAA,IACX;AAAA,IACA,mBAAmB,KAAK;AAAA,IACxB,WAAW;AAAA,MACT,gBAAgB,KAAK,OAAO,eAAe;AAAA,MAC3C,wBAAwB,KAAK,OAAO,uBAAuB;AAAA,IAC7D;AAAA,EACF;AACF;;;ACrJA;AAAA,EACE,MAAQ;AAAA,EACR,mBAAqB;AAAA,EACrB,QAAU;AAAA,IACR,UAAY,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAC/C,YAAc,EAAE,IAAM,UAAU;AAAA,IAChC,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,YAAc,EAAE,IAAM,UAAU;AAAA,IAChC,aAAe,EAAE,IAAM,UAAU;AAAA,IACjC,WAAa,EAAE,IAAM,UAAU;AAAA,IAC/B,gBAAkB,EAAE,IAAM,UAAU;AAAA,IAEpC,kBAAoB,EAAE,IAAM,UAAU;AAAA,IACtC,wBAA0B,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAC7D,0BAA4B,EAAE,IAAM,UAAU;AAAA,IAC9C,wBAA0B,EAAE,IAAM,WAAW,MAAQ,KAAK;AAAA,IAC1D,wBAA0B,EAAE,IAAM,UAAU;AAAA,IAC5C,2BAA6B,EAAE,IAAM,UAAU;AAAA,IAE/C,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,aAAe,EAAE,IAAM,UAAU;AAAA,IAEjC,aAAe,EAAE,IAAM,UAAU;AAAA,IACjC,kBAAoB,EAAE,IAAM,UAAU;AAAA,IACtC,eAAiB,EAAE,IAAM,UAAU;AAAA,IAEnC,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,QAAU,EAAE,IAAM,UAAU;AAAA,IAC5B,QAAU,EAAE,IAAM,UAAU;AAAA,IAC5B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,UAAY,EAAE,IAAM,UAAU;AAAA,IAE9B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,OAAS,EAAE,IAAM,UAAU;AAAA,IAC3B,MAAQ,EAAE,IAAM,UAAU;AAAA,IAE1B,aAAe,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAClD,gBAAkB,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,EACvD;AACF;;;AC1CA;AAAA,EACE,MAAQ;AAAA,EACR,mBAAqB;AAAA,EACrB,QAAU;AAAA,IACR,UAAY,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAC/C,YAAc,EAAE,IAAM,UAAU;AAAA,IAChC,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,YAAc,EAAE,IAAM,UAAU;AAAA,IAChC,aAAe,EAAE,IAAM,UAAU;AAAA,IACjC,WAAa,EAAE,IAAM,UAAU;AAAA,IAC/B,gBAAkB,EAAE,IAAM,UAAU;AAAA,IAEpC,kBAAoB,EAAE,IAAM,UAAU;AAAA,IACtC,wBAA0B,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAC7D,0BAA4B,EAAE,IAAM,UAAU;AAAA,IAC9C,wBAA0B,EAAE,IAAM,WAAW,MAAQ,KAAK;AAAA,IAC1D,wBAA0B,EAAE,IAAM,UAAU;AAAA,IAC5C,2BAA6B,EAAE,IAAM,UAAU;AAAA,IAE/C,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,aAAe,EAAE,IAAM,UAAU;AAAA,IAEjC,aAAe,EAAE,IAAM,UAAU;AAAA,IACjC,kBAAoB,EAAE,IAAM,UAAU;AAAA,IACtC,eAAiB,EAAE,IAAM,UAAU;AAAA,IAEnC,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,QAAU,EAAE,IAAM,UAAU;AAAA,IAC5B,QAAU,EAAE,IAAM,UAAU;AAAA,IAC5B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,UAAY,EAAE,IAAM,UAAU;AAAA,IAE9B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,OAAS,EAAE,IAAM,UAAU;AAAA,IAC3B,MAAQ,EAAE,IAAM,UAAU;AAAA,IAE1B,aAAe,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAClD,gBAAkB,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,EACvD;AACF;;;AC1CA;AAAA,EACE,MAAQ;AAAA,EACR,mBAAqB;AAAA,EACrB,QAAU;AAAA,IACR,UAAY,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAC/C,YAAc,EAAE,IAAM,UAAU;AAAA,IAChC,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,YAAc,EAAE,IAAM,UAAU;AAAA,IAChC,aAAe,EAAE,IAAM,UAAU;AAAA,IACjC,WAAa,EAAE,IAAM,UAAU;AAAA,IAC/B,gBAAkB,EAAE,IAAM,UAAU;AAAA,IAEpC,kBAAoB,EAAE,IAAM,UAAU;AAAA,IACtC,wBAA0B,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAC7D,0BAA4B,EAAE,IAAM,UAAU;AAAA,IAC9C,wBAA0B,EAAE,IAAM,WAAW,MAAQ,KAAK;AAAA,IAC1D,wBAA0B,EAAE,IAAM,UAAU;AAAA,IAC5C,2BAA6B,EAAE,IAAM,UAAU;AAAA,IAE/C,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,aAAe,EAAE,IAAM,UAAU;AAAA,IAEjC,aAAe,EAAE,IAAM,UAAU;AAAA,IACjC,kBAAoB,EAAE,IAAM,UAAU;AAAA,IACtC,eAAiB,EAAE,IAAM,UAAU;AAAA,IAEnC,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,QAAU,EAAE,IAAM,UAAU;AAAA,IAC5B,QAAU,EAAE,IAAM,UAAU;AAAA,IAC5B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,UAAY,EAAE,IAAM,UAAU;AAAA,IAE9B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,OAAS,EAAE,IAAM,UAAU;AAAA,IAC3B,MAAQ,EAAE,IAAM,UAAU;AAAA,IAE1B,aAAe,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAClD,gBAAkB,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,EACvD;AACF;;;AC1CA;AAAA,EACE,MAAQ;AAAA,EACR,mBAAqB;AAAA,EACrB,QAAU;AAAA,IACR,UAAY,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAC/C,YAAc,EAAE,IAAM,UAAU;AAAA,IAChC,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,YAAc,EAAE,IAAM,UAAU;AAAA,IAChC,aAAe,EAAE,IAAM,UAAU;AAAA,IACjC,WAAa,EAAE,IAAM,UAAU;AAAA,IAC/B,gBAAkB,EAAE,IAAM,UAAU;AAAA,IAEpC,kBAAoB,EAAE,IAAM,UAAU;AAAA,IACtC,wBAA0B,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAC7D,0BAA4B,EAAE,IAAM,UAAU;AAAA,IAC9C,wBAA0B,EAAE,IAAM,WAAW,MAAQ,KAAK;AAAA,IAC1D,wBAA0B,EAAE,IAAM,UAAU;AAAA,IAC5C,2BAA6B,EAAE,IAAM,UAAU;AAAA,IAE/C,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,aAAe,EAAE,IAAM,UAAU;AAAA,IAEjC,aAAe,EAAE,IAAM,UAAU;AAAA,IACjC,kBAAoB,EAAE,IAAM,UAAU;AAAA,IACtC,eAAiB,EAAE,IAAM,UAAU;AAAA,IAEnC,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,QAAU,EAAE,IAAM,UAAU;AAAA,IAC5B,QAAU,EAAE,IAAM,UAAU;AAAA,IAC5B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,UAAY,EAAE,IAAM,UAAU;AAAA,IAE9B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,OAAS,EAAE,IAAM,UAAU;AAAA,IAC3B,MAAQ,EAAE,IAAM,UAAU;AAAA,IAE1B,aAAe,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAClD,gBAAkB,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,EACvD;AACF;;;AC1CA;AAAA,EACE,MAAQ;AAAA,EACR,mBAAqB;AAAA,EACrB,QAAU;AAAA,IACR,UAAY,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAC/C,YAAc,EAAE,IAAM,UAAU;AAAA,IAChC,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,YAAc,EAAE,IAAM,UAAU;AAAA,IAChC,aAAe,EAAE,IAAM,UAAU;AAAA,IACjC,WAAa,EAAE,IAAM,UAAU;AAAA,IAC/B,gBAAkB,EAAE,IAAM,UAAU;AAAA,IAEpC,kBAAoB,EAAE,IAAM,UAAU;AAAA,IACtC,wBAA0B,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAC7D,0BAA4B,EAAE,IAAM,UAAU;AAAA,IAC9C,wBAA0B,EAAE,IAAM,WAAW,MAAQ,KAAK;AAAA,IAC1D,wBAA0B,EAAE,IAAM,UAAU;AAAA,IAC5C,2BAA6B,EAAE,IAAM,UAAU;AAAA,IAE/C,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,aAAe,EAAE,IAAM,UAAU;AAAA,IAEjC,aAAe,EAAE,IAAM,UAAU;AAAA,IACjC,kBAAoB,EAAE,IAAM,UAAU;AAAA,IACtC,eAAiB,EAAE,IAAM,UAAU;AAAA,IAEnC,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,QAAU,EAAE,IAAM,UAAU;AAAA,IAC5B,QAAU,EAAE,IAAM,UAAU;AAAA,IAC5B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,UAAY,EAAE,IAAM,UAAU;AAAA,IAE9B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,OAAS,EAAE,IAAM,UAAU;AAAA,IAC3B,MAAQ,EAAE,IAAM,UAAU;AAAA,IAE1B,aAAe,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAClD,gBAAkB,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,EACvD;AACF;;;AC1CA;AAAA,EACE,MAAQ;AAAA,EACR,mBAAqB;AAAA,EACrB,QAAU;AAAA,IACR,UAAY,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAC/C,YAAc,EAAE,IAAM,UAAU;AAAA,IAChC,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,YAAc,EAAE,IAAM,UAAU;AAAA,IAChC,aAAe,EAAE,IAAM,UAAU;AAAA,IACjC,WAAa,EAAE,IAAM,UAAU;AAAA,IAC/B,gBAAkB,EAAE,IAAM,UAAU;AAAA,IAEpC,kBAAoB,EAAE,IAAM,UAAU;AAAA,IACtC,wBAA0B,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAC7D,0BAA4B,EAAE,IAAM,UAAU;AAAA,IAC9C,wBAA0B,EAAE,IAAM,WAAW,MAAQ,KAAK;AAAA,IAC1D,wBAA0B,EAAE,IAAM,UAAU;AAAA,IAC5C,2BAA6B,EAAE,IAAM,UAAU;AAAA,IAE/C,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,aAAe,EAAE,IAAM,UAAU;AAAA,IAEjC,aAAe,EAAE,IAAM,UAAU;AAAA,IACjC,kBAAoB,EAAE,IAAM,UAAU;AAAA,IACtC,eAAiB,EAAE,IAAM,UAAU;AAAA,IAEnC,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,QAAU,EAAE,IAAM,UAAU;AAAA,IAC5B,QAAU,EAAE,IAAM,UAAU;AAAA,IAC5B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,UAAY,EAAE,IAAM,UAAU;AAAA,IAE9B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,OAAS,EAAE,IAAM,UAAU;AAAA,IAC3B,MAAQ,EAAE,IAAM,UAAU;AAAA,IAE1B,aAAe,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAClD,gBAAkB,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,EACvD;AACF;;;AC1CA;AAAA,EACE,MAAQ;AAAA,EACR,mBAAqB;AAAA,EACrB,QAAU;AAAA,IACR,UAAY,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAC/C,YAAc,EAAE,IAAM,UAAU;AAAA,IAChC,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,YAAc,EAAE,IAAM,UAAU;AAAA,IAChC,aAAe,EAAE,IAAM,UAAU;AAAA,IACjC,WAAa,EAAE,IAAM,UAAU;AAAA,IAC/B,gBAAkB,EAAE,IAAM,UAAU;AAAA,IAEpC,kBAAoB,EAAE,IAAM,UAAU;AAAA,IACtC,wBAA0B,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAC7D,0BAA4B,EAAE,IAAM,UAAU;AAAA,IAC9C,wBAA0B,EAAE,IAAM,WAAW,MAAQ,KAAK;AAAA,IAC1D,wBAA0B,EAAE,IAAM,UAAU;AAAA,IAC5C,2BAA6B,EAAE,IAAM,UAAU;AAAA,IAE/C,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,aAAe,EAAE,IAAM,UAAU;AAAA,IAEjC,aAAe,EAAE,IAAM,UAAU;AAAA,IACjC,kBAAoB,EAAE,IAAM,UAAU;AAAA,IACtC,eAAiB,EAAE,IAAM,UAAU;AAAA,IAEnC,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,QAAU,EAAE,IAAM,UAAU;AAAA,IAC5B,QAAU,EAAE,IAAM,UAAU;AAAA,IAC5B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,UAAY,EAAE,IAAM,UAAU;AAAA,IAC9B,UAAY,EAAE,IAAM,UAAU;AAAA,IAE9B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,SAAW,EAAE,IAAM,UAAU;AAAA,IAC7B,OAAS,EAAE,IAAM,UAAU;AAAA,IAC3B,MAAQ,EAAE,IAAM,UAAU;AAAA,IAE1B,aAAe,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,IAClD,gBAAkB,EAAE,IAAM,WAAW,IAAM,UAAU;AAAA,EACvD;AACF;;;ACuBA,IAAM,SAAS,oBAAI,IAA4B;AAExC,SAAS,cAAc,OAAc,YAAmC;AAC7E,SAAO,IAAI,OAAO,UAAU;AAC9B;AAEO,SAAS,SAAS,OAA+B;AACtD,QAAM,aAAa,OAAO,IAAI,KAAK;AACnC,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,SAAS,KAAK,YAAY;AAAA,EAC5C;AACA,SAAO;AACT;AAEO,SAAS,eAAwB;AACtC,SAAO,MAAM,KAAK,OAAO,KAAK,CAAC;AACjC;AAEO,SAAS,iBAAiB,OAAgC;AAC/D,QAAM,aAAa,SAAS,KAAK;AACjC,SAAO;AAAA,IACL,MAAM,WAAW;AAAA,EACnB;AACF;AAaA,IAAM,mBAA8C;AAAA,EAClD,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AAAA,EACP,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,aAAa;AAAA,EACb,cAAc;AAChB;AAGA,OAAO,QAAQ,gBAAgB,EAAE,QAAQ,CAAC,CAAC,KAAK,IAAI,MAAM;AACxD,gBAAc,KAAc,eAAe,IAAI,CAAC;AAClD,CAAC;;;ACrEM,SAAS,qBAAiF;AAC/F,SAAO;AAAA,IACL,EAAE,MAAM,UAAU,MAAM,+BAA+B;AAAA,IACvD,EAAE,MAAM,OAAO,MAAM,uCAAuC;AAAA,IAC5D,EAAE,MAAM,UAAU,MAAM,cAAc;AAAA,IACtC,EAAE,MAAM,UAAU,MAAM,IAAI;AAAA,EAC9B;AACF;;;AVMM,gBAAAC,MAiBE,QAAAC,aAjBF;AAtCC,IAAM,gBAA8C,CAAC;AAAA,EAC1D;AAAA,EACA,UAAU;AAAA,EACV;AACF,MAAM;AACJ,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAS,CAAC;AAG1D,QAAM,kBAAkB,aAAa;AACrC,QAAM,QAAQ,gBAAgB,IAAI,CAAC,aAAa;AAC9C,UAAM,WAAW,iBAAiB,QAAQ;AAC1C,WAAO;AAAA,MACL,OAAO,SAAS;AAAA,MAChB,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,QAAM,kBAAkB,gBAAgB,gBAAgB;AACxD,MAAI,CAAC,gBAAiB,QAAO;AAC7B,QAAM,cAAc,SAAS,eAAe;AAC5C,QAAM,UAAU,mBAAmB;AAEnC,QAAM,KAAKC,OAAM,MAAM,SAAS;AAChC,QAAMC,MAAKD,OAAM,IAAI,SAAS;AAG9B,QAAM,aAAaE,SAAQ,MAAM;AAC/B,UAAM,QAAQ,YAAY,WAAW,CAAC,KAAK;AAC3C,UAAM,UAAU,YAAY,aAAa,CAAC,KAAK;AAC/C,WAAO,gBAAgB;AAAA,MACrB,EAAE,UAAU,CAAC,OAAO,OAAO,GAAG,OAAO,WAAW;AAAA,MAChD,EAAE,UAAU,YAAY,UAAU,SAAS,OAAO,SAAS;AAAA,MAC3D,EAAE,UAAU,YAAY,aAAa,UAAU,OAAO,SAAS;AAAA,IACjE,CAAC;AAAA,EACH,GAAG,CAAC,WAAW,CAAC;AAEhB,SACE,gBAAAH,MAACI,MAAA,EAAI,eAAc,UACjB;AAAA,oBAAAL,KAACM,OAAA,EAAM,aAAGH,IAAG,KAAK,sBAAsB,CAAC,GAAE;AAAA,IAC3C,gBAAAH,KAACM,OAAA,EAAM,aAAG,GAAG,GAAE;AAAA,IAEf,gBAAAN,KAACK,MAAA,EAAI,eAAc,UACjB,0BAAAL;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,UAAU,CAAC,SAAS,SAAS,KAAK,KAAK;AAAA,QACvC,aAAa,CAAC,SAAS;AACrB,gBAAM,QAAQ,gBAAgB,UAAU,CAAC,MAAM,MAAM,KAAK,KAAK;AAC/D,cAAI,UAAU,GAAI,qBAAoB,KAAK;AAAA,QAC7C;AAAA;AAAA,IACF,GACF;AAAA,IAEA,gBAAAA,KAACM,OAAA,EAAM,aAAG,GAAG,GAAE;AAAA,IACf,gBAAAN,KAACM,OAAA,EAAM,aAAGH,IAAG,YAAY,CAAC,GAAE;AAAA,IAC3B,QAAQ,IAAI,CAAC,MAAM,QAClB,gBAAAF,MAACK,OAAA,EACE;AAAA,WAAK,SAAS,YAAY,GAAG,YAAY,OAAO,eAAe,KAAK,KAAK,IAAI,EAAE,CAAC;AAAA,MAChF,KAAK,SAAS,SAAS,GAAG,YAAY,OAAO,YAAY,KAAK,KAAK,IAAI,EAAE,CAAC;AAAA,MAC1E,KAAK,SAAS,YACb;AAAA,QACEH;AAAA,UACE,KAAK,YAAY,OAAO,QAAQ,KAAK,KAAK,MAAM,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,KAAK,KAAK,QAAQ,UAAU,EAAE,CAAC;AAAA,QACzG;AAAA,MACF;AAAA,SARO,GASX,CACD;AAAA,IACD,gBAAAH,KAACM,OAAA,EAAM,aAAG,GAAG,GAAE;AAAA,IAEf,gBAAAN,KAACM,OAAA,EAAM,aAAGJ,OAAM,IAAI,IAAI,UAAU,GAAG,CAAC,GAAE;AAAA,KAC1C;AAEJ;;;AP3DI,SAGM,OAAAK,MAHN,QAAAC,aAAA;AAZG,IAAM,cAA0C,CAAC,EAAE,YAAY,UAAU,YAAY,MAAM;AAChG,QAAM,CAAC,MAAM,OAAO,IAAIC,UAAqB,UAAU;AAEvD,QAAM,uBAAuB,MAAM;AACjC,YAAQ,OAAO;AAAA,EACjB;AAEA,QAAM,oBAAoB,CAAC,UAAiB;AAC1C,SAAK,WAAW,KAAK;AAAA,EACvB;AAEA,SACE,gBAAAD,MAACE,MAAA,EAAI,eAAc,UAChB;AAAA,aAAS,cACR,gBAAAH,KAAC,gBAAa,OAAM,yBAClB,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,UAAU;AAAA,QACV;AAAA,QACA;AAAA;AAAA,IACF,GACF;AAAA,IAED,SAAS,WACR,gBAAAA,KAAC,gBAAa,OAAM,IAClB,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,UAAU;AAAA,QACV;AAAA,QACA;AAAA;AAAA,IACF,GACF;AAAA,KAEJ;AAEJ;;;ADzCO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAAoBI,eAA4B;AAA5B,wBAAAA;AAAA,EAA6B;AAAA,EAEjD,MAAM,UAAyB;AAE7B,YAAQ,OAAO,MAAM,aAAa;AAGlC,UAAM,EAAE,OAAO,IAAI,MAAM,KAAK,aAAa,KAAK;AAEhD,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,EAAE,eAAe,MAAM,IAAI;AAAA,QAC/BC,OAAM,cAAc,aAAa;AAAA,UAC/B,aAAa,OAAO;AAAA,UACpB,YAAY,OAAO,UAAgC;AACjD,gBAAI;AAEF,oBAAM,KAAK,aAAa;AAAA,gBACtB;AAAA,kBACE,IAAI;AAAA,oBACF;AAAA,oBACA,oBAAoB;AAAA,oBACpB,iBAAiB;AAAA,oBACjB,aAAa;AAAA,oBACb,sBAAsB;AAAA,oBACtB,6BAA6B;AAAA,kBAC/B;AAAA,gBACF;AAAA,gBACA;AAAA,cACF;AAEA,qBAAO,KAAK,8BAA8B;AAE1C,sBAAQ,OAAO,MAAM,aAAa;AAClC,yBAAW,MAAM,QAAQ,GAAG,GAAG;AAAA,YACjC,SAAS,OAAO;AACd,qBAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC;AAEtC,sBAAQ,OAAO,MAAM,aAAa;AAClC,qBAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,YAClE;AAAA,UACF;AAAA,UACA,UAAU,MAAY;AACpB,mBAAO,KAAK,yBAAyB;AAErC,oBAAQ,OAAO,MAAM,aAAa;AAClC,oBAAQ;AAAA,UACV;AAAA,QACF,CAAC;AAAA,QACD;AAAA;AAAA,UAEE,cAAc;AAAA,QAChB;AAAA,MACF;AAGA,YAAM,UAAU,MAAY;AAC1B,gBAAQ,OAAO,MAAM,aAAa;AAClC,cAAM;AACN,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,cAAQ,GAAG,UAAU,OAAO;AAC5B,cAAQ,GAAG,WAAW,OAAO;AAE7B,WAAK,cAAc,EAAE,KAAK,MAAM;AAE9B,gBAAQ,IAAI,UAAU,OAAO;AAC7B,gBAAQ,IAAI,WAAW,OAAO;AAAA,MAChC,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;;;AmB/EA,OAAOC,aAAW;AAClB,SAAS,UAAAC,eAAc;;;ACDvB,SAAgB,aAAAC,kBAAiB;AACjC,SAAS,gBAAgB;;;ACDzB,SAAgB,YAAAC,WAAU,WAAAC,UAAS,eAAAC,cAAa,UAAAC,SAAQ,aAAAC,kBAAiB;AACzE,SAAS,OAAAC,OAAK,QAAAC,cAAY;;;ACA1B,SAAS,OAAAC,MAAK,QAAAC,aAAY;AAiDlB,SAEI,OAAAC,MAFJ,QAAAC,aAAA;AAnCD,IAAM,cAA0C,CAAC;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,kBAAkB,SAAS,KAAK;AAGtC,QAAM,YACJ,SAAS,SACL,gBAAgB,OAAO,WACvB,SAAS,QACP,gBAAgB,OAAO,UACvB,gBAAgB,OAAO;AAE/B,QAAM,eAAe,gBAAgB,OAAO;AAC5C,QAAM,gBAAgB,gBAAgB,OAAO;AAC7C,QAAM,UAAU,gBAAgB,OAAO;AAEvC,QAAM,YAAY;AAAA,IAChB,aAAa,eAAe,OAAO,EAAE;AAAA,IACrC,cAAc,GAAG,QAAQ,SAAM,KAAK,EAAE;AAAA,IACtC,QAAQ,SAAS;AAAA,IACjB,gBAAgB,OAAO,KAAK,UAAU,gBAAgB,IAAI,EAAE;AAAA,EAC9D;AAGA,QAAM,aAAa;AAEnB,SACE,gBAAAD,KAACE,MAAA,EAAI,eAAc,UAAS,QAAQ,WAAW,QAAQ,YAAY,GAChE,qBAAW,IAAI,CAAC,UAAU,UACzB,gBAAAD,MAACC,MAAA,EACC;AAAA,oBAAAF,KAACE,MAAA,EAAI,OAAO,YACV,0BAAAF,KAACG,OAAA,EAAM,oBAAU,KAAK,QAAQ,GAAE,GAClC;AAAA,IACC,UAAU,KAAK,KAAK,gBAAAH,KAACG,OAAA,EAAM,oBAAU,KAAK,GAAE;AAAA,OAJrC,KAKV,CACD,GACH;AAEJ;;;ACzDA,SAAS,OAAAC,MAAK,QAAAC,OAAM,cAAc;AA2E5B,gBAAAC,MACE,QAAAC,aADF;AAhEC,IAAM,cAA0C,CAAC;AAAA,EACtD;AAAA,EACA;AAAA,EACA,oBAAoB;AACtB,MAAM;AACJ,QAAM,kBAAkB,SAAS,KAAK;AACtC,QAAM,EAAE,aAAa,kBAAkB,cAAc,IAAI,gBAAgB;AAEzE,QAAM,eAAe,CAAC,SAA0B;AAC9C,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAEA,QAAM,iBAAiB,CAAC,OAAuB;AAC7C,QAAI,KAAK,IAAM,QAAO,GAAG,KAAK,MAAM,EAAE,CAAC;AACvC,WAAO,IAAI,KAAK,KAAM,QAAQ,CAAC,CAAC;AAAA,EAClC;AAEA,QAAM,aAAa,CAACC,UAAyB;AAC3C,QAAIA,UAAS,EAAG,QAAO;AACvB,QAAIA,QAAO,KAAQ,QAAO,IAAIA,MAAK,cAAc,CAAC,CAAC;AACnD,WAAO,IAAIA,MAAK,QAAQ,CAAC,CAAC;AAAA,EAC5B;AAEA,QAAM,0BAA0B,CAAC,YAAqB;AACpD,QAAI,CAAC,QAAQ,SAAU,QAAO;AAE9B,UAAM,EAAE,UAAU,OAAO,MAAAA,OAAM,OAAO,SAAS,IAAI,QAAQ;AAE3D,UAAM,QAAkB,CAAC;AAGzB,QAAI,YAAY,OAAO;AACrB,YAAM,KAAK,GAAG,QAAQ,IAAI,KAAK,EAAE;AAAA,IACnC,WAAW,OAAO;AAChB,YAAM,KAAK,KAAK;AAAA,IAClB;AAGA,QAAI,YAAY,MAAM;AACpB,YAAM,KAAK,eAAe,QAAQ,CAAC;AAAA,IACrC;AAGA,QAAI,OAAO;AACT,YAAM,KAAK,GAAG,MAAM,WAAW,SAAI,MAAM,YAAY,SAAS;AAAA,IAChE;AAGA,QAAIA,SAAQ,MAAM;AAChB,YAAM,KAAK,WAAWA,KAAI,CAAC;AAAA,IAC7B;AAEA,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,WACE,gBAAAF,KAACG,MAAA,EAAI,WAAW,GACd,0BAAAF,MAACG,OAAA,EAAK,UAAQ,MAAC,QAAM,MAAC;AAAA;AAAA,MAClB,MAAM,KAAK,UAAK;AAAA,MAAE;AAAA,OACtB,GACF;AAAA,EAEJ;AAEA,QAAM,gBAAgB,CAAC,SAAkB,UACvC,gBAAAH,MAACE,MAAA,EAAgB,eAAc,UAAS,cAAc,GACpD;AAAA,oBAAAH,KAACI,OAAA,EAAM,uBAAa,QAAQ,IAAI,EAAE,KAAK,IAAI,QAAQ,KAAK,YAAY,CAAC,IAAI,GAAE;AAAA,IAC3E,gBAAAJ,KAACI,OAAA,EAAM,kBAAQ,SAAQ;AAAA,IACtB,QAAQ,SAAS,eAAe,wBAAwB,OAAO;AAAA,OAHxD,KAIV;AAGF,SACE,gBAAAH,MAACE,MAAA,EAAI,eAAc,UAAS,UAAU,GAAG,UAAU,GAAG,UAAU,GAC7D;AAAA,aAAS,WAAW,KAAK,gBAAAH,KAACI,OAAA,EAAK,UAAQ,MAAC,oDAAsC;AAAA,IAC9E,SAAS,SAAS,KACjB,gBAAAJ,KAAC,UAAO,OAAO,UAAW,WAAC,SAAS,UAAU,cAAc,SAAS,KAAK,GAAE;AAAA,KAEhF;AAEJ;;;AC/EA,OAAOK,UAAS,YAAAC,WAAU,aAAa,aAAAC,kBAAiB;AACxD,SAAS,OAAAC,MAAK,QAAAC,aAAY;AAC1B,OAAO,eAAe;;;ACXf,IAAM,qBAAN,MAAyB;AAAA,EAC9B,OAAwB,gBAAgB;AAAA;AAAA;AAAA;AAAA,EAKxC,OAAO,gBAAgB,OAAwB;AAC7C,WAAO,MAAM,UAAU,EAAE,WAAW,GAAG;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAO,MAAM,OAA4B;AACvC,UAAM,UAAU,MAAM,KAAK;AAE3B,QAAI,CAAC,KAAK,gBAAgB,OAAO,GAAG;AAClC,aAAO,EAAE,WAAW,MAAM;AAAA,IAC5B;AAEA,UAAM,QAAQ,KAAK,cAAc,KAAK,OAAO;AAE7C,QAAI,CAAC,OAAO;AACV,aAAO,EAAE,WAAW,MAAM;AAAA,IAC5B;AAEA,UAAM,cAAc,MAAM,CAAC;AAC3B,UAAM,UAAU,MAAM,CAAC,KAAK;AAC5B,UAAM,OAAO,UAAU,QAAQ,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AAEtD,WAAO;AAAA,MACL,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,sBAAsB,OAA8B;AACzD,UAAM,UAAU,MAAM,UAAU;AAEhC,QAAI,CAAC,QAAQ,WAAW,GAAG,GAAG;AAC5B,aAAO;AAAA,IACT;AAGA,UAAM,aAAa,QAAQ,QAAQ,GAAG;AACtC,QAAI,eAAe,IAAI;AACrB,aAAO,QAAQ,UAAU,CAAC;AAAA,IAC5B;AAEA,WAAO,QAAQ,UAAU,GAAG,UAAU;AAAA,EACxC;AACF;;;AC3EA,OAAOC,UAAS,WAAAC,gBAAe;AAC/B,SAAS,OAAAC,MAAK,QAAAC,aAAY;AAC1B,OAAOC,YAAW;;;ACPlB,SAAS,WAAW,YAAAC,iBAAgB;AACpC,SAAS,iBAAiB;AAUnB,IAAM,kBAAkB,MAAyC;AACtE,QAAM,EAAE,OAAO,IAAI,UAAU;AAG7B,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAS;AAAA,IAC3C,OAAO,QAAQ,WAAW;AAAA,IAC1B,QAAQ,QAAQ,QAAQ;AAAA,EAC1B,CAAC;AAED,YAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAGb,UAAM,eAAe,MAAM;AACzB,oBAAc;AAAA,QACZ,OAAO,OAAO,WAAW;AAAA,QACzB,QAAQ,OAAO,QAAQ;AAAA,MACzB,CAAC;AAAA,IACH;AAIA,WAAO,GAAG,UAAU,YAAY;AAGhC,iBAAa;AAGb,WAAO,MAAM;AACX,aAAO,IAAI,UAAU,YAAY;AAAA,IACnC;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,SAAO;AACT;;;ADqLM,SACE,OAAAC,MADF,QAAAC,aAAA;AA9MN,SAAS,oBAAoB,KAAa,QAAwB;AAEhE,QAAM,WAAW,IAAI,QAAQ,KAAK,EAAE;AAGpC,QAAM,IAAI,SAAS,SAAS,UAAU,GAAG,CAAC,GAAG,EAAE;AAC/C,QAAM,IAAI,SAAS,SAAS,UAAU,GAAG,CAAC,GAAG,EAAE;AAC/C,QAAM,IAAI,SAAS,SAAS,UAAU,GAAG,CAAC,GAAG,EAAE;AAG/C,QAAM,SAAS,CAAC,UAAkB;AAChC,UAAM,WACJ,SAAS,IACL,SAAS,IAAI,UACb,SAAS,MAAM,SAAS;AAC9B,WAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,QAAQ,CAAC,CAAC;AAAA,EACxD;AAEA,QAAM,OAAO,OAAO,CAAC;AACrB,QAAM,OAAO,OAAO,CAAC;AACrB,QAAM,OAAO,OAAO,CAAC;AAGrB,QAAM,QAAQ,CAAC,MAAc,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAC3D,SAAO,IAAI,MAAM,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC;AACpD;AAqBO,IAAM,sBAA0D,CAAC;AAAA,EACtE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb,oBAAoB;AAAA,EACpB,iBAAiB;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,kBAAkB,SAAS,KAAK;AACtC,QAAM,aAAa,gBAAgB,UAAU,kBAAkB;AAC/D,QAAM,KAAKC,OAAM,MAAM,UAAU;AACjC,QAAM,mBAAmB,gBAAgB,OAAO;AAChD,QAAM,4BAA4B,gBAAgB,UAAU,0BAA0B;AACtF,QAAM,yBAAyBA,OAAM,MAAM,yBAAyB;AACpE,QAAM,2BAA2B,gBAAgB,OAAO;AACxD,QAAM,yBAAyB,gBAAgB,OAAO;AACtD,QAAM,yBAAyB,gBAAgB,OAAO;AACtD,QAAM,4BAA4B,gBAAgB,OAAO;AAGzD,QAAM,aAAa,oBAAoB,YAAY,KAAK;AACxD,QAAM,UAAUA,OAAM,MAAM,UAAU;AAGtC,QAAM,EAAE,OAAO,cAAc,IAAI,gBAAgB;AACjD,QAAM,kBAAkB,KAAK,IAAI,IAAI,gBAAgB,CAAC;AAGtD,QAAM,eAAe,CAAC,MAAc,WAA2B;AAG7D,UAAM,WAAW,KAAK,QAAQ,mBAAmB,EAAE;AACnD,QAAI,SAAS,UAAU,QAAQ;AAC7B,aAAO;AAAA,IACT;AAEA,WAAO,SAAS,MAAM,GAAG,SAAS,CAAC,IAAI;AAAA,EACzC;AAGA,QAAM,SAAS,CAAC,SAAiB,OAAe,UAAU,qBAAqB;AAC7E,UAAM,YAAY,aAAa,SAAS,KAAK;AAE7C,UAAM,UAAU,KAAK,IAAI,GAAG,QAAQ,UAAU,MAAM;AACpD,WAAO,GAAG,QAAQ,YAAY,IAAI,OAAO,OAAO,CAAC,CAAC;AAAA,EACpD;AAGA,QAAM,aAAaC,SAAQ,MAAM;AAC/B,UAAM,eAAe,uBAAuB,YAAY,YAAY,YAAY,YAAY;AAE5F,UAAM,aAAa,uBAAuB,YAAY,YAAY,OAAO,YAAY,MAAM,CAAC;AAC5F,UAAM,aAAa,uBAAuB,YAAY,SAAS;AAC/D,WAAO,IAAI,YAAY,eAAe,UAAU,aAAa,UAAU;AAAA,EACzE,GAAG,CAAC,WAAW,CAAC;AAGhB,MAAI,wBAAwB,qBAAqB,SAAS,GAAG;AAE3D,UAAMC,qBAAoB,KAAK,IAAI,GAAG,KAAK,IAAI,eAAe,qBAAqB,SAAS,CAAC,CAAC;AAE9F,UAAM,EAAE,oBAAoB,YAAAC,aAAY,UAAAC,UAAS,IAAIH,SAAQ,MAAM;AACjE,UAAI,qBAAqB,UAAU,YAAY;AAC7C,eAAO;AAAA,UACL,oBAAoB;AAAA,UACpB,YAAY;AAAA,UACZ,UAAU,qBAAqB;AAAA,QACjC;AAAA,MACF;AAGA,UAAIE;AACJ,UAAIC;AAEJ,UAAIF,qBAAoB,KAAK,MAAM,aAAa,CAAC,GAAG;AAElD,QAAAC,cAAa;AACb,QAAAC,YAAW;AAAA,MACb,WAAWF,sBAAqB,qBAAqB,SAAS,KAAK,MAAM,aAAa,CAAC,GAAG;AAExF,QAAAC,cAAa,qBAAqB,SAAS;AAC3C,QAAAC,YAAW,qBAAqB;AAAA,MAClC,OAAO;AAEL,QAAAD,cAAaD,qBAAoB,KAAK,MAAM,aAAa,CAAC;AAC1D,QAAAE,YAAWD,cAAa;AAAA,MAC1B;AAGA,MAAAA,cAAa,KAAK,IAAI,GAAGA,WAAU;AACnC,MAAAC,YAAW,KAAK,IAAI,qBAAqB,QAAQA,SAAQ;AAEzD,aAAO;AAAA,QACL,oBAAoB,qBAAqB,MAAMD,aAAYC,SAAQ;AAAA,QACnE,YAAAD;AAAA,QACA,UAAAC;AAAA,MACF;AAAA,IACF,GAAG,CAAC,sBAAsBF,oBAAmB,UAAU,CAAC;AAExD,UAAMG,aAAYF,cAAa;AAC/B,UAAMG,aAAYF,YAAW,qBAAqB;AAClD,UAAMG,kBAAiBJ;AACvB,UAAMK,kBAAiB,qBAAqB,SAASJ;AAQrD,UAAMK,gBAAeR,SAAQ,MAAM;AACjC,UAAI,SAAS;AACb,gBAAU;AACV,UAAII,WAAW,WAAU;AACzB,gBAAU,mBAAmB;AAC7B,UAAIC,WAAW,WAAU;AACzB,gBAAU;AACV,aAAO;AAAA,IACT,GAAG,CAACD,YAAW,mBAAmB,QAAQC,UAAS,CAAC;AAGpD,IAAAI,OAAM,UAAU,MAAM;AACpB,UAAI,oBAAoB;AACtB,2BAAmBD,aAAY;AAAA,MACjC;AAAA,IACF,GAAG,CAAC,oBAAoBA,aAAY,CAAC;AAGrC,UAAME,YAAWV,SAAQ,MAAM;AAC7B,YAAM,SAAS,IAAI,iBAAiB,WAAW,KAAK,qBAAqB,MAAM;AAC/E,YAAM,WAAWI,aAAY,WAAME,eAAc,iBAAiB;AAClE,YAAM,gBAAgBD,aAAY,WAAME,eAAc,iBAAiB;AACvE,YAAM,QAAQ,mBAAmB,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;AAEpD,YAAM,UAAU;AAAA,QACd,OAAO;AAAA,QACP,WAAW;AAAA,QACX,SAAS;AAAA,QACT,cAAc;AAAA,QACd,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,MAAM;AAAA,MAC9B;AACA,YAAM,aAAa,KAAK,IAAI,GAAG,SAAS,EAAE;AAC1C,aAAO,KAAK,IAAI,YAAY,eAAe;AAAA,IAC7C,GAAG;AAAA,MACD;AAAA,MACA,qBAAqB;AAAA,MACrB;AAAA,MACAH;AAAA,MACAC;AAAA,MACAC;AAAA,MACAC;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,WACE,gBAAAT,MAACa,MAAA,EAAI,eAAc,UAAS,YAAY,GACtC;AAAA,sBAAAd,KAACe,OAAA,EACE;AAAA,QACC,IAAI,iBAAiB,WAAW,KAAK,qBAAqB,MAAM;AAAA,QAChEF;AAAA,QACA;AAAA,MACF,GACF;AAAA,MACCN,cACC,gBAAAP,KAACe,OAAA,EACE,iBAAO,WAAMN,eAAc,gBAAgBI,WAAU,yBAAyB,GACjF;AAAA,MAED,mBAAmB,IAAI,CAAC,YAAY,QAAQ;AAE3C,cAAM,cAAcR,cAAa;AACjC,cAAM,aAAa,gBAAgBD;AACnC,cAAM,SAAS,aAAa,OAAO;AACnC,cAAM,UAAU,GAAG,MAAM,GAAG,UAAU;AAEtC,eACE,gBAAAJ,KAACe,OAAA,EACE,uBACG;AAAA,UACE,yBAAyB,aAAa,SAASF,SAAQ,EAAE,OAAOA,WAAU,GAAG,CAAC;AAAA,QAChF,IACA,OAAO,SAASA,SAAQ,KALnB,GAAG,WAAW,IAAI,UAAU,EAMvC;AAAA,MAEJ,CAAC;AAAA,MACAL,cACC,gBAAAR,KAACe,OAAA,EACE,iBAAO,WAAML,eAAc,gBAAgBG,WAAU,yBAAyB,GACjF;AAAA,MAEF,gBAAAb,KAACe,OAAA,EAAM,iBAAO,YAAYF,WAAU,sBAAsB,GAAE;AAAA,OAC9D;AAAA,EAEJ;AAGA,MAAI,CAAC,YAAY,SAAS,WAAW,GAAG;AACtC,WAAO;AAAA,EACT;AAGA,QAAM,oBAAoB,KAAK,IAAI,GAAG,KAAK,IAAI,eAAe,SAAS,SAAS,CAAC,CAAC;AAElF,QAAM,EAAE,iBAAiB,YAAY,SAAS,IAAIV,SAAQ,MAAM;AAE9D,UAAM,aAAa,CAAC,KAAgC,QAAgB;AAClE,UAAI,CAAC,IAAK,QAAO;AACjB,UAAI,QAAQ;AACZ,UAAI,qBAAqB,QAAQ,qBAAqB,IAAI,YAAY;AACpE,iBAAS,IAAI,WAAW;AAAA,MAC1B;AACA,aAAO;AAAA,IACT;AAGA,UAAM,aAAa,SAAS,OAAO,CAAC,KAAK,KAAK,QAAQ,MAAM,WAAW,KAAK,GAAG,GAAG,CAAC;AAGnF,QAAI,cAAc,YAAY;AAC5B,aAAO;AAAA,QACL,iBAAiB;AAAA,QACjB,YAAY;AAAA,QACZ,UAAU,SAAS;AAAA,MACrB;AAAA,IACF;AAIA,QAAIE,cAAa;AACjB,QAAIC,YAAW,oBAAoB;AACnC,QAAI,YAAY,WAAW,SAAS,iBAAiB,GAAG,iBAAiB;AAGzE,WAAOA,YAAW,SAAS,UAAU,YAAY,YAAY;AAC3D,YAAM,YAAY,WAAW,SAASA,SAAQ,GAAGA,SAAQ;AACzD,UAAI,YAAY,YAAY,WAAY;AACxC,mBAAa;AACb,MAAAA;AAAA,IACF;AAGA,WAAOD,cAAa,KAAK,YAAY,YAAY;AAC/C,YAAM,YAAY,WAAW,SAASA,cAAa,CAAC,GAAGA,cAAa,CAAC;AACrE,UAAI,YAAY,YAAY,WAAY;AACxC,mBAAa;AACb,MAAAA;AAAA,IACF;AAEA,WAAO;AAAA,MACL,iBAAiB,SAAS,MAAMA,aAAYC,SAAQ;AAAA,MACpD,YAAAD;AAAA,MACA,UAAAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,UAAU,mBAAmB,YAAY,iBAAiB,CAAC;AAE/D,QAAM,YAAY,aAAa;AAC/B,QAAM,YAAY,WAAW,SAAS;AACtC,QAAM,iBAAiB;AACvB,QAAM,iBAAiB,SAAS,SAAS;AAGzC,QAAM,YAAY,KAAK,IAAI,GAAG,KAAK,IAAI,eAAe,SAAS,SAAS,CAAC,CAAC;AAC1E,QAAM,cAAc,SAAS,SAAS;AACtC,QAAM,oBACJ,qBAAqB,aAAa,aAAa,YAAY,WAAW,SAAS;AASjF,QAAM,eAAeH,SAAQ,MAAM;AACjC,QAAI,SAAS;AACb,cAAU;AACV,QAAI,UAAW,WAAU;AACzB,cAAU,gBAAgB;AAC1B,cAAU;AACV,QAAI,UAAW,WAAU;AACzB,cAAU;AACV,WAAO;AAAA,EACT,GAAG,CAAC,WAAW,gBAAgB,QAAQ,mBAAmB,SAAS,CAAC;AAGpE,EAAAS,OAAM,UAAU,MAAM;AACpB,QAAI,oBAAoB;AACtB,yBAAmB,YAAY;AAAA,IACjC;AAAA,EACF,GAAG,CAAC,oBAAoB,YAAY,CAAC;AAGrC,QAAM,WAAWT,SAAQ,MAAM;AAC7B,UAAM,SAAS,cAAc,SAAS,MAAM;AAC5C,UAAM,WAAW,YAAY,WAAM,cAAc,iBAAiB;AAClE,UAAM,gBAAgB,YAAY,WAAM,cAAc,iBAAiB;AAEvE,UAAM,aAAa,gBAAgB,IAAI,CAAC,QAAQ;AAC9C,YAAM,UAAU,MAAM,IAAI,IAAI,MAAM,IAAI,WAAW;AACnD,UAAI,SAAS,QAAQ;AACrB,UAAI,qBAAqB,IAAI,YAAY;AACvC,YAAI,WAAW,QAAQ,CAAC,UAAU;AAChC,gBAAM,YAAY,QAAQ,MAAM,IAAI,MAAM,MAAM,WAAW;AAC3D,mBAAS,KAAK,IAAI,QAAQ,UAAU,MAAM;AAAA,QAC5C,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT,CAAC;AAED,UAAM,UAAU;AAAA,MACd,OAAO;AAAA,MACP,WAAW;AAAA,MACX,SAAS;AAAA,MACT,cAAc;AAAA,MACd,GAAG;AAAA,IACL;AACA,UAAM,aAAa,KAAK,IAAI,GAAG,SAAS,EAAE;AAC1C,WAAO,KAAK,IAAI,YAAY,eAAe;AAAA,EAC7C,GAAG;AAAA,IACD,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,SACE,gBAAAF,MAACa,MAAA,EAAI,eAAc,UAAS,YAAY,GACtC;AAAA,oBAAAd,KAACe,OAAA,EAAM,iBAAO,cAAc,SAAS,MAAM,MAAM,UAAU,sBAAsB,GAAE;AAAA,IAClF,aACC,gBAAAf,KAACe,OAAA,EACE,iBAAO,WAAM,cAAc,gBAAgB,UAAU,yBAAyB,GACjF;AAAA,KAEA,MAAM;AAGN,YAAM,iBAAiB,KAAK,IAAI,GAAG,gBAAgB,IAAI,CAAC,MAAM,EAAE,KAAK,MAAM,CAAC;AAC5E,YAAM,iBAAiB,iBAAiB;AAGxC,UAAI,kBAAkB;AACtB,UAAI,mBAAmB;AACrB,mBAAW,OAAO,iBAAiB;AACjC,cAAI,IAAI,YAAY;AAClB,uBAAW,KAAK,IAAI,YAAY;AAC9B,oBAAM,WAAW,IAAI,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI;AAC5C,gCAAkB,KAAK,IAAI,iBAAiB,QAAQ;AAAA,YACtD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,YAAM,uBAAuB,KAAK,IAAI,gBAAgB,kBAAkB,CAAC;AAEzE,aAAO,gBAAgB,IAAI,CAAC,SAAS,QAAQ;AAC3C,cAAM,cAAc,aAAa;AACjC,cAAM,aAAa,gBAAgB;AACnC,cAAM,SAAS,aAAa,OAAO;AAGnC,cAAM,UAAU,GAAG,MAAM,IAAI,QAAQ,IAAI;AACzC,cAAM,aAAa,IAAI,OAAO,KAAK,IAAI,GAAG,uBAAuB,QAAQ,SAAS,CAAC,CAAC;AACpF,cAAM,UAAU,UAAU,aAAa,QAAQ;AAC/C,cAAM,eAAe,aAAa,SAAS,QAAQ;AAGnD,cAAM,eAAe,QAAQ,SAAS,WAAW;AACjD,cAAM,UAAU,aAAa,UAAU,GAAG,KAAK,IAAI,cAAc,aAAa,MAAM,CAAC;AACrF,cAAM,WAAW,aAAa,UAAU,KAAK,IAAI,cAAc,aAAa,MAAM,CAAC;AACnF,cAAM,aAAa,IAAI,OAAO,KAAK,IAAI,GAAG,WAAW,aAAa,MAAM,CAAC;AAEzE,eACE,gBAAAd,MAACW,OAAM,UAAN,EACC;AAAA,0BAAAZ,KAACe,OAAA,EACE,uBACG;AAAA,YACE,yBAAyB,OAAO,IAC9B,yBAAyBb,OAAM,IAAI,QAAQ,CAAC,IAC5C,yBAAyB,UAAU;AAAA,UACvC,IACA;AAAA,YACE,iBAAiB,OAAO,IACtB,iBAAiBA,OAAM,IAAI,QAAQ,CAAC,IACpC,iBAAiB,UAAU;AAAA,UAC/B,GACN;AAAA,UACC,cACC,qBACA,QAAQ,cACR,QAAQ,WAAW,SAAS,KAC5B,QAAQ,WAAW,IAAI,CAAC,UAAU;AAEhC,kBAAM,WAAW,QAAQ,MAAM,IAAI;AACnC,kBAAM,eAAe,IAAI;AAAA,cACvB,KAAK,IAAI,GAAG,uBAAuB,SAAS,SAAS,CAAC;AAAA,YACxD;AACA,kBAAM,YAAY,WAAW,eAAe,MAAM;AAClD,kBAAM,iBAAiB,aAAa,WAAW,QAAQ;AAEvD,kBAAM,oBAAoB,SAAS,SAAS,aAAa;AACzD,kBAAM,eAAe,eAAe;AAAA,cAClC;AAAA,cACA,KAAK,IAAI,mBAAmB,eAAe,MAAM;AAAA,YACnD;AACA,kBAAM,gBAAgB,eAAe;AAAA,cACnC,KAAK,IAAI,mBAAmB,eAAe,MAAM;AAAA,YACnD;AACA,kBAAM,kBAAkB,IAAI,OAAO,KAAK,IAAI,GAAG,WAAW,eAAe,MAAM,CAAC;AAEhF,mBACE,gBAAAF,KAACe,OAAA,EACE;AAAA,cACC,iBAAiBb,OAAM,IAAI,YAAY,CAAC,IACtC,iBAAiBA,OAAM,IAAI,SAAS,EAAE,aAAa,CAAC,IACpD,iBAAiB,eAAe;AAAA,YACpC,KALS,GAAG,WAAW,IAAI,QAAQ,IAAI,IAAI,MAAM,IAAI,EAMvD;AAAA,UAEJ,CAAC;AAAA,aA9CgB,GAAG,WAAW,IAAI,QAAQ,IAAI,EA+CnD;AAAA,MAEJ,CAAC;AAAA,IACH,GAAG;AAAA,IACF,aACC,gBAAAF,KAACe,OAAA,EACE,iBAAO,WAAM,cAAc,gBAAgB,UAAU,yBAAyB,GACjF;AAAA,IAEF,gBAAAf,KAACe,OAAA,EAAM,iBAAO,YAAY,UAAU,sBAAsB,GAAE;AAAA,KAC9D;AAEJ;;;AF7GQ,SACE,OAAAC,MADF,QAAAC,aAAA;AAzUD,IAAM,WAAoCC,OAAM;AAAA,EACrD,CAAC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb;AAAA,IACA,8BAA8B;AAAA,EAChC,MAAM;AACJ,UAAM,kBAAkB,SAAS,KAAK;AACtC,UAAM,CAAC,kBAAkB,mBAAmB,IAAIC,UAA0B,CAAC,CAAC;AAC5E,UAAM,CAAC,sBAAsB,uBAAuB,IAAIA,UAAmB,CAAC,CAAC;AAC7E,UAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAiB,EAAE;AAC7D,UAAM,CAAC,iBAAiB,kBAAkB,IAAIA,UAAS,KAAK;AAC5D,UAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,CAAC;AAC1C,UAAM,CAAC,oBAAoB,qBAAqB,IAAIA,UAAS,CAAC;AAG9D,UAAM,mBAAmB,0BAA0B,SAAY,wBAAwB;AACvF,UAAM,gBAAgB,sBAAsB,SAAY,oBAAoB;AAG5E,IAAAC,WAAU,MAAM;AACd,UAAI,sBAAsB;AACxB,6BAAqB,gBAAgB;AAAA,MACvC;AAAA,IACF,GAAG,CAAC,kBAAkB,oBAAoB,CAAC;AAI3C,UAAM,uBAAuB,YAAY,MAAM;AAC7C,UAAI,CAAC,iBAAiB;AACpB,eAAO,EAAE,MAAM,OAAO,SAAS,OAAO,UAAU,CAAC,GAAG,QAAQ,CAAC,GAAG,WAAW,GAAG;AAAA,MAChF;AAEA,YAAM,UAAU,MAAM,KAAK;AAG3B,UAAI,CAAC,QAAQ,WAAW,GAAG,GAAG;AAC5B,eAAO,EAAE,MAAM,OAAO,SAAS,OAAO,UAAU,CAAC,GAAG,QAAQ,CAAC,GAAG,WAAW,GAAG;AAAA,MAChF;AAEA,YAAM,SAAS,mBAAmB,MAAM,KAAK;AAG7C,UAAI,OAAO,aAAa,OAAO,eAAe,MAAM,SAAS,GAAG,GAAG;AACjE,cAAM,UAAU,gBAAgB,IAAI,OAAO,WAAW;AAGtD,YAAI,SAAS,2BAA2B,SAAS;AAC/C,gBAAM,eAAe,OAAO,WAAW;AAIvC,gBAAM,QAAQ,aAAa,MAAM,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAKlE,gBAAM,gBAAgB,MAAM,KAAK,KAAK;AAEtC,cAAI;AACJ,cAAI;AAEJ,cAAI,eAAe;AAIjB,yBAAa,MAAM;AACnB,2BAAe;AAIf,kBAAM,uBAAuB,QAAQ;AAAA,cACnC;AAAA,cACA;AAAA,cACA;AAAA,YACF;AACA,gBAAI,qBAAqB,WAAW,GAAG;AAErC,qBAAO,EAAE,MAAM,OAAO,SAAS,OAAO,UAAU,CAAC,GAAG,QAAQ,CAAC,GAAG,WAAW,GAAG;AAAA,YAChF;AAEA,mBAAO;AAAA,cACL,MAAM;AAAA,cACN,SAAS;AAAA,cACT,UAAU,CAAC;AAAA,cACX,QAAQ;AAAA,cACR,WAAW,QAAQ,aAAa,UAAU,GAAG,QAAQ;AAAA,YACvD;AAAA,UACF,WAAW,MAAM,WAAW,GAAG;AAE7B,yBAAa;AACb,2BAAe;AAAA,UACjB,OAAO;AAGL,yBAAa,MAAM,SAAS;AAC5B,2BAAe,MAAM,MAAM,SAAS,CAAC,GAAG,YAAY,KAAK;AAAA,UAC3D;AAGA,gBAAM,gBAAgB,aAAa,IAAI,MAAM,MAAM,GAAG,UAAU,IAAI,CAAC;AACrE,gBAAM,iBAAiB,QAAQ;AAAA,YAC7B;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAGA,gBAAM,sBAAsB,eACxB,eAAe,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,YAAY,CAAC,IACrE;AAEJ,cAAI,oBAAoB,SAAS,GAAG;AAClC,mBAAO;AAAA,cACL,MAAM;AAAA,cACN,SAAS;AAAA,cACT,UAAU,CAAC;AAAA,cACX,QAAQ;AAAA,cACR,WAAW,QAAQ,aAAa,UAAU,GAAG,QAAQ;AAAA,YACvD;AAAA,UACF;AAAA,QACF;AAGA,eAAO,EAAE,MAAM,OAAO,SAAS,OAAO,UAAU,CAAC,GAAG,QAAQ,CAAC,GAAG,WAAW,GAAG;AAAA,MAChF;AAGA,YAAM,cAAc,mBAAmB,sBAAsB,KAAK;AAElE,UAAI,gBAAgB,MAAM;AACxB,eAAO,EAAE,MAAM,OAAO,SAAS,OAAO,UAAU,CAAC,GAAG,QAAQ,CAAC,GAAG,WAAW,GAAG;AAAA,MAChF;AAGA,YAAM,WAAW,MAAM,SAAS,GAAG;AACnC,UAAI,UAAU;AACZ,eAAO,EAAE,MAAM,OAAO,SAAS,OAAO,UAAU,CAAC,GAAG,QAAQ,CAAC,GAAG,WAAW,GAAG;AAAA,MAChF;AAEA,YAAM,UAAU,gBAAgB,OAAO,WAAW;AAElD,aAAO;AAAA,QACL,MAAM,QAAQ,SAAS;AAAA,QACvB,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ,CAAC;AAAA,QACT,WAAW;AAAA,MACb;AAAA,IACF,GAAG,CAAC,OAAO,iBAAiB,OAAO,CAAC;AAGpC,IAAAA,WAAU,MAAM;AACd,YAAM,cAAc,qBAAqB;AAEzC,yBAAmB,YAAY,OAAO;AACtC,0BAAoB,YAAY,QAAQ;AACxC,8BAAwB,YAAY,MAAM;AAC1C,uBAAiB,YAAY,SAAS;AAGtC,YAAM,YAAY,YAAY,UAC1B,YAAY,OAAO,SACnB,YAAY,SAAS;AAEzB,UAAI,2BAA2B;AAC7B,kCAA0B;AAAA,UACxB;AAAA,UACA,iBAAiB,YAAY;AAAA,UAC7B,YAAY,YAAY,QAAQ,YAAY;AAAA,QAC9C,CAAC;AAAA,MACH;AAAA,IACF,GAAG,CAAC,sBAAsB,yBAAyB,CAAC;AAGpD,UAAM,yBAAyB,YAAY,CAAC,WAAmB;AAC7D,4BAAsB,MAAM;AAAA,IAC9B,GAAG,CAAC,CAAC;AAGL,IAAAA,WAAU,MAAM;AACd,UAAI,CAAC,kBAAkB;AACrB,8BAAsB,CAAC;AAAA,MACzB;AAAA,IACF,GAAG,CAAC,gBAAgB,CAAC;AAGrB,IAAAA,WAAU,MAAM;AACd,YAAM,YAAY,kBAAkB,qBAAqB,SAAS,iBAAiB;AAEnF,UAAI,2BAA2B;AAC7B,kCAA0B;AAAA,UACxB;AAAA,UACA;AAAA,UACA,YAAY,oBAAoB,YAAY;AAAA,UAC5C,cAAc,mBAAmB,qBAAqB;AAAA,QACxD,CAAC;AAAA,MACH;AAAA,IACF,GAAG;AAAA,MACD;AAAA,MACA;AAAA,MACA,qBAAqB;AAAA,MACrB,iBAAiB;AAAA,MACjB;AAAA,MACA;AAAA,IACF,CAAC;AAGD,UAAM,kBAAkB,YAAY,MAAM;AACxC,YAAM,YAAY,kBAAkB,qBAAqB,SAAS,iBAAiB;AACnF,UAAI,cAAc,EAAG;AAErB,UAAI,iBAAiB;AAEnB,cAAM,WAAW,qBAAqB,aAAa;AACnD,YAAI,UAAU;AACZ,gBAAM,SAAS,mBAAmB,MAAM,KAAK;AAC7C,gBAAM,eAAe,OAAO,WAAW;AAGvC,gBAAM,QAAQ,aAAa,MAAM,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAClE,gBAAM,gBAAgB,aAAa,SAAS,KAAK,MAAM,KAAK,YAAY;AAExE,cAAI;AACJ,cAAI,iBAAiB,MAAM,WAAW,GAAG;AAEvC,4BAAgB,CAAC,GAAG,OAAO,QAAQ;AAAA,UACrC,OAAO;AAEL,4BAAgB,CAAC,GAAG,MAAM,MAAM,GAAG,EAAE,GAAG,QAAQ;AAAA,UAClD;AAEA,gBAAM,cAAc,OAAO;AAC3B,cAAI,CAAC,YAAa;AAElB,gBAAM,cAAc,IAAI,WAAW;AACnC,gBAAM,WAAW,GAAG,WAAW,IAAI,cAAc,KAAK,GAAG,CAAC;AAG1D,gBAAM,UAAU,iBAAiB,IAAI,WAAW;AAChD,gBAAM,gBACJ,SAAS,2BAA2B,UAChC,QAAQ,wBAAwB,cAAc,QAAQ,SAAS,aAAa,EACzE,SAAS,IACZ;AAEN,cAAI,CAAC,iBAAiB,6BAA6B;AAEjD,wBAAY,CAAC,SAAS,OAAO,CAAC;AAC9B,kBAAM,aAAa,SAAS,KAAK;AACjC,qBAAS,UAAU;AAEnB,uBAAW,MAAM;AACf,uBAAS,UAAU;AAAA,YACrB,GAAG,CAAC;AAAA,UACN,OAAO;AAEL,wBAAY,CAAC,SAAS,OAAO,CAAC;AAC9B,qBAAS,QAAQ;AAAA,UACnB;AAAA,QACF;AAAA,MACF,OAAO;AAEL,cAAM,kBAAkB,iBAAiB,aAAa;AACtD,YAAI,iBAAiB;AACnB,gBAAM,WAAW,IAAI,gBAAgB,IAAI;AAGzC,gBAAM,YACJ,gBAAgB,2BAA2B,UACvC,gBAAgB,wBAAwB,GAAG,SAAS,CAAC,CAAC,EAAE,SAAS,IACjE;AAEN,cAAI,CAAC,aAAa,6BAA6B;AAE7C,wBAAY,CAAC,SAAS,OAAO,CAAC;AAC9B,kBAAM,aAAa,SAAS,KAAK;AACjC,qBAAS,UAAU;AAEnB,uBAAW,MAAM;AACf,uBAAS,UAAU;AAAA,YACrB,GAAG,CAAC;AAAA,UACN,OAAO;AAEL,wBAAY,CAAC,SAAS,OAAO,CAAC;AAC9B,qBAAS,QAAQ;AAAA,UACnB;AAAA,QACF;AAAA,MACF;AAAA,IACF,GAAG;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAGD,IAAAA,WAAU,MAAM;AACd,UAAI,sBAAsB;AACxB,6BAAqB,UAAU;AAAA,MACjC;AAAA,IACF,GAAG,CAAC,sBAAsB,eAAe,CAAC;AAE1C,UAAM,eAAe,YAAY,MAAM;AAErC,UAAI,CAAC,kBAAkB;AACrB,iBAAS,MAAS;AAAA,MACpB;AAAA,IACF,GAAG,CAAC,kBAAkB,QAAQ,CAAC;AAE/B,WACE,gBAAAH,MAACI,MAAA,EAAI,eAAc,UAAS,YAAY,GAEtC;AAAA,sBAAAJ,MAACI,MAAA,EAAI,UAAU,GAAG,YAAY,GAC5B;AAAA,wBAAAL,KAACM,OAAA,EAAM,0BAAgB,OAAO,YAAY,IAAI,GAAE;AAAA,QAChD,gBAAAN,KAAC,aAAyB,OAAc,UAAoB,UAAU,gBAAtD,QAAoE;AAAA,SACtF;AAAA,MAGC,oBACC,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,UAAU,kBAAkB,SAAY;AAAA,UACxC,sBAAsB,kBAAkB,uBAAuB;AAAA,UAC/D,eAAe,kBAAkB,gBAAgB;AAAA,UACjD;AAAA,UACA,mBAAmB,CAAC;AAAA,UACpB,iBAAiB,kBAAkB,SAAY,iBAAiB,aAAa;AAAA,UAC7E;AAAA,UACA;AAAA,UACA;AAAA,UACA,oBAAoB;AAAA;AAAA,MACtB;AAAA,OAEJ;AAAA,EAEJ;AACF;AAEA,SAAS,cAAc;;;AIjavB,SAAgB,YAAAO,WAAU,aAAAC,kBAAiB;AAC3C,SAAS,OAAAC,OAAK,QAAAC,aAAY;;;ACI1B,SAAS,aAAa,aAA0C;AAC9D,QAAM,gBAAgB,uBAAuB,YAAY,YAAY,EAAE,eAAe,KAAK,CAAC;AAC5F,QAAM,UAAU,uBAAuB,YAAY,aAAa,EAAE,eAAe,KAAK,CAAC;AAEvF,SAAO;AAAA,IACL;AAAA,IACA,0BAA0B,aAAa;AAAA,IACvC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,OAAO;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKO,SAAS,aAAa,aAAwC;AACnE,QAAM,OAAO,aAAa,WAAW;AACrC,QAAM,cAAc,KAAK,MAAM,KAAK,OAAO,IAAI,KAAK,MAAM;AAC1D,SAAO,KAAK,WAAW,KAAK;AAC9B;;;ADHe,gBAAAC,OAyCP,QAAAC,aAzCO;AAdR,IAAM,SAAgC,CAAC;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA,MAAAC;AAAA,EACA,sBAAsB;AAAA,EACtB,iBAAiB;AACnB,MAAM;AACJ,QAAM,kBAAkB,SAAS,KAAK;AAGtC,QAAM,iBAAiB,MAAmB;AACxC,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO,gBAAAF,MAACG,OAAA,EAAM,0BAAgB,OAAO,SAAS,gBAAW,GAAE;AAAA,MAC7D,KAAK;AACH,eAAO,gBAAAH,MAACG,OAAA,EAAM,0BAAgB,OAAO,QAAQ,gBAAW,GAAE;AAAA,MAC5D,KAAK;AACH,eAAO,gBAAAH,MAACG,OAAA,EAAM,0BAAgB,OAAO,YAAY,gBAAW,GAAE;AAAA,IAClE;AAAA,EACF;AAGA,QAAM,CAAC,YAAY,aAAa,IAAIC,UAAS,aAAa,SAAS,CAAC;AAEpE,EAAAC,WAAU,MAAM;AACd,UAAM,WAAW,YAAY,MAAM;AACjC,oBAAc,aAAa,SAAS,CAAC;AAAA,IACvC,GAAG,GAAK;AAER,WAAO,MAAM,cAAc,QAAQ;AAAA,EACrC,GAAG,CAAC,SAAS,CAAC;AAGd,QAAM,aAAa,MAAM;AACvB,QAAI,wBAAwB,GAAG;AAC7B,YAAM,eAAe,uBAAuB,UAAU,SAAS;AAC/D,UAAI,gBAAgB;AAClB,eACE,gBAAAL,MAACG,OAAA,EACE,0BAAgB,OAAO;AAAA,UACtB,4BAA4B,YAAY;AAAA,QAC1C,GACF;AAAA,MAEJ,OAAO;AACL,eAAO,gBAAAH,MAACG,OAAA,EAAM,0BAAgB,OAAO,QAAQ,SAAS,YAAY,gBAAgB,GAAE;AAAA,MACtF;AAAA,IACF;AACA,WAAO,gBAAAH,MAACG,OAAA,EAAK,UAAQ,MAAE,sBAAW;AAAA,EACpC;AAEA,SACE,gBAAAF,MAACK,OAAA,EAAI,eAAc,UACjB;AAAA,oBAAAN,MAACM,OAAA,EACC,0BAAAL,MAACE,OAAA,EAAK;AAAA;AAAA,MACG,eAAe;AAAA,MACrB;AAAA,MAAM;AAAA,MACD,gBAAAH,MAACG,OAAA,EAAM,0BAAgB,OAAO,QAAQ,IAAID,MAAK,QAAQ,CAAC,CAAC,EAAE,GAAE;AAAA,OACrE,GACF;AAAA,IACA,gBAAAF,MAACM,OAAA,EACC,0BAAAL,MAACE,OAAA,EAAK,UAAQ,MACX;AAAA,6BAAuB,UAAU,SAAS;AAAA,MAAE;AAAA,MAAU;AAAA,MACtD,uBAAuB,UAAU,UAAU;AAAA,MAAE;AAAA,OAChD,GACF;AAAA,IACA,gBAAAH,MAACM,OAAA,EAAK,qBAAW,GAAE;AAAA,KACrB;AAEJ;;;AEtFA,SAAS,oBAAoB;AA2CtB,IAAM,mBAAN,cAA+B,aAAa;AAAA,EAQjD,YAAoB,iBAAqC;AACvD,UAAM;AADY;AAElB,SAAK,gBAAgB,EAAE;AAAA,EACzB;AAAA,EAVQ,WAA0D,oBAAI,IAAI;AAAA,EAClE,UAAgC;AAAA,IACtC,uBAAuB;AAAA,IACvB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAUA,cAAc,SAA8C;AAC1D,SAAK,UAAU,EAAE,GAAG,KAAK,SAAS,GAAG,QAAQ;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,aAA6C;AAC3C,WAAO,OAAO,OAAO,EAAE,GAAG,KAAK,QAAQ,CAAC;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UACE,QACA,SACA,UAA8C,CAAC,GACnC;AACZ,UAAM,aAAmC;AAAA,MACvC;AAAA,MACA;AAAA,MACA,UAAU,QAAQ,YAAY;AAAA,MAC9B,IAAI,QAAQ,MAAM,GAAG,MAAM,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC;AAAA,IAC5D;AAEA,UAAM,WAAW,KAAK,SAAS,IAAI,MAAM,KAAK,CAAC;AAC/C,aAAS,KAAK,UAAU;AAGxB,aAAS,KAAK,CAAC,GAAG,OAAO,EAAE,YAAY,MAAM,EAAE,YAAY,EAAE;AAE7D,SAAK,SAAS,IAAI,QAAQ,QAAQ;AAGlC,WAAO,MAAM;AACX,YAAMC,YAAW,KAAK,SAAS,IAAI,MAAM;AACzC,UAAIA,WAAU;AACZ,cAAM,QAAQA,UAAS,UAAU,CAAC,MAAM,EAAE,OAAO,WAAW,EAAE;AAC9D,YAAI,UAAU,IAAI;AAChB,UAAAA,UAAS,OAAO,OAAO,CAAC;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS,QAAyB;AAChC,UAAM,SAAS,KAAK,gBAAgB,gBAAgB,MAAM;AAE1D,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,eAAe,QAAQ,MAAM;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAe,QAA0B,QAA0B;AACjE,UAAM,WAAW,KAAK,SAAS,IAAI,MAAM;AAEzC,QAAI,CAAC,YAAY,SAAS,WAAW,GAAG;AACtC,aAAO;AAAA,IACT;AAEA,QAAI,qBAAqB;AAEzB,UAAM,QAAuB;AAAA,MAC3B;AAAA,MACA,QAAQ,UAAU;AAAA,MAClB,SAAS,KAAK,WAAW;AAAA,MACzB,iBAAiB,MAAM;AACrB,6BAAqB;AAAA,MACvB;AAAA,MACA,sBAAsB,MAAM;AAAA,IAC9B;AAGA,eAAW,EAAE,SAAS,IAAI,SAAS,KAAK,UAAU;AAChD,UAAI,oBAAoB;AACtB;AAAA,MACF;AAEA,UAAI;AACF,cAAM,SAAS,QAAQ,KAAK;AAG5B,YAAI,WAAW,OAAO;AACpB;AAAA,QACF,WAAW,WAAW,MAAM;AAC1B,gBAAM,gBAAgB;AAAA,QACxB;AAAA,MACF,SAAS,OAAO;AACd,eAAO,MAAM,iCAAiC,MAAM,IAAI;AAAA,UACtD;AAAA,UACA,WAAW;AAAA,UACX;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,QAAgC;AAC1C,SAAK,SAAS,OAAO,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,WAAiB;AACf,SAAK,SAAS,MAAM;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,uBAA2C;AACzC,WAAO,MAAM,KAAK,KAAK,SAAS,KAAK,CAAC;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,QAAkC;AAChD,WAAO,KAAK,SAAS,IAAI,MAAM,GAAG,UAAU;AAAA,EAC9C;AACF;;;ACrMA,SAAS,eAAe,YAAY,aAAAC,YAAW,YAAAC,iBAA2B;;;ACE1E,OAAOC,SAAQ;AAuBR,IAAM,qBAAN,MAAM,oBAAmB;AAAA,EAI9B,YAAoB,QAA2B;AAA3B;AAClB,SAAK,WAAWA,IAAG,SAAS;AAC5B,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EANQ,WAA8C,oBAAI,IAAI;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAUA,qBAA2B;AACjC,UAAM,QAAQ,KAAK,aAAa;AAChC,UAAM,SAAS,QAAQ,QAAQ;AAG/B,UAAM,aAAa,CAAC,SAA6B;AAC/C,aAAO,KAAK,IAAI,CAAC,QAAQ,IAAI,QAAQ,SAAS,MAAM,CAAC;AAAA,IACvD;AAGA,SAAK,WAAW,aAAa;AAAA,MAC3B,MAAM,WAAW,KAAK,OAAO,SAAS;AAAA,MACtC,aAAa,WAAW,KAAK,OAAO,SAAS,EAAE,CAAC,KAAK;AAAA,MACrD,QAAQ;AAAA,MACR,aAAa;AAAA,IACf,CAAC;AAED,SAAK,WAAW,UAAU;AAAA,MACxB,MAAM,KAAK,OAAO;AAAA,MAClB,aAAa,KAAK,OAAO,OAAO,CAAC,KAAK;AAAA,MACtC,QAAQ;AAAA,MACR,aAAa;AAAA,IACf,CAAC;AAID,QAAI,KAAK,OAAO,UAAU,KAAK,OAAO,OAAO,SAAS,GAAG;AACvD,WAAK,WAAW,UAAU;AAAA,QACxB,MAAM,KAAK,OAAO;AAAA,QAClB,aAAa,KAAK,OAAO,OAAO,CAAC,KAAK;AAAA,QACtC,QAAQ;AAAA,QACR,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AAEA,SAAK,WAAW,cAAc;AAAA,MAC5B,MAAM,KAAK,OAAO;AAAA,MAClB,aAAa,KAAK,OAAO,WAAW,CAAC,KAAK;AAAA,MAC1C,QAAQ;AAAA,MACR,aAAa;AAAA,IACf,CAAC;AAED,SAAK,WAAW,eAAe;AAAA,MAC7B,MAAM,WAAW,KAAK,OAAO,WAAW;AAAA,MACxC,aAAa,WAAW,KAAK,OAAO,WAAW,EAAE,CAAC,KAAK,GAAG,MAAM;AAAA,MAChE,QAAQ;AAAA,MACR,aAAa;AAAA,IACf,CAAC;AAED,SAAK,WAAW,eAAe;AAAA,MAC7B,MAAM,WAAW,KAAK,OAAO,WAAW;AAAA,MACxC,aAAa,WAAW,KAAK,OAAO,WAAW,EAAE,CAAC,KAAK,GAAG,MAAM;AAAA,MAChE,QAAQ;AAAA,MACR,aAAa;AAAA,IACf,CAAC;AAED,SAAK,WAAW,cAAc;AAAA,MAC5B,MAAM,KAAK,OAAO;AAAA,MAClB,aAAa,KAAK,OAAO,WAAW,CAAC,KAAK;AAAA,MAC1C,QAAQ;AAAA,MACR,aAAa;AAAA,IACf,CAAC;AAED,SAAK,WAAW,gBAAgB;AAAA,MAC9B,MAAM,KAAK,OAAO;AAAA,MAClB,aAAa,KAAK,OAAO,aAAa,CAAC,KAAK;AAAA,MAC5C,QAAQ;AAAA,MACR,aAAa;AAAA,IACf,CAAC;AAED,SAAK,WAAW,QAAQ;AAAA,MACtB,MAAM,KAAK,OAAO;AAAA,MAClB,aAAa,KAAK,OAAO,KAAK,CAAC,KAAK;AAAA,MACpC,QAAQ;AAAA,MACR,aAAa;AAAA,IACf,CAAC;AAED,SAAK,WAAW,eAAe;AAAA,MAC7B,MAAM,WAAW,KAAK,OAAO,WAAW;AAAA,MACxC,aAAa,WAAW,KAAK,OAAO,WAAW,EAAE,CAAC,KAAK,GAAG,MAAM;AAAA,MAChE,QAAQ;AAAA,MACR,aAAa;AAAA,IACf,CAAC;AAED,SAAK,WAAW,QAAQ;AAAA,MACtB,MAAM,WAAW,KAAK,OAAO,IAAI;AAAA,MACjC,aAAa,WAAW,KAAK,OAAO,IAAI,EAAE,CAAC,KAAK,GAAG,MAAM;AAAA,MACzD,QAAQ;AAAA,MACR,aAAa;AAAA,IACf,CAAC;AAGD,UAAM,WAAW,QAAQ,CAAC,GAAG,MAAM,UAAU,IAAI,WAAW,KAAK,OAAO,IAAI;AAE5E,SAAK,WAAW,QAAQ;AAAA,MACtB,MAAM;AAAA,MACN,aAAa,SAAS,CAAC,KAAK,GAAG,MAAM;AAAA,MACrC,QAAQ;AAAA,MACR,aAAa;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,WAAW,QAA0B,SAA2B;AACtE,SAAK,SAAS,IAAI,QAAQ,OAAO;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,QAAkD;AAC3D,WAAO,KAAK,SAAS,IAAI,MAAM;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAoD;AAClD,WAAO,IAAI,IAAI,KAAK,QAAQ;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,cAAsB;AACpB,UAAM,QAAQ,CAAC,uBAAuB,EAAE;AAExC,eAAW,CAAC,EAAE,OAAO,KAAK,KAAK,UAAU;AAEvC,YAAM,cAAc,QAAQ,KAAK,KAAK,IAAI;AAC1C,YAAM,KAAK,KAAK,YAAY,OAAO,EAAE,CAAC,IAAI,QAAQ,WAAW,EAAE;AAAA,IACjE;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,aAAa,KAAqB;AACvC,WAAO,IACJ,QAAQ,aAAa,MAAM,EAC3B,QAAQ,aAAa,KAAK,EAC1B,QAAQ,YAAY,KAAK,EACzB,QAAQ,YAAY,KAAK,EACzB,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,EACxE,KAAK,GAAG;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,YAAoB,QAAmC;AAC7D,UAAM,UAAU,KAAK,SAAS,IAAI,MAAM;AACxC,QAAI,CAAC,WAAW,CAAC,QAAQ,KAAM,QAAO;AAEtC,UAAM,oBAAoB,oBAAmB,aAAa,UAAU;AAGpE,WAAO,QAAQ,KAAK,KAAK,CAAC,QAAQ;AAChC,YAAM,oBAAoB,oBAAmB,aAAa,GAAG;AAC7D,aAAO,sBAAsB;AAAA,IAC/B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,YAA6C;AAC3D,UAAM,oBAAoB,oBAAmB,aAAa,UAAU;AAEpE,eAAW,CAAC,QAAQ,OAAO,KAAK,KAAK,UAAU;AAE7C,UAAI,CAAC,WAAW,CAAC,QAAQ,MAAM;AAC7B,eAAO,KAAK,+BAA+B,MAAM,IAAI,EAAE,QAAQ,CAAC;AAChE;AAAA,MACF;AAEA,UAAI,QAAQ,KAAK,KAAK,CAAC,QAAQ,oBAAmB,aAAa,GAAG,MAAM,iBAAiB,GAAG;AAC1F,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,eAAe,UAAoC;AACxD,UAAM,IAAI,YAAYA,IAAG,SAAS;AAClC,WAAO,MAAM,WAAW,QAAQ;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,kBAAkB,SAAiB,UAAoC;AAC5E,UAAM,SAAS,oBAAmB,eAAe,QAAQ;AACzD,WAAO,QAAQ,QAAQ,cAAc,MAAM;AAAA,EAC7C;AACF;;;ADhMS,gBAAAC,aAAA;AAtCT,IAAM,kBAAkB,cAA2C,IAAI;AAahE,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA,IAAI;AAAA,EACJ,aAAa;AACf,GAAuC;AACrC,QAAM,CAAC,YAAY,IAAIC,UAA+B,MAAM;AAC1D,UAAM,kBAAkB,IAAI,mBAAmB,cAAc;AAC7D,UAAM,WAAW,IAAI,iBAAiB,eAAe;AAErD,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,eAAe,CAAC,YAAY,SAAS,cAAc,OAAO;AAAA,MAC1D,YAAY,MAAM,SAAS,WAAW;AAAA,IACxC;AAAA,EACF,CAAC;AAGD,EAAAC,WAAU,MAAM;AACd,WAAO,MAAM;AACX,mBAAa,SAAS,SAAS;AAAA,IACjC;AAAA,EACF,GAAG,CAAC,YAAY,CAAC;AAEjB,SAAO,gBAAAF,MAAC,gBAAgB,UAAhB,EAAyB,OAAO,cAAe,UAAS;AAClE;AAKO,SAAS,cAAoC;AAClD,QAAM,UAAU,WAAW,eAAe;AAE1C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACpE;AAEA,SAAO;AACT;;;AEjEA,SAAS,aAAAG,YAAW,cAAc;AA4C3B,SAAS,kBACd,QACA,SACA,UAAoC,CAAC,GAC/B;AACN,QAAM,EAAE,SAAS,IAAI,YAAY;AACjC,QAAM,EAAE,WAAW,GAAG,UAAU,MAAM,GAAG,IAAI;AAG7C,QAAM,aAAa,OAAO,OAAO;AACjC,EAAAC,WAAU,MAAM;AACd,eAAW,UAAU;AAAA,EACvB,GAAG,CAAC,OAAO,CAAC;AAEZ,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,QAAS;AAGd,UAAM,iBAAiB,CAAC,UAAyB;AAC/C,aAAO,WAAW,QAAQ,KAAK;AAAA,IACjC;AAEA,UAAM,cAAc,SAAS,UAAU,QAAQ,gBAAgB;AAAA,MAC7D;AAAA,MACA;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,QAAQ,UAAU,SAAS,EAAE,CAAC;AAC9C;;;ACzEA,SAAS,YAAAC,iBAAgB;AA4BzB,IAAM,mBAA2C;AAAA,EAC/C,GAAM;AAAA,EACN,GAAM;AAAA,EACN,GAAM;AAAA,EACN,GAAM;AAAA,EACN,GAAM;AAAA,EACN,GAAM;AAAA,EACN,GAAM;AAAA,EACN,GAAM;AAAA,EACN,GAAM;AAAA,EACN,GAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AAAA,EACN,IAAM;AACR;AAKA,SAAS,eAAe,OAAe,KAAqB;AAE1D,MAAI,IAAI,OAAQ,QAAO;AACvB,MAAI,IAAI,OAAQ,QAAO;AACvB,MAAI,IAAI,IAAK,QAAO,IAAI,QAAQ,cAAc;AAC9C,MAAI,IAAI,UAAW,QAAO;AAC1B,MAAI,IAAI,OAAQ,QAAO;AACvB,MAAI,IAAI,QAAS,QAAO;AACxB,MAAI,IAAI,UAAW,QAAO;AAC1B,MAAI,IAAI,UAAW,QAAO;AAC1B,MAAI,IAAI,WAAY,QAAO;AAC3B,MAAI,IAAI,OAAQ,QAAO;AACvB,MAAI,IAAI,SAAU,QAAO;AAEzB,QAAM,WAAW,MAAM,SAAS,IAAI,MAAM,WAAW,CAAC,IAAI;AAG1D,MAAI,IAAI,MAAM;AAEZ,QAAI,YAAY,KAAQ,YAAY,IAAM;AACxC,YAAM,SAAS,iBAAiB,QAAQ;AACxC,UAAI,QAAQ;AACV,eAAO,QAAQ,MAAM;AAAA,MACvB;AAAA,IACF;AAGA,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO,QAAQ,MAAM,YAAY,CAAC;AAAA,IACpC;AAEA,WAAO;AAAA,EACT;AAGA,MAAI,IAAI,MAAM;AACZ,QAAI,IAAI,SAAS,MAAM,WAAW,GAAG;AACnC,aAAO,aAAa,MAAM,YAAY,CAAC;AAAA,IACzC;AACA,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO,OAAO,MAAM,YAAY,CAAC;AAAA,IACnC;AACA,WAAO;AAAA,EACT;AAGA,MAAI,IAAI,SAAS,MAAM,WAAW,GAAG;AACnC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AASO,SAAS,iBAAiB,UAAmC,CAAC,GAAS;AAC5E,QAAM,EAAE,WAAW,KAAK,IAAI;AAC5B,QAAM,EAAE,UAAU,gBAAgB,IAAI,YAAY;AAElD,EAAAC;AAAA,IACE,CAAC,OAAO,QAAQ;AACd,UAAI,CAAC,SAAU;AAEf,YAAM,YAAY,eAAe,OAAO,GAAG;AAC3C,YAAM,SAAS,gBAAgB,gBAAgB,SAAS;AAExD,UAAI,QAAQ;AACV,iBAAS,eAAe,QAAQ,SAAS;AAAA,MAC3C;AAAA,IACF;AAAA,IACA,EAAE,SAAS;AAAA,EACb;AACF;;;AbgMI,SAEE,OAAAC,OAFF,QAAAC,cAAA;AArTG,IAAM,gBAA8C,CAAC;AAAA,EAC1D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,YAAY,QAAQ,IAAI;AAAA,EACxB,iBAAiB;AAAA,EACjB;AACF,MAAM;AACJ,QAAM,CAAC,OAAO,QAAQ,IAAIC,UAAS,EAAE;AACrC,QAAM,CAAC,MAAM,OAAO,IAAIA,UAAqC,WAAW;AACxE,QAAM,CAAC,qBAAqB,sBAAsB,IAAIA,UAAS,CAAC;AAChE,QAAM,CAAC,uBAAuB,wBAAwB,IAAIA,UAAS,KAAK;AACxE,QAAM,CAAC,2BAA2B,4BAA4B,IAAIA,UAAS,CAAC;AAC5E,QAAM,CAAC,uBAAuB,wBAAwB,IAAIA,UAAS,CAAC;AACpE,QAAM,CAAC,4BAA4B,6BAA6B,IAAIA,UAAS,KAAK;AAClF,QAAM,qBAAqBC,QAA4B,IAAI;AAC3D,QAAM,oBAAoBA,QAA8B,IAAI;AAC5D,QAAM,EAAE,OAAO,eAAe,QAAQ,eAAe,IAAI,gBAAgB;AACzE,QAAM,EAAE,cAAc,IAAI,YAAY;AAGtC,EAAAC,WAAU,MAAM;AACd,YAAQ,WAAW;AAAA,EACrB,GAAG,CAAC,WAAW,CAAC;AAGhB,EAAAA,WAAU,MAAM;AACd,kBAAc;AAAA,MACZ,uBAAuB;AAAA,MACvB;AAAA,MACA,gBAAgB;AAAA,IAClB,CAAC;AAAA,EACH,GAAG,CAAC,uBAAuB,gBAAgB,aAAa,CAAC;AAIzD,QAAM,eAAeC,SAAQ,MAAM;AACjC,WAAO,KAAK,IAAI,GAAG,aAAa;AAAA,EAClC,GAAG,CAAC,aAAa,CAAC;AAGlB,EAAAD,WAAU,MAAM;AACd,QAAI,sBAAsB,GAAG;AAC3B,UAAI,kBAAkB,SAAS;AAC7B,qBAAa,kBAAkB,OAAO;AAAA,MACxC;AACA,wBAAkB,UAAU,WAAW,MAAM;AAC3C,+BAAuB,CAAC;AAAA,MAC1B,GAAG,GAAI;AAAA,IACT;AACA,WAAO,MAAM;AACX,UAAI,kBAAkB,SAAS;AAC7B,qBAAa,kBAAkB,OAAO;AAAA,MACxC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,mBAAmB,CAAC;AAGxB,QAAM,CAAC,0BAA0B,2BAA2B,IAAIF,UAAS,CAAC;AAG1E,QAAM,gCAAgCI;AAAA,IACpC,CAAC,UAKK;AACJ,+BAAyB,MAAM,SAAS;AAGxC,UAAI,MAAM,iBAAiB,QAAW;AACpC,oCAA4B,MAAM,YAAY;AAAA,MAChD;AAOA,UACE,OAAO,GAAG,wBACV,MAAM,cACN,CAAC,8BACD,MAAM,YAAY,GAClB;AACA,iCAAyB,CAAC,SAAS;AAEjC,cAAI,CAAC,MAAM;AACT,yCAA6B,CAAC;AAAA,UAChC;AACA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH,WAAW,CAAC,MAAM,YAAY;AAE5B,iCAAyB,KAAK;AAC9B,oCAA4B,CAAC;AAAA,MAC/B;AAAA,IACF;AAAA,IACA,CAAC,4BAA4B,OAAO,GAAG,oBAAoB;AAAA,EAC7D;AAGA,QAAM,oBAAoBA,aAAY,CAAC,aAAqB;AAC1D,aAAS,QAAQ;AAEjB,kCAA8B,KAAK;AAEnC,iCAA6B,CAAC;AAAA,EAChC,GAAG,CAAC,CAAC;AAKL;AAAA,IACE;AAAA,IACA,CAAC,UAAU;AACT,UAAI,CAAC,MAAM,QAAQ,yBAAyB,0BAA0B,GAAG;AACvE,eAAO;AAAA,MACT;AAEA,mCAA6B,CAAC,SAAU,OAAO,IAAI,OAAO,IAAI,wBAAwB,CAAE;AACxF,aAAO;AAAA,IACT;AAAA,IACA,EAAE,UAAU,GAAG;AAAA,EACjB;AAGA;AAAA,IACE;AAAA,IACA,CAAC,UAAU;AACT,UAAI,CAAC,MAAM,QAAQ,yBAAyB,0BAA0B,GAAG;AACvE,eAAO;AAAA,MACT;AAEA,mCAA6B,CAAC,SAAU,OAAO,wBAAwB,IAAI,OAAO,IAAI,CAAE;AACxF,aAAO;AAAA,IACT;AAAA,IACA,EAAE,UAAU,GAAG;AAAA,EACjB;AAGA;AAAA,IACE;AAAA,IACA,CAAC,UAAU;AACT,UAAI,CAAC,MAAM,QAAQ,yBAAyB,0BAA0B,GAAG;AACvE,eAAO;AAAA,MACT;AAEA,UAAI,mBAAmB,SAAS;AAC9B,2BAAmB,QAAQ;AAAA,MAC7B;AACA,mCAA6B,CAAC;AAC9B,aAAO;AAAA,IACT;AAAA,IACA,EAAE,UAAU,GAAG;AAAA,EACjB;AAGA;AAAA,IACE;AAAA,IACA,CAAC,UAAU;AACT,UAAI,MAAM,QAAQ,yBAAyB,wBAAwB,GAAG;AAEpE,YAAI,mBAAmB,SAAS;AAC9B,6BAAmB,QAAQ;AAAA,QAC7B;AACA,qCAA6B,CAAC;AAC9B,eAAO;AAAA,MACT;AAGA,+BAAyB,IAAI;AAC7B,oCAA8B,KAAK;AACnC,mCAA6B,CAAC;AAC9B,aAAO;AAAA,IACT;AAAA,IACA,EAAE,UAAU,EAAE;AAAA,EAChB;AAIA;AAAA,IACE;AAAA,IACA,CAAC,UAAU;AAET,UAAI,MAAM,QAAQ,uBAAuB;AACvC,iCAAyB,KAAK;AAC9B,sCAA8B,IAAI;AAClC,qCAA6B,CAAC;AAC9B,eAAO;AAAA,MACT;AAGA,YAAM,WAAW,sBAAsB;AACvC,6BAAuB,QAAQ;AAE/B,UAAI,MAAM,QAAQ,gBAAgB;AAChC,YAAI,aAAa,GAAG;AAAA,QAGpB,WAAW,YAAY,GAAG;AAExB,iBAAO;AAAA,QACT;AAAA,MACF,OAAO;AACL,YAAI,YAAY,GAAG;AAEjB,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA,IACA,EAAE,UAAU,GAAG;AAAA,EACjB;AAGA;AAAA,IACE;AAAA,IACA,CAAC,UAAU;AACT,UAAI,MAAM,QAAQ,uBAAuB;AACvC,eAAO;AAAA,MACT;AAEA,YAAM,QAA2C,CAAC,QAAQ,OAAO,SAAS;AAC1E,YAAM,eAAe,MAAM,QAAQ,IAAI;AACvC,YAAM,aAAa,eAAe,KAAK,MAAM;AAC7C,YAAM,WAAW,MAAM,SAAS;AAChC,UAAI,UAAU;AACZ,gBAAQ,QAAQ;AAChB,YAAI,cAAc;AAChB,uBAAa,QAAQ;AAAA,QACvB;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IACA,EAAE,UAAU,EAAE;AAAA,EAChB;AAIA,QAAM,eAAeA;AAAA,IACnB,CAAC,UAAmB;AAClB,YAAM,iBAAiB,UAAU,SAAY,QAAQ;AACrD,UAAI,eAAe,KAAK,GAAG;AACzB,oBAAY,cAAc;AAC1B,iBAAS,EAAE;AAAA,MACb;AAAA,IACF;AAAA,IACA,CAAC,OAAO,WAAW;AAAA,EACrB;AAGA,QAAM,iBAAiBD,SAAQ,MAAM,SAAI,OAAO,YAAY,GAAG,CAAC,YAAY,CAAC;AAG7E,QAAM,iBAAiBA;AAAA,IACrB,OAAO;AAAA,MACL,aAAa;AAAA,MACb,iBAAiB,OAAO,IAAI;AAAA,MAC5B,cAAc,OAAO,IAAI;AAAA,MACzB,cAAc,SAAS;AAAA,IACzB;AAAA,IACA,CAAC,MAAM,OAAO,IAAI,UAAU,OAAO,IAAI,OAAO,SAAS,MAAM;AAAA,EAC/D;AASA,QAAM,gBAAgB;AACtB,QAAM,kBAAkB;AAKxB,QAAM,uBAAuB;AAC7B,QAAM,2BAA2B,iBAAiB,gBAAgB;AAClE,QAAM,gCAAgC,KAAK;AAAA,IACzC;AAAA,IACA,2BAA2B;AAAA,EAC7B;AAGA,QAAM,kBAAkB,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,6BAA6B,CAAC;AAK/E,QAAM,yBAAyB;AAC/B,QAAM,8BAA8B,wBAChC,4BAA4B,kBAAkB,uBAAuB,yBACrE;AAEJ,QAAM,oBAAoB,KAAK;AAAA,IAC7B;AAAA,IACA,iBAAiB,gBAAgB;AAAA,EACnC;AAEA,SACE,gBAAAJ,OAACM,OAAA,EAAI,eAAc,UAAS,QAAQ,gBAElC;AAAA,oBAAAP;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,UAAU,OAAO,IAAI;AAAA,QACrB,OAAO,OAAO,IAAI;AAAA,QAClB;AAAA,QACA,OAAO,OAAO,GAAG;AAAA,QACjB;AAAA;AAAA,IACF;AAAA,IAEA,gBAAAA,MAACO,OAAA,EACC,0BAAAP,MAACQ,QAAA,EAAK,UAAQ,MAAE,0BAAe,GACjC;AAAA,IAGA,gBAAAR,MAACO,OAAA,EAAI,QAAQ,mBACX,0BAAAP;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,OAAO,OAAO,GAAG;AAAA,QACjB,oBAAoB,OAAO,GAAG;AAAA;AAAA,IAChC,GACF;AAAA,IAIA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP,UAAU;AAAA,QACV,UAAU;AAAA,QACV,OAAO,OAAO,GAAG;AAAA,QACjB;AAAA,QACA,SAAS;AAAA,QACT,sBAAsB;AAAA,QACtB,uBAAuB;AAAA,QACvB,2BAA2B;AAAA,QAC3B,mBAAmB;AAAA,QACnB,sBAAsB;AAAA,QACtB,YAAY;AAAA,QACZ,aAAa,OAAO;AAAA,QACpB,6BAA6B,OAAO,GAAG;AAAA;AAAA,IACzC;AAAA,IAEA,gBAAAA,MAACO,OAAA,EACC,0BAAAP,MAACQ,QAAA,EAAK,UAAQ,MAAE,0BAAe,GACjC;AAAA,IAEA,gBAAAR;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,OAAO,GAAG;AAAA,QACjB,WAAW,OAAO;AAAA,QAClB;AAAA,QACA,MAAM;AAAA,QACN;AAAA,QACA;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;;;AD5VS,gBAAAS,aAAA;AA5BT,SAAS,0BAA0B,OAA8C;AAC/E,QAAM,EAAE,OAAO,QAAQ,YAAY,mBAAmB,IAAI,SAAS;AAGnE,EAAAC,WAAU,MAAM;AACd,QAAI,oBAAoB;AACtB,iBAAW,IAAI;AACf,aAAO,MAAM,qCAAqC;AAAA,QAChD;AAAA,QACA,UAAU,QAAQ;AAAA,MACpB,CAAC;AAAA,IACH,OAAO;AACL,aAAO,KAAK,8CAA8C;AAAA,QACxD,UAAU,QAAQ;AAAA,QAClB,OAAO,QAAQ,MAAM;AAAA,MACvB,CAAC;AAAA,IACH;AAIA,WAAO,MAAM;AAAA,IAEb;AAAA,EACF,GAAG,CAAC,YAAY,kBAAkB,CAAC;AAGnC,mBAAiB,EAAE,UAAU,KAAK,CAAC;AAEnC,SAAO,gBAAAD,MAAC,iBAAe,GAAG,OAAO;AACnC;AAKO,SAAS,QAAQ,EAAE,IAAAE,KAAI,aAAa,GAAG,UAAU,GAA8B;AACpF,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC,gBAAgB,UAAU,OAAO;AAAA,MACjC,IAAIE;AAAA,MACJ;AAAA,MAEA,0BAAAF,MAAC,6BAA2B,GAAG,WAAW;AAAA;AAAA,EAC5C;AAEJ;;;AeWO,IAAM,uBAAN,MAA2B;AAAA,EACxB,WAAuC,oBAAI,IAAI;AAAA,EAC/C,UAA+B,oBAAI,IAAI;AAAA,EAE/C,SAAS,SAA8B;AACrC,SAAK,SAAS,IAAI,QAAQ,MAAM,OAAO;AAGvC,QAAI,QAAQ,SAAS;AACnB,cAAQ,QAAQ,QAAQ,CAAC,UAAU;AACjC,aAAK,QAAQ,IAAI,OAAO,QAAQ,IAAI;AAAA,MACtC,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,WAAW,aAA2B;AACpC,UAAM,UAAU,KAAK,SAAS,IAAI,WAAW;AAC7C,QAAI,SAAS,SAAS;AACpB,cAAQ,QAAQ,QAAQ,CAAC,UAAU,KAAK,QAAQ,OAAO,KAAK,CAAC;AAAA,IAC/D;AACA,SAAK,SAAS,OAAO,WAAW;AAAA,EAClC;AAAA,EAEA,IAAI,aAAgD;AAElD,UAAM,aAAa,KAAK,QAAQ,IAAI,WAAW,KAAK;AACpD,WAAO,KAAK,SAAS,IAAI,UAAU;AAAA,EACrC;AAAA,EAEA,SAA0B;AACxB,WAAO,MAAM,KAAK,KAAK,SAAS,OAAO,CAAC;AAAA,EAC1C;AAAA,EAEA,IAAI,aAA8B;AAChC,WAAO,KAAK,QAAQ,IAAI,WAAW,KAAK,KAAK,SAAS,IAAI,WAAW;AAAA,EACvE;AAAA,EAEA,MAAM,QACJ,aACA,MACA,SAC6B;AAC7B,UAAM,UAAU,KAAK,IAAI,WAAW;AAEpC,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,uBAAuB,WAAW;AAAA,MAC3C;AAAA,IACF;AAEA,QAAI;AAEF,UAAI,QAAQ,YAAY;AACtB,gBAAQ,WAAW,MAAM,IAAI;AAAA,MAC/B;AAEA,aAAO,MAAM,QAAQ,QAAQ,MAAM,OAAO;AAAA,IAC5C,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,OAAO,QAAiC;AACtC,UAAM,UAA2B,CAAC;AAClC,UAAM,cAAc,OAAO,YAAY;AAEvC,eAAW,WAAW,KAAK,SAAS,OAAO,GAAG;AAC5C,UAAI,QAAQ,KAAK,YAAY,EAAE,WAAW,WAAW,GAAG;AACtD,gBAAQ,KAAK,OAAO;AAAA,MACtB,WAAW,QAAQ,SAAS,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,WAAW,CAAC,GAAG;AAChF,gBAAQ,KAAK,OAAO;AAAA,MACtB;AAAA,IACF;AAGA,WAAO,QAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAAA,EAC5D;AACF;;;ACzJA,SAAS,KAAAG,UAAS;AAClB,OAAOC,WAAU;AACjB,OAAOC,WAAU;AACjB,OAAOC,SAAQ;AAQf,IAAM,sBAAsBC,GAAE,OAAO;AAAA,EACnC,MAAMA,GACH,OAAO,EACP,MAAM,qBAAqB,0DAA0D;AAAA,EACxF,aAAaA,GAAE,OAAO;AAAA,EACtB,OAAOA,GAAE,OAAO;AAAA,EAChB,SAASA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACtC,QAAQA,GAAE,OAAO;AACnB,CAAC;AAOD,IAAM,gBAAN,MAA6C;AAAA,EAC3C,YAAoB,YAAqC;AAArC;AAAA,EAAsC;AAAA,EAE1D,IAAI,OAAe;AACjB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,IAAI,cAAsB;AACxB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,IAAI,QAAgB;AAClB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,IAAI,UAAgC;AAClC,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,MAAM,QAAQ,MAAgB,SAA2D;AAEvF,QAAI,SAAS,KAAK,WAAW;AAG7B,SAAK,QAAQ,CAAC,KAAK,UAAU;AAC3B,YAAM,cAAc,IAAI,QAAQ,CAAC;AACjC,eAAS,OAAO,QAAQ,IAAI,OAAO,KAAK,WAAW,IAAI,GAAG,GAAG,GAAG;AAAA,IAClE,CAAC;AAGD,UAAM,UAAU,KAAK,KAAK,GAAG;AAC7B,aAAS,OAAO,QAAQ,gBAAgB,OAAO;AAG/C,QAAI,QAAQ,YAAY;AACtB,cAAQ,WAAW,MAAM;AACzB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AACF;AAKO,IAAM,sBAAN,MAA0B;AAAA,EAC/B,YAAoBC,KAAiB;AAAjB,cAAAA;AAAA,EAAkB;AAAA;AAAA;AAAA;AAAA,EAKtC,MAAM,QAAQ,aAAgD;AAC5D,UAAM,aAAa,oBAAI,IAA2B;AAGlD,UAAM,iBAAiB,MAAM,KAAK;AAAA,MAChCC,MAAK,KAAKC,IAAG,QAAQ,GAAG,UAAU,UAAU;AAAA,IAC9C;AACA,mBAAe,QAAQ,CAAC,QAAQ,WAAW,IAAI,IAAI,MAAM,GAAG,CAAC;AAG7D,QAAI,aAAa;AACf,YAAM,kBAAkB,MAAM,KAAK;AAAA,QACjCD,MAAK,KAAK,aAAa,UAAU,UAAU;AAAA,MAC7C;AACA,sBAAgB,QAAQ,CAAC,QAAQ;AAC/B,YAAI,WAAW,IAAI,IAAI,IAAI,GAAG;AAC5B,iBAAO,KAAK,oCAAoC,EAAE,MAAM,IAAI,KAAK,CAAC;AAAA,QACpE;AACA,mBAAW,IAAI,IAAI,MAAM,GAAG;AAAA,MAC9B,CAAC;AAAA,IACH;AAEA,WAAO,MAAM,KAAK,WAAW,OAAO,CAAC;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,kBAAkB,SAA2C;AACzE,UAAM,WAA4B,CAAC;AAEnC,QAAI;AACF,UAAI,CAAE,MAAM,KAAK,GAAG,OAAO,OAAO,GAAI;AACpC,eAAO;AAAA,MACT;AAEA,YAAM,QAAQ,MAAM,KAAK,GAAG,KAAK,SAAS,EAAE,KAAK,QAAQ,CAAC;AAE1D,iBAAW,QAAQ,OAAO;AACxB,cAAM,WAAWA,MAAK,KAAK,SAAS,IAAI;AACxC,cAAM,UAAU,MAAM,KAAK,YAAY,QAAQ;AAC/C,YAAI,SAAS;AACX,mBAAS,KAAK,OAAO;AAAA,QACvB;AAAA,MACF;AAEA,aAAO,KAAK,0BAA0B;AAAA,QACpC,WAAW;AAAA,QACX,OAAO,SAAS;AAAA,MAClB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,aAAO,KAAK,0CAA0C;AAAA,QACpD,WAAW;AAAA,QACX;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,YAAY,UAAiD;AACzE,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,GAAG,SAAS,QAAQ;AAC/C,YAAM,OAAOE,MAAK,MAAM,OAAO;AAC/B,YAAM,aAAa,oBAAoB,MAAM,IAAI;AAEjD,aAAO,IAAI,cAAc,UAAU;AAAA,IACrC,SAAS,OAAO;AACd,aAAO,KAAK,iCAAiC;AAAA,QAC3C,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,UAA+D;AAC5E,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,GAAG,SAAS,QAAQ;AAC/C,YAAM,OAAOA,MAAK,MAAM,OAAO;AAC/B,0BAAoB,MAAM,IAAI;AAC9B,aAAO,EAAE,OAAO,KAAK;AAAA,IACvB,SAAS,OAAO;AACd,aAAO;AAAA,QACL,OAAO;AAAA,QACP,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AACF;;;AC/IO,IAAM,gBAAN,MAAoB;AAAA,EACjB,cAAc;AAAA,EACd,iBAAwC;AAAA,EACxC,oBAA2C;AAAA,EAC3C,eAAe;AAAA,EACf,iBAAuC;AAAA,EAE9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,UAAgC,CAAC,GAAG;AAC9C,SAAK,qBAAqB,QAAQ,sBAAsB;AACxD,SAAK,mBAAmB,QAAQ,kBAAkB;AAClD,SAAK,qBAAqB,QAAQ,oBAAoB;AACtD,SAAK,YAAY,QAAQ;AAGzB,SAAK,sBAAsB,QAAQ,cAC/B,uBAAuB,QAAQ,YAAY,WAAW,EAAE,eAAe,KAAK,CAAC,IAC7E;AAAA,EACN;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAgB;AAEd,YAAQ,GAAG,UAAU,MAAM,KAAK,KAAK,aAAa,CAAC;AAGnD,YAAQ,GAAG,WAAW,MAAM,KAAK,KAAK,cAAc,CAAC;AAIrD,QAAI,QAAQ,aAAa,SAAS;AAChC,cAAQ,GAAG,YAAY,MAAM,KAAK,KAAK,aAAa,CAAC;AAAA,IACvD;AAEA,WAAO,MAAM,6BAA6B;AAAA,MACxC,UAAU,QAAQ;AAAA,MAClB,oBAAoB,KAAK;AAAA,MACzB,gBAAgB,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,eAA8B;AAC1C,SAAK;AAGL,QAAI,KAAK,mBAAmB;AAC1B,mBAAa,KAAK,iBAAiB;AAAA,IACrC;AACA,SAAK,oBAAoB,WAAW,MAAM;AACxC,WAAK,cAAc;AAAA,IACrB,GAAG,KAAK,kBAAkB;AAE1B,WAAO,MAAM,oBAAoB,KAAK,WAAW,IAAI,KAAK,kBAAkB,GAAG;AAG/E,QAAI,KAAK,eAAe,KAAK,oBAAoB;AAC/C,aAAO,KAAK,0BAA0B;AACtC,WAAK,cAAc;AACnB;AAAA,IACF;AAGA,QAAI,KAAK,gBAAgB,GAAG;AAC1B,YAAM,KAAK,aAAa,QAAQ;AAAA,IAClC,OAAO;AAEL,cAAQ;AAAA,QACN;AAAA,QAAW,KAAK,mBAAmB,IAAI,KAAK,qBAAqB,KAAK,WAAW;AAAA,MACnF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,gBAA+B;AAC3C,WAAO,MAAM,kBAAkB;AAC/B,UAAM,KAAK,aAAa,SAAS;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,aAAa,QAA+B;AACxD,QAAI,KAAK,cAAc;AACrB,aAAO,MAAM,6BAA6B;AAE1C,UAAI,KAAK,gBAAgB;AACvB,cAAM,KAAK;AAAA,MACb;AACA;AAAA,IACF;AAEA,SAAK,eAAe;AAEpB,WAAO,KAAK,gCAAgC,MAAM,GAAG;AAGrD,SAAK,iBAAiB,WAAW,MAAM;AACrC,aAAO,KAAK,wCAAwC;AACpD,WAAK,UAAU,CAAC;AAAA,IAClB,GAAG,KAAK,gBAAgB;AAGxB,SAAK,iBAAiB,KAAK,WAAW;AAEtC,QAAI;AACF,YAAM,KAAK;AACX,aAAO,KAAK,gCAAgC;AAC5C,WAAK,KAAK,CAAC;AAAA,IACb,SAAS,OAAO;AACd,aAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC;AAC9C,WAAK,KAAK,CAAC;AAAA,IACb,UAAE;AACA,UAAI,KAAK,gBAAgB;AACvB,qBAAa,KAAK,cAAc;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,aAA4B;AACxC,QAAI,CAAC,KAAK,WAAW;AACnB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,KAAK,UAAU;AAAA,IACvB,SAAS,OAAO;AACd,aAAO,MAAM,gCAAgC,EAAE,MAAM,CAAC;AACtD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAsB;AAC5B,YAAQ,MAAM,2CAA2C;AACzD,SAAK,UAAU,GAAG;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKQ,KAAK,MAAoB;AAE/B,YAAQ,OAAO,MAAM,aAAa;AAElC,YAAQ,KAAK,IAAI;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKQ,UAAU,MAAoB;AACpC,YAAQ,OAAO,MAAM,aAAa;AAClC,YAAQ,KAAK,IAAI;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAkB;AAChB,YAAQ,mBAAmB,QAAQ;AACnC,YAAQ,mBAAmB,SAAS;AAGpC,QAAI,QAAQ,aAAa,SAAS;AAChC,cAAQ,mBAAmB,UAAU;AAAA,IACvC;AAEA,QAAI,KAAK,mBAAmB;AAC1B,mBAAa,KAAK,iBAAiB;AAAA,IACrC;AACA,QAAI,KAAK,gBAAgB;AACvB,mBAAa,KAAK,cAAc;AAAA,IAClC;AAEA,WAAO,MAAM,yBAAyB;AAAA,EACxC;AACF;AAMO,SAAS,sBAAsB,UAAgC,CAAC,GAAkB;AACvF,QAAM,UAAU,IAAI,cAAc,OAAO;AACzC,UAAQ,QAAQ;AAChB,SAAO;AACT;;;AC9OO,IAAM,aAAN,MAA0C;AAAA,EAC/C,OAAO;AAAA,EACP,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,UAAU,CAAC,KAAK,OAAO;AAAA,EAEvB,MAAM,QAAQ,OAAiB,SAA2D;AACxF,QAAI,QAAQ,gBAAgB;AAC1B,cAAQ,eAAe;AACvB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AACF;;;AC1BA,SAAS,KAAAC,UAAS;AAQX,IAAM,eAAN,MAA4C;AAAA,EACjD,OAAO;AAAA,EACP,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,UAAU,CAAC,YAAY,GAAG;AAAA,EAE1B,aAAiC;AAAA,IAC/B;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,MACV,aAAa,CAAC,YAAY,aAAa,UAAU,UAAU,UAAU,QAAQ,QAAQ;AAAA,IACvF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EAEA,aAAaA,GAAE,MAAM;AAAA,IACnBA,GAAE,KAAK,CAAC,YAAY,aAAa,UAAU,UAAU,UAAU,QAAQ,QAAQ,CAAC;AAAA,IAChFA,GAAE,OAAO,EAAE,SAAS;AAAA,EACtB,CAAC;AAAA,EAED,wBACE,YACA,SACA,aACU;AACV,QAAI,eAAe,GAAG;AACpB,aAAO,CAAC,YAAY,aAAa,UAAU,UAAU,UAAU,QAAQ,QAAQ;AAAA,IACjF;AAIA,QAAI,eAAe,GAAG;AACpB,YAAM,WAAW,cAAc,CAAC,GAAG,YAAY,KAAK,QAAQ,gBAAgB,YAAY;AACxF,cAAQ,UAAU;AAAA,QAChB,KAAK;AACH,iBAAO,CAAC,iBAAiB,mBAAmB;AAAA,QAC9C,KAAK;AACH,iBAAO,CAAC,8BAA8B,4BAA4B,kBAAkB;AAAA,QACtF,KAAK;AACH,iBAAO,CAAC,SAAS,eAAe,eAAe;AAAA,QACjD,KAAK;AAAA,QACL,KAAK;AACH,iBAAO,CAAC,cAAc,cAAc;AAAA,QACtC;AACE,iBAAO,CAAC;AAAA,MACZ;AAAA,IACF;AAEA,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,MAAM,QAAQ,MAAgB,SAA2D;AACvF,QAAI,KAAK,WAAW,GAAG;AACrB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,WAAW,KAAK,CAAC;AACvB,UAAM,QAAQ,KAAK,CAAC,KAAK;AAEzB,QAAI,QAAQ,sBAAsB,UAAU;AAC1C,WAAK,QAAQ,mBAAmB,UAAU,KAAK;AAC/C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,MAAM,EAAE,UAAU,MAAM;AAAA,MAC1B;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AACF;;;ACzFA,SAAS,KAAAC,UAAS;AAQX,IAAM,cAAN,MAA2C;AAAA,EAChD,OAAO;AAAA,EACP,cAAc;AAAA,EACd,QAAQ;AAAA,EAER,aAAiC;AAAA,IAC/B;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,MACV,aAAa,CAAC,QAAQ,OAAO,SAAS;AAAA,IACxC;AAAA,EACF;AAAA,EAEA,aAAaA,GAAE,MAAM,CAACA,GAAE,KAAK,CAAC,QAAQ,OAAO,SAAS,CAAC,CAAC,CAAC;AAAA,EAEzD,wBACE,YACA,UACA,cACU;AACV,QAAI,eAAe,GAAG;AACpB,aAAO,CAAC,QAAQ,OAAO,SAAS;AAAA,IAClC;AACA,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,MAAM,QAAQ,MAAgB,SAA2D;AACvF,QAAI,KAAK,WAAW,GAAG;AACrB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,CAAC;AAEnB,QAAI,QAAQ,mBAAmB;AAC7B,cAAQ,kBAAkB,IAAI;AAC9B,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,MAAM,EAAE,KAAK;AAAA,MACf;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AACF;;;ACpDO,IAAM,cAAN,MAA2C;AAAA,EAMhD,YAAoB,UAAgC;AAAhC;AAAA,EAAiC;AAAA,EALrD,OAAO;AAAA,EACP,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,UAAU,CAAC,KAAK,GAAG;AAAA,EAInB,MAAM,QAAQ,MAAgB,SAA2D;AAEvF,QAAI,KAAK,SAAS,GAAG;AACnB,YAAM,cAAc,KAAK,CAAC;AAC1B,UAAI,CAAC,aAAa;AAChB,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO;AAAA,QACT;AAAA,MACF;AACA,YAAM,UAAU,KAAK,SAAS,IAAI,WAAW;AAE7C,UAAI,CAAC,SAAS;AACZ,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO,uBAAuB,WAAW;AAAA,QAC3C;AAAA,MACF;AAEA,YAAMC,YAAW;AAAA,QACf,aAAa,QAAQ,IAAI;AAAA,QACzB,gBAAgB,QAAQ,WAAW;AAAA,QACnC,UAAU,QAAQ,KAAK;AAAA,QACvB,QAAQ,SAAS,SAAS,YAAY,QAAQ,QAAQ,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC,KAAK;AAAA,MAC3F,EACG,OAAO,OAAO,EACd,KAAK,IAAI;AAEZ,UAAI,QAAQ,YAAY;AACtB,gBAAQ,WAAWA,SAAQ;AAAA,MAC7B;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,MAAM,EAAE,UAAAA,UAAS;AAAA,MACnB;AAAA,IACF;AAGA,UAAM,cAAc,KAAK,SAAS,OAAO;AACzC,UAAM,WAAW;AAAA,MACf;AAAA,MACA;AAAA,MACA,GAAG,YAAY,IAAI,CAAC,QAAQ,MAAM,IAAI,KAAK,OAAO,EAAE,CAAC,MAAM,IAAI,WAAW,EAAE;AAAA,MAC5E;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAEX,QAAI,QAAQ,YAAY;AACtB,cAAQ,WAAW,QAAQ;AAAA,IAC7B;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,MAAM,EAAE,SAAS;AAAA,IACnB;AAAA,EACF;AACF;;;AChEO,IAAM,eAAN,MAA4C;AAAA,EACjD,OAAO;AAAA,EACP,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,UAAU,CAAC,GAAG;AAAA,EAEd,aAAiC;AAAA,IAC/B;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,MACV,aAAa,aAAa;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,wBACE,YACA,UACA,cACU;AACV,QAAI,eAAe,GAAG;AACpB,aAAO,aAAa;AAAA,IACtB;AACA,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,MAAM,QAAQ,MAAgB,SAA2D;AAEvF,QAAI,KAAK,WAAW,GAAG;AACrB,YAAMC,UAAS,aAAa;AAC5B,YAAM,YAAYA,QACf,IAAI,CAAC,GAAG,MAAM;AACb,cAAM,OAAO,iBAAiB,CAAC;AAC/B,eAAO,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,IAAI;AAAA,MACxC,CAAC,EACA,KAAK,IAAI;AAEZ,YAAM,UAAU;AAAA,EAAsB,SAAS;AAAA;AAAA;AAE/C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,IACF;AAGA,UAAM,YAAY,KAAK,CAAC,GAAG,YAAY;AACvC,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAMA,UAAS,aAAa;AAU5B,QAAI,CAACA,QAAO,SAAS,SAAsB,GAAG;AAC5C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,UAAU,SAAS,2BAA2BA,QAAO,KAAK,IAAI,CAAC;AAAA,MACxE;AAAA,IACF;AAGA,QAAI,QAAQ,oBAAoB;AAC9B,YAAM,QAAQ,mBAAmB,SAAsB;AACvD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,QAAQ,qBAAqB,SAAS;AAAA,MACxC;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AACF;;;AC/FA,OAAO,eAA8C;;;ACI9C,IAAM,iBAA+B;AAAA;AAAA,EAE1C;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA;AAAA,EAGA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA;AAAA,EAGA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA;AAAA,EAGA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA;AAAA,EAGA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA;AAAA,EAGA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,OAAO;AAAA,EACT;AACF;;;ADrIA,SAAS,SAAS,YAAY;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,cAAc,kBAAkB;AAoBzC,SAAS,iBAA8B;AACrC,QAAM,eAAe;AAKrB,QAAM,iBAAiB,QAAQ,KAAK,CAAC,KAAK,QAAQ;AAClD,QAAM,YAAY,QAAQ,cAAc;AAIxC,QAAM,iBAAiB;AAAA;AAAA,IAErB,KAAK,WAAW,aAAa,YAAY;AAAA;AAAA,IAEzC,KAAK,QAAQ,IAAI,GAAG,aAAa,YAAY;AAAA;AAAA,IAE7C,KAAK,WAAW,MAAM,aAAa,YAAY;AAAA,EACjD;AAEA,aAAW,gBAAgB,gBAAgB;AACzC,QAAI,WAAW,YAAY,GAAG;AAC5B,YAAM,SAAS,aAAa,YAAY;AAExC,aAAO,OAAO,OAAO,MAAM,OAAO,YAAY,OAAO,aAAa,OAAO,UAAU;AAAA,IACrF;AAAA,EACF;AAGA,QAAM,aAAa,QAAQ,cAAc,YAAY,GAAG,CAAC;AACzD,QAAM,mBAAmB;AAAA,IACvB,KAAK,YAAY,MAAM,MAAM,gBAAgB,UAAU,QAAQ,YAAY;AAAA,IAC3E,KAAK,QAAQ,IAAI,GAAG,gBAAgB,UAAU,QAAQ,YAAY;AAAA,EACpE;AAEA,aAAW,cAAc,kBAAkB;AACzC,QAAI,WAAW,UAAU,GAAG;AAC1B,YAAM,SAAS,aAAa,UAAU;AAEtC,aAAO,OAAO,OAAO,MAAM,OAAO,YAAY,OAAO,aAAa,OAAO,UAAU;AAAA,IACrF;AAAA,EACF;AAGA,QAAM,cAAc;AAAA,IAClB,oBAAoB,QAAQ,KAAK,CAAC,CAAC;AAAA,IACnC,qBAAqB,QAAQ,QAAQ;AAAA,IACrC,mBAAmB,cAAc;AAAA,IACjC,cAAc,SAAS;AAAA,IACvB,eAAe,UAAU;AAAA,IACzB,kBAAkB,QAAQ,IAAI,CAAC;AAAA,EACjC;AAEA,QAAM,IAAI;AAAA,IACR,oBAAoB,YAAY;AAAA;AAAA;AAAA,EAAsB,YAAY,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,IAC1E,CAAC,GAAG,gBAAgB,GAAG,gBAAgB,EAAE,IAAI,CAAC,MAAM,OAAO,CAAC,EAAE,EAAE,KAAK,IAAI;AAAA,EAC7E;AACF;AAKO,IAAM,kBAAN,MAAM,iBAAgB;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAqC;AAAA,EAErC,YAAY,QAAwB,KAAU;AACpD,SAAK,SAAS;AACd,SAAK,MAAM;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,OAAO,QAAkD;AAEpE,UAAM,QAAQ,QAAQ,OAAO,IAAI;AAEjC,QAAI,OAAO,YAAY;AACrB,YAAM,YAAY,MAAM,OAAO,WAAW,OAAO,KAAK;AACtD,UAAI,CAAC,WAAW;AACd,cAAM,OAAO,WAAW,MAAM,OAAO,EAAE,WAAW,KAAK,CAAC;AAAA,MAC1D;AAAA,IACF,OAAO;AACL,YAAM,EAAE,YAAAC,aAAY,UAAU,IAAI,MAAM,OAAO,IAAI;AACnD,UAAI,CAACA,YAAW,KAAK,GAAG;AACtB,kBAAU,OAAO,EAAE,WAAW,KAAK,CAAC;AAAA,MACtC;AAAA,IACF;AAGA,UAAM,aAAa,eAAe;AAClC,UAAM,MAAM,MAAM,UAAU;AAAA,MAC1B;AAAA,IACF,CAAC;AACD,UAAM,UAAU,IAAI,iBAAgB,QAAQ,GAAG;AAG/C,YAAQ,SAAS,MAAM,OAAO,IAAI;AAGlC,UAAM,QAAQ,aAAa;AAG3B,YAAQ,WAAW;AAGnB,UAAM,QAAQ,KAAK;AAEnB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAA8B;AAC1C,QAAI;AACF,UAAI,KAAK,OAAO,YAAY;AAC1B,cAAM,SAAS,MAAM,KAAK,OAAO,WAAW,OAAO,KAAK,OAAO,IAAI;AACnE,YAAI,QAAQ;AACV,gBAAM,SAAS,MAAM,KAAK,OAAO,WAAW;AAAA,YAC1C,KAAK,OAAO;AAAA,YACZ;AAAA,UACF;AACA,gBAAM,aAAa,IAAI,WAAW,OAAO,KAAK,QAAe,QAAQ,CAAC;AACtE,eAAK,KAAK,IAAI,KAAK,IAAI,SAAS,UAAU;AAC1C,cAAI,KAAK,OAAO,SAAS;AACvB,oBAAQ,IAAI,iCAAiC,KAAK,OAAO,IAAI;AAAA,UAC/D;AAAA,QACF,OAAO;AACL,eAAK,KAAK,IAAI,KAAK,IAAI,SAAS;AAChC,cAAI,KAAK,OAAO,SAAS;AACvB,oBAAQ,IAAI,sBAAsB;AAAA,UACpC;AAAA,QACF;AAAA,MACF,OAAO;AACL,cAAM,EAAE,YAAAA,aAAY,cAAAC,cAAa,IAAI,MAAM,OAAO,IAAI;AACtD,YAAID,YAAW,KAAK,OAAO,IAAI,GAAG;AAChC,gBAAM,SAASC,cAAa,KAAK,OAAO,IAAI;AAC5C,eAAK,KAAK,IAAI,KAAK,IAAI,SAAS,MAAM;AAAA,QACxC,OAAO;AACL,eAAK,KAAK,IAAI,KAAK,IAAI,SAAS;AAAA,QAClC;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,WAAK,KAAK,IAAI,KAAK,IAAI,SAAS;AAChC,UAAI,KAAK,OAAO,SAAS;AACvB,gBAAQ,IAAI,qCAAqC,KAAK;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAsB;AAC1B,UAAM,OAAO,KAAK,GAAG,OAAO;AAC5B,UAAM,SAAS,OAAO,KAAK,IAAI;AAE/B,QAAI,KAAK,OAAO,YAAY;AAC1B,YAAM,KAAK,OAAO,WAAW;AAAA,QAC3B,KAAK,OAAO;AAAA,QACZ,OAAO,SAAS,QAAQ;AAAA,QACxB;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM,EAAE,cAAc,IAAI,MAAM,OAAO,IAAI;AAC3C,oBAAc,KAAK,OAAO,MAAM,MAAM;AAAA,IACxC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,WAAiB;AACvB,UAAM,OAAO,KAAK,GAAG,OAAO;AAC5B,UAAM,SAAS,OAAO,KAAK,IAAI;AAG/B,QAAI,KAAK,QAAQ;AACf,WAAK,OAAO,cAAc,KAAK,OAAO,MAAM,MAAM;AAAA,IACpD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAmB;AACzB,QAAI;AACF,WAAK,qBAAqB;AAC1B,WAAK,aAAa;AAAA,IACpB,SAAS,OAAO;AACd,cAAQ,MAAM,mCAAmC,KAAK;AACtD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAA6B;AACnC,UAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmKxB,UAAM,aAAa,gBAAgB,MAAM,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC;AACpE,eAAW,aAAa,YAAY;AAClC,UAAI;AACF,aAAK,GAAG,IAAI,SAAS;AAAA,MACvB,SAAS,OAAO;AACd,YAAI,KAAK,OAAO,SAAS;AACvB,kBAAQ,IAAI,2BAA2B,KAAK;AAAA,QAC9C;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAK,OAAO,SAAS;AACvB,cAAQ,IAAI,sCAAsC;AAAA,IACpD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAqB;AAC3B,UAAM,eAAe,KAAK,GAAG;AAAA,MAC3B;AAAA,IACF;AAEA,QAAI,aAAa,WAAW,KAAK,aAAa,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG;AACtE,WAAK,qBAAqB;AAAA,IAC5B;AAEA,UAAM,kBAAkB,KAAK,GAAG,KAAK,uCAAuC;AAC5E,UAAM,QAAQ,gBAAgB,SAAS,IAAI,gBAAgB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI;AAEhF,QAAI,UAAU,GAAG;AACf,iBAAW,SAAS,gBAAgB;AAClC,cAAM,OAAO,KAAK,GAAG;AAAA,UACnB;AAAA;AAAA,QAEF;AAEA,cAAM,gBAAgB,MAAM,gBACxB,OAAO,MAAM,kBAAkB,WAC7B,MAAM,gBACN,KAAK,MAAM,MAAM,cAAc,QAAQ,IAAI,GAAI,IACjD,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAEhC,aAAK,IAAI;AAAA,UACP,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN;AAAA,UACA,MAAM,YAAY;AAAA,QACpB,CAAC;AACD,aAAK,KAAK;AAAA,MACZ;AAEA,UAAI,KAAK,OAAO,SAAS;AACvB,gBAAQ,IAAI,UAAU,eAAe,MAAM,kBAAkB;AAAA,MAC/D;AAAA,IACF;AAEA,QAAI;AACF,YAAM,kBAAkB,KAAK,GAAG;AAAA,QAC9B;AAAA,MACF;AACA,YAAM,WAAW,gBAAgB,SAAS,IAAI,gBAAgB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI;AAEnF,UAAI,aAAa,GAAG;AAClB,aAAK,GAAG,IAAI,mDAAmD;AAAA,MACjE;AAAA,IACF,SAAS,OAAO;AAAA,IAEhB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,KAAa,QAA+B;AAClD,UAAM,OAAO,KAAK,GAAG,QAAQ,GAAG;AAChC,SAAK,KAAM,UAAU,CAAC,CAA6C;AACnE,SAAK,KAAK;AACV,UAAM,OAAO,KAAK,GAAG,gBAAgB;AACrC,SAAK,KAAK;AAGV,UAAM,UAAU,gDAAgD,KAAK,GAAG;AACxE,QAAI,WAAW,OAAO,GAAG;AAEvB,WAAK,SAAS;AAAA,IAChB;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,iBAAiB;AAAA;AAAA,IACnB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAmB,KAAa,QAAyB;AACvD,UAAM,OAAO,KAAK,GAAG,QAAQ,GAAG;AAChC,SAAK,KAAM,UAAU,CAAC,CAA6C;AACnE,UAAM,UAAe,CAAC;AAEtB,WAAO,KAAK,KAAK,GAAG;AAClB,YAAM,MAAM,KAAK,YAAY;AAC7B,cAAQ,KAAK,GAAQ;AAAA,IACvB;AACA,SAAK,KAAK;AACV,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,SAAY,KAAa,QAA8B;AACrD,QAAI;AACF,YAAM,OAAO,KAAK,GAAG,QAAQ,GAAG;AAChC,WAAK,KAAM,UAAU,CAAC,CAA6C;AACnE,UAAI,KAAK,KAAK,GAAG;AACf,cAAM,MAAM,KAAK,YAAY;AAC7B,aAAK,KAAK;AACV,eAAO;AAAA,MACT;AACA,WAAK,KAAK;AACV,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM,iBAAiB,KAAK;AACpC,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAe,IAAmC;AAChD,SAAK,GAAG,IAAI,mBAAmB;AAC/B,QAAI;AACF,YAAM,SAAS,GAAG,IAAI;AACtB,WAAK,GAAG,IAAI,QAAQ;AAEpB,WAAK,SAAS;AACd,aAAO;AAAA,IACT,SAAS,OAAO;AACd,WAAK,GAAG,IAAI,UAAU;AACtB,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,GAAG,MAAM;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,SAAe;AACb,SAAK,GAAG,IAAI,QAAQ;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,WAKE;AACA,UAAM,YAAY,KAAK,SAAiC,mBAAmB;AAC3E,UAAM,WAAW,KAAK,SAAgC,kBAAkB;AAExE,WAAO;AAAA,MACL,WAAW,WAAW,cAAc;AAAA,MACpC,UAAU,UAAU,aAAa;AAAA,MACjC,YAAY,WAAW,cAAc,MAAM,UAAU,aAAa;AAAA,MAClE,SAAS;AAAA;AAAA,IACX;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAgC;AACpC,QAAI;AACF,YAAM,SAAS,KAAK,SAAsC,wBAAwB;AAClF,aAAO,QAAQ,oBAAoB;AAAA,IACrC,SAAS,OAAO;AACd,cAAQ,MAAM,wBAAwB,KAAK;AAC3C,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAGA,IAAI,aAAqC;AAKzC,eAAsB,wBAAwB,QAAmD;AAC/F,MAAI,CAAC,cAAc,QAAQ;AACzB,iBAAa,MAAM,gBAAgB,OAAO,MAAM;AAAA,EAClD;AACA,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AACA,SAAO;AACT;AAKO,SAAS,uBAA6B;AAC3C,MAAI,YAAY;AACd,eAAW,MAAM;AACjB,iBAAa;AAAA,EACf;AACF;;;AEjmBA,OAAOC,SAAQ,WAAAC,gBAAe;AAUvB,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YACUC,KACAC,eACR;AAFQ,cAAAD;AACA,wBAAAC;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA,EAMH,MAAM,oBAAoB,eAAsD;AAC9E,UAAM,SAA+B;AAAA,MACnC,SAAS;AAAA,MACT,SAAS,CAAC;AAAA,MACV,QAAQ,CAAC;AAAA,MACT,eAAe;AAAA,MACf,eAAe;AAAA,IACjB;AAEA,QAAI;AACF,YAAM,WAAWH,MAAK,KAAK,eAAe,QAAQ;AAGlD,UAAI,CAAE,MAAM,KAAK,GAAG,OAAO,QAAQ,GAAI;AACrC,cAAM,KAAK,GAAG,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AACjD,eAAO,QAAQ,KAAK,SAAS;AAC7B,eAAO,KAAK,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAAA,MAC5D;AAGA,YAAM,UAAU;AAAA,QACd,EAAE,MAAM,QAAQ,SAAS,mBAAmB;AAAA,QAC5C,EAAE,MAAM,YAAY,SAAS,wBAAwB;AAAA,QACrD,EAAE,MAAM,eAAe,SAAS,2BAA2B;AAAA,QAC3D,EAAE,MAAM,UAAU,SAAS,uBAAuB;AAAA,MACpD;AAEA,iBAAW,EAAE,MAAM,QAAQ,KAAK,SAAS;AACvC,cAAM,SAASA,MAAK,KAAK,UAAU,IAAI;AACvC,YAAI,CAAE,MAAM,KAAK,GAAG,OAAO,MAAM,GAAI;AACnC,gBAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,WAAW,KAAK,CAAC;AAC/C,iBAAO,QAAQ,KAAK,UAAU,IAAI,GAAG;AACrC,iBAAO,KAAK,WAAW,IAAI,cAAc,EAAE,MAAM,QAAQ,QAAQ,CAAC;AAAA,QACpE;AAAA,MACF;AAGA,YAAM,KAAK,qBAAqB,UAAU,MAAM;AAGhD,YAAM,KAAK,kBAAkB,UAAU,MAAM;AAG7C,YAAM,KAAK,oBAAoB,UAAU,MAAM;AAG/C,YAAM,KAAK,mBAAmB,UAAU,MAAM;AAG9C,YAAM,KAAK,qBAAqB,UAAU,MAAM;AAGhD,YAAM,KAAK,aAAa,UAAU,MAAM;AAAA,IAC1C,SAAS,OAAO;AACd,aAAO,UAAU;AACjB,aAAO,OAAO;AAAA,QACZ,0BAA0B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAClF;AACA,aAAO,MAAM,mCAAmC,EAAE,MAAM,CAAC;AAAA,IAC3D;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,uBAAuB,eAAyC;AACpE,UAAM,WAAWA,MAAK,KAAK,eAAe,QAAQ;AAClD,UAAM,SAASA,MAAK,KAAK,UAAU,UAAU;AAG7C,WAAQ,MAAM,KAAK,GAAG,OAAO,QAAQ,KAAO,MAAM,KAAK,GAAG,OAAO,MAAM;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,qBACZ,UACA,QACe;AACf,UAAM,gBAAgBA,MAAK,KAAK,UAAU,YAAY;AAEtD,QAAI,MAAM,KAAK,GAAG,OAAO,aAAa,GAAG;AACvC;AAAA,IACF;AAEA,UAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BzB,QAAI;AACF,YAAM,KAAK,GAAG,UAAU,eAAe,gBAAgB;AACvD,aAAO,QAAQ,KAAK,mBAAmB;AACvC,aAAO,KAAK,2BAA2B;AAAA,IACzC,SAAS,OAAO;AACd,aAAO,OAAO;AAAA,QACZ,gCAAgC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACxF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,kBAAkB,UAAkB,QAA6C;AAC7F,UAAM,YAAYA,MAAK,KAAK,UAAU,QAAQ;AAG9C,UAAM,gBAAgB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI;AAIF,YAAM,iBAAiB,QAAQ,KAAK,CAAC,KAAK,QAAQ;AAClD,YAAM,YAAYC,SAAQ,cAAc;AAGxC,YAAM,qBAAqB;AAAA,QACzBD,MAAK,KAAK,WAAW,aAAa,QAAQ;AAAA;AAAA,QAC1CA,MAAK,KAAK,WAAW,eAAe;AAAA;AAAA,QACpCA,MAAK,KAAK,WAAW,sBAAsB;AAAA;AAAA,MAC7C;AAEA,iBAAW,aAAa,eAAe;AACrC,cAAM,WAAWA,MAAK,KAAK,WAAW,SAAS;AAG/C,YAAI,MAAM,KAAK,GAAG,OAAO,QAAQ,GAAG;AAClC;AAAA,QACF;AAGA,YAAI,SAAS;AACb,mBAAW,aAAa,oBAAoB;AAC1C,cAAI;AACF,kBAAM,aAAaA,MAAK,KAAK,WAAW,SAAS;AACjD,kBAAM,eAAe,MAAM,KAAK,GAAG,SAAS,YAAY,OAAO;AAG/D,kBAAM,KAAK,GAAG,UAAU,UAAU,YAAY;AAC9C,mBAAO,QAAQ,KAAK,iBAAiB,SAAS,EAAE;AAChD,mBAAO,KAAK,wBAAwB,EAAE,OAAO,WAAW,MAAM,UAAU,CAAC;AACzE,qBAAS;AACT;AAAA,UACF,SAAS,OAAO;AAEd;AAAA,UACF;AAAA,QACF;AAEA,YAAI,CAAC,QAAQ;AACX,iBAAO,KAAK,wBAAwB,SAAS,gCAAgC;AAAA,YAC3E,gBAAgB;AAAA,UAClB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO,OAAO;AAAA,QACZ,kCAAkC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAC1F;AACA,aAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC;AAAA,IACjD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,oBAAoB,UAAkB,QAA6C;AAC/F,UAAM,cAAcA,MAAK,KAAK,UAAU,UAAU;AAGlD,UAAM,kBAAkB,CAAC,iBAAiB;AAE1C,QAAI;AAIF,YAAM,iBAAiB,QAAQ,KAAK,CAAC,KAAK,QAAQ;AAClD,YAAM,YAAYC,SAAQ,cAAc;AAGxC,YAAM,qBAAqB;AAAA,QACzBD,MAAK,KAAK,WAAW,aAAa,UAAU;AAAA;AAAA,QAC5CA,MAAK,KAAK,WAAW,kCAAkC;AAAA;AAAA,QACvDA,MAAK,KAAK,WAAW,qCAAqC;AAAA;AAAA,MAC5D;AAEA,iBAAW,eAAe,iBAAiB;AACzC,cAAM,WAAWA,MAAK,KAAK,aAAa,WAAW;AAGnD,YAAI,MAAM,KAAK,GAAG,OAAO,QAAQ,GAAG;AAClC;AAAA,QACF;AAGA,YAAI,SAAS;AACb,mBAAW,aAAa,oBAAoB;AAC1C,cAAI;AACF,kBAAM,aAAaA,MAAK,KAAK,WAAW,WAAW;AACnD,kBAAM,iBAAiB,MAAM,KAAK,GAAG,SAAS,YAAY,OAAO;AAGjE,kBAAM,KAAK,GAAG,UAAU,UAAU,cAAc;AAChD,mBAAO,QAAQ,KAAK,mBAAmB,WAAW,EAAE;AACpD,mBAAO,KAAK,0BAA0B,EAAE,SAAS,aAAa,MAAM,UAAU,CAAC;AAC/E,qBAAS;AACT;AAAA,UACF,SAAS,OAAO;AAEd;AAAA,UACF;AAAA,QACF;AAEA,YAAI,CAAC,QAAQ;AACX,iBAAO,KAAK,0BAA0B,WAAW,gBAAgB;AAAA,YAC/D,gBAAgB;AAAA,UAClB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO,OAAO;AAAA,QACZ,oCAAoC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAC5F;AACA,aAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC;AAAA,IACnD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,mBAAmB,UAAkB,QAA6C;AAC9F,UAAM,SAASA,MAAK,KAAK,UAAU,UAAU;AAG7C,QAAI,MAAM,KAAK,GAAG,OAAO,MAAM,GAAG;AAChC,aAAO,KAAK,oDAAoD,EAAE,MAAM,OAAO,CAAC;AAChF;AAAA,IACF;AAEA,QAAI;AAGF,YAAM,KAAK,MAAM,wBAAwB;AAAA,QACvC,MAAM;AAAA,QACN,SAAS;AAAA,QACT,YAAY,KAAK;AAAA,MACnB,CAAC;AAID,SAAG,QAAQ,UAAU;AAGrB,2BAAqB;AAGrB,UAAI,MAAM,KAAK,GAAG,OAAO,MAAM,GAAG;AAChC,eAAO,QAAQ,KAAK,iBAAiB;AACrC,eAAO,gBAAgB;AACvB,eAAO,KAAK,wBAAwB,EAAE,MAAM,OAAO,CAAC;AAAA,MACtD,OAAO;AACL,eAAO,OAAO,KAAK,uCAAuC;AAAA,MAC5D;AAAA,IACF,SAAS,OAAO;AACd,aAAO,OAAO;AAAA,QACZ,mCAAmC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAC3F;AACA,aAAO,MAAM,iCAAiC,EAAE,MAAM,CAAC;AAAA,IACzD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,KAAuB;AAC7C,QAAI,CAAC,OAAO,IAAI,WAAW,EAAG,QAAO;AACrC,QAAI,IAAI,WAAW,GAAG;AAEpB,YAAM,MAAM,IAAI,CAAC;AACjB,UAAI,CAAC,IAAK,QAAO;AACjB,UAAI,cAAc,KAAK,GAAG,KAAK,QAAQ,OAAO,QAAQ,KAAK;AACzD,eAAO,IAAI,GAAG;AAAA,MAChB;AACA,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,IAAI,IAAI,CAAC,SAAS;AAC/B,UAAI,cAAc,KAAK,IAAI,KAAK,SAAS,OAAO,SAAS,KAAK;AAC5D,eAAO,IAAI,IAAI;AAAA,MACjB;AACA,aAAO;AAAA,IACT,CAAC;AACD,WAAO,IAAI,OAAO,KAAK,IAAI,CAAC;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,qBACZ,UACA,QACe;AACf,UAAM,aAAaA,MAAK,KAAK,UAAU,YAAY;AAEnD,QAAI,MAAM,KAAK,GAAG,OAAO,UAAU,GAAG;AACpC;AAAA,IACF;AAEA,QAAI;AAEF,YAAM,EAAE,QAAQ,SAAS,IAAI,MAAM,KAAK,aAAa,KAAK;AAG1D,YAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAMd,SAAS,IAAI,QAAQ;AAAA,WACxB,SAAS,IAAI,KAAK;AAAA;AAAA;AAAA,iBAGZ,SAAS,IAAI,WAAW;AAAA,eAC1B,SAAS,IAAI,SAAS;AAAA;AAAA;AAAA;AAAA,gBAIrB,SAAS,YAAY,UAAU;AAAA,qBAC1B,SAAS,YAAY,eAAe;AAAA,0BAC/B,KAAK,gBAAgB,SAAS,YAAY,oBAAoB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAU1E,KAAK,gBAAgB,SAAS,YAAY,SAAS,CAAC;AAAA,YACvD,KAAK,gBAAgB,SAAS,YAAY,MAAM,CAAC;AAAA,gBAC7C,KAAK,gBAAgB,SAAS,YAAY,UAAU,CAAC;AAAA,iBACpD,KAAK,gBAAgB,SAAS,YAAY,WAAW,CAAC;AAAA,iBACtD,KAAK,gBAAgB,SAAS,YAAY,WAAW,CAAC;AAAA,gBACvD,KAAK,gBAAgB,SAAS,YAAY,UAAU,CAAC;AAAA,kBACnD,KAAK,gBAAgB,SAAS,YAAY,YAAY,CAAC;AAAA,UAC/D,KAAK,gBAAgB,SAAS,YAAY,IAAI,CAAC;AAAA,iBACxC,KAAK,gBAAgB,SAAS,YAAY,WAAW,CAAC;AAAA,UAC7D,KAAK,gBAAgB,SAAS,YAAY,IAAI,CAAC;AAAA,UAC/C,KAAK,gBAAgB,SAAS,YAAY,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,aAI5C,SAAS,OAAO,OAAO;AAAA,eACrB,SAAS,OAAO,SAAS;AAAA;AAAA;AAAA;AAAA,WAI7B,SAAS,GAAG,KAAK;AAAA,wBACJ,SAAS,GAAG,kBAAkB;AAAA,qBACjC,SAAS,GAAG,eAAe;AAAA,iBAC/B,SAAS,GAAG,WAAW;AAAA,0BACd,SAAS,GAAG,oBAAoB;AAAA,iCACzB,SAAS,GAAG,2BAA2B;AAAA;AAAA;AAAA;AAAA,0BAI9C,SAAS,WAAW,oBAAoB;AAAA,wBAC1C,SAAS,WAAW,kBAAkB;AAAA,gCAC9B,SAAS,WAAW,0BAA0B;AAAA,8BAChD,SAAS,WAAW,wBAAwB;AAAA,+BAC3C,SAAS,WAAW,yBAAyB;AAAA;AAAA;AAAA;AAAA,aAI/D,SAAS,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA,sBAId,SAAS,OAAO,gBAAgB;AAAA;AAAA;AAAA;AAAA,aAIzC,SAAS,UAAU,OAAO;AAAA,uBAChB,SAAS,UAAU,iBAAiB;AAAA,6BAC9B,SAAS,UAAU,uBAAuB;AAAA,uBAChD,SAAS,UAAU,iBAAiB;AAAA,mBACxC,SAAS,UAAU,aAAa;AAAA;AAG7C,YAAM,KAAK,GAAG,UAAU,YAAY,aAAa;AACjD,aAAO,QAAQ,KAAK,mBAAmB;AACvC,aAAO,gBAAgB;AACvB,aAAO,KAAK,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAAA,IACxD,SAAS,OAAO;AACd,aAAO,OAAO;AAAA,QACZ,gCAAgC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACxF;AACA,aAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC;AAAA,IACnD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,aAAa,UAAkB,QAA6C;AACxF,UAAM,aAAaA,MAAK,KAAK,UAAU,WAAW;AAElD,QAAI,MAAM,KAAK,GAAG,OAAO,UAAU,GAAG;AACpC;AAAA,IACF;AAEA,UAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgItB,QAAI;AACF,YAAM,KAAK,GAAG,UAAU,YAAY,aAAa;AACjD,aAAO,QAAQ,KAAK,kBAAkB;AACtC,aAAO,KAAK,mBAAmB;AAAA,IACjC,SAAS,OAAO;AACd,aAAO,OAAO;AAAA,QACZ,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACpF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,QAA8B,eAA6B;AAEtE,YAAQ,IAAI,4CAAqC;AAEjD,QAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,cAAQ,IAAI,UAAU;AACtB,aAAO,QAAQ,QAAQ,CAAC,SAAS,QAAQ,IAAI,YAAO,IAAI,EAAE,CAAC;AAAA,IAC7D;AAEA,QAAI,OAAO,eAAe;AACxB,cAAQ,IAAI,uBAAgB;AAC5B,cAAQ,IAAI,+DAA0D;AAAA,IACxE;AAEA,QAAI,OAAO,eAAe;AACxB,cAAQ,IAAI,gCAAsB;AAClC,cAAQ,IAAI,mDAA8C;AAC1D,cAAQ,IAAI,0DAAmD;AAC/D,cAAQ,IAAI,4DAAqD;AAAA,IACnE;AAEA,QAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,cAAQ,IAAI,2BAAiB;AAC7B,aAAO,OAAO,QAAQ,CAAC,UAAU,QAAQ,IAAI,OAAO,KAAK,EAAE,CAAC;AAAA,IAC9D;AAEA,YAAQ,IAAI,kCAA2B;AACvC,YAAQ,IAAI,KAAKA,MAAK,KAAK,eAAe,QAAQ,CAAC,EAAE;AACrD,YAAQ,IAAI,2DAA4C;AACxD,YAAQ,IAAI,oDAAqC;AACjD,YAAQ,IAAI,oDAAqC;AACjD,YAAQ,IAAI,kFAAmE;AAC/E,YAAQ,IAAI,uEAAwD;AACpE,YAAQ,IAAI,oDAAqC;AAEjD,YAAQ,IAAI,8BAAuB;AACnC,YAAQ,IAAI,gDAAgD;AAC5D,YAAQ,IAAI,qEAAgE;AAC5E,YAAQ,IAAI,4DAAuD;AACnE,YAAQ,IAAI,wDAAmD;AAC/D,YAAQ,IAAI,wDAAmD;AAC/D,YAAQ,IAAI,wDAAmD;AAC/D,YAAQ,IAAI,iDAA4C;AACxD,YAAQ,IAAI,iEAAiE;AAE7E,YAAQ,IAAI,4EAAuE;AAAA,EAErF;AACF;;;ACrpBA,SAAS,cAAc;;;ACDhB,IAAM,aAAN,cAAyB,MAAM;AAAA,EACpC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,qBAAN,cAAiC,WAAW;AAAA,EACjD,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,gBAAN,cAA4B,WAAW;AAAA,EAC5C,YACE,SACgB,UAChB;AACA,UAAM,OAAO;AAFG;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;AA6BO,IAAM,eAAN,cAA2B,WAAW;AAAA,EAC3C,YACE,SACgB,YAChB;AACA,UAAM,OAAO;AAFG;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,iBAAN,cAA6B,WAAW;AAAA,EAC7C,YACE,SACgB,YAChB;AACA,UAAM,OAAO;AAFG;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;;;AC1DO,IAAe,kBAAf,MAAuD;AAAA,EAClD;AAAA,EACA;AAAA,EAEV,YAAY,QAAmB,aAA2B;AACxD,SAAK,SAAS;AACd,SAAK,cAAc,eAAe;AAAA,MAChC,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,mBAAmB;AAAA,IACrB;AAAA,EACF;AAAA,EAOA,kBAA0B;AACxB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,eAAuB;AACrB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAgB,UAAa,IAAkC;AAC7D,QAAI;AACJ,QAAI,QAAQ,KAAK,YAAY;AAE7B,aAAS,UAAU,GAAG,WAAW,KAAK,YAAY,YAAY,WAAW;AACvE,UAAI;AACF,eAAO,MAAM,GAAG;AAAA,MAClB,SAAS,OAAO;AACd,oBAAY;AAIZ,cAAM,cAAc,iBAAiB,gBAAgB,UAAU,KAAK,YAAY;AAEhF,YAAI,aAAa;AACf,gBAAM,KAAK,MAAM,KAAK;AACtB,mBAAS,KAAK,YAAY;AAAA,QAC5B,OAAO;AAEL,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM;AAAA,EACR;AAAA,EAEQ,MAAM,IAA2B;AACvC,WAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAAA,EACzD;AACF;;;ACvEA,OAAO,WAAyD;AASzD,IAAM,YAAN,MAAgB;AAAA,EACb;AAAA,EACA;AAAA,EAER,YAAY,QAAyB;AACnC,SAAK,gBAAgB,MAAM,OAAO;AAAA,MAChC,SAAS,OAAO;AAAA,MAChB,SAAS,OAAO;AAAA,MAChB,SAAS,OAAO,WAAW;AAAA;AAAA,IAC7B,CAAC;AAGD,SAAK,eAAe,KAAK,oBAAoB,OAAO,OAAO;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAQ,UAAkB,MAA2B;AACzD,QAAI;AACF,YAAM,WAA6B,MAAM,KAAK,cAAc,KAAK,UAAU,IAAI;AAC/E,aAAO,SAAS;AAAA,IAClB,SAAS,OAAO;AACd,YAAM,KAAK,SAAS,KAAK;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAO,UAA8B;AACzC,QAAI;AACF,YAAM,WAA6B,MAAM,KAAK,cAAc,IAAI,QAAQ;AACxE,aAAO,SAAS;AAAA,IAClB,SAAS,OAAO;AACd,YAAM,KAAK,SAAS,KAAK;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,OAAO,UAAkB,MAAsD;AACpF,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,cAAc,KAAK,UAAU,MAAM;AAAA,QAC7D,cAAc;AAAA,QACd,SAAS;AAAA,UACP,QAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAED,YAAM,SAAS,SAAS;AAGxB,uBAAiB,SAAS,QAAQ;AAChC,cAAM,WAAW,MAAM,SAAS,OAAO;AACvC,cAAM;AAAA,MACR;AAAA,IACF,SAAS,OAAO;AACd,YAAM,KAAK,SAAS,KAAK;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,SAAS,OAAuB;AACtC,QAAI,CAAC,MAAM,aAAa,KAAK,GAAG;AAC9B,aAAO;AAAA,IACT;AAEA,UAAM,aAAa;AACnB,UAAM,SAAS,WAAW,UAAU;AACpC,UAAM,YAAY,WAAW,UAAU;AAIvC,UAAM,UAAU,WAAW,OAAO,WAAW,WAAW,WAAW,WAAW;AAG9E,QAAI,WAAW,KAAK;AAClB,YAAM,aAAa,SAAU,WAAW,UAAU,QAAQ,aAAa,KAAgB,IAAI;AAC3F,aAAO,IAAI,eAAe,GAAG,KAAK,YAAY,yBAAyB,OAAO,IAAI,UAAU;AAAA,IAC9F;AAGA,QAAI,WAAW,OAAO,WAAW,KAAK;AACpC,aAAO,IAAI;AAAA,QACT,GAAG,KAAK,YAAY,2BAA2B,OAAO;AAAA,QACtD,KAAK;AAAA,MACP;AAAA,IACF;AAGA,QAAI,UAAU,UAAU,KAAK;AAC3B,aAAO,IAAI,aAAa,GAAG,KAAK,YAAY,kBAAkB,OAAO,IAAI,MAAM;AAAA,IACjF;AAGA,QAAI,UAAU,UAAU,KAAK;AAC3B,aAAO,IAAI,cAAc,GAAG,KAAK,YAAY,mBAAmB,OAAO,IAAI,KAAK,YAAY;AAAA,IAC9F;AAGA,QAAI,WAAW,SAAS,kBAAkB,WAAW,SAAS,aAAa;AACzE,aAAO,IAAI,aAAa,GAAG,KAAK,YAAY,qBAAqB,OAAO,EAAE;AAAA,IAC5E;AAGA,WAAO,IAAI,cAAc,GAAG,KAAK,YAAY,WAAW,OAAO,IAAI,KAAK,YAAY;AAAA,EACtF;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAAoB,SAAyB;AACnD,QAAI;AACF,YAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,YAAM,WAAW,IAAI;AAErB,UAAI,SAAS,SAAS,UAAU,EAAG,QAAO;AAC1C,UAAI,SAAS,SAAS,WAAW,EAAG,QAAO;AAC3C,UAAI,SAAS,SAAS,QAAQ,EAAG,QAAO;AACxC,UAAI,SAAS,SAAS,QAAQ,EAAG,QAAO;AAExC,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;ACtIA,IAAM,uBAAqE;AAAA,EACzE,UAAU;AAAA,IACR,iBAAiB;AAAA,MACf,uBAAuB;AAAA,MACvB,wBAAwB;AAAA,IAC1B;AAAA,IACA,qBAAqB;AAAA,MACnB,uBAAuB;AAAA,MACvB,wBAAwB;AAAA,IAC1B;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT,4BAA4B;AAAA,MAC1B,uBAAuB;AAAA,MACvB,wBAAwB;AAAA,IAC1B;AAAA,IACA,mBAAmB;AAAA,MACjB,uBAAuB;AAAA,MACvB,wBAAwB;AAAA,IAC1B;AAAA,IACA,8BAA8B;AAAA,MAC5B,uBAAuB;AAAA,MACvB,wBAAwB;AAAA,IAC1B;AAAA,IACA,qBAAqB;AAAA,MACnB,uBAAuB;AAAA,MACvB,wBAAwB;AAAA,IAC1B;AAAA,IACA,oBAAoB;AAAA,MAClB,uBAAuB;AAAA,MACvB,wBAAwB;AAAA,IAC1B;AAAA,IACA,4BAA4B;AAAA,MAC1B,uBAAuB;AAAA,MACvB,wBAAwB;AAAA,IAC1B;AAAA,IACA,2BAA2B;AAAA,MACzB,uBAAuB;AAAA,MACvB,wBAAwB;AAAA,IAC1B;AAAA,EACF;AACF;AAGA,IAAM,eAAe,KAAK,KAAK,KAAK;AAY7B,SAAS,iBAAiB,UAAkB,OAAoC;AACrF,QAAM,kBAAkB,qBAAqB,SAAS,YAAY,CAAC;AACnE,MAAI,CAAC,iBAAiB;AACpB,WAAO;AAAA,EACT;AAEA,SAAO,gBAAgB,KAAK,KAAK;AACnC;;;AC9DO,SAAS,cAAc,OAA6B;AACzD,SAAO,MAAM,IAAI,CAAC,UAAU;AAAA,IAC1B,MAAM;AAAA,IACN,UAAU;AAAA,MACR,MAAM,KAAK;AAAA,MACX,aAAa,KAAK;AAAA,MAClB,YAAY,KAAK;AAAA;AAAA,IACnB;AAAA,EACF,EAAE;AACJ;AAMO,SAAS,iBAAiB,OAA6B;AAC5D,SAAO,MAAM,IAAI,CAAC,UAAU;AAAA,IAC1B,MAAM,KAAK;AAAA,IACX,aAAa,KAAK;AAAA,IAClB,cAAc;AAAA,MACZ,MAAM;AAAA,MACN,GAAG,KAAK;AAAA;AAAA,IACV;AAAA,EACF,EAAE;AACJ;AAKO,SAAS,qBAAqB,UAatB;AACb,QAAM,YAAY,SAAS,UAAU,CAAC,GAAG,SAAS,cAAc,CAAC;AAEjE,SAAO,UAAU,IAAI,CAAC,OAAO;AAC3B,QAAI;AACJ,QAAI;AACF,mBAAa,KAAK,MAAM,GAAG,SAAS,SAAS;AAAA,IAC/C,QAAQ;AACN,mBAAa,CAAC;AAAA,IAChB;AAEA,WAAO;AAAA,MACL,IAAI,GAAG;AAAA,MACP,MAAM,GAAG,SAAS;AAAA,MAClB,WAAW;AAAA,IACb;AAAA,EACF,CAAC;AACH;AAKO,SAAS,wBAAwB,UAUzB;AACb,QAAM,UAAU,SAAS,WAAW,CAAC;AAErC,SAAO,QACJ;AAAA,IACC,CAAC,UAAgE,MAAM,SAAS;AAAA,EAClF,EACC,IAAI,CAAC,WAAW;AAAA,IACf,IAAI,MAAM;AAAA,IACV,MAAM,MAAM;AAAA,IACZ,WAAW,MAAM;AAAA,EACnB,EAAE;AACN;AAKO,SAAS,sBAAsB,QAA4D;AAChG,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAKO,SAAS,yBACd,QAC4C;AAC5C,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;;;AC1HA,gBAAuB,kBAAkB,QAA0D;AACjG,MAAI,SAAS;AAEb,mBAAiB,SAAS,QAAQ;AAChC,cAAU;AAGV,UAAM,QAAQ,OAAO,MAAM,IAAI;AAG/B,aAAS,MAAM,IAAI,KAAK;AAExB,eAAW,QAAQ,OAAO;AACxB,YAAM,UAAU,KAAK,KAAK;AAG1B,UAAI,CAAC,QAAS;AAGd,UAAI,YAAY,gBAAgB;AAC9B,cAAM,EAAE,SAAS,IAAI,MAAM,KAAK;AAChC;AAAA,MACF;AAGA,UAAI,QAAQ,WAAW,QAAQ,GAAG;AAChC,cAAM,UAAU,QAAQ,UAAU,CAAC;AACnC,YAAI;AACF,gBAAM,OAAO,KAAK,MAAM,OAAO;AAU/B,gBAAM,QAAQ,KAAK,UAAU,CAAC,GAAG;AACjC,gBAAM,UAAU,OAAO,WAAW;AAClC,gBAAM,eAAe,KAAK,UAAU,CAAC,GAAG;AAExC,cAAI,SAAS;AACX,kBAAM,EAAE,SAAS,MAAM,MAAM;AAAA,UAC/B;AAEA,cAAI,cAAc;AAChB,kBAAM,EAAE,SAAS,IAAI,MAAM,KAAK;AAChC;AAAA,UACF;AAAA,QACF,SAAS,OAAO;AAEd;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO,KAAK,GAAG;AACjB,UAAM,EAAE,SAAS,IAAI,MAAM,KAAK;AAAA,EAClC;AACF;AAgBA,gBAAuB,qBACrB,QAC2B;AAC3B,MAAI,SAAS;AACb,MAAI,eAAe;AAEnB,mBAAiB,SAAS,QAAQ;AAChC,cAAU;AAGV,UAAM,SAAS,OAAO,MAAM,MAAM;AAGlC,aAAS,OAAO,IAAI,KAAK;AAEzB,eAAW,SAAS,QAAQ;AAC1B,YAAM,QAAQ,MAAM,MAAM,IAAI;AAE9B,iBAAW,QAAQ,OAAO;AACxB,cAAM,UAAU,KAAK,KAAK;AAE1B,YAAI,QAAQ,WAAW,SAAS,GAAG;AACjC,yBAAe,QAAQ,UAAU,CAAC;AAAA,QACpC,WAAW,QAAQ,WAAW,QAAQ,GAAG;AACvC,gBAAM,UAAU,QAAQ,UAAU,CAAC;AAEnC,cAAI;AACF,kBAAM,OAAO,KAAK,MAAM,OAAO;AAG/B,gBAAI,iBAAiB,uBAAuB;AAC1C,oBAAM,UAAU,KAAK,OAAO,QAAQ;AACpC,kBAAI,SAAS;AACX,sBAAM,EAAE,SAAS,MAAM,MAAM;AAAA,cAC/B;AAAA,YACF;AAGA,gBAAI,iBAAiB,uBAAuB;AAC1C,oBAAM,UAAU,KAAK,eAAe,QAAQ;AAC5C,kBAAI,SAAS;AACX,sBAAM,EAAE,SAAS,MAAM,MAAM;AAAA,cAC/B;AAAA,YACF;AAGA,gBAAI,iBAAiB,iBAAiB;AAEpC;AAAA,YACF;AAGA,gBAAI,iBAAiB,gBAAgB;AACnC,oBAAM,EAAE,SAAS,IAAI,MAAM,KAAK;AAChC;AAAA,YACF;AAGA,gBAAI,iBAAiB,SAAS;AAC5B,oBAAM,IAAI,MAAM,KAAK,OAAO,WAAW,2BAA2B;AAAA,YACpE;AAAA,UACF,SAAS,OAAO;AAEd,gBAAI,iBAAiB,SAAS;AAC5B,oBAAM;AAAA,YACR;AACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO,KAAK,GAAG;AACjB,UAAM,EAAE,SAAS,IAAI,MAAM,KAAK;AAAA,EAClC;AACF;;;ANvJO,IAAM,mBAAN,cAA+B,gBAAwC;AAAA,EACpE;AAAA,EAER,YAAY,QAAmB;AAC7B,UAAM,MAAM;AAEZ,UAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAC5C,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AAEA,UAAM,UAAU,OAAO,WAAW;AAElC,SAAK,YAAY,IAAI,UAAU;AAAA,MAC7B;AAAA,MACA,SAAS;AAAA,QACP,eAAe,UAAU,MAAM;AAAA,QAC/B,gBAAgB;AAAA,MAClB;AAAA,MACA,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,KAAK,UAAqB,OAA0C;AACxE,WAAO,KAAK,UAAU,YAAY;AAChC,YAAM,cAAc;AAAA,QAClB,OAAO,KAAK,OAAO;AAAA,QACnB,UAAU,KAAK,eAAe,QAAQ;AAAA,QACtC,OAAO,QAAQ,cAAc,KAAK,IAAI;AAAA,QACtC,aAAa,KAAK,OAAO;AAAA,QACzB,YAAY,KAAK,OAAO;AAAA,MAC1B;AAEA,YAAM,WAAW,MAAM,KAAK,UAAU;AAAA,QACpC;AAAA,QACA;AAAA,MACF;AAEA,aAAO,KAAK,cAAc,QAAQ;AAAA,IACpC,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,WAAW,UAAqB,OAA8C;AACnF,UAAM,cAAc;AAAA,MAClB,OAAO,KAAK,OAAO;AAAA,MACnB,UAAU,KAAK,eAAe,QAAQ;AAAA,MACtC,OAAO,QAAQ,cAAc,KAAK,IAAI;AAAA,MACtC,aAAa,KAAK,OAAO;AAAA,MACzB,YAAY,KAAK,OAAO;AAAA,MACxB,QAAQ;AAAA,IACV;AAEA,UAAM,SAAS,KAAK,UAAU,OAAO,qBAAqB,WAAW;AAErE,qBAAiB,SAAS,kBAAkB,MAAM,GAAG;AACnD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,YAAY,MAAsB;AAChC,WAAO,OAAO,IAAI,EAAE;AAAA,EACtB;AAAA,EAEA,cAAc,aAAqB,cAA8B;AAC/D,UAAM,UAAU,iBAAiB,YAAY,KAAK,OAAO,KAAK;AAC9D,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,WACG,cAAc,MAAa,QAAQ,wBACnC,eAAe,MAAa,QAAQ;AAAA,EAEzC;AAAA;AAAA;AAAA;AAAA,EAKQ,eACN,UACyD;AACzD,WAAO,SAAS,IAAI,CAAC,SAAS;AAAA,MAC5B,MAAM,IAAI;AAAA,MACV,SAAS,IAAI;AAAA,MACb,MAAM,IAAI;AAAA,IACZ,EAAE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,UAA8C;AAClE,UAAM,SAAS,SAAS,QAAQ,CAAC;AACjC,UAAM,UAAU,QAAQ;AACxB,UAAM,QAAQ,SAAS;AAEvB,QAAI,CAAC,UAAU,CAAC,SAAS;AACvB,YAAM,IAAI,MAAM,+DAA+D;AAAA,IACjF;AAEA,WAAO;AAAA,MACL,SAAS,QAAQ,WAAW;AAAA,MAC5B,WAAW,qBAAqB,QAAQ;AAAA,MACxC,cAAc,sBAAsB,OAAO,aAAa;AAAA,MACxD,OAAO;AAAA,QACL,aAAa,MAAM;AAAA,QACnB,cAAc,MAAM;AAAA,QACpB,aAAa,MAAM;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AACF;;;AOhIA,SAAS,UAAAI,eAAc;AAchB,IAAM,oBAAN,cAAgC,gBAAwC;AAAA,EACrE;AAAA,EAER,YAAY,QAAmB;AAC7B,UAAM,MAAM;AAEZ,UAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAC5C,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,UAAM,UAAU,OAAO,WAAW;AAElC,SAAK,YAAY,IAAI,UAAU;AAAA,MAC7B;AAAA,MACA,SAAS;AAAA,QACP,aAAa;AAAA,QACb,qBAAqB;AAAA,QACrB,gBAAgB;AAAA,MAClB;AAAA,MACA,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,KAAK,UAAqB,OAA0C;AACxE,WAAO,KAAK,UAAU,YAAY;AAChC,YAAM,EAAE,QAAQ,UAAU,aAAa,IAAI,KAAK,wBAAwB,QAAQ;AAEhF,YAAM,cAAoC;AAAA,QACxC,OAAO,KAAK,OAAO;AAAA,QACnB,UAAU;AAAA,QACV,YAAY,KAAK,OAAO;AAAA,QACxB,aAAa,KAAK,OAAO;AAAA,MAC3B;AAGA,UAAI,QAAQ;AACV,oBAAY,SAAS;AAAA,MACvB;AAGA,UAAI,SAAS,MAAM,SAAS,GAAG;AAC7B,oBAAY,QAAQ,iBAAiB,KAAK;AAAA,MAC5C;AAEA,YAAM,WAAW,MAAM,KAAK,UAAU;AAAA,QACpC;AAAA,QACA;AAAA,MACF;AAEA,aAAO,KAAK,cAAc,QAAQ;AAAA,IACpC,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,WAAW,UAAqB,OAA8C;AACnF,UAAM,EAAE,QAAQ,UAAU,aAAa,IAAI,KAAK,wBAAwB,QAAQ;AAEhF,UAAM,cAAoC;AAAA,MACxC,OAAO,KAAK,OAAO;AAAA,MACnB,UAAU;AAAA,MACV,YAAY,KAAK,OAAO;AAAA,MACxB,aAAa,KAAK,OAAO;AAAA,MACzB,QAAQ;AAAA,IACV;AAEA,QAAI,QAAQ;AACV,kBAAY,SAAS;AAAA,IACvB;AAEA,QAAI,SAAS,MAAM,SAAS,GAAG;AAC7B,kBAAY,QAAQ,iBAAiB,KAAK;AAAA,IAC5C;AAEA,UAAM,SAAS,KAAK,UAAU,OAAO,gBAAgB,WAAW;AAEhE,qBAAiB,SAAS,qBAAqB,MAAM,GAAG;AACtD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,YAAY,MAAsB;AAChC,WAAOC,QAAO,IAAI,EAAE;AAAA,EACtB;AAAA,EAEA,cAAc,aAAqB,cAA8B;AAC/D,UAAM,UAAU,iBAAiB,aAAa,KAAK,OAAO,KAAK;AAC/D,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,WACG,cAAc,MAAa,QAAQ,wBACnC,eAAe,MAAa,QAAQ;AAAA,EAEzC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,wBAAwB,UAG9B;AACA,UAAM,iBAAiB,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,QAAQ;AACjE,UAAM,eAAe,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,QAAQ;AAE/D,UAAM,SACJ,eAAe,SAAS,IAAI,eAAe,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,MAAM,IAAI;AAElF,WAAO;AAAA,MACL;AAAA,MACA,UAAU,aAAa,IAAI,CAAC,SAAS;AAAA,QACnC,MAAM,IAAI,SAAS,cAAc,cAAc;AAAA,QAC/C,SAAS,IAAI;AAAA,MACf,EAAE;AAAA,IACJ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,UAA+C;AACnE,UAAM,UAAU,SAAS,WAAW,CAAC;AACrC,UAAM,QAAQ,SAAS;AAGvB,UAAM,cAAc,QACjB,OAAO,CAAC,UAAU,MAAM,SAAS,MAAM,EACvC,IAAI,CAAC,UAAW,MAAyC,IAAI,EAC7D,KAAK,EAAE;AAEV,WAAO;AAAA,MACL,SAAS;AAAA,MACT,WAAW,wBAAwB,QAAQ;AAAA,MAC3C,cAAc,yBAAyB,SAAS,WAAW;AAAA,MAC3D,OAAO;AAAA,QACL,aAAa,MAAM;AAAA,QACnB,cAAc,MAAM;AAAA,QACpB,aAAa,MAAM,eAAe,MAAM;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AACF;;;AC3JO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,OAAO,OAAO,QAAiC;AAC7C,YAAQ,OAAO,SAAS,YAAY,GAAG;AAAA,MACrC,KAAK;AACH,eAAO,IAAI,iBAAiB,MAAM;AAAA,MACpC,KAAK;AACH,eAAO,IAAI,kBAAkB,MAAM;AAAA,MACrC,KAAK;AACH,cAAM,IAAI;AAAA,UACR;AAAA,QAEF;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,cAAM,IAAI,MAAM,2DAA2D;AAAA,MAC7E,KAAK;AACH,cAAM,IAAI;AAAA,UACR;AAAA,QAEF;AAAA,MACF,KAAK;AACH,cAAM,IAAI,MAAM,oDAAoD;AAAA,MACtE;AACE,cAAM,IAAI,MAAM,yBAAyB,OAAO,QAAQ,EAAE;AAAA,IAC9D;AAAA,EACF;AACF;;;AnCLA,OAAOC,WAAU;AACjB,OAAOC,WAAU;AAEV,IAAM,cAAN,MAAkB;AAAA,EAGvB,YACUC,eACAC,mBACAC,eACAC,KACR;AAJQ,wBAAAH;AACA,4BAAAC;AACA,wBAAAC;AACA,cAAAC;AAER,SAAK,kBAAkB,IAAI,qBAAqB;AAAA,EAClD;AAAA,EATQ;AAAA,EAWR,MAAc,mBAAmB,aAAoC;AAEnE,SAAK,gBAAgB,SAAS,IAAI,WAAW,CAAC;AAC9C,SAAK,gBAAgB,SAAS,IAAI,aAAa,CAAC;AAChD,SAAK,gBAAgB,SAAS,IAAI,YAAY,CAAC;AAC/C,SAAK,gBAAgB,SAAS,IAAI,aAAa,CAAC;AAChD,SAAK,gBAAgB,SAAS,IAAI,YAAY,KAAK,eAAe,CAAC;AAGnE,UAAM,eAAe,IAAI,oBAAoB,KAAK,EAAE;AACpD,UAAM,iBAAiB,MAAM,aAAa,QAAQ,WAAW;AAG7D,mBAAe,QAAQ,CAAC,QAAQ;AAC9B,UAAI,KAAK,gBAAgB,IAAI,IAAI,IAAI,GAAG;AACtC,eAAO,KAAK,oDAAoD;AAAA,UAC9D,MAAM,IAAI;AAAA,QACZ,CAAC;AACD;AAAA,MACF;AACA,WAAK,gBAAgB,SAAS,GAAG;AAAA,IACnC,CAAC;AAED,WAAO,KAAK,8BAA8B;AAAA,MACxC,OAAO,KAAK,gBAAgB,OAAO,EAAE;AAAA,IACvC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,mBAAmB,QAA6D;AACtF,QAAI;AACF,YAAM,WAAW,gBAAgB,OAAO,OAAO,GAAG;AAClD,aAAO,EAAE,SAAS;AAAA,IACpB,SAAS,OAAO;AACd,UAAI,iBAAiB,oBAAoB;AACvC,eAAO,EAAE,OAAO,MAAM,QAAQ;AAAA,MAChC;AACA,aAAO,EAAE,OAAO,kCAAmC,MAAgB,OAAO,GAAG;AAAA,IAC/E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,WAAW,aAAqB,QAA+B;AAC3E,QAAI;AACF,YAAM,aAAaL,MAAK,KAAK,aAAa,UAAU,YAAY;AAChE,YAAM,cAAcC,MAAK,UAAU,MAAM;AACzC,YAAM,KAAK,GAAG,UAAU,YAAY,WAAW;AAC/C,aAAO,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAAA,IAClD,SAAS,OAAO;AACd,aAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC;AAC/C,YAAM,IAAI,MAAM,0BAA2B,MAAgB,OAAO,EAAE;AAAA,IACtE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eACZ,UACA,UACA,WACkB;AAClB,UAAM,YAAY,KAAK,IAAI;AAE3B,QAAI;AAEF,YAAM,cAAuB;AAAA,QAC3B,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AACA,eAAS,KAAK,WAAW;AAGzB,YAAM,WAAW,MAAM,SAAS,KAAK,QAAQ;AAC7C,YAAM,WAAW,KAAK,IAAI,IAAI;AAG9B,YAAM,mBAA4B;AAAA,QAChC,MAAM;AAAA,QACN,SAAS,SAAS;AAAA,QAClB,UAAU;AAAA,UACR,WAAW,KAAK,IAAI;AAAA,UACpB;AAAA,UACA,OAAO,SAAS;AAAA,UAChB,MAAM,SAAS,cAAc,SAAS,MAAM,aAAa,SAAS,MAAM,YAAY;AAAA,UACpF,OAAO,SAAS,aAAa;AAAA,UAC7B,UAAU,SAAS,gBAAgB;AAAA,QACrC;AAAA,MACF;AAEA,eAAS,KAAK,gBAAgB;AAC9B,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,aAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC;AAGzC,YAAM,eAAwB;AAAA,QAC5B,MAAM;AAAA,QACN,SAAS,iBAAa,MAAgB,OAAO;AAAA,QAC7C,UAAU;AAAA,UACR,WAAW,KAAK,IAAI;AAAA,UACpB;AAAA,UACA,OAAO,SAAS,aAAa;AAAA,UAC7B,UAAU,SAAS,gBAAgB;AAAA,QACrC;AAAA,MACF;AAEA,eAAS,KAAK,YAAY;AAC1B,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,eAAuC;AAGnD,UAAM,MAAM,iBAAiB,QAAQ,IAAI;AAGzC,QAAI,MAAM,KAAK,iBAAiB,WAAW,GAAG;AAC5C,aAAO,KAAK,4CAA4C;AACxD,YAAM,KAAK,aAAa,QAAQ;AAAA,IAElC;AAGA,UAAM,cAAc,IAAI,iBAAiB,KAAK,IAAI,KAAK,YAAY;AACnE,QAAI,CAAE,MAAM,YAAY,uBAAuB,GAAG,GAAI;AACpD,aAAO,KAAK,6CAA6C;AACzD,YAAM,SAAS,MAAM,YAAY,oBAAoB,GAAG;AAExD,UAAI,CAAC,OAAO,SAAS;AACnB,cAAM,WAAW,qCAAqC,OAAO,OAAO,KAAK,IAAI;AAC7E,eAAO,MAAM,QAAQ;AACrB,cAAM,IAAI,MAAM,iCAAiC;AAAA,MACnD;AAEA,aAAO,KAAK,oCAAoC;AAAA,IAClD;AAIA,YAAQ,OAAO,MAAM,aAAa;AAGlC,UAAM,EAAE,OAAO,IAAI,MAAM,KAAK,aAAa,KAAK;AAAA,MAC9C,aAAa;AAAA,IACf,CAAC;AAGD,UAAM,KAAK,mBAAmB,GAAG;AAGjC,QAAI,iBAAiB,KAAK,mBAAmB,MAAM;AAGnD,UAAM,QAAQ;AAAA,MACZ,UAAU,CAAC;AAAA,MACX,aAAa;AAAA,MACb,WAAW;AAAA,MACX,UAAU,eAAe;AAAA,MACzB;AAAA,IACF;AAGA,QAAI,CAAC,MAAM,YAAY,eAAe,OAAO;AAC3C,YAAM,SAAS,KAAK;AAAA,QAClB,MAAM;AAAA,QACN,SAAS,iBAAO,eAAe,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MACtC,CAAC;AAAA,IACH;AAEA,WAAO,IAAI,QAAQ,CAAC,YAAY;AAE9B,YAAM,WAAW,CAACK,cAA0D;AAC1E,cAAM,UAAUC,QAAM,cAAc,SAAS;AAAA,UAC3C,IAAI,KAAK;AAAA,UACT,aAAa,QAAQ,IAAI;AAAA,UACzB,QAAQ,MAAM;AAAA,UACd,UAAU,MAAM;AAAA,UAChB,aAAa,MAAM;AAAA,UACnB,WAAW,MAAM;AAAA,UACjB,iBAAiB,KAAK;AAAA;AAAA,UAEtB,aAAa,OAAO,UAAkB;AAEpC,kBAAM,cAAc,mBAAmB,MAAM,KAAK;AAElD,gBAAI,YAAY,aAAa,YAAY,aAAa;AAEpD,oBAAM,SAAS,MAAM,KAAK,gBAAgB;AAAA,gBACxC,YAAY;AAAA,gBACZ,YAAY,QAAQ,CAAC;AAAA,gBACrB;AAAA,kBACE,aAAa,MAAM;AAAA,kBACnB,iBAAiB,MAAM,OAAO,IAAI;AAAA,kBAClC,cAAc,MAAM,OAAO,IAAI;AAAA,kBAC/B,cAAc,MAAM,SAAS;AAAA,kBAC7B,mBAAmB,CAAC,SAAe;AACjC,0BAAM,cAAc;AACpB,2BAAO,KAAK,6BAA6B,EAAE,KAAK,CAAC;AAEjD,6BAASD,SAAQ;AAAA,kBACnB;AAAA,kBACA,oBAAoB,OAAO,UAAU,UAAyB;AAC5D,2BAAO,KAAK,0BAA0B,EAAE,UAAU,MAAM,CAAC;AAGzD,0BAAM,iBAAiB;AAAA,sBACrB;AAAA,sBACA;AAAA,sBACA;AAAA,sBACA;AAAA,sBACA;AAAA,sBACA;AAAA,sBACA;AAAA,oBACF;AACA,wBAAI,CAAC,eAAe,SAAS,QAA2C,GAAG;AACzE,4BAAM,SAAS,KAAK;AAAA,wBAClB,MAAM;AAAA,wBACN,SAAS,4BAAuB,QAAQ,sBAAsB,eAAe,KAAK,IAAI,CAAC;AAAA,sBACzF,CAAC;AACD;AAAA,oBACF;AAGA,0BAAM,OAAO,IAAI,WAAW;AAG5B,wBAAI,OAAO;AACT,4BAAM,OAAO,IAAI,QAAQ;AAAA,oBAC3B,OAAO;AAEL,8BAAQ,SAAS,YAAY,GAAG;AAAA,wBAC9B,KAAK;AACH,gCAAM,OAAO,IAAI,QAAQ;AACzB;AAAA,wBACF,KAAK;AACH,gCAAM,OAAO,IAAI,QAAQ;AACzB;AAAA,wBACF,KAAK;AACH,gCAAM,OAAO,IAAI,QAAQ;AACzB;AAAA,wBACF,KAAK;AAAA,wBACL,KAAK;AACH,gCAAM,OAAO,IAAI,QAAQ;AACzB;AAAA,wBACF;AACE,gCAAM,OAAO,IAAI,QAAQ;AAAA,sBAC7B;AAAA,oBACF;AAGA,wBAAI;AACF,4BAAM,KAAK,WAAW,KAAK,MAAM,MAAM;AAGvC,4BAAM,oBAAoB,KAAK,mBAAmB,MAAM,MAAM;AAC9D,0BAAI,kBAAkB,UAAU;AAC9B,8BAAM,WAAW,kBAAkB;AACnC,8BAAM,SAAS,KAAK;AAAA,0BAClB,MAAM;AAAA,0BACN,SAAS,sBAAiB,QAAQ,GAAG,QAAQ,IAAI,KAAK,KAAK,EAAE;AAAA,wBAC/D,CAAC;AAAA,sBACH,OAAO;AACL,8BAAM,SAAS,KAAK;AAAA,0BAClB,MAAM;AAAA,0BACN,SAAS,4BAAuB,kBAAkB,KAAK;AAAA,wBACzD,CAAC;AAAA,sBACH;AAAA,oBACF,SAAS,OAAO;AACd,4BAAM,SAAS,KAAK;AAAA,wBAClB,MAAM;AAAA,wBACN,SAAS,iCAA6B,MAAgB,OAAO;AAAA,sBAC/D,CAAC;AAAA,oBACH;AAAA,kBACF;AAAA,kBACA,gBAAgB,MAAY;AAC1B,0BAAM,WAAW,CAAC;AAClB,0BAAM,YAAY;AAClB,2BAAO,KAAK,kBAAkB;AAAA,kBAChC;AAAA,kBACA,oBAAoB,OAAO,UAAyB;AAElD,0BAAM,SAAS;AAAA,sBACb,GAAG,MAAM;AAAA,sBACT,IAAI;AAAA,wBACF,GAAG,MAAM,OAAO;AAAA,wBAChB;AAAA,sBACF;AAAA,oBACF;AAEA,wBAAI;AACF,4BAAM,KAAK,WAAW,KAAK,MAAM,MAAM;AACvC,6BAAO,KAAK,2BAA2B,EAAE,MAAM,CAAC;AAGhD,+BAASA,SAAQ;AAAA,oBACnB,SAAS,OAAO;AACd,6BAAO,MAAM,+BAA+B,EAAE,MAAM,CAAC;AAAA,oBACvD;AAAA,kBACF;AAAA,kBACA,YAAY,CAAC,WAAW;AAEtB,0BAAM,SAAS,KAAK;AAAA,sBAClB,MAAM;AAAA,sBACN,SAAS;AAAA,oBACX,CAAC;AAED,0BAAM,SAAS,KAAK;AAAA,sBAClB,MAAM;AAAA,sBACN,SAAS,iCAAiC,MAAM;AAAA,oBAClD,CAAC;AAAA,kBACH;AAAA,gBACF;AAAA,cACF;AAEA,kBAAI,CAAC,OAAO,SAAS;AAEnB,sBAAM,SAAS,KAAK;AAAA,kBAClB,MAAM;AAAA,kBACN,SAAS,UAAU,OAAO,KAAK;AAAA,gBACjC,CAAC;AAAA,cACH;AAGA,uBAASA,SAAQ;AACjB;AAAA,YACF;AAGA,mBAAO,KAAK,uBAAuB,EAAE,MAAM,CAAC;AAG5C,gBAAI,CAAC,MAAM,UAAU;AACnB,oBAAM,SAAS,KAAK;AAAA,gBAClB,MAAM;AAAA,gBACN,SAAS;AAAA,cACX,CAAC;AACD,oBAAM,SAAS,KAAK;AAAA,gBAClB,MAAM;AAAA,gBACN,SACE;AAAA,cACJ,CAAC;AACD,uBAASA,SAAQ;AACjB;AAAA,YACF;AAGA,kBAAM,KAAK,eAAe,MAAM,UAAU,MAAM,UAAU,KAAK;AAG/D,kBAAM,cAAc,MAAM,SAAS,MAAM,SAAS,SAAS,CAAC;AAC5D,gBAAI,aAAa,UAAU,MAAM;AAC/B,oBAAM,aAAa,YAAY,SAAS;AAAA,YAC1C;AAGA,qBAASA,SAAQ;AAAA,UACnB;AAAA,UACA,cAAc,CAAC,SAA2C;AACxD,kBAAM,cAAc;AACpB,mBAAO,KAAK,iBAAiB,EAAE,KAAK,CAAC;AAErC,qBAASA,SAAQ;AAAA,UACnB;AAAA,UACA,QAAQ,MAAY;AAClB,mBAAO,KAAK,oBAAoB;AAChC,oBAAQ;AAAA,UACV;AAAA,QACF,CAAC;AAED,QAAAA,UAAS,OAAO;AAAA,MAClB;AAGA,aAAO,eAAe;AAMtB,YAAM,EAAE,eAAe,UAAU,MAAM,IAAIE;AAAA,QACzCD,QAAM,cAAc,SAAS;AAAA,UAC3B,IAAI,KAAK;AAAA,UACT,aAAa,QAAQ,IAAI;AAAA,UACzB,QAAQ,MAAM;AAAA,UACd,UAAU,MAAM;AAAA,UAChB,aAAa,MAAM;AAAA,UACnB,WAAW,MAAM;AAAA,UACjB,iBAAiB,KAAK;AAAA;AAAA,UAEtB,aAAa,OAAO,UAAkB;AAEpC,kBAAM,cAAc,mBAAmB,MAAM,KAAK;AAElD,gBAAI,YAAY,aAAa,YAAY,aAAa;AAEpD,oBAAM,SAAS,MAAM,KAAK,gBAAgB;AAAA,gBACxC,YAAY;AAAA,gBACZ,YAAY,QAAQ,CAAC;AAAA,gBACrB;AAAA,kBACE,aAAa,MAAM;AAAA,kBACnB,iBAAiB,MAAM,OAAO,IAAI;AAAA,kBAClC,cAAc,MAAM,OAAO,IAAI;AAAA,kBAC/B,cAAc,MAAM,SAAS;AAAA,kBAC7B,mBAAmB,CAAC,SAAe;AACjC,0BAAM,cAAc;AACpB,2BAAO,KAAK,6BAA6B,EAAE,KAAK,CAAC;AAEjD,6BAAS,QAAQ;AAAA,kBACnB;AAAA,kBACA,oBAAoB,OAAO,UAAU,UAAyB;AAC5D,2BAAO,KAAK,0BAA0B,EAAE,UAAU,MAAM,CAAC;AAGzD,0BAAM,iBAAiB;AAAA,sBACrB;AAAA,sBACA;AAAA,sBACA;AAAA,sBACA;AAAA,sBACA;AAAA,sBACA;AAAA,sBACA;AAAA,oBACF;AACA,wBAAI,CAAC,eAAe,SAAS,QAA2C,GAAG;AACzE,4BAAM,SAAS,KAAK;AAAA,wBAClB,MAAM;AAAA,wBACN,SAAS,4BAAuB,QAAQ,sBAAsB,eAAe,KAAK,IAAI,CAAC;AAAA,sBACzF,CAAC;AACD;AAAA,oBACF;AAGA,0BAAM,OAAO,IAAI,WAAW;AAG5B,wBAAI,OAAO;AACT,4BAAM,OAAO,IAAI,QAAQ;AAAA,oBAC3B,OAAO;AAEL,8BAAQ,SAAS,YAAY,GAAG;AAAA,wBAC9B,KAAK;AACH,gCAAM,OAAO,IAAI,QAAQ;AACzB;AAAA,wBACF,KAAK;AACH,gCAAM,OAAO,IAAI,QAAQ;AACzB;AAAA,wBACF,KAAK;AACH,gCAAM,OAAO,IAAI,QAAQ;AACzB;AAAA,wBACF,KAAK;AAAA,wBACL,KAAK;AACH,gCAAM,OAAO,IAAI,QAAQ;AACzB;AAAA,wBACF;AACE,gCAAM,OAAO,IAAI,QAAQ;AAAA,sBAC7B;AAAA,oBACF;AAGA,wBAAI;AACF,4BAAM,KAAK,WAAW,KAAK,MAAM,MAAM;AAGvC,4BAAM,oBAAoB,KAAK,mBAAmB,MAAM,MAAM;AAC9D,0BAAI,kBAAkB,UAAU;AAC9B,8BAAM,WAAW,kBAAkB;AACnC,8BAAM,SAAS,KAAK;AAAA,0BAClB,MAAM;AAAA,0BACN,SAAS,sBAAiB,QAAQ,GAAG,QAAQ,IAAI,KAAK,KAAK,EAAE;AAAA,wBAC/D,CAAC;AAAA,sBACH,OAAO;AACL,8BAAM,SAAS,KAAK;AAAA,0BAClB,MAAM;AAAA,0BACN,SAAS,4BAAuB,kBAAkB,KAAK;AAAA,wBACzD,CAAC;AAAA,sBACH;AAAA,oBACF,SAAS,OAAO;AACd,4BAAM,SAAS,KAAK;AAAA,wBAClB,MAAM;AAAA,wBACN,SAAS,iCAA6B,MAAgB,OAAO;AAAA,sBAC/D,CAAC;AAAA,oBACH;AAAA,kBACF;AAAA,kBACA,gBAAgB,MAAY;AAC1B,0BAAM,WAAW,CAAC;AAClB,0BAAM,YAAY;AAClB,2BAAO,KAAK,kBAAkB;AAAA,kBAChC;AAAA,kBACA,oBAAoB,OAAO,UAAyB;AAElD,0BAAM,SAAS;AAAA,sBACb,GAAG,MAAM;AAAA,sBACT,IAAI;AAAA,wBACF,GAAG,MAAM,OAAO;AAAA,wBAChB;AAAA,sBACF;AAAA,oBACF;AAEA,wBAAI;AACF,4BAAM,KAAK,WAAW,KAAK,MAAM,MAAM;AACvC,6BAAO,KAAK,2BAA2B,EAAE,MAAM,CAAC;AAGhD,+BAAS,QAAQ;AAAA,oBACnB,SAAS,OAAO;AACd,6BAAO,MAAM,+BAA+B,EAAE,MAAM,CAAC;AAAA,oBACvD;AAAA,kBACF;AAAA,kBACA,YAAY,CAAC,WAAiB;AAE5B,0BAAM,SAAS,KAAK;AAAA,sBAClB,MAAM;AAAA,sBACN,SAAS;AAAA,oBACX,CAAC;AAED,0BAAM,SAAS,KAAK;AAAA,sBAClB,MAAM;AAAA,sBACN,SAAS,iCAAiC,MAAM;AAAA,oBAClD,CAAC;AAAA,kBACH;AAAA,gBACF;AAAA,cACF;AAEA,kBAAI,CAAC,OAAO,SAAS;AAEnB,sBAAM,SAAS,KAAK;AAAA,kBAClB,MAAM;AAAA,kBACN,SAAS,UAAU,OAAO,KAAK;AAAA,gBACjC,CAAC;AAAA,cACH;AAGA,uBAAS,QAAQ;AACjB;AAAA,YACF;AAGA,mBAAO,KAAK,uBAAuB,EAAE,MAAM,CAAC;AAG5C,gBAAI,CAAC,MAAM,UAAU;AACnB,oBAAM,SAAS,KAAK;AAAA,gBAClB,MAAM;AAAA,gBACN,SAAS;AAAA,cACX,CAAC;AACD,oBAAM,SAAS,KAAK;AAAA,gBAClB,MAAM;AAAA,gBACN,SACE;AAAA,cACJ,CAAC;AACD,uBAAS,QAAQ;AACjB;AAAA,YACF;AAGA,kBAAM,KAAK,eAAe,MAAM,UAAU,MAAM,UAAU,KAAK;AAG/D,kBAAM,cAAc,MAAM,SAAS,MAAM,SAAS,SAAS,CAAC;AAC5D,gBAAI,aAAa,UAAU,MAAM;AAC/B,oBAAM,aAAa,YAAY,SAAS;AAAA,YAC1C;AAEA,qBAAS,QAAQ;AAAA,UACnB;AAAA,UACA,cAAc,CAAC,SAA2C;AACxD,kBAAM,cAAc;AACpB,mBAAO,KAAK,iBAAiB,EAAE,KAAK,CAAC;AAErC,qBAAS,QAAQ;AAAA,UACnB;AAAA,UACA,QAAQ,MAAY;AAClB,mBAAO,KAAK,oBAAoB;AAEhC,oBAAQ,OAAO,MAAM,aAAa;AAClC,oBAAQ;AAAA,UACV;AAAA,QACF,CAAC;AAAA,QACD;AAAA;AAAA,UAEE,cAAc;AAAA;AAAA;AAAA,UAGd,aAAa;AAAA,QACf;AAAA,MACF;AAGA,YAAM,gBAAgB,sBAAsB;AAAA,QAC1C,aAAa,OAAO;AAAA,QACpB,WAAW,YAAY;AAErB,iBAAO,cAAc;AAIrB,kBAAQ,OAAO,MAAM,aAAa;AAElC,gBAAM;AACN,iBAAO,KAAK,kCAAkC;AAAA,QAChD;AAAA,QACA,oBAAoB;AAAA,QACpB,gBAAgB;AAAA,MAClB,CAAC;AAED,oBAAc,EACX,KAAK,MAAM;AAEV,eAAO,cAAc;AACrB,eAAO,KAAK,uBAAuB;AAGnC,gBAAQ,OAAO,MAAM,aAAa;AAElC,sBAAc,UAAU;AACxB,gBAAQ;AAAA,MACV,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,eAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC;AAEjD,eAAO,cAAc;AACrB,gBAAQ,OAAO,MAAM,aAAa;AAClC,sBAAc,UAAU;AACxB,gBAAQ;AAAA,MACV,CAAC;AAAA,IACL,CAAC;AAAA,EACH;AACF;;;AoCxpBO,IAAM,cAAN,MAAkB;AAAA,EACf;AAAA,EAER,YAAY,KAAkB,eAA6B;AACzD,SAAK,cAAc,IAAI,iBAAiB,KAAK,aAAa;AAAA,EAC5D;AAAA,EAEA,MAAM,QAAQ,aAAsB,UAAuB,CAAC,GAAkB;AAC5E,UAAM,OAAO,eAAe,QAAQ,IAAI;AAExC,QAAI,CAAC,QAAQ,OAAO;AAClB,aAAO,KAAK,gCAAgC,EAAE,aAAa,KAAK,CAAC;AAAA,IACnE;AAGA,QAAI,MAAM,KAAK,YAAY,uBAAuB,IAAI,GAAG;AACvD,UAAI,CAAC,QAAQ,OAAO;AAClB,eAAO,KAAK,2DAA2D;AACvE,eAAO,KAAK,mDAAmD;AAAA,MACjE;AACA;AAAA,IACF;AAGA,UAAM,SAAS,MAAM,KAAK,YAAY,oBAAoB,IAAI;AAG9D,QAAI,CAAC,QAAQ,OAAO;AAClB,WAAK,YAAY,aAAa,QAAQ,IAAI;AAAA,IAC5C;AAGA,QAAI,CAAC,OAAO,SAAS;AACnB,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACF;;;AC3CA,OAAOE,WAAU;AACjB,OAAOC,SAAQ;AACf,OAAOC,aAAW;AAClB,SAAS,UAAAC,SAAQ,OAAAC,OAAK,QAAAC,cAAY;AAClC,OAAO,aAAa;AACpB,OAAOC,gBAAe;AAgBf,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YACUC,KACAC,WACR;AAFQ,cAAAD;AACA,oBAAAC;AAAA,EACP;AAAA,EAEH,MAAM,QAAQ,UAA4B,CAAC,GAAkB;AAC3D,QAAI;AAEF,YAAM,cAAc,QAAQ,OAAO,QAAQ;AAG3C,UAAI,YAAY;AAChB,UAAI,CAAC,aAAa;AAChB,oBAAY,MAAM,KAAK,mBAAmB;AAAA,MAC5C;AAEA,UAAI,CAAC,WAAW;AACd,YAAI,CAAC,QAAQ,OAAO;AAClB,iBAAO,KAAK,sBAAsB;AAAA,QACpC;AACA;AAAA,MACF;AAGA,UAAI;AACJ,UAAI,QAAQ,iBAAiB,QAAW;AACtC,qBAAa,CAAC,QAAQ;AAAA,MACxB,WAAW,QAAQ,eAAe,QAAW;AAC3C,qBAAa,QAAQ;AAAA,MACvB,WAAW,aAAa;AAEtB,qBAAa;AAAA,MACf,OAAO;AACL,qBAAa,MAAM,KAAK,iBAAiB;AAAA,MAC3C;AAGA,YAAM,SAAS,MAAM,KAAK,UAAU,YAAY,QAAQ,KAAK;AAG7D,UAAI,CAAC,QAAQ,OAAO;AAClB,aAAK,aAAa,MAAM;AAAA,MAC1B;AAEA,UAAI,CAAC,OAAO,SAAS;AACnB,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,SAAS,OAAO;AACd,UAAI,CAAC,QAAQ,OAAO;AAClB,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC;AAAA,MAC5C;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAc,qBAAuC;AACnD,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,gBAAgB,MAAM;AAC1B,cAAM,CAAC,OAAO,QAAQ,IAAIN,QAAM,SAAS,EAAE;AAC3C,cAAM,CAAC,WAAW,YAAY,IAAIA,QAAM,SAAS,KAAK;AAEtD,QAAAA,QAAM,UAAU,MAAM;AACpB,cAAI,WAAW;AACb,kBAAM,SAAS,MAAM,YAAY;AACjC,oBAAQ,WAAW,OAAO,WAAW,KAAK;AAAA,UAC5C;AAAA,QACF,GAAG,CAAC,WAAW,KAAK,CAAC;AAErB,YAAI,WAAW;AACb,iBAAO;AAAA,QACT;AAEA,eAAOA,QAAM;AAAA,UACXE;AAAA,UACA,EAAE,eAAe,UAAU,SAAS,EAAE;AAAA,UACtCF,QAAM;AAAA,YACJE;AAAA,YACA,EAAE,cAAc,EAAE;AAAA,YAClBF,QAAM;AAAA,cACJG;AAAA,cACA,EAAE,MAAM,MAAM,OAAO,SAAS;AAAA,cAC9B;AAAA,YACF;AAAA,UACF;AAAA,UACAH,QAAM;AAAA,YACJE;AAAA,YACA;AAAA,YACAF,QAAM,cAAcG,QAAM,MAAM,4CAA4C;AAAA,YAC5EH,QAAM,cAAcI,YAAW;AAAA,cAC7B,OAAO;AAAA,cACP,UAAU;AAAA,cACV,UAAU,MAAM,aAAa,IAAI;AAAA,YACnC,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,MAAAH,QAAOD,QAAM,cAAc,aAAa,CAAC;AAAA,IAC3C,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,mBAAqC;AACjD,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,eAAe,MAAM;AACzB,cAAM,CAAC,OAAO,QAAQ,IAAIA,QAAM,SAAS,EAAE;AAC3C,cAAM,CAAC,WAAW,YAAY,IAAIA,QAAM,SAAS,KAAK;AAEtD,QAAAA,QAAM,UAAU,MAAM;AACpB,cAAI,WAAW;AACb,kBAAM,SAAS,MAAM,YAAY;AAEjC,oBAAQ,WAAW,OAAO,WAAW,IAAI;AAAA,UAC3C;AAAA,QACF,GAAG,CAAC,WAAW,KAAK,CAAC;AAErB,YAAI,WAAW;AACb,iBAAO;AAAA,QACT;AAEA,eAAOA,QAAM;AAAA,UACXE;AAAA,UACA,EAAE,eAAe,UAAU,SAAS,EAAE;AAAA,UACtCF,QAAM;AAAA,YACJE;AAAA,YACA,EAAE,cAAc,EAAE;AAAA,YAClBF,QAAM;AAAA,cACJG;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,UACAH,QAAM;AAAA,YACJE;AAAA,YACA;AAAA,YACAF,QAAM,cAAcG,QAAM,MAAM,6BAA6B;AAAA,YAC7DH,QAAM,cAAcI,YAAW;AAAA,cAC7B,OAAO;AAAA,cACP,UAAU;AAAA,cACV,UAAU,MAAM,aAAa,IAAI;AAAA,YACnC,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,MAAAH,QAAOD,QAAM,cAAc,YAAY,CAAC;AAAA,IAC1C,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,UAAU,YAAqB,QAAQ,OAAiC;AACpF,UAAM,SAA0B;AAAA,MAC9B,SAAS;AAAA,MACT,SAAS,CAAC;AAAA,MACV,QAAQ,CAAC;AAAA,MACT;AAAA,IACF;AAEA,QAAI;AAEJ,QAAI,CAAC,OAAO;AACV,YAAM,oBAAoB,MACxBA,QAAM;AAAA,QACJE;AAAA,QACA;AAAA,QACAF,QAAM;AAAA,UACJG;AAAA,UACA,EAAE,OAAO,OAAO;AAAA,UAChBH,QAAM,cAAc,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,UAC7C;AAAA,QACF;AAAA,MACF;AAEF,YAAM,WAAWC,QAAOD,QAAM,cAAc,iBAAiB,CAAC;AAC9D,cAAQ,SAAS;AAAA,IACnB;AAEA,QAAI;AACF,YAAM,UAAUD,IAAG,QAAQ;AAG3B,YAAM,cAAc,MAAM,KAAK,kBAAkB;AACjD,UAAI,CAAC,OAAO;AACV,eAAO,KAAK,+BAA+B,WAAW,EAAE;AAAA,MAC1D;AAGA,UAAI,gBAAgB,UAAU;AAC5B,cAAM,KAAK,yBAAyB,SAAS,QAAQ,KAAK;AAAA,MAC5D;AAGA,UAAI,gBAAgB,OAAO;AACzB,cAAM,KAAK,sBAAsB,QAAQ,KAAK;AAAA,MAChD;AAGA,UAAI,CAAC,YAAY;AACf,cAAM,KAAK,mBAAmB,SAAS,QAAQ,KAAK;AAAA,MACtD,WAAW,CAAC,OAAO;AACjB,eAAO,KAAK,0CAA0C;AAAA,MACxD;AAAA,IACF,SAAS,OAAO;AACd,aAAO,UAAU;AACjB,aAAO,OAAO;AAAA,QACZ,qBAAqB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAC7E;AACA,UAAI,CAAC,OAAO;AACV,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC;AAAA,MAC3C;AAAA,IACF,UAAE;AACA,UAAI,OAAO;AACT,cAAM;AAAA,MACR;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,oBAA2D;AACvE,QAAI;AAEF,YAAM,aAAa,QAAQ,KAAK,CAAC;AAEjC,UAAI,CAAC,YAAY;AACf,eAAO,MAAM,yCAAyC;AACtD,eAAO;AAAA,MACT;AAEA,aAAO,MAAM,4CAA4C,UAAU,EAAE;AAGrE,YAAM,iBAAiBD,MAAK,UAAU,UAAU,EAAE,YAAY;AAG9D,UAAI,eAAe,SAAS,cAAc,GAAG;AAC3C,eAAO,MAAM,kDAAkD;AAC/D,eAAO;AAAA,MACT;AAGA,YAAM,UAAUC,IAAG,QAAQ;AAC3B,YAAM,eAAeD,MAAK,UAAUA,MAAK,KAAK,SAAS,UAAU,KAAK,CAAC,EAAE,YAAY;AACrF,YAAM,eAAeA,MAAK,UAAUA,MAAK,KAAK,SAAS,UAAU,KAAK,CAAC,EAAE,YAAY;AAErF,UAAI,eAAe,SAAS,YAAY,GAAG;AACzC,eAAO,MAAM,mDAAmD;AAChE,eAAO;AAAA,MACT;AAEA,UAAI,eAAe,SAAS,YAAY,GAAG;AACzC,eAAO,MAAM,mDAAmD;AAChE,eAAO;AAAA,MACT;AAGA,YAAM,cAAc;AAAA;AAAA,QAElBA,MAAK,KAAK,SAAS,UAAU,OAAO,OAAO;AAAA,QAC3CA,MAAK,KAAK,SAAS,UAAU,OAAO,OAAO;AAAA;AAAA,QAE3CA,MAAK,KAAK,SAAS,UAAU,OAAO,WAAW;AAAA,QAC/CA,MAAK,KAAK,SAAS,UAAU,OAAO,WAAW;AAAA,QAC/CA,MAAK,KAAK,SAAS,UAAU,OAAO,WAAW;AAAA,QAC/CA,MAAK,KAAK,SAAS,UAAU,OAAO,WAAW;AAAA,MACjD;AAEA,iBAAW,WAAW,aAAa;AACjC,YAAI,MAAM,KAAK,GAAG,OAAO,OAAO,GAAG;AACjC,iBAAO,MAAM,+CAA+C,OAAO,GAAG;AACtE,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,aAAO,MAAM,4DAA4D;AACzE,aAAO;AAAA,IACT,SAAS,OAAO;AACd,aAAO,MAAM,qCAAqC,EAAE,MAAM,CAAC;AAC3D,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,sBAAsB,QAAyB,QAAQ,OAAsB;AACzF,QAAI,CAAC,KAAK,UAAU;AAClB,UAAI,CAAC,OAAO;AACV,eAAO,KAAK,6CAA6C;AACzD,eAAO,KAAK,2DAA2D;AAAA,MACzE;AACA;AAAA,IACF;AAEA,QAAI;AACF,UAAI,CAAC,OAAO;AACV,eAAO,KAAK,gCAAgC;AAAA,MAC9C;AAEA,YAAM,YAAY,MAAM,KAAK,SAAS;AAAA,QACpC;AAAA,QACA,CAAC,aAAa,MAAM,qBAAqB;AAAA,QACzC;AAAA,UACE,KAAK,QAAQ,IAAI;AAAA,QACnB;AAAA,MACF;AAEA,UAAI,UAAU,aAAa,GAAG;AAC5B,eAAO,QAAQ,KAAK,0CAA0C;AAC9D,YAAI,CAAC,OAAO;AACV,iBAAO,KAAK,sCAAsC;AAAA,QACpD;AAAA,MACF,OAAO;AACL,cAAM,IAAI,MAAM,yBAAyB,UAAU,MAAM,EAAE;AAAA,MAC7D;AAAA,IACF,SAAS,OAAO;AACd,UAAI,CAAC,OAAO;AACV,eAAO,MAAM,mCAAmC,EAAE,MAAM,CAAC;AACzD,eAAO,KAAK,2DAA2D;AAAA,MACzE;AACA,aAAO,OAAO;AAAA,QACZ,yBAAyB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACjF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,yBACZ,SACA,QACA,QAAQ,OACO;AACf,UAAM,YAAY,QAAQ,aAAa;AACvC,UAAM,eAAeA,MAAK,KAAK,SAAS,UAAU,OAAO,OAAO;AAChE,UAAM,cAAcA,MAAK,KAAK,SAAS,UAAU,KAAK;AAEtD,QAAI,WAAW;AAEb,YAAM,KAAK,oBAAoB,cAAc,aAAa,KAAK;AAG/D,YAAM,KAAK,sBAAsB,KAAK;AAEtC,aAAO,QAAQ,KAAK,4CAA4C;AAChE,aAAO,QAAQ,KAAK,YAAY;AAEhC,UAAI,CAAC,OAAO;AACV,eAAO,KAAK,kCAA6B;AACzC,eAAO,KAAK,0BAAqB;AACjC,eAAO,KAAK,6CAAwC;AAAA,MACtD;AAAA,IACF,OAAO;AAEL,UAAI,MAAM,KAAK,GAAG,OAAO,YAAY,GAAG;AACtC,cAAM,KAAK,GAAG,OAAO,YAAY;AACjC,eAAO,QAAQ,KAAK,oBAAoB;AACxC,YAAI,CAAC,OAAO;AACV,iBAAO,KAAK,kCAAkC;AAAA,QAChD;AAAA,MACF;AAEA,UAAI,MAAM,KAAK,GAAG,OAAO,WAAW,GAAG;AACrC,cAAM,KAAK,GAAG,MAAM,aAAa,EAAE,WAAW,KAAK,CAAC;AACpD,eAAO,QAAQ,KAAK,eAAe;AACnC,YAAI,CAAC,OAAO;AACV,iBAAO,KAAK,0BAA0B;AAAA,QACxC;AAAA,MACF;AAEA,UAAI,CAAC,OAAO;AACV,eAAO,KAAK,2BAAsB;AAClC,eAAO,KAAK,iDAA4C;AACxD,eAAO,KAAK,yCAAyC;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,oBACZ,SACA,QACA,OACe;AACf,QAAI,CAAC,KAAK,UAAU;AAClB,UAAI,CAAC,OAAO;AACV,eAAO,KAAK,sDAAsD;AAAA,MACpE;AACA;AAAA,IACF;AAEA,QAAI;AAEF,YAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA,YAKhB,OAAO;AAAA,eACJ,OAAO;AAAA;AAAA,YAEV,OAAO;AAAA,eACJ,OAAO;AAAA;AAAA,YAEV,OAAO;AAAA,eACJ,OAAO;AAAA;AAAA;AAAA;AAAA,YAIV,MAAM;AAAA,iBACD,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAOjB,YAAM,UAAUC,IAAG,OAAO;AAC1B,YAAM,cAAcD,MAAK,KAAK,SAAS,iBAAiB,KAAK,IAAI,CAAC,MAAM;AAExE,YAAM,KAAK,GAAG,UAAU,aAAa,aAAa;AAGlD,YAAM,EAAE,MAAM,IAAI,MAAM,OAAO,eAAe;AAC9C,YAAM,QAAQ,MAAM,OAAO,CAAC,MAAM,WAAW,GAAG;AAAA,QAC9C,UAAU;AAAA,QACV,OAAO;AAAA,QACP,aAAa;AAAA,MACf,CAAC;AACD,YAAM,MAAM;AAEZ,UAAI,CAAC,OAAO;AACV,eAAO,KAAK,oCAAoC;AAAA,MAClD;AAAA,IACF,SAAS,OAAO;AACd,UAAI,CAAC,OAAO;AACV,eAAO,MAAM,mCAAmC,EAAE,MAAM,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,sBAAsB,OAA+B;AACjE,QAAI,CAAC,KAAK,SAAU;AAEpB,QAAI;AAEF,YAAM,SAAS,MAAM,KAAK,SAAS;AAAA,QACjC;AAAA,QACA,CAAC,cAAc,YAAY,uDAAuD;AAAA,QAClF,EAAE,KAAK,QAAQ,IAAI,EAAE;AAAA,MACvB;AAEA,UAAI,OAAO,aAAa,GAAG;AACzB,cAAM,IAAI,MAAM,qBAAqB;AAAA,MACvC;AAEA,YAAM,cAAc,OAAO,OAAO,KAAK;AACvC,YAAM,cAAc,YAAY,MAAM,GAAG,EAAE,OAAO,OAAO;AAGzD,YAAM,kBAAkB,YAAY,OAAO,CAAC,UAAU;AACpD,cAAM,kBAAkBA,MAAK,UAAU,MAAM,KAAK,CAAC,EAAE,YAAY;AACjE,eAAO,CAAC,gBAAgB,SAAS,OAAO;AAAA,MAC1C,CAAC;AAGD,UAAI,gBAAgB,SAAS,YAAY,QAAQ;AAC/C,cAAM,UAAU,gBAAgB,KAAK,GAAG;AAExC,cAAM,KAAK,SAAS;AAAA,UAClB;AAAA,UACA;AAAA,YACE;AAAA,YACA;AAAA,YACA,kDAAkD,OAAO;AAAA,UAC3D;AAAA,UACA,EAAE,KAAK,QAAQ,IAAI,EAAE;AAAA,QACvB;AAEA,cAAM,eAAe,YAAY,SAAS,gBAAgB;AAC1D,YAAI,CAAC,OAAO;AACV,iBAAO,KAAK,WAAW,YAAY,wCAAwC;AAAA,QAC7E;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,UAAI,CAAC,OAAO;AACV,eAAO,KAAK,8BAA8B,EAAE,MAAM,CAAC;AACnD,eAAO,KAAK,2CAA2C;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,mBACZ,SACA,QACA,QAAQ,OACO;AACf,UAAM,WAAWA,MAAK,KAAK,SAAS,QAAQ;AAE5C,QAAI,MAAM,KAAK,GAAG,OAAO,QAAQ,GAAG;AAElC,YAAM,KAAK,GAAG,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AACjD,aAAO,QAAQ,KAAK,WAAW;AAC/B,UAAI,CAAC,OAAO;AACV,eAAO,KAAK,2CAA2C;AACvD,eAAO,KAAK,kCAAkC;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,aAAa,QAA+B;AAC1C,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,4UAAyD;AAErE,QAAI,OAAO,SAAS;AAClB,cAAQ,IAAI,mCAA8B;AAAA,IAC5C,OAAO;AACL,cAAQ,IAAI,wCAAmC;AAAA,IACjD;AAEA,YAAQ,IAAI,4UAAyD;AAErE,QAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,UAAU;AACtB,aAAO,QAAQ,QAAQ,CAAC,SAAS,QAAQ,IAAI,OAAO,IAAI,EAAE,CAAC;AAAA,IAC7D;AAEA,QAAI,OAAO,YAAY;AACrB,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,0BAA0B;AACtC,cAAQ,IAAI,wCAAwC;AACpD,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,0BAA0B;AACtC,cAAQ,IAAI,yCAAyC;AACrD,cAAQ,IAAI,gCAAgC;AAAA,IAC9C;AAEA,QAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,SAAS;AACrB,aAAO,OAAO,QAAQ,CAAC,UAAU,QAAQ,IAAI,OAAO,KAAK,EAAE,CAAC;AAAA,IAC9D;AAEA,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,sCAA+B;AAC3C,YAAQ,IAAI,EAAE;AAAA,EAChB;AAAA;AAEF;;;AhExiBA,IAAMS,MAAK,IAAI,kBAAkB;AACjC,IAAM,WAAW,IAAI,uBAAuB;AAC5C,IAAM,eAAe,IAAI,aAAaA,GAAE;AACxC,IAAM,mBAAmB,IAAI,iBAAiBA,GAAE;AAChD,IAAM,eAAe,IAAI,aAAa,YAAY;AAClD,IAAM,cAAc,IAAI,YAAY,cAAc,kBAAkB,cAAcA,GAAE;AACpF,IAAM,cAAc,IAAI,YAAYA,KAAI,YAAY;AACpD,IAAM,mBAAmB,IAAI,iBAAiBA,KAAI,QAAQ;AAE1D,IAAM,UAAU,IAAI,QAAQ;AAE5B,QAAQ,KAAK,OAAO,EAAE,YAAY,6CAA6C,EAAE,QAAQ,OAAO;AAGhG,QACG,QAAQ,OAAO,EACf,YAAY,kBAAkB,EAC9B,OAAO,YAAY;AAClB,QAAM,aAAa,QAAQ;AAC3B,UAAQ,KAAK,CAAC;AAChB,CAAC;AAGH,QACG,QAAQ,QAAQ,EAAE,WAAW,KAAK,CAAC,EACnC,YAAY,gCAAgC,EAC5C,OAAO,YAAY;AAClB,QAAM,YAAY,QAAQ;AAC1B,UAAQ,KAAK,CAAC;AAChB,CAAC;AAGH,QACG,QAAQ,MAAM,EACd,YAAY,qCAAqC,EACjD,OAAO,oBAAoB,uDAAuD,EAClF,OAAO,eAAe,iBAAiB,EACvC,OAAO,OAAO,YAAwD;AACrE,QAAM,YAAY,QAAQ,QAAW,OAAO;AAC5C,UAAQ,KAAK,CAAC;AAChB,CAAC;AAGH,QACG,QAAQ,WAAW,EACnB,YAAY,kCAAkC,EAC9C,OAAO,aAAa,2BAA2B,EAC/C,OAAO,iBAAiB,yCAAyC,EACjE,OAAO,mBAAmB,2CAA2C,EACrE,OAAO,eAAe,iCAAiC,EACvD;AAAA,EACC,OAAO,YAKD;AACJ,UAAM,iBAAiB,QAAQ,OAAO;AACtC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAGF,IAAM,UAAU,QAAQ,QAAQ,SAAS,EAAE,YAAY,6BAA6B;AAEpF,QACG,QAAQ,MAAM,EACd,YAAY,2BAA2B,EACvC,OAAO,MAAM;AACZ,SAAO,KAAK,gDAAgD;AAC9D,CAAC;AAEH,QACG,QAAQ,aAAa,EACrB,YAAY,uBAAuB,EACnC,OAAO,CAAC,OAAe;AACtB,SAAO,KAAK,yBAAyB,EAAE,2BAA2B;AACpE,CAAC;AAEH,QACG,QAAQ,aAAa,EACrB,YAAY,6BAA6B,EACzC,OAAO,CAAC,OAAe;AACtB,SAAO,KAAK,0BAA0B,EAAE,2BAA2B;AACrE,CAAC;AAEH,QACG,QAAQ,OAAO,EACf,YAAY,4BAA4B,EACxC,OAAO,MAAM;AACZ,SAAO,KAAK,2CAA2C;AACzD,CAAC;AAGH,IAAM,OAAO,QAAQ,QAAQ,MAAM,EAAE,YAAY,qBAAqB;AAEtE,KACG,QAAQ,OAAO,EACf,YAAY,uBAAuB,EACnC,OAAO,MAAM;AACZ,SAAO,KAAK,iDAAiD;AAC/D,CAAC;AAEH,KACG,QAAQ,MAAM,EACd,YAAY,sBAAsB,EAClC,OAAO,MAAM;AACZ,SAAO,KAAK,gDAAgD;AAC9D,CAAC;AAEH,KACG,QAAQ,OAAO,EACf,YAAY,uBAAuB,EACnC,OAAO,MAAM;AACZ,SAAO,KAAK,iDAAiD;AAC/D,CAAC;AAEH,KACG,QAAQ,SAAS,EACjB,YAAY,wBAAwB,EACpC,OAAO,MAAM;AACZ,SAAO,KAAK,8CAA8C;AAC5D,CAAC;AAGH,QACG,QAAQ,QAAQ,EAChB,YAAY,iBAAiB,EAC7B,OAAO,MAAM;AACZ,SAAO,KAAK,8CAA8C;AAC5D,CAAC;AAGH,IAAM,cAAc,QAAQ,QAAQ,aAAa,EAAE,YAAY,4BAA4B;AAE3F,YACG,QAAQ,MAAM,EACd,YAAY,uBAAuB,EACnC,OAAO,MAAM;AACZ,SAAO,KAAK,8CAA8C;AAC5D,CAAC;AAEH,YACG,QAAQ,eAAe,EACvB,YAAY,0BAA0B,EACtC,OAAO,CAAC,YAAoB;AAC3B,SAAO,KAAK,UAAU,OAAO,wCAAwC;AACvE,CAAC;AAEH,YACG,QAAQ,kBAAkB,EAC1B,YAAY,+BAA+B,EAC3C,OAAO,CAAC,YAAoB;AAC3B,SAAO,KAAK,YAAY,OAAO,0CAA0C;AAC3E,CAAC;AAEH,QAAQ,MAAM;","names":["path","fs","path","z","fs","yaml","path","fs","path","yaml","path","os","fs","React","useState","Box","Box","Text","jsx","Box","Text","Box","Text","chalk","os","jsx","jsxs","chalk","Box","Text","useMemo","Box","Text","chalk","chalk","jsx","jsxs","chalk","fg","useMemo","Box","Text","jsx","jsxs","useState","Box","configLoader","React","React","render","useEffect","useState","useMemo","useCallback","useRef","useEffect","Box","Text","Box","Text","jsx","jsxs","Box","Text","Box","Text","jsx","jsxs","cost","Box","Text","React","useState","useEffect","Box","Text","React","useMemo","Box","Text","chalk","useState","jsx","jsxs","chalk","useMemo","safeSelectedIndex","startIndex","endIndex","moreAbove","moreBelow","moreAboveCount","moreBelowCount","actualHeight","React","maxWidth","Box","Text","jsx","jsxs","React","useState","useEffect","Box","Text","useState","useEffect","Box","Text","jsx","jsxs","cost","Text","useState","useEffect","Box","handlers","useEffect","useState","os","jsx","useState","useEffect","useEffect","useEffect","useInput","useInput","jsx","jsxs","useState","useRef","useEffect","useMemo","useCallback","Box","Text","jsx","useEffect","fs","z","yaml","path","os","z","fs","path","os","yaml","z","z","helpText","themes","existsSync","readFileSync","path","dirname","fs","configLoader","encode","encode","path","yaml","configLoader","firstRunDetector","setupCommand","fs","rerender","React","render","path","os","React","render","Box","Text","TextInput","fs","executor","fs"]}
|