politty 0.3.2 → 0.3.3

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner-9dLE13Dv.cjs","names":["createLogCollector","mergeLogs","emptyLogs","getExtractedFields","extractFields","resolveLazyCommand","extractFields","formatValidationErrors","createLogCollector","mergeLogs","emptyLogs","listSubCommands","resolveSubcommand","formatValidationErrors"],"sources":["../src/executor/command-runner.ts","../src/output/logger.ts","../src/output/markdown-renderer.ts","../src/output/help-generator.ts","../src/validator/validation-errors.ts","../src/validator/command-validator.ts","../src/parser/argv-parser.ts","../src/parser/arg-parser.ts","../src/validator/error-formatter.ts","../src/validator/zod-validator.ts","../src/core/runner.ts"],"sourcesContent":["import type {\n AnyCommand,\n CleanupContext,\n CollectedLogs,\n RunResult,\n SetupContext,\n} from \"../types.js\";\nimport { createLogCollector, emptyLogs, mergeLogs } from \"./log-collector.js\";\n\n/**\n * Options for lifecycle execution\n */\nexport interface ExecuteLifecycleOptions {\n /** Handle signals (SIGINT, SIGTERM) */\n handleSignals?: boolean | undefined;\n /** Capture console output */\n captureLogs?: boolean | undefined;\n /** Existing logs to include in result (from runCommandInternal) */\n existingLogs?: CollectedLogs | undefined;\n}\n\n/**\n * Execute a command lifecycle: setup → run → cleanup\n *\n * This is an internal function that executes the command's lifecycle hooks.\n * For running commands with argument parsing, use `runCommand` instead.\n *\n * @param command - The command to execute\n * @param args - Already validated arguments\n * @param options - Lifecycle options\n * @returns The result of command execution\n * @internal\n */\nexport async function executeLifecycle<TResult = unknown>(\n command: AnyCommand,\n args: unknown,\n _options: ExecuteLifecycleOptions = {},\n): Promise<RunResult<TResult>> {\n let error: Error | undefined;\n let result: TResult | undefined;\n\n const shouldCollectLogs = _options.captureLogs ?? false;\n const collector = shouldCollectLogs ? createLogCollector() : null;\n collector?.start();\n\n const setupContext: SetupContext<unknown> = {\n args,\n };\n\n const cleanupContext: CleanupContext<unknown> = {\n args,\n error,\n };\n\n // Signal handler\n let signalHandler: ((signal: NodeJS.Signals) => Promise<void>) | undefined;\n\n if (_options.handleSignals) {\n signalHandler = async (_signal: NodeJS.Signals) => {\n // Remove listeners to prevent multiple calls\n if (signalHandler) {\n process.off(\"SIGINT\", signalHandler);\n process.off(\"SIGTERM\", signalHandler);\n }\n\n // Run cleanup\n if (command.cleanup) {\n try {\n // Update error in context if needed, though usually signal is the cause\n // We don't set 'error' here because it might overwrite a real error if we were in a catch block?\n // But here we are interrupting.\n await command.cleanup(cleanupContext);\n } catch (e) {\n console.error(\"Error during signal cleanup:\", e);\n }\n }\n\n // Stop log collection before exit\n collector?.stop();\n\n // Exit\n process.exit(1);\n };\n\n process.on(\"SIGINT\", signalHandler);\n process.on(\"SIGTERM\", signalHandler);\n }\n\n try {\n // Execute setup\n if (command.setup) {\n await command.setup(setupContext);\n }\n\n // Execute run\n if (command.run) {\n result = await command.run(args);\n }\n } catch (e) {\n error = e instanceof Error ? e : new Error(String(e));\n } finally {\n // Remove signal listeners\n if (signalHandler) {\n process.off(\"SIGINT\", signalHandler);\n process.off(\"SIGTERM\", signalHandler);\n }\n }\n\n // Always execute cleanup\n if (command.cleanup) {\n // Update error in context\n cleanupContext.error = error;\n\n try {\n await command.cleanup(cleanupContext);\n } catch (cleanupError) {\n // If cleanup fails and there was no previous error, use cleanup error\n if (!error) {\n error = cleanupError instanceof Error ? cleanupError : new Error(String(cleanupError));\n }\n }\n }\n\n // Stop log collection\n collector?.stop();\n\n // Merge existing logs with collected logs\n const existingLogs = _options.existingLogs ?? emptyLogs();\n const collectedLogs = collector?.getLogs() ?? emptyLogs();\n const logs = mergeLogs(existingLogs, collectedLogs);\n\n if (error) {\n return {\n success: false,\n error,\n exitCode: 1,\n logs,\n };\n }\n\n return {\n success: true,\n result,\n exitCode: 0,\n logs,\n };\n}\n","import { styleText } from \"node:util\";\n\n/**\n * Check if color output should be disabled\n */\nfunction shouldDisableColor(): boolean {\n // Disable if NO_COLOR is set (https://no-color.org/)\n if (process.env.NO_COLOR !== undefined) {\n return true;\n }\n\n // Disable if FORCE_COLOR is explicitly set to 0\n if (process.env.FORCE_COLOR === \"0\") {\n return true;\n }\n\n // Enable if FORCE_COLOR is set (even in CI or non-TTY)\n if (process.env.FORCE_COLOR) {\n return false;\n }\n\n // Disable in CI environments\n if (process.env.CI) {\n return true;\n }\n\n // Disable if not a TTY\n if (!process.stdout.isTTY) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Global flag to control color output\n */\nlet colorDisabled = shouldDisableColor();\n\n/**\n * Enable or disable color output programmatically\n */\nexport function setColorEnabled(enabled: boolean): void {\n colorDisabled = !enabled;\n}\n\n/**\n * Check if color output is currently enabled\n */\nexport function isColorEnabled(): boolean {\n return !colorDisabled;\n}\n\n/**\n * Create a style function that applies the given styles\n */\nfunction createStyleFn(...styleArgs: Parameters<typeof styleText>[0][]): (text: string) => string {\n return (text: string) => {\n if (colorDisabled) {\n return text;\n }\n let result = text;\n for (const style of styleArgs) {\n result = styleText(style, result);\n }\n return result;\n };\n}\n\n/**\n * Semantic style functions for inline text styling\n */\nexport const styles = {\n // Status colors\n success: createStyleFn(\"green\"),\n error: createStyleFn(\"red\"),\n warning: createStyleFn(\"yellow\"),\n info: createStyleFn(\"cyan\"),\n\n // Emphasis\n bold: createStyleFn(\"bold\"),\n dim: createStyleFn(\"dim\"),\n italic: createStyleFn(\"italic\"),\n underline: createStyleFn(\"underline\"),\n\n // Colors\n red: createStyleFn(\"red\"),\n green: createStyleFn(\"green\"),\n yellow: createStyleFn(\"yellow\"),\n blue: createStyleFn(\"blue\"),\n magenta: createStyleFn(\"magenta\"),\n cyan: createStyleFn(\"cyan\"),\n white: createStyleFn(\"white\"),\n gray: createStyleFn(\"gray\"),\n\n // Help-specific styles\n command: createStyleFn(\"bold\"),\n commandName: createStyleFn(\"bold\", \"underline\", \"cyan\"),\n option: createStyleFn(\"cyan\"),\n optionName: createStyleFn(\"bold\"),\n placeholder: createStyleFn(\"dim\"),\n defaultValue: createStyleFn(\"dim\"),\n required: createStyleFn(\"yellow\"),\n description: (text: string) => text, // No style for descriptions\n sectionHeader: createStyleFn(\"bold\", \"underline\"),\n version: createStyleFn(\"dim\"),\n};\n\n/**\n * Standardized symbols for CLI output\n */\nexport const symbols = {\n success: styles.green(\"✓\"),\n error: styles.red(\"✖\"),\n warning: styles.yellow(\"⚠\"),\n info: styles.cyan(\"ℹ\"),\n bullet: styles.gray(\"•\"),\n arrow: styles.gray(\"→\"),\n};\n\n/**\n * Logger for CLI output\n */\nexport const logger = {\n /**\n * Log informational message\n */\n info(message: string): void {\n console.log(message);\n },\n\n /**\n * Log success message\n */\n success(message: string): void {\n console.log(`${symbols.success} ${styles.success(message)}`);\n },\n\n /**\n * Log warning message\n */\n warn(message: string): void {\n console.warn(`${symbols.warning} ${styles.warning(message)}`);\n },\n\n /**\n * Log error message\n */\n error(message: string): void {\n console.error(`${symbols.error} ${styles.error(message)}`);\n },\n\n /**\n * Log raw message without prefix\n */\n log(message: string): void {\n console.log(message);\n },\n\n /**\n * Log empty line\n */\n newline(): void {\n console.log(\"\");\n },\n\n /**\n * Log debug message with dim color\n */\n debug(message: string): void {\n console.log(styles.dim(message));\n },\n};\n","import stringWidth from \"string-width\";\nimport { styles } from \"./logger.js\";\n\n/**\n * Lightweight Markdown-to-terminal renderer.\n *\n * Supports a subset of Markdown tailored for CLI help notes:\n * - Inline: bold, italic, inline code, links\n * - Block: paragraphs, unordered/ordered lists, blockquotes, headings,\n * horizontal rules, fenced code blocks\n */\n\n/**\n * Apply inline Markdown formatting to a string.\n *\n * Processing order matters to avoid conflicts:\n * 1. Inline code (backticks) — content inside is literal, no further processing\n * 2. Bold (**text**)\n * 3. Italic (*text* or _text_)\n * 4. Links [text](url)\n */\nexport function renderInline(text: string): string {\n // 1. Protect inline code spans — extract them, replace with placeholders, restore later\n const codeSpans: string[] = [];\n let result = text.replace(/`([^`]+)`/g, (_match, code: string) => {\n const index = codeSpans.length;\n codeSpans.push(styles.cyan(code));\n return `\\x00CODE${index}\\x00`;\n });\n\n // 2. Bold: **text** or __text__\n result = result.replace(/\\*\\*(.+?)\\*\\*/g, (_match, content: string) => styles.bold(content));\n result = result.replace(/__(.+?)__/g, (_match, content: string) => styles.bold(content));\n\n // 3. Italic: *text* or _text_\n // Negative lookbehind/lookahead to avoid matching inside words for underscore\n result = result.replace(/\\*(.+?)\\*/g, (_match, content: string) => styles.italic(content));\n result = result.replace(/(?<!\\w)_(.+?)_(?!\\w)/g, (_match, content: string) =>\n styles.italic(content),\n );\n\n // 4. Links: [text](url)\n result = result.replace(\n /\\[([^\\]]+)\\]\\(([^)]+)\\)/g,\n (_match, linkText: string, url: string) =>\n `${styles.underline(linkText)} ${styles.dim(`(${url})`)}`,\n );\n\n // Restore code spans\n result = result.replace(\n // eslint-disable-next-line no-control-regex -- null bytes are intentionally used as code span delimiters\n /\\x00CODE(\\d+)\\x00/g,\n (_match, index: string) => codeSpans[Number(index)]!,\n );\n\n return result;\n}\n\n/**\n * Render a Markdown string to styled terminal output.\n *\n * Block-level processing:\n * - Splits input into blocks separated by blank lines\n * - Detects headings, horizontal rules, blockquotes, lists, code blocks, and paragraphs\n * - Applies inline formatting within each block\n */\nexport function renderMarkdown(markdown: string): string {\n const lines = markdown.split(\"\\n\");\n const blocks = splitIntoBlocks(lines);\n const rendered = blocks.map(renderBlock);\n return rendered.join(\"\\n\\n\");\n}\n\n// --- Block-level types ---\n\ninterface ParagraphBlock {\n type: \"paragraph\";\n lines: string[];\n}\n\ninterface HeadingBlock {\n type: \"heading\";\n level: number;\n content: string;\n}\n\ninterface HorizontalRuleBlock {\n type: \"hr\";\n}\n\ninterface BlockquoteBlock {\n type: \"blockquote\";\n lines: string[];\n}\n\ntype AlertType = \"NOTE\" | \"TIP\" | \"IMPORTANT\" | \"WARNING\" | \"CAUTION\";\n\ninterface AlertBlock {\n type: \"alert\";\n alertType: AlertType;\n lines: string[];\n}\n\ninterface UnorderedListBlock {\n type: \"ul\";\n items: string[];\n}\n\ninterface OrderedListBlock {\n type: \"ol\";\n items: string[];\n start: number;\n}\n\ninterface CodeBlock {\n type: \"code\";\n lang: string;\n lines: string[];\n}\n\ninterface TableBlock {\n type: \"table\";\n headers: string[];\n alignments: (\"left\" | \"center\" | \"right\")[];\n rows: string[][];\n}\n\ntype Block =\n | ParagraphBlock\n | HeadingBlock\n | HorizontalRuleBlock\n | BlockquoteBlock\n | AlertBlock\n | UnorderedListBlock\n | OrderedListBlock\n | CodeBlock\n | TableBlock;\n\n// --- Block detection patterns ---\n\nconst HEADING_RE = /^(#{1,6})\\s+(.+)$/;\nconst HR_RE = /^(?:---+|\\*\\*\\*+|___+)\\s*$/;\nconst BLOCKQUOTE_RE = /^>\\s?(.*)$/;\nconst UL_RE = /^-\\s+(.+)$/;\nconst OL_RE = /^(\\d+)[.)]\\s+(.+)$/;\nconst FENCE_OPEN_RE = /^(`{3,}|~{3,})(\\S*)\\s*$/;\nconst ALERT_RE = /^\\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\\]\\s*$/;\nconst TABLE_ROW_RE = /^\\|(.+)\\|$/;\nconst TABLE_SEP_RE = /^\\|(\\s*:?-+:?\\s*\\|)+$/;\n\n/**\n * Split lines into logical blocks separated by blank lines.\n * Consecutive lines of the same block type are grouped together.\n */\nfunction splitIntoBlocks(lines: string[]): Block[] {\n const blocks: Block[] = [];\n let i = 0;\n\n while (i < lines.length) {\n const line = lines[i]!;\n\n // Skip blank lines\n if (line.trim() === \"\") {\n i++;\n continue;\n }\n\n // Fenced code block\n const fenceMatch = line.match(FENCE_OPEN_RE);\n if (fenceMatch) {\n const fence = fenceMatch[1]!;\n const lang = fenceMatch[2] ?? \"\";\n const codeLines: string[] = [];\n i++; // skip opening fence\n while (i < lines.length) {\n // Closing fence: same char, at least same length\n if (\n lines[i]!.startsWith(fence.charAt(0).repeat(fence.length)) &&\n lines[i]!.trim() ===\n fence.charAt(0).repeat(Math.max(fence.length, lines[i]!.trim().length))\n ) {\n i++; // skip closing fence\n break;\n }\n codeLines.push(lines[i]!);\n i++;\n }\n blocks.push({ type: \"code\", lang, lines: codeLines });\n continue;\n }\n\n // Heading\n const headingMatch = line.match(HEADING_RE);\n if (headingMatch) {\n blocks.push({\n type: \"heading\",\n level: headingMatch[1]!.length,\n content: headingMatch[2]!,\n });\n i++;\n continue;\n }\n\n // Horizontal rule\n if (HR_RE.test(line)) {\n blocks.push({ type: \"hr\" });\n i++;\n continue;\n }\n\n // Blockquote or GitHub alert (consecutive > lines)\n if (BLOCKQUOTE_RE.test(line)) {\n const bqLines: string[] = [];\n while (i < lines.length) {\n const bqMatch = lines[i]!.match(BLOCKQUOTE_RE);\n if (bqMatch) {\n bqLines.push(bqMatch[1]!);\n i++;\n } else {\n break;\n }\n }\n // Check if first line is a GitHub alert marker: [!TYPE]\n if (bqLines.length > 0) {\n const alertMatch = bqLines[0]!.match(ALERT_RE);\n if (alertMatch) {\n const contentLines = bqLines.slice(1).filter((l) => l !== \"\");\n blocks.push({\n type: \"alert\",\n alertType: alertMatch[1] as AlertType,\n lines: contentLines,\n });\n continue;\n }\n }\n blocks.push({ type: \"blockquote\", lines: bqLines });\n continue;\n }\n\n // Unordered list (consecutive - lines only)\n if (UL_RE.test(line)) {\n const items: string[] = [];\n while (i < lines.length) {\n const ulMatch = lines[i]!.match(UL_RE);\n if (ulMatch) {\n items.push(ulMatch[1]!);\n i++;\n } else {\n break;\n }\n }\n blocks.push({ type: \"ul\", items });\n continue;\n }\n\n // Ordered list (consecutive numbered lines)\n const olMatch = line.match(OL_RE);\n if (olMatch) {\n const start = Number(olMatch[1]);\n const items: string[] = [];\n while (i < lines.length) {\n const match = lines[i]!.match(OL_RE);\n if (match) {\n items.push(match[2]!);\n i++;\n } else {\n break;\n }\n }\n blocks.push({ type: \"ol\", items, start });\n continue;\n }\n\n // Table: header row | separator row | body rows\n if (TABLE_ROW_RE.test(line) && i + 1 < lines.length && TABLE_SEP_RE.test(lines[i + 1]!)) {\n const headers = parseCells(line);\n const alignments = parseAlignments(lines[i + 1]!);\n i += 2; // skip header + separator\n const rows: string[][] = [];\n while (i < lines.length && TABLE_ROW_RE.test(lines[i]!)) {\n rows.push(parseCells(lines[i]!));\n i++;\n }\n blocks.push({ type: \"table\", headers, alignments, rows });\n continue;\n }\n\n // Paragraph: collect consecutive non-blank, non-block-start lines\n const paraLines: string[] = [];\n while (i < lines.length) {\n const l = lines[i]!;\n if (\n l.trim() === \"\" ||\n HEADING_RE.test(l) ||\n HR_RE.test(l) ||\n BLOCKQUOTE_RE.test(l) ||\n UL_RE.test(l) ||\n OL_RE.test(l) ||\n FENCE_OPEN_RE.test(l) ||\n (TABLE_ROW_RE.test(l) && i + 1 < lines.length && TABLE_SEP_RE.test(lines[i + 1]!))\n ) {\n break;\n }\n paraLines.push(l);\n i++;\n }\n if (paraLines.length > 0) {\n blocks.push({ type: \"paragraph\", lines: paraLines });\n }\n }\n\n return blocks;\n}\n\n/**\n * Parse cells from a table row: `| a | b | c |` → `[\"a\", \"b\", \"c\"]`\n */\nfunction parseCells(row: string): string[] {\n return row\n .slice(1, -1)\n .split(\"|\")\n .map((cell) => cell.trim());\n}\n\n/**\n * Parse alignment from separator row: `|:---|:---:|---:|` → `[\"left\", \"center\", \"right\"]`\n */\nfunction parseAlignments(sepRow: string): (\"left\" | \"center\" | \"right\")[] {\n return sepRow\n .slice(1, -1)\n .split(\"|\")\n .map((cell) => {\n const trimmed = cell.trim();\n if (trimmed.startsWith(\":\") && trimmed.endsWith(\":\")) return \"center\";\n if (trimmed.endsWith(\":\")) return \"right\";\n return \"left\";\n });\n}\n\n/**\n * Pad a string to a given width with the specified alignment.\n */\nfunction alignText(text: string, width: number, alignment: \"left\" | \"center\" | \"right\"): string {\n const visualWidth = stringWidth(text);\n const total = Math.max(0, width - visualWidth);\n if (alignment === \"right\") return \" \".repeat(total) + text;\n if (alignment === \"center\") {\n const left = Math.floor(total / 2);\n return \" \".repeat(left) + text + \" \".repeat(total - left);\n }\n return text + \" \".repeat(total);\n}\n\n/**\n * Style configuration for GitHub-style alert blocks.\n */\nconst alertStyles: Record<\n AlertType,\n { icon: string; label: string; styleFn: (s: string) => string }\n> = {\n NOTE: { icon: \"ℹ\", label: \"Note\", styleFn: styles.cyan },\n TIP: { icon: \"💡\", label: \"Tip\", styleFn: styles.green },\n IMPORTANT: { icon: \"❗\", label: \"Important\", styleFn: styles.magenta },\n WARNING: { icon: \"⚠\", label: \"Warning\", styleFn: styles.yellow },\n CAUTION: { icon: \"🔴\", label: \"Caution\", styleFn: styles.red },\n};\n\n/**\n * Render a single block to styled terminal output.\n */\nfunction renderBlock(block: Block): string {\n switch (block.type) {\n case \"heading\": {\n // Inspired by marked-terminal: green + bold to distinguish from section headers (bold + underline)\n return styles.green(styles.bold(renderInline(block.content)));\n }\n\n case \"hr\": {\n return styles.dim(\"─\".repeat(40));\n }\n\n case \"blockquote\": {\n const prefix = styles.dim(\"│ \");\n return block.lines.map((line) => `${prefix}${renderInline(line)}`).join(\"\\n\");\n }\n\n case \"alert\": {\n const { icon, label, styleFn } = alertStyles[block.alertType];\n const prefix = styleFn(styles.bold(\"│\")) + \" \";\n const header = `${prefix}${styleFn(icon)} ${styleFn(label)}`;\n if (block.lines.length === 0) {\n return header;\n }\n const body = block.lines.map((line) => `${prefix}${renderInline(line)}`).join(\"\\n\");\n return `${header}\\n${body}`;\n }\n\n case \"ul\": {\n return block.items.map((item) => `${styles.dim(\"•\")} ${renderInline(item)}`).join(\"\\n\");\n }\n\n case \"ol\": {\n const maxNum = block.start + block.items.length - 1;\n const width = String(maxNum).length;\n return block.items\n .map((item, i) => {\n const num = String(block.start + i).padStart(width, \" \");\n return `${styles.dim(`${num}.`)} ${renderInline(item)}`;\n })\n .join(\"\\n\");\n }\n\n case \"table\": {\n const colCount = block.headers.length;\n // Render inline formatting first, then calculate visual widths\n const renderedHeaders = block.headers.map((h) => renderInline(h));\n const renderedRows = block.rows.map((row) =>\n Array.from({ length: colCount }, (_, i) => renderInline(row[i] ?? \"\")),\n );\n // Calculate column widths based on visual width (handles ANSI codes and full-width chars)\n const colWidths = renderedHeaders.map((h, i) => {\n const headerWidth = stringWidth(h);\n const cellWidths = renderedRows.map((row) => stringWidth(row[i]!));\n return Math.max(headerWidth, ...cellWidths);\n });\n const pipe = styles.dim(\"│\");\n // Border rows\n const topBorder = styles.dim(`┌─${colWidths.map((w) => \"─\".repeat(w)).join(\"─┬─\")}─┐`);\n const midBorder = styles.dim(`├─${colWidths.map((w) => \"─\".repeat(w)).join(\"─┼─\")}─┤`);\n const botBorder = styles.dim(`└─${colWidths.map((w) => \"─\".repeat(w)).join(\"─┴─\")}─┘`);\n // Header row (bold, with inline rendering already applied)\n const headerCells = renderedHeaders.map((h, i) =>\n styles.bold(alignText(h, colWidths[i]!, block.alignments[i] ?? \"left\")),\n );\n const headerRow = `${pipe} ${headerCells.join(` ${pipe} `)} ${pipe}`;\n // Body rows (inline rendering already applied)\n const bodyRows = renderedRows.map((row) => {\n const cells = row.map((cell, i) =>\n alignText(cell, colWidths[i]!, block.alignments[i] ?? \"left\"),\n );\n return `${pipe} ${cells.join(` ${pipe} `)} ${pipe}`;\n });\n return [topBorder, headerRow, midBorder, ...bodyRows, botBorder].join(\"\\n\");\n }\n\n case \"code\": {\n // Extra indent for code blocks to distinguish from surrounding text\n return block.lines.map((line) => ` ${styles.yellow(line)}`).join(\"\\n\");\n }\n\n case \"paragraph\": {\n // Join consecutive lines with a space (soft line break → reflow)\n const text = block.lines.join(\" \");\n return renderInline(text);\n }\n }\n}\n","import {\n getExtractedFields,\n type ExtractedFields,\n type ResolvedFieldMeta,\n} from \"../core/schema-extractor.js\";\nimport type { AnyCommand, Example } from \"../types.js\";\nimport { styles } from \"./logger.js\";\nimport { renderMarkdown } from \"./markdown-renderer.js\";\n\n/**\n * Descriptions for built-in options\n */\nexport interface BuiltinOptionDescriptions {\n /** Description for --help option */\n help?: string;\n /** Description for --help-all option */\n helpAll?: string;\n /** Description for --version option */\n version?: string;\n}\n\n/**\n * Default descriptions for built-in options\n */\nconst defaultBuiltinDescriptions: Required<BuiltinOptionDescriptions> = {\n help: \"Show help\",\n helpAll: \"Show help with all subcommand options\",\n version: \"Show version\",\n};\n\n/**\n * Context for command hierarchy\n */\nexport interface CommandContext {\n /** Full command path (e.g., [\"config\", \"get\"]) */\n commandPath?: string[] | undefined;\n /** Root command name */\n rootName?: string | undefined;\n /** Root command version */\n rootVersion?: string | undefined;\n}\n\n/**\n * Options for help generation\n */\nexport interface HelpOptions {\n /** Show subcommand list */\n showSubcommands?: boolean | undefined;\n /** Show subcommand options */\n showSubcommandOptions?: boolean | undefined;\n /** Custom descriptions for built-in options */\n descriptions?: BuiltinOptionDescriptions | undefined;\n /** Command hierarchy context */\n context?: CommandContext | undefined;\n}\n\n/**\n * Internal subcommands are reserved for framework internals and hidden from help output.\n */\nfunction isVisibleSubcommand(name: string): boolean {\n return !name.startsWith(\"__\");\n}\n\nfunction getVisibleSubcommandEntries(\n subCommands: Record<string, AnyCommand | (() => Promise<AnyCommand>)>,\n): Array<[string, AnyCommand | (() => Promise<AnyCommand>)]> {\n return Object.entries(subCommands).filter(([name]) => isVisibleSubcommand(name));\n}\n\n/**\n * Build full command name from context\n */\nfunction buildFullCommandName(command: AnyCommand, context?: CommandContext): string {\n if (context?.rootName && context.commandPath && context.commandPath.length > 0) {\n // Subcommand: show path (e.g., \"config get\")\n return context.commandPath.join(\" \");\n }\n return command.name ?? \"command\";\n}\n\n/**\n * Build usage command name (includes root name for subcommands)\n */\nfunction buildUsageCommandName(command: AnyCommand, context?: CommandContext): string {\n if (context?.rootName && context.commandPath && context.commandPath.length > 0) {\n // Subcommand: include root name (e.g., \"git-like config get\")\n return `${context.rootName} ${context.commandPath.join(\" \")}`;\n }\n return command.name ?? \"command\";\n}\n\n/**\n * Render the usage line for a command\n */\nexport function renderUsageLine(command: AnyCommand, context?: CommandContext): string {\n const parts: string[] = [];\n const name = buildUsageCommandName(command, context);\n\n parts.push(styles.commandName(name));\n\n const extracted = getExtractedFields(command);\n if (extracted) {\n const positionals = extracted.fields.filter((a) => a.positional);\n const options = extracted.fields.filter((a) => !a.positional);\n\n // Add [options] if there are options\n if (options.length > 0) {\n parts.push(styles.placeholder(\"[options]\"));\n }\n\n // Add [command] if there are subcommands\n if (command.subCommands && getVisibleSubcommandEntries(command.subCommands).length > 0) {\n parts.push(styles.placeholder(\"[command]\"));\n }\n\n // Add positional arguments\n for (const arg of positionals) {\n if (arg.required) {\n parts.push(styles.option(`<${arg.name}>`));\n } else {\n parts.push(styles.placeholder(`[${arg.name}]`));\n }\n }\n } else {\n // Add [command] if there are subcommands\n if (command.subCommands && getVisibleSubcommandEntries(command.subCommands).length > 0) {\n parts.push(styles.placeholder(\"[command]\"));\n }\n }\n\n return parts.join(\" \");\n}\n\n/**\n * Render the options section\n */\nexport function renderOptions(\n command: AnyCommand,\n descriptions: BuiltinOptionDescriptions = {},\n context?: CommandContext,\n): string {\n const lines: string[] = [];\n const desc: Required<BuiltinOptionDescriptions> = {\n help: descriptions.help ?? defaultBuiltinDescriptions.help,\n helpAll: descriptions.helpAll ?? defaultBuiltinDescriptions.helpAll,\n version: descriptions.version ?? defaultBuiltinDescriptions.version,\n };\n\n const extracted = getExtractedFields(command);\n\n // Check if user has overridden built-in aliases\n const hasUserDefinedh =\n extracted?.fields.some((f) => f.alias === \"h\" && f.overrideBuiltinAlias === true) ?? false;\n const hasUserDefinedH =\n extracted?.fields.some((f) => f.alias === \"H\" && f.overrideBuiltinAlias === true) ?? false;\n\n // Add built-in options\n if (hasUserDefinedh) {\n // Don't show -h alias if user is using it\n lines.push(formatOption(styles.option(\"--help\"), desc.help));\n } else {\n lines.push(formatOption(`${styles.option(\"-h\")}, ${styles.option(\"--help\")}`, desc.help));\n }\n\n if (hasUserDefinedH) {\n // Don't show -H alias if user is using it\n lines.push(formatOption(styles.option(\"--help-all\"), desc.helpAll));\n } else {\n lines.push(\n formatOption(`${styles.option(\"-H\")}, ${styles.option(\"--help-all\")}`, desc.helpAll),\n );\n }\n\n // Show --version only if version is provided in context\n if (context?.rootVersion) {\n lines.push(formatOption(styles.option(\"--version\"), desc.version));\n }\n\n if (!extracted) {\n return lines.join(\"\\n\");\n }\n\n // Handle discriminated union specially\n if (extracted.schemaType === \"discriminatedUnion\" && extracted.discriminator) {\n return renderDiscriminatedUnionOptions(extracted, command, lines);\n }\n\n // Handle union specially\n if (extracted.schemaType === \"union\" && extracted.unionOptions) {\n return renderUnionOptions(extracted, command, lines);\n }\n\n // Handle xor (exclusive union) the same as union\n if (extracted.schemaType === \"xor\" && extracted.unionOptions) {\n return renderUnionOptions(extracted, command, lines);\n }\n\n // Regular options\n const options = extracted.fields.filter((a) => !a.positional);\n for (const opt of options) {\n const flags = formatFlags(opt);\n let desc = opt.description ?? \"\";\n\n // Add default value indicator\n if (opt.defaultValue !== undefined) {\n desc += ` ${styles.defaultValue(`(default: ${JSON.stringify(opt.defaultValue)})`)}`;\n }\n\n // Add required indicator\n if (opt.required) {\n desc += ` ${styles.required(\"(required)\")}`;\n }\n\n // Add environment variable info\n const envInfo = formatEnvInfo(opt.env);\n if (envInfo) {\n desc += ` ${envInfo}`;\n }\n\n lines.push(formatOption(flags, desc));\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render options for discriminated union with variants\n */\nfunction renderDiscriminatedUnionOptions(\n extracted: ExtractedFields,\n _command: AnyCommand,\n lines: string[],\n): string {\n const discriminator = extracted.discriminator!;\n const variants = extracted.variants ?? [];\n\n // Add discriminator field\n const discriminatorField = extracted.fields.find((f) => f.name === discriminator);\n if (discriminatorField) {\n const variantValues = variants.map((v) => v.discriminatorValue).join(\"|\");\n const flags = `${styles.option(`--${discriminator}`)} ${styles.placeholder(`<${variantValues}>`)}`;\n // Use discriminatedUnion's description for the discriminator field\n const description =\n extracted.description ?? discriminatorField.description ?? \"Action to perform\";\n lines.push(formatOption(flags, description));\n }\n\n // Add common fields (fields that appear in all variants)\n const commonFields = new Set<string>();\n const allFieldNames = new Set<string>();\n\n for (const variant of variants) {\n for (const field of variant.fields) {\n allFieldNames.add(field.name);\n }\n }\n\n for (const fieldName of allFieldNames) {\n if (fieldName === discriminator) continue;\n\n const inAllVariants = variants.every((v) => v.fields.some((f) => f.name === fieldName));\n if (inAllVariants) {\n commonFields.add(fieldName);\n }\n }\n\n // Render common fields\n for (const fieldName of commonFields) {\n const field = extracted.fields.find((f) => f.name === fieldName);\n if (field && !field.positional) {\n const flags = formatFlags(field);\n let desc = field.description ?? \"\";\n if (field.defaultValue !== undefined) {\n desc += ` ${styles.defaultValue(`(default: ${JSON.stringify(field.defaultValue)})`)}`;\n }\n const envInfo = formatEnvInfo(field.env);\n if (envInfo) {\n desc += ` ${envInfo}`;\n }\n lines.push(formatOption(flags, desc));\n }\n }\n\n // Render variant-specific fields\n for (const variant of variants) {\n const variantFields = variant.fields.filter(\n (f) => f.name !== discriminator && !commonFields.has(f.name) && !f.positional,\n );\n\n if (variantFields.length > 0) {\n lines.push(\"\");\n // Format: \"When action=create: description\" if description exists, otherwise \"When action=create:\"\n const variantLabel = variant.description\n ? `${styles.dim(\"When\")} ${styles.option(discriminator)}=${styles.bold(variant.discriminatorValue)}: ${variant.description}`\n : `${styles.dim(\"When\")} ${styles.option(discriminator)}=${styles.bold(variant.discriminatorValue)}:`;\n lines.push(variantLabel);\n\n for (const field of variantFields) {\n const flags = formatFlags(field);\n let desc = field.description ?? \"\";\n if (field.defaultValue !== undefined) {\n desc += ` ${styles.defaultValue(`(default: ${JSON.stringify(field.defaultValue)})`)}`;\n }\n if (field.required) {\n desc += ` ${styles.required(\"(required)\")}`;\n }\n const envInfo = formatEnvInfo(field.env);\n if (envInfo) {\n desc += ` ${envInfo}`;\n }\n lines.push(formatOption(` ${flags}`, desc));\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render options for union with multiple options\n */\nfunction renderUnionOptions(\n extracted: ExtractedFields,\n _command: AnyCommand,\n lines: string[],\n): string {\n const unionOptions = extracted.unionOptions ?? [];\n\n // Add common fields (fields that appear in all options)\n const commonFields = new Set<string>();\n const allFieldNames = new Set<string>();\n\n for (const option of unionOptions) {\n for (const field of option.fields) {\n allFieldNames.add(field.name);\n }\n }\n\n for (const fieldName of allFieldNames) {\n const inAllOptions = unionOptions.every((o) => o.fields.some((f) => f.name === fieldName));\n if (inAllOptions) {\n commonFields.add(fieldName);\n }\n }\n\n // Render common fields\n for (const fieldName of commonFields) {\n const field = extracted.fields.find((f) => f.name === fieldName);\n if (field && !field.positional) {\n const flags = formatFlags(field);\n let desc = field.description ?? \"\";\n if (field.defaultValue !== undefined) {\n desc += ` ${styles.defaultValue(`(default: ${JSON.stringify(field.defaultValue)})`)}`;\n }\n const envInfo = formatEnvInfo(field.env);\n if (envInfo) {\n desc += ` ${envInfo}`;\n }\n lines.push(formatOption(flags, desc));\n }\n }\n\n // Render option-specific fields\n for (let i = 0; i < unionOptions.length; i++) {\n const option = unionOptions[i];\n if (!option) continue;\n\n const uniqueFields = option.fields.filter((f) => !commonFields.has(f.name) && !f.positional);\n\n if (uniqueFields.length > 0) {\n lines.push(\"\");\n\n const label = option.description ?? `Variant ${i + 1}`;\n lines.push(` ${styles.bold(`${label}:`)}`);\n\n for (const field of uniqueFields) {\n const flags = formatFlags(field);\n let desc = field.description ?? \"\";\n if (field.defaultValue !== undefined) {\n desc += ` ${styles.defaultValue(`(default: ${JSON.stringify(field.defaultValue)})`)}`;\n }\n if (field.required) {\n desc += ` ${styles.required(\"(required)\")}`;\n }\n const envInfo = formatEnvInfo(field.env);\n if (envInfo) {\n desc += ` ${envInfo}`;\n }\n lines.push(formatOption(` ${flags}`, desc));\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Format option flags (-v, --verbose <VALUE>)\n * Uses cliName (kebab-case) for display\n */\nfunction formatFlags(opt: ResolvedFieldMeta): string {\n const parts: string[] = [];\n\n if (opt.alias) {\n parts.push(styles.option(`-${opt.alias}`));\n }\n\n // Use cliName (kebab-case) for display\n let longFlag = styles.option(`--${opt.cliName}`);\n\n // Add placeholder for non-boolean options\n if (opt.type !== \"boolean\") {\n const placeholder = opt.placeholder ?? opt.cliName.toUpperCase();\n longFlag += ` ${styles.placeholder(`<${placeholder}>`)}`;\n }\n\n parts.push(longFlag);\n\n return parts.join(\", \");\n}\n\n/**\n * Format environment variable info for help display\n */\nfunction formatEnvInfo(env: string | string[] | undefined): string {\n if (!env) return \"\";\n\n const envNames = Array.isArray(env) ? env : [env];\n return styles.dim(`[env: ${envNames.join(\", \")}]`);\n}\n\n/**\n * Strip ANSI escape codes from a string to get visual length\n */\nfunction stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1B\\[[0-9;]*m/g, \"\");\n}\n\n/**\n * Pad a string that may contain ANSI codes to a visual width\n */\nfunction padEndVisual(str: string, width: number): string {\n const visualLength = stripAnsi(str).length;\n const padding = Math.max(0, width - visualLength);\n return str + \" \".repeat(padding);\n}\n\n/**\n * Format a single option line\n * If flags exceed the column width, description is moved to the next line\n */\nfunction formatOption(\n flags: string,\n description: string,\n indent = 0,\n extraDescPadding = 0,\n): string {\n const flagWidth = 32;\n const indentStr = \" \".repeat(indent);\n const visualFlagLength = stripAnsi(flags).length;\n const effectiveFlagWidth = flagWidth - indent * 2 + extraDescPadding;\n\n // If flags are too long, put description on next line\n if (visualFlagLength >= effectiveFlagWidth) {\n const descIndent = \" \".repeat(effectiveFlagWidth + 2 + indent * 2);\n return `${indentStr} ${flags}\\n${descIndent}${description}`;\n }\n\n const paddedFlags = padEndVisual(flags, effectiveFlagWidth);\n return `${indentStr} ${paddedFlags}${description}`;\n}\n\n/**\n * Render options for a subcommand (used by showSubcommandOptions)\n */\nfunction renderSubcommandOptionsCompact(command: AnyCommand, indent: number): string[] {\n const lines: string[] = [];\n const extracted = getExtractedFields(command);\n\n if (extracted) {\n const options = extracted.fields.filter((a) => !a.positional);\n for (const opt of options) {\n const flags = formatFlags(opt);\n let desc = opt.description ?? \"\";\n if (opt.defaultValue !== undefined) {\n desc += ` ${styles.defaultValue(`(default: ${JSON.stringify(opt.defaultValue)})`)}`;\n }\n const envInfo = formatEnvInfo(opt.env);\n if (envInfo) {\n desc += ` ${envInfo}`;\n }\n lines.push(formatOption(flags, desc, indent, 2));\n }\n }\n\n return lines;\n}\n\n/**\n * Render subcommands recursively with their options (flat style)\n */\nfunction renderSubcommandsWithOptions(\n subCommands: Record<string, AnyCommand | (() => Promise<AnyCommand>)>,\n parentPath: string,\n baseIndent: number,\n): string[] {\n const lines: string[] = [];\n\n for (const [name, subCmd] of getVisibleSubcommandEntries(subCommands)) {\n // Handle both sync and async commands\n const cmd = typeof subCmd === \"function\" ? null : subCmd;\n const fullPath = parentPath ? `${parentPath} ${name}` : name;\n const desc = cmd?.description ?? \"\";\n\n // Add subcommand name with description (all subcommands at same indent level)\n lines.push(formatOption(styles.command(fullPath), desc, baseIndent));\n\n if (cmd) {\n // Add subcommand options (one level deeper than the subcommand itself)\n const optionLines = renderSubcommandOptionsCompact(cmd, baseIndent + 1);\n lines.push(...optionLines);\n\n // Recursively add nested subcommands (same base indent - flat style)\n const visibleNestedSubCommands = cmd.subCommands\n ? Object.fromEntries(getVisibleSubcommandEntries(cmd.subCommands))\n : undefined;\n if (visibleNestedSubCommands && Object.keys(visibleNestedSubCommands).length > 0) {\n const nestedLines = renderSubcommandsWithOptions(\n visibleNestedSubCommands,\n fullPath,\n baseIndent,\n );\n lines.push(...nestedLines);\n }\n }\n }\n\n return lines;\n}\n\n/**\n * Generate help text for a command\n *\n * @param command - The command to generate help for\n * @param options - Help generation options\n * @returns Formatted help text\n */\nexport function generateHelp(command: AnyCommand, options: HelpOptions): string {\n const sections: string[] = [];\n const context = options.context;\n\n // Command name + version\n const displayName = buildFullCommandName(command, context);\n if (displayName) {\n let header = styles.commandName(displayName);\n // Show root name and version for subcommands, or version for root\n if (context?.rootName && context.commandPath && context.commandPath.length > 0) {\n // Subcommand: show (rootName vX.X.X)\n if (context.rootVersion) {\n header += ` ${styles.version(`(${context.rootName} v${context.rootVersion})`)}`;\n } else {\n header += ` ${styles.version(`(${context.rootName})`)}`;\n }\n } else if (context?.rootVersion) {\n // Root command: show vX.X.X\n header += ` ${styles.version(`v${context.rootVersion}`)}`;\n }\n sections.push(header);\n }\n\n // Description\n if (command.description) {\n sections.push(command.description);\n }\n\n // Usage\n sections.push(`${styles.sectionHeader(\"Usage:\")} ${renderUsageLine(command, context)}`);\n\n // Options\n const optionsText = renderOptions(command, options.descriptions, context);\n if (optionsText) {\n sections.push(`${styles.sectionHeader(\"Options:\")}\\n${optionsText}`);\n }\n\n // Subcommands\n if (\n options.showSubcommands !== false &&\n command.subCommands &&\n getVisibleSubcommandEntries(command.subCommands).length > 0\n ) {\n // Get current command path for prefixing subcommands\n const currentPath = context?.commandPath?.join(\" \") ?? \"\";\n\n const visibleSubCommands = Object.fromEntries(getVisibleSubcommandEntries(command.subCommands));\n\n if (options.showSubcommandOptions) {\n // Show subcommands with their options (recursive)\n const subLines = renderSubcommandsWithOptions(visibleSubCommands, currentPath, 0);\n sections.push(`${styles.sectionHeader(\"Commands:\")}\\n${subLines.join(\"\\n\")}`);\n } else {\n // Show only subcommand names and descriptions\n const subLines: string[] = [];\n for (const [name, subCmd] of Object.entries(visibleSubCommands)) {\n // Handle both sync and async commands\n const cmd = typeof subCmd === \"function\" ? { description: undefined } : subCmd;\n const desc = cmd.description ?? \"\";\n // Include parent path in subcommand name\n const fullName = currentPath ? `${currentPath} ${name}` : name;\n subLines.push(formatOption(styles.command(fullName), desc));\n }\n sections.push(`${styles.sectionHeader(\"Commands:\")}\\n${subLines.join(\"\\n\")}`);\n }\n }\n\n // Examples\n if (command.examples && command.examples.length > 0) {\n const exampleLines = renderExamplesForHelp(command.examples, context);\n sections.push(`${styles.sectionHeader(\"Examples:\")}\\n${exampleLines}`);\n }\n\n // Notes (render Markdown for styled terminal output, indented under header)\n if (command.notes) {\n const rendered = renderMarkdown(command.notes);\n const indented = rendered\n .split(\"\\n\")\n .map((line) => (line === \"\" ? \"\" : ` ${line}`))\n .join(\"\\n\");\n sections.push(`${styles.sectionHeader(\"Notes:\")}\\n${indented}`);\n }\n\n return `\\n${sections.join(\"\\n\\n\")}\\n`;\n}\n\n/**\n * Render examples for CLI help output\n */\nfunction renderExamplesForHelp(examples: Example[], context?: CommandContext): string {\n const lines: string[] = [];\n const cmdPrefix = context?.rootName ? `${context.rootName} ` : \"\";\n const cmdPath = context?.commandPath?.join(\" \") ?? \"\";\n const fullPrefix = cmdPath ? `${cmdPrefix}${cmdPath} ` : cmdPrefix;\n\n for (const example of examples) {\n // Description\n lines.push(` ${styles.dim(example.desc)}`);\n // Command\n lines.push(` ${styles.dim(\"$\")} ${fullPrefix}${example.cmd}`);\n // Output (if provided)\n if (example.output) {\n for (const line of example.output.split(\"\\n\")) {\n lines.push(` ${line}`);\n }\n }\n lines.push(\"\"); // Empty line between examples\n }\n\n // Remove trailing empty line\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n\n return lines.join(\"\\n\");\n}\n","/**\n * Error thrown when positional argument configuration is invalid\n */\nexport class PositionalConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"PositionalConfigError\";\n }\n}\n\n/**\n * Error thrown when a reserved alias is used\n */\nexport class ReservedAliasError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ReservedAliasError\";\n }\n}\n\n/**\n * Error thrown when duplicate field names are detected\n */\nexport class DuplicateFieldError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"DuplicateFieldError\";\n }\n}\n\n/**\n * Error thrown when duplicate aliases are detected\n */\nexport class DuplicateAliasError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"DuplicateAliasError\";\n }\n}\n","import { extractFields, type ExtractedFields } from \"../core/schema-extractor.js\";\nimport { resolveLazyCommand } from \"../executor/subcommand-router.js\";\nimport type { AnyCommand } from \"../types.js\";\nimport {\n DuplicateAliasError,\n DuplicateFieldError,\n PositionalConfigError,\n ReservedAliasError,\n} from \"./validation-errors.js\";\n\n// Re-export error classes for convenience\nexport { DuplicateAliasError, DuplicateFieldError, PositionalConfigError, ReservedAliasError };\n\n/**\n * Error detail for command validation\n */\nexport interface CommandValidationError {\n /** Path to the command (e.g., [\"cli\", \"build\", \"watch\"]) */\n commandPath: string[];\n /** Error type */\n type: \"duplicate_field\" | \"duplicate_alias\" | \"positional_config\" | \"reserved_alias\";\n /** Error message */\n message: string;\n /** Related field name (if applicable) */\n field?: string;\n}\n\n/**\n * Result of command validation\n */\nexport type CommandValidationResult =\n | { valid: true }\n | { valid: false; errors: CommandValidationError[] };\n\n/**\n * Options for validateCommand\n */\nexport interface ValidateCommandOptions {\n /** Starting command path (for nested validation) */\n commandPath?: string[];\n}\n\n// ============================================================================\n// Private check functions (single source of truth for validation logic)\n// ============================================================================\n\n/**\n * Check for duplicate field names\n */\nfunction checkDuplicateFields(\n extracted: ExtractedFields,\n commandPath: string[],\n): CommandValidationError[] {\n const errors: CommandValidationError[] = [];\n const seenNames = new Map<string, string>();\n\n for (const field of extracted.fields) {\n if (seenNames.has(field.name)) {\n errors.push({\n commandPath,\n type: \"duplicate_field\",\n message: `Duplicate field name \"${field.name}\" detected.`,\n field: field.name,\n });\n }\n seenNames.set(field.name, field.name);\n }\n return errors;\n}\n\n/**\n * Check for duplicate aliases and alias-field name conflicts\n */\nfunction checkDuplicateAliases(\n extracted: ExtractedFields,\n commandPath: string[],\n): CommandValidationError[] {\n const errors: CommandValidationError[] = [];\n const seenAliases = new Map<string, string>();\n const fieldNames = new Set(extracted.fields.map((f) => f.name));\n\n for (const field of extracted.fields) {\n if (!field.alias) continue;\n\n // Check if alias conflicts with an existing field name\n if (fieldNames.has(field.alias)) {\n errors.push({\n commandPath,\n type: \"duplicate_alias\",\n message: `Alias \"${field.alias}\" for field \"${field.name}\" conflicts with existing field name \"${field.alias}\".`,\n field: field.name,\n });\n }\n\n // Check if alias is already used by another field\n const existingField = seenAliases.get(field.alias);\n if (existingField) {\n errors.push({\n commandPath,\n type: \"duplicate_alias\",\n message: `Duplicate alias \"${field.alias}\" detected. Both \"${existingField}\" and \"${field.name}\" use the same alias.`,\n field: field.name,\n });\n }\n seenAliases.set(field.alias, field.name);\n }\n return errors;\n}\n\n/**\n * Check positional argument configuration\n */\nfunction checkPositionalConfig(\n extracted: ExtractedFields,\n commandPath: string[],\n): CommandValidationError[] {\n const errors: CommandValidationError[] = [];\n const positionalFields = extracted.fields.filter((f) => f.positional);\n\n let foundArrayPositional: string | null = null;\n let foundOptionalPositional: string | null = null;\n\n for (const field of positionalFields) {\n // Check: no positional can follow array positional\n if (foundArrayPositional !== null) {\n errors.push({\n commandPath,\n type: \"positional_config\",\n message: `Positional argument \"${field.name}\" cannot follow array positional argument \"${foundArrayPositional}\".`,\n field: field.name,\n });\n }\n\n // Check: array positional cannot coexist with optional positional\n if (field.type === \"array\" && foundOptionalPositional !== null) {\n errors.push({\n commandPath,\n type: \"positional_config\",\n message: `Array positional \"${field.name}\" cannot be used with optional positional \"${foundOptionalPositional}\" (ambiguous parsing).`,\n field: field.name,\n });\n }\n\n // Check: required positional cannot follow optional positional\n if (foundOptionalPositional !== null && field.required) {\n errors.push({\n commandPath,\n type: \"positional_config\",\n message: `Required positional \"${field.name}\" cannot follow optional positional \"${foundOptionalPositional}\".`,\n field: field.name,\n });\n }\n\n if (field.type === \"array\") {\n foundArrayPositional = field.name;\n }\n if (!field.required) {\n foundOptionalPositional = field.name;\n }\n }\n return errors;\n}\n\n/**\n * Check for reserved aliases used without override flag\n */\nfunction checkReservedAliases(\n extracted: ExtractedFields,\n commandPath: string[],\n): CommandValidationError[] {\n const errors: CommandValidationError[] = [];\n\n for (const field of extracted.fields) {\n if ((field.alias === \"h\" || field.alias === \"H\") && field.overrideBuiltinAlias !== true) {\n errors.push({\n commandPath,\n type: \"reserved_alias\",\n message: `Alias \"${field.alias}\" is reserved for --${field.alias === \"h\" ? \"help\" : \"help-all\"}.`,\n field: field.name,\n });\n }\n }\n return errors;\n}\n\n// ============================================================================\n// Public throwing validators (for runtime validation)\n// ============================================================================\n\n/**\n * Validate that no duplicate field names exist\n *\n * @param extracted - Extracted fields from schema\n * @throws {DuplicateFieldError} If duplicate field names are found\n */\nexport function validateDuplicateFields(extracted: ExtractedFields): void {\n const errors = checkDuplicateFields(extracted, []);\n if (errors.length > 0) {\n const field = errors[0]?.field ?? \"unknown\";\n throw new DuplicateFieldError(\n `Duplicate field name \"${field}\" detected. Each field must have a unique name.`,\n );\n }\n}\n\n/**\n * Validate that no duplicate aliases exist\n *\n * Also checks for conflicts between aliases and field names\n *\n * @param extracted - Extracted fields from schema\n * @throws {DuplicateAliasError} If duplicate aliases are found or alias conflicts with field name\n */\nexport function validateDuplicateAliases(extracted: ExtractedFields): void {\n const errors = checkDuplicateAliases(extracted, []);\n if (errors.length > 0) {\n const err = errors[0]!;\n throw new DuplicateAliasError(err.message);\n }\n}\n\n/**\n * Validate positional argument configuration\n *\n * Rules:\n * - Array positional arguments must be the last positional\n * - No positional arguments can follow an array positional\n * - Required positional arguments cannot follow optional positional arguments\n * - Array positional and optional positional cannot be used together (ambiguous parsing)\n *\n * @param extracted - Extracted fields from schema\n * @throws {PositionalConfigError} If configuration is invalid\n */\nexport function validatePositionalConfig(extracted: ExtractedFields): void {\n const errors = checkPositionalConfig(extracted, []);\n if (errors.length > 0) {\n const err = errors[0]!;\n throw new PositionalConfigError(err.message);\n }\n}\n\n/**\n * Validate that no reserved aliases are used without explicit override\n *\n * Reserved aliases:\n * - 'h' is reserved for --help\n * - 'H' is reserved for --help-all\n *\n * Users can override these by setting overrideBuiltinAlias: true\n *\n * @param extracted - Extracted fields from schema\n * @param _hasSubCommands - Whether the command has subcommands (reserved for future use)\n * @throws {ReservedAliasError} If a reserved alias is used without override flag\n */\nexport function validateReservedAliases(\n extracted: ExtractedFields,\n _hasSubCommands: boolean,\n): void {\n const errors = checkReservedAliases(extracted, []);\n if (errors.length > 0) {\n const err = errors[0]!;\n const field = err.field ?? \"unknown\";\n const alias = extracted.fields.find((f) => f.name === field)?.alias ?? \"h\";\n throw new ReservedAliasError(\n `Alias \"${alias}\" is reserved for --${alias === \"h\" ? \"help\" : \"help-all\"}. ` +\n `To override this, set { alias: \"${alias}\", overrideBuiltinAlias: true } for \"${field}\".`,\n );\n }\n}\n\n// ============================================================================\n// Non-throwing validators (for collecting all errors)\n// ============================================================================\n\n/**\n * Collect validation errors for a single command's schema (non-throwing)\n */\nfunction collectSchemaErrors(\n extracted: ExtractedFields,\n _hasSubCommands: boolean,\n commandPath: string[],\n): CommandValidationError[] {\n return [\n ...checkDuplicateFields(extracted, commandPath),\n ...checkDuplicateAliases(extracted, commandPath),\n ...checkPositionalConfig(extracted, commandPath),\n ...checkReservedAliases(extracted, commandPath),\n ];\n}\n\n/**\n * Validate a command and all its subcommands recursively\n *\n * This function collects all validation errors without throwing,\n * making it suitable for test assertions.\n *\n * @param command - The command to validate\n * @param options - Validation options\n * @returns Validation result with all errors collected\n *\n * @example\n * ```ts\n * const result = await validateCommand(myCommand);\n * if (!result.valid) {\n * console.error(result.errors);\n * }\n * ```\n */\nexport async function validateCommand(\n command: AnyCommand,\n options: ValidateCommandOptions = {},\n): Promise<CommandValidationResult> {\n const commandPath = options.commandPath ?? [command.name];\n const errors: CommandValidationError[] = [];\n const hasSubCommands = command.subCommands ? Object.keys(command.subCommands).length > 0 : false;\n\n // Validate current command's schema\n if (command.args) {\n const extracted = extractFields(command.args);\n errors.push(...collectSchemaErrors(extracted, hasSubCommands, commandPath));\n }\n\n // Recursively validate subcommands\n if (command.subCommands) {\n for (const [name, subCmd] of Object.entries(command.subCommands)) {\n const resolvedSubCmd = await resolveLazyCommand(subCmd);\n const subResult = await validateCommand(resolvedSubCmd, {\n commandPath: [...commandPath, name],\n });\n if (!subResult.valid) {\n errors.push(...subResult.errors);\n }\n }\n }\n\n if (errors.length === 0) {\n return { valid: true };\n }\n\n return { valid: false, errors };\n}\n\n/**\n * Format command validation errors for display\n *\n * @param errors - Array of validation errors\n * @returns Formatted error message\n */\nexport function formatCommandValidationErrors(errors: CommandValidationError[]): string {\n if (errors.length === 0) return \"\";\n\n const lines: string[] = [\"Command definition errors:\"];\n for (const error of errors) {\n const path = error.commandPath.join(\" > \");\n lines.push(` - [${path}] ${error.message}`);\n }\n return lines.join(\"\\n\");\n}\n","import type { ExtractedFields } from \"../core/schema-extractor.js\";\n\n/**\n * Parsed arguments result\n */\nexport interface ParsedArgv {\n /** Named options (--flag, -f) */\n options: Record<string, unknown>;\n /** Positional arguments */\n positionals: string[];\n /** Arguments after -- */\n rest: string[];\n}\n\n/**\n * Parser options\n */\nexport interface ParserOptions {\n /** Alias map (short -> long) */\n aliasMap?: Map<string, string>;\n /** Boolean flags (no value expected) */\n booleanFlags?: Set<string>;\n /** Array flags (can be repeated) */\n arrayFlags?: Set<string>;\n}\n\n/**\n * Parse argv into a flat record\n *\n * Supports:\n * - Long options: --flag, --flag=value, --flag value\n * - Short options: -f, -f=value, -f value\n * - Combined short options: -abc (treated as -a -b -c if all are boolean)\n * - Positional arguments\n * - -- to stop parsing options\n *\n * @param argv - Command line arguments\n * @param options - Parser options\n * @returns Parsed arguments\n */\nexport function parseArgv(argv: string[], options: ParserOptions = {}): ParsedArgv {\n const { aliasMap = new Map(), booleanFlags = new Set(), arrayFlags = new Set() } = options;\n\n const result: ParsedArgv = {\n options: {},\n positionals: [],\n rest: [],\n };\n\n let i = 0;\n let stopParsing = false;\n\n const setOption = (name: string, value: unknown) => {\n // Resolve alias\n const resolvedName = aliasMap.get(name) ?? name;\n\n if (arrayFlags.has(resolvedName)) {\n // Array flag: accumulate values\n const existing = result.options[resolvedName];\n if (Array.isArray(existing)) {\n existing.push(value);\n } else if (existing !== undefined) {\n result.options[resolvedName] = [existing, value];\n } else {\n result.options[resolvedName] = [value];\n }\n } else {\n result.options[resolvedName] = value;\n }\n };\n\n while (i < argv.length) {\n const arg = argv[i]!;\n\n // Stop parsing after --\n if (stopParsing) {\n result.rest.push(arg);\n i++;\n continue;\n }\n\n // Check for --\n if (arg === \"--\") {\n stopParsing = true;\n i++;\n continue;\n }\n\n // Long option: --flag or --flag=value\n if (arg.startsWith(\"--\")) {\n const withoutDashes = arg.slice(2);\n\n // Handle --no-flag for boolean negation\n if (withoutDashes.startsWith(\"no-\")) {\n const flagName = withoutDashes.slice(3);\n const resolvedName = aliasMap.get(flagName) ?? flagName;\n if (booleanFlags.has(resolvedName)) {\n setOption(flagName, false);\n i++;\n continue;\n }\n }\n\n const eqIndex = withoutDashes.indexOf(\"=\");\n if (eqIndex !== -1) {\n // --flag=value\n const name = withoutDashes.slice(0, eqIndex);\n const value = withoutDashes.slice(eqIndex + 1);\n setOption(name, value);\n i++;\n } else {\n // --flag or --flag value\n const name = withoutDashes;\n const resolvedName = aliasMap.get(name) ?? name;\n\n if (booleanFlags.has(resolvedName)) {\n // Boolean flag: no value expected\n setOption(name, true);\n i++;\n } else {\n // Check if next arg is a value\n const nextArg = argv[i + 1];\n if (nextArg !== undefined && !nextArg.startsWith(\"-\")) {\n setOption(name, nextArg);\n i += 2;\n } else {\n // No value provided, treat as true\n setOption(name, true);\n i++;\n }\n }\n }\n continue;\n }\n\n // Short option: -f or -f=value or -abc\n if (arg.startsWith(\"-\") && arg.length > 1 && !arg.startsWith(\"--\")) {\n const withoutDash = arg.slice(1);\n\n const eqIndex = withoutDash.indexOf(\"=\");\n if (eqIndex !== -1) {\n // -f=value\n const name = withoutDash.slice(0, eqIndex);\n const value = withoutDash.slice(eqIndex + 1);\n setOption(name, value);\n i++;\n } else if (withoutDash.length === 1) {\n // Single short option: -f\n const name = withoutDash;\n const resolvedName = aliasMap.get(name) ?? name;\n\n if (booleanFlags.has(resolvedName)) {\n setOption(name, true);\n i++;\n } else {\n // Check if next arg is a value\n const nextArg = argv[i + 1];\n if (nextArg !== undefined && !nextArg.startsWith(\"-\")) {\n setOption(name, nextArg);\n i += 2;\n } else {\n setOption(name, true);\n i++;\n }\n }\n } else {\n // Combined short options: -abc\n // Treat each character as a boolean flag\n for (const char of withoutDash) {\n setOption(char, true);\n }\n i++;\n }\n continue;\n }\n\n // Positional argument\n result.positionals.push(arg);\n i++;\n }\n\n return result;\n}\n\n/**\n * Build parser options from extracted fields\n */\nexport function buildParserOptions(extracted: ExtractedFields): ParserOptions {\n const aliasMap = new Map<string, string>();\n const booleanFlags = new Set<string>();\n const arrayFlags = new Set<string>();\n\n for (const field of extracted.fields) {\n // Map kebab-case CLI name to camelCase field name\n // e.g., \"dry-run\" → \"dryRun\"\n if (field.cliName !== field.name) {\n aliasMap.set(field.cliName, field.name);\n }\n\n if (field.alias) {\n aliasMap.set(field.alias, field.name);\n }\n\n if (field.type === \"boolean\") {\n booleanFlags.add(field.name);\n }\n\n if (field.type === \"array\") {\n arrayFlags.add(field.name);\n }\n }\n\n return { aliasMap, booleanFlags, arrayFlags };\n}\n\n/**\n * Merge parsed argv with positional fields to create a flat record\n */\nexport function mergeWithPositionals(\n parsed: ParsedArgv,\n extracted: ExtractedFields,\n): Record<string, unknown> {\n const result: Record<string, unknown> = { ...parsed.options };\n\n // Assign positional arguments to their fields\n const positionalFields = extracted.fields.filter((f) => f.positional);\n\n // Combine positionals with rest args (after --) for assignment\n const allPositionals =\n parsed.rest.length > 0 ? [...parsed.positionals, ...parsed.rest] : parsed.positionals;\n\n let positionalIndex = 0;\n for (const field of positionalFields) {\n if (positionalIndex >= allPositionals.length) {\n break;\n }\n\n if (field.type === \"array\") {\n // Array positional consumes all remaining positionals (including rest args after --)\n result[field.name] = allPositionals.slice(positionalIndex);\n break; // No more positionals can follow (validated by validatePositionalConfig)\n } else {\n result[field.name] = allPositionals[positionalIndex]!;\n positionalIndex++;\n }\n }\n\n return result;\n}\n","import { extractFields, type ExtractedFields } from \"../core/schema-extractor.js\";\nimport type { AnyCommand } from \"../types.js\";\nimport {\n validateDuplicateAliases,\n validateDuplicateFields,\n validatePositionalConfig,\n validateReservedAliases,\n} from \"../validator/command-validator.js\";\nimport { buildParserOptions, mergeWithPositionals, parseArgv } from \"./argv-parser.js\";\n\n/**\n * Result of parsing CLI arguments\n */\nexport interface ParseResult {\n /** Help flag was requested (--help or -h) */\n helpRequested: boolean;\n /** Detailed help flag was requested (--help-all) */\n helpAllRequested: boolean;\n /** Version flag was requested (--version) */\n versionRequested: boolean;\n /** Detected subcommand name */\n subCommand?: string | undefined;\n /** Remaining args after subcommand extraction */\n remainingArgs: string[];\n /** Parsed arguments (not yet validated) */\n rawArgs: Record<string, unknown>;\n /** Positional argument values */\n positionals: string[];\n /** Unknown flags that were detected */\n unknownFlags: string[];\n /** Extracted fields from schema (for internal use) */\n extractedFields?: ExtractedFields | undefined;\n}\n\n/**\n * Options for parseArgs\n */\nexport interface ParseArgsOptions {\n /** Skip command definition validation (useful in production where tests already verified) */\n skipValidation?: boolean | undefined;\n}\n\n/**\n * Parse CLI arguments for a command\n *\n * @param argv - Command line arguments\n * @param command - The command to parse for\n * @param options - Parse options\n * @returns Parse result\n */\nexport function parseArgs(\n argv: string[],\n command: AnyCommand,\n options: ParseArgsOptions = {},\n): ParseResult {\n // Check for subcommand FIRST (before help/version)\n // This ensures `cmd subcmd --help` shows subcmd's help, not cmd's help\n const subCommandNames = command.subCommands ? Object.keys(command.subCommands) : [];\n const hasSubCommands = subCommandNames.length > 0;\n\n if (hasSubCommands && argv.length > 0) {\n const firstArg = argv[0];\n // Only treat as subcommand if it doesn't start with '-' (not a flag)\n if (firstArg && !firstArg.startsWith(\"-\") && subCommandNames.includes(firstArg)) {\n return {\n helpRequested: false,\n helpAllRequested: false,\n versionRequested: false,\n subCommand: firstArg,\n remainingArgs: argv.slice(1),\n rawArgs: {},\n positionals: [],\n unknownFlags: [],\n };\n }\n }\n\n // Extract fields from schema and validate BEFORE checking help flags\n // This ensures validation errors are thrown even when --help is used\n let extracted: ExtractedFields | undefined;\n if (command.args) {\n extracted = extractFields(command.args);\n // Only validate if not skipped (tests can pre-validate, production can skip)\n if (!options.skipValidation) {\n validateDuplicateFields(extracted);\n validateDuplicateAliases(extracted);\n validatePositionalConfig(extracted);\n validateReservedAliases(extracted, hasSubCommands);\n }\n }\n\n // Check for help/version flags only when no subcommand is detected\n // -h/-H are treated as --help/--help-all unless explicitly overridden by user\n const hasUserDefinedH =\n extracted?.fields.some((f) => f.alias === \"H\" && f.overrideBuiltinAlias === true) ?? false;\n const hasUserDefinedh =\n extracted?.fields.some((f) => f.alias === \"h\" && f.overrideBuiltinAlias === true) ?? false;\n const helpAllRequested = argv.includes(\"--help-all\") || (!hasUserDefinedH && argv.includes(\"-H\"));\n const helpRequested =\n !helpAllRequested && (argv.includes(\"--help\") || (!hasUserDefinedh && argv.includes(\"-h\")));\n const versionRequested = argv.includes(\"--version\");\n\n if (helpRequested || helpAllRequested || versionRequested) {\n return {\n helpRequested,\n helpAllRequested,\n versionRequested,\n subCommand: undefined,\n remainingArgs: [],\n rawArgs: {},\n positionals: [],\n unknownFlags: [],\n };\n }\n\n // If no schema, return minimal result\n if (!extracted) {\n return {\n helpRequested: false,\n helpAllRequested: false,\n versionRequested: false,\n subCommand: undefined,\n remainingArgs: [],\n rawArgs: {},\n positionals: [],\n unknownFlags: [],\n };\n }\n\n // Build parser options from extracted fields\n const parserOptions = buildParserOptions(extracted);\n\n // Parse argv\n const parsed = parseArgv(argv, parserOptions);\n\n // Merge with positionals\n const rawArgs = mergeWithPositionals(parsed, extracted);\n\n // Apply environment variable fallbacks\n for (const field of extracted.fields) {\n if (field.env && rawArgs[field.name] === undefined) {\n // Normalize to array\n const envNames = Array.isArray(field.env) ? field.env : [field.env];\n\n // First defined env var wins\n for (const envName of envNames) {\n const envValue = process.env[envName];\n if (envValue !== undefined) {\n rawArgs[field.name] = envValue;\n break;\n }\n }\n }\n }\n\n // Detect unknown flags\n const knownFlags = new Set(extracted.fields.map((f) => f.name));\n const knownCliNames = new Set(extracted.fields.map((f) => f.cliName));\n const knownAliases = new Set(extracted.fields.filter((f) => f.alias).map((f) => f.alias!));\n const unknownFlags: string[] = [];\n\n for (const key of Object.keys(parsed.options)) {\n if (!knownFlags.has(key) && !knownCliNames.has(key) && !knownAliases.has(key)) {\n unknownFlags.push(key);\n }\n }\n\n return {\n helpRequested: false,\n helpAllRequested: false,\n versionRequested: false,\n subCommand: undefined,\n remainingArgs: [],\n rawArgs,\n positionals: parsed.positionals,\n unknownFlags,\n extractedFields: extracted,\n };\n}\n","import { styles, symbols } from \"../output/logger.js\";\nimport type { ValidationError } from \"./zod-validator.js\";\n\n/**\n * Calculate Levenshtein distance between two strings\n */\nfunction levenshteinDistance(a: string, b: string): number {\n const matrix: number[][] = [];\n\n for (let i = 0; i <= b.length; i++) {\n matrix[i] = [i];\n }\n\n for (let j = 0; j <= a.length; j++) {\n matrix[0]![j] = j;\n }\n\n for (let i = 1; i <= b.length; i++) {\n for (let j = 1; j <= a.length; j++) {\n if (b.charAt(i - 1) === a.charAt(j - 1)) {\n matrix[i]![j] = matrix[i - 1]![j - 1]!;\n } else {\n matrix[i]![j] = Math.min(\n matrix[i - 1]![j - 1]! + 1, // substitution\n matrix[i]![j - 1]! + 1, // insertion\n matrix[i - 1]![j]! + 1, // deletion\n );\n }\n }\n }\n\n return matrix[b.length]![a.length]!;\n}\n\n/**\n * Find similar strings from a list\n */\nfunction findSimilar(target: string, candidates: string[]): string[] {\n const threshold = Math.max(2, Math.floor(target.length / 2));\n\n return candidates\n .map((candidate) => ({\n candidate,\n distance: levenshteinDistance(target.toLowerCase(), candidate.toLowerCase()),\n }))\n .filter(({ distance }) => distance <= threshold)\n .sort((a, b) => a.distance - b.distance)\n .map(({ candidate }) => candidate)\n .slice(0, 3);\n}\n\n/**\n * Format validation errors into a human-readable message\n *\n * @param errors - Array of validation errors\n * @returns Formatted error message\n */\nexport function formatValidationErrors(errors: ValidationError[]): string {\n if (errors.length === 0) {\n return \"\";\n }\n\n const lines: string[] = [styles.error(\"Validation errors:\")];\n\n for (const error of errors) {\n const path = error.path.join(\".\");\n lines.push(` ${symbols.bullet} ${styles.bold(path)}: ${error.message}`);\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Format unknown flag error with suggestions\n *\n * @param flag - The unknown flag (e.g., \"--verbos\")\n * @param knownFlags - List of known flag names\n * @returns Formatted error message with suggestions\n */\nexport function formatUnknownFlag(flag: string, knownFlags: string[]): string {\n const flagName = flag.replace(/^-{1,2}/, \"\");\n const similar = findSimilar(flagName, knownFlags);\n\n let message = `${styles.error(\"Unknown option:\")} ${styles.bold(flag)}`;\n\n if (similar.length > 0) {\n message += `\\n\\n${styles.info(\"Did you mean?\")}`;\n for (const suggestion of similar) {\n message += `\\n ${symbols.arrow} ${styles.option(`--${suggestion}`)}`;\n }\n }\n\n return message;\n}\n\n/**\n * Format unknown flag warning with suggestions (for strip mode)\n *\n * @param flag - The unknown flag (e.g., \"--verbos\")\n * @param knownFlags - List of known flag names\n * @returns Formatted warning message with suggestions\n */\nexport function formatUnknownFlagWarning(flag: string, knownFlags: string[]): string {\n const flagName = flag.replace(/^-{1,2}/, \"\");\n const similar = findSimilar(flagName, knownFlags);\n\n let message = `${styles.warning(\"Warning: Unknown option:\")} ${styles.bold(flag)}`;\n\n if (similar.length > 0) {\n message += `\\n\\n${styles.info(\"Did you mean?\")}`;\n for (const suggestion of similar) {\n message += `\\n ${symbols.arrow} ${styles.option(`--${suggestion}`)}`;\n }\n }\n\n return message;\n}\n\n/**\n * Format runtime error\n *\n * @param error - The error that occurred\n * @param debug - Whether to include stack trace\n * @returns Formatted error message\n */\nexport function formatRuntimeError(error: Error, debug: boolean): string {\n if (debug && error.stack) {\n return `${styles.error(\"Error:\")} ${error.message}\\n\\n${styles.dim(error.stack)}`;\n }\n\n return `${styles.error(\"Error:\")} ${error.message}`;\n}\n\n/**\n * Format unknown subcommand error with suggestions\n *\n * @param subcommand - The unknown subcommand name\n * @param knownSubcommands - List of known subcommand names\n * @returns Formatted error message with suggestions\n */\nexport function formatUnknownSubcommand(subcommand: string, knownSubcommands: string[]): string {\n const similar = findSimilar(subcommand, knownSubcommands);\n\n let message = `${styles.error(\"Unknown command:\")} ${styles.bold(subcommand)}`;\n\n if (similar.length > 0) {\n message += `\\n\\n${styles.info(\"Did you mean?\")}`;\n for (const suggestion of similar) {\n message += `\\n ${symbols.arrow} ${styles.command(suggestion)}`;\n }\n }\n\n return message;\n}\n","import { z } from \"zod\";\nimport type { ArgsSchema } from \"../types.js\";\n\n/**\n * Validation error details\n */\nexport interface ValidationError {\n /** Path to the invalid field */\n path: string[];\n /** Error message */\n message: string;\n /** Zod error code */\n code: string;\n /** Value that was received */\n received?: unknown | undefined;\n /** Expected type or value */\n expected?: string | undefined;\n}\n\n/**\n * Validation result\n */\nexport type ValidationResult<T> =\n | { success: true; data: T }\n | { success: false; errors: ValidationError[] };\n\n/**\n * Convert ZodError to ValidationError array (zod v4 compatible)\n */\nfunction formatZodErrors(error: z.ZodError): ValidationError[] {\n return error.issues.map((issue) => ({\n path: issue.path.map(String),\n message: issue.message,\n code: issue.code,\n received: \"received\" in issue ? issue.received : undefined,\n expected: \"expected\" in issue ? String(issue.expected) : undefined,\n }));\n}\n\n/**\n * Validate raw arguments against a schema\n *\n * @param rawArgs - Parsed but unvalidated arguments\n * @param schema - Zod schema (ZodObject, ZodDiscriminatedUnion, etc.)\n * @returns Validation result with typed data or errors\n */\nexport function validateArgs<T extends ArgsSchema>(\n rawArgs: Record<string, unknown>,\n schema: T,\n): ValidationResult<z.infer<T>> {\n const result = schema.safeParse(rawArgs);\n\n if (result.success) {\n return {\n success: true,\n data: result.data as z.infer<T>,\n };\n }\n\n return {\n success: false,\n errors: formatZodErrors(result.error),\n };\n}\n\n/**\n * Format validation errors for display\n */\nexport function formatValidationErrors(errors: ValidationError[]): string {\n return errors\n .map((e) => {\n const path = e.path.length > 0 ? `${e.path.join(\".\")}: ` : \"\";\n return `${path}${e.message}`;\n })\n .join(\"\\n\");\n}\n","import { executeLifecycle } from \"../executor/command-runner.js\";\nimport { createLogCollector, emptyLogs, mergeLogs } from \"../executor/log-collector.js\";\nimport { listSubCommands, resolveSubcommand } from \"../executor/subcommand-router.js\";\nimport { generateHelp, type CommandContext } from \"../output/help-generator.js\";\nimport { parseArgs } from \"../parser/arg-parser.js\";\nimport type {\n AnyCommand,\n CollectedLogs,\n InternalRunOptions,\n Logger,\n MainOptions,\n RunCommandOptions,\n RunResult,\n} from \"../types.js\";\nimport {\n formatRuntimeError,\n formatUnknownFlag,\n formatUnknownFlagWarning,\n formatUnknownSubcommand,\n formatValidationErrors,\n} from \"../validator/error-formatter.js\";\nimport { validateArgs } from \"../validator/zod-validator.js\";\n\n/**\n * Default logger using console\n */\nconst defaultLogger: Logger = {\n log: (message: string) => console.log(message),\n error: (message: string) => console.error(message),\n};\n\n/**\n * Internal options for runCommand (includes context tracking)\n */\ninterface InternalCommandOptions extends InternalRunOptions {\n /** Command hierarchy context (internal use) */\n _context?: CommandContext;\n /** Existing logs to include (for subcommand routing) */\n _existingLogs?: CollectedLogs;\n}\n\n/**\n * Run a command with the given arguments (programmatic/test usage)\n *\n * This function parses arguments, validates them, routes to subcommands,\n * and executes the command. It does NOT call process.exit.\n *\n * @param command - The command to run\n * @param argv - Command line arguments to parse\n * @param options - Run options\n * @returns The result of command execution\n *\n * @example\n * ```ts\n * import { defineCommand, runCommand } from \"politty\";\n *\n * const command = defineCommand({\n * name: \"my-cli\",\n * args: z.object({ name: z.string() }),\n * run: ({ name }) => console.log(`Hello, ${name}!`),\n * });\n *\n * // In tests\n * const result = await runCommand(command, [\"--name\", \"World\"]);\n * expect(result.exitCode).toBe(0);\n * ```\n */\nexport async function runCommand<TResult = unknown>(\n command: AnyCommand,\n argv: string[],\n options: RunCommandOptions = {},\n): Promise<RunResult<TResult>> {\n return runCommandInternal(command, argv, {\n ...options,\n handleSignals: false,\n skipValidation: options.skipValidation,\n logger: options.logger,\n });\n}\n\n/**\n * Run a CLI command as the main entry point\n *\n * This function:\n * - Uses process.argv for arguments\n * - Handles SIGINT/SIGTERM signals\n * - Calls process.exit with the appropriate exit code\n *\n * @param command - The command to run\n * @param options - Main options (version, debug)\n *\n * @example\n * ```ts\n * import { defineCommand, runMain } from \"politty\";\n *\n * const command = defineCommand({\n * name: \"my-cli\",\n * run: () => console.log(\"Hello!\"),\n * });\n *\n * runMain(command, { version: \"1.0.0\" });\n * ```\n */\nexport async function runMain(command: AnyCommand, options: MainOptions = {}): Promise<never> {\n const result = await runCommandInternal(command, process.argv.slice(2), {\n debug: options.debug,\n captureLogs: options.captureLogs,\n skipValidation: options.skipValidation,\n handleSignals: true,\n logger: options.logger,\n _context: {\n commandPath: [],\n rootName: command.name,\n rootVersion: options.version,\n },\n });\n\n process.exit(result.exitCode);\n}\n\n/**\n * Internal implementation of command running\n */\nasync function runCommandInternal<TResult = unknown>(\n command: AnyCommand,\n argv: string[],\n options: InternalCommandOptions = {},\n): Promise<RunResult<TResult>> {\n // Get logger (use default if not provided)\n const logger = options.logger ?? defaultLogger;\n\n // Initialize or get existing context\n const context: CommandContext = options._context ?? {\n commandPath: [],\n rootName: command.name,\n };\n\n // Start log collection if enabled\n const shouldCaptureLogs = options.captureLogs ?? false;\n const collector = shouldCaptureLogs ? createLogCollector() : null;\n collector?.start();\n\n // Helper to get current logs merged with existing\n const getCurrentLogs = (): CollectedLogs => {\n const existingLogs = options._existingLogs ?? emptyLogs();\n const collectedLogs = collector?.getLogs() ?? emptyLogs();\n return mergeLogs(existingLogs, collectedLogs);\n };\n\n try {\n // Parse arguments\n const parseResult = parseArgs(argv, command, { skipValidation: options.skipValidation });\n\n // Handle --help or --help-all\n if (parseResult.helpRequested || parseResult.helpAllRequested) {\n // Check if there's an unknown subcommand specified\n let hasUnknownSubcommand = false;\n const subCmdNames = listSubCommands(command);\n if (subCmdNames.length > 0) {\n // Find first positional argument (potential subcommand)\n const potentialSubCmd = argv.find((arg) => !arg.startsWith(\"-\"));\n if (potentialSubCmd && !subCmdNames.includes(potentialSubCmd)) {\n logger.error(formatUnknownSubcommand(potentialSubCmd, subCmdNames));\n logger.error(\"\");\n hasUnknownSubcommand = true;\n }\n }\n\n const help = generateHelp(command, {\n showSubcommands: options.showSubcommands ?? true,\n showSubcommandOptions: parseResult.helpAllRequested || options.showSubcommandOptions,\n context,\n });\n logger.log(help);\n collector?.stop();\n if (hasUnknownSubcommand) {\n return {\n success: false,\n error: new Error(`Unknown subcommand: ${argv.find((arg) => !arg.startsWith(\"-\"))}`),\n exitCode: 1,\n logs: getCurrentLogs(),\n };\n }\n return { success: true, result: undefined, exitCode: 0, logs: getCurrentLogs() };\n }\n\n // Handle --version\n if (parseResult.versionRequested) {\n // For subcommands, show root version\n const version = context.rootVersion;\n if (version) {\n logger.log(version);\n }\n collector?.stop();\n return { success: true, result: undefined, exitCode: 0, logs: getCurrentLogs() };\n }\n\n // Handle subcommand\n if (parseResult.subCommand) {\n const subCmd = await resolveSubcommand(command, parseResult.subCommand);\n if (subCmd) {\n // Build new context for subcommand\n const subContext: CommandContext = {\n commandPath: [...(context.commandPath ?? []), parseResult.subCommand],\n rootName: context.rootName,\n rootVersion: context.rootVersion,\n };\n // Stop this collector and pass logs to subcommand\n collector?.stop();\n return runCommandInternal<TResult>(subCmd, parseResult.remainingArgs, {\n ...options,\n _context: subContext,\n _existingLogs: getCurrentLogs(),\n });\n }\n }\n\n // If command has subcommands but none specified, show help\n const subCmds = listSubCommands(command);\n if (subCmds.length > 0 && !parseResult.subCommand && !command.run) {\n const help = generateHelp(command, {\n showSubcommands: options.showSubcommands ?? true,\n context,\n });\n logger.log(help);\n collector?.stop();\n return { success: true, result: undefined, exitCode: 0, logs: getCurrentLogs() };\n }\n\n // Handle unknown flags based on schema's unknownKeysMode\n if (parseResult.unknownFlags.length > 0) {\n const unknownKeysMode = parseResult.extractedFields?.unknownKeysMode ?? \"strip\";\n const knownFlags = parseResult.extractedFields?.fields.map((f) => f.name) ?? [];\n\n if (unknownKeysMode === \"strict\") {\n // strict mode: treat unknown flags as errors\n for (const flag of parseResult.unknownFlags) {\n logger.error(formatUnknownFlag(flag, knownFlags));\n }\n collector?.stop();\n return {\n success: false,\n error: new Error(`Unknown flags: ${parseResult.unknownFlags.join(\", \")}`),\n exitCode: 1,\n logs: getCurrentLogs(),\n };\n } else if (unknownKeysMode === \"strip\") {\n // strip mode (default): warn about unknown flags but continue\n for (const flag of parseResult.unknownFlags) {\n logger.error(formatUnknownFlagWarning(flag, knownFlags));\n }\n // Continue execution - don't return error\n }\n // passthrough mode: silently ignore unknown flags\n }\n\n // Validate arguments\n if (!command.args) {\n // No schema, run with empty args\n // Stop this collector and pass logs to executeLifecycle\n collector?.stop();\n const result = await executeLifecycle(command, {} as Record<string, never>, {\n handleSignals: options.handleSignals,\n captureLogs: options.captureLogs,\n existingLogs: getCurrentLogs(),\n });\n return result as RunResult<TResult>;\n }\n\n const validationResult = validateArgs(parseResult.rawArgs, command.args);\n\n if (!validationResult.success) {\n logger.error(formatValidationErrors(validationResult.errors));\n collector?.stop();\n return {\n success: false,\n error: new Error(formatValidationErrors(validationResult.errors)),\n exitCode: 1,\n logs: getCurrentLogs(),\n };\n }\n\n // Run the command\n // Stop this collector and pass logs to executeLifecycle\n collector?.stop();\n const result = await executeLifecycle(command, validationResult.data, {\n handleSignals: options.handleSignals,\n captureLogs: options.captureLogs,\n existingLogs: getCurrentLogs(),\n });\n\n return result as RunResult<TResult>;\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n logger.error(formatRuntimeError(err, options.debug ?? false));\n collector?.stop();\n return {\n success: false,\n error: err,\n exitCode: 1,\n logs: getCurrentLogs(),\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAiCA,eAAsB,iBACpB,SACA,MACA,WAAoC,EAAE,EACT;CAC7B,IAAI;CACJ,IAAI;CAGJ,MAAM,YADoB,SAAS,eAAe,QACZA,8CAAoB,GAAG;AAC7D,YAAW,OAAO;CAElB,MAAM,eAAsC,EAC1C,MACD;CAED,MAAM,iBAA0C;EAC9C;EACA;EACD;CAGD,IAAI;AAEJ,KAAI,SAAS,eAAe;AAC1B,kBAAgB,OAAO,YAA4B;AAEjD,OAAI,eAAe;AACjB,YAAQ,IAAI,UAAU,cAAc;AACpC,YAAQ,IAAI,WAAW,cAAc;;AAIvC,OAAI,QAAQ,QACV,KAAI;AAIF,UAAM,QAAQ,QAAQ,eAAe;YAC9B,GAAG;AACV,YAAQ,MAAM,gCAAgC,EAAE;;AAKpD,cAAW,MAAM;AAGjB,WAAQ,KAAK,EAAE;;AAGjB,UAAQ,GAAG,UAAU,cAAc;AACnC,UAAQ,GAAG,WAAW,cAAc;;AAGtC,KAAI;AAEF,MAAI,QAAQ,MACV,OAAM,QAAQ,MAAM,aAAa;AAInC,MAAI,QAAQ,IACV,UAAS,MAAM,QAAQ,IAAI,KAAK;UAE3B,GAAG;AACV,UAAQ,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,EAAE,CAAC;WAC7C;AAER,MAAI,eAAe;AACjB,WAAQ,IAAI,UAAU,cAAc;AACpC,WAAQ,IAAI,WAAW,cAAc;;;AAKzC,KAAI,QAAQ,SAAS;AAEnB,iBAAe,QAAQ;AAEvB,MAAI;AACF,SAAM,QAAQ,QAAQ,eAAe;WAC9B,cAAc;AAErB,OAAI,CAAC,MACH,SAAQ,wBAAwB,QAAQ,eAAe,IAAI,MAAM,OAAO,aAAa,CAAC;;;AAM5F,YAAW,MAAM;CAKjB,MAAM,OAAOC,oCAFQ,SAAS,gBAAgBC,qCAAW,EACnC,WAAW,SAAS,IAAIA,qCAAW,CACN;AAEnD,KAAI,MACF,QAAO;EACL,SAAS;EACT;EACA,UAAU;EACV;EACD;AAGH,QAAO;EACL,SAAS;EACT;EACA,UAAU;EACV;EACD;;;;;;;;AC5IH,SAAS,qBAA8B;AAErC,KAAI,QAAQ,IAAI,aAAa,OAC3B,QAAO;AAIT,KAAI,QAAQ,IAAI,gBAAgB,IAC9B,QAAO;AAIT,KAAI,QAAQ,IAAI,YACd,QAAO;AAIT,KAAI,QAAQ,IAAI,GACd,QAAO;AAIT,KAAI,CAAC,QAAQ,OAAO,MAClB,QAAO;AAGT,QAAO;;;;;AAMT,IAAI,gBAAgB,oBAAoB;;;;AAKxC,SAAgB,gBAAgB,SAAwB;AACtD,iBAAgB,CAAC;;;;;AAMnB,SAAgB,iBAA0B;AACxC,QAAO,CAAC;;;;;AAMV,SAAS,cAAc,GAAG,WAAwE;AAChG,SAAQ,SAAiB;AACvB,MAAI,cACF,QAAO;EAET,IAAI,SAAS;AACb,OAAK,MAAM,SAAS,UAClB,mCAAmB,OAAO,OAAO;AAEnC,SAAO;;;;;;AAOX,MAAa,SAAS;CAEpB,SAAS,cAAc,QAAQ;CAC/B,OAAO,cAAc,MAAM;CAC3B,SAAS,cAAc,SAAS;CAChC,MAAM,cAAc,OAAO;CAG3B,MAAM,cAAc,OAAO;CAC3B,KAAK,cAAc,MAAM;CACzB,QAAQ,cAAc,SAAS;CAC/B,WAAW,cAAc,YAAY;CAGrC,KAAK,cAAc,MAAM;CACzB,OAAO,cAAc,QAAQ;CAC7B,QAAQ,cAAc,SAAS;CAC/B,MAAM,cAAc,OAAO;CAC3B,SAAS,cAAc,UAAU;CACjC,MAAM,cAAc,OAAO;CAC3B,OAAO,cAAc,QAAQ;CAC7B,MAAM,cAAc,OAAO;CAG3B,SAAS,cAAc,OAAO;CAC9B,aAAa,cAAc,QAAQ,aAAa,OAAO;CACvD,QAAQ,cAAc,OAAO;CAC7B,YAAY,cAAc,OAAO;CACjC,aAAa,cAAc,MAAM;CACjC,cAAc,cAAc,MAAM;CAClC,UAAU,cAAc,SAAS;CACjC,cAAc,SAAiB;CAC/B,eAAe,cAAc,QAAQ,YAAY;CACjD,SAAS,cAAc,MAAM;CAC9B;;;;AAKD,MAAa,UAAU;CACrB,SAAS,OAAO,MAAM,IAAI;CAC1B,OAAO,OAAO,IAAI,IAAI;CACtB,SAAS,OAAO,OAAO,IAAI;CAC3B,MAAM,OAAO,KAAK,IAAI;CACtB,QAAQ,OAAO,KAAK,IAAI;CACxB,OAAO,OAAO,KAAK,IAAI;CACxB;;;;AAKD,MAAa,SAAS;CAIpB,KAAK,SAAuB;AAC1B,UAAQ,IAAI,QAAQ;;CAMtB,QAAQ,SAAuB;AAC7B,UAAQ,IAAI,GAAG,QAAQ,QAAQ,GAAG,OAAO,QAAQ,QAAQ,GAAG;;CAM9D,KAAK,SAAuB;AAC1B,UAAQ,KAAK,GAAG,QAAQ,QAAQ,GAAG,OAAO,QAAQ,QAAQ,GAAG;;CAM/D,MAAM,SAAuB;AAC3B,UAAQ,MAAM,GAAG,QAAQ,MAAM,GAAG,OAAO,MAAM,QAAQ,GAAG;;CAM5D,IAAI,SAAuB;AACzB,UAAQ,IAAI,QAAQ;;CAMtB,UAAgB;AACd,UAAQ,IAAI,GAAG;;CAMjB,MAAM,SAAuB;AAC3B,UAAQ,IAAI,OAAO,IAAI,QAAQ,CAAC;;CAEnC;;;;;;;;;;;;;;;;;;;;;ACvJD,SAAgB,aAAa,MAAsB;CAEjD,MAAM,YAAsB,EAAE;CAC9B,IAAI,SAAS,KAAK,QAAQ,eAAe,QAAQ,SAAiB;EAChE,MAAM,QAAQ,UAAU;AACxB,YAAU,KAAK,OAAO,KAAK,KAAK,CAAC;AACjC,SAAO,WAAW,MAAM;GACxB;AAGF,UAAS,OAAO,QAAQ,mBAAmB,QAAQ,YAAoB,OAAO,KAAK,QAAQ,CAAC;AAC5F,UAAS,OAAO,QAAQ,eAAe,QAAQ,YAAoB,OAAO,KAAK,QAAQ,CAAC;AAIxF,UAAS,OAAO,QAAQ,eAAe,QAAQ,YAAoB,OAAO,OAAO,QAAQ,CAAC;AAC1F,UAAS,OAAO,QAAQ,0BAA0B,QAAQ,YACxD,OAAO,OAAO,QAAQ,CACvB;AAGD,UAAS,OAAO,QACd,6BACC,QAAQ,UAAkB,QACzB,GAAG,OAAO,UAAU,SAAS,CAAC,GAAG,OAAO,IAAI,IAAI,IAAI,GAAG,GAC1D;AAGD,UAAS,OAAO,QAEd,uBACC,QAAQ,UAAkB,UAAU,OAAO,MAAM,EACnD;AAED,QAAO;;;;;;;;;;AAWT,SAAgB,eAAe,UAA0B;AAIvD,QAFe,gBADD,SAAS,MAAM,KAAK,CACG,CACb,IAAI,YAAY,CACxB,KAAK,OAAO;;AAsE9B,MAAM,aAAa;AACnB,MAAM,QAAQ;AACd,MAAM,gBAAgB;AACtB,MAAM,QAAQ;AACd,MAAM,QAAQ;AACd,MAAM,gBAAgB;AACtB,MAAM,WAAW;AACjB,MAAM,eAAe;AACrB,MAAM,eAAe;;;;;AAMrB,SAAS,gBAAgB,OAA0B;CACjD,MAAM,SAAkB,EAAE;CAC1B,IAAI,IAAI;AAER,QAAO,IAAI,MAAM,QAAQ;EACvB,MAAM,OAAO,MAAM;AAGnB,MAAI,KAAK,MAAM,KAAK,IAAI;AACtB;AACA;;EAIF,MAAM,aAAa,KAAK,MAAM,cAAc;AAC5C,MAAI,YAAY;GACd,MAAM,QAAQ,WAAW;GACzB,MAAM,OAAO,WAAW,MAAM;GAC9B,MAAM,YAAsB,EAAE;AAC9B;AACA,UAAO,IAAI,MAAM,QAAQ;AAEvB,QACE,MAAM,GAAI,WAAW,MAAM,OAAO,EAAE,CAAC,OAAO,MAAM,OAAO,CAAC,IAC1D,MAAM,GAAI,MAAM,KACd,MAAM,OAAO,EAAE,CAAC,OAAO,KAAK,IAAI,MAAM,QAAQ,MAAM,GAAI,MAAM,CAAC,OAAO,CAAC,EACzE;AACA;AACA;;AAEF,cAAU,KAAK,MAAM,GAAI;AACzB;;AAEF,UAAO,KAAK;IAAE,MAAM;IAAQ;IAAM,OAAO;IAAW,CAAC;AACrD;;EAIF,MAAM,eAAe,KAAK,MAAM,WAAW;AAC3C,MAAI,cAAc;AAChB,UAAO,KAAK;IACV,MAAM;IACN,OAAO,aAAa,GAAI;IACxB,SAAS,aAAa;IACvB,CAAC;AACF;AACA;;AAIF,MAAI,MAAM,KAAK,KAAK,EAAE;AACpB,UAAO,KAAK,EAAE,MAAM,MAAM,CAAC;AAC3B;AACA;;AAIF,MAAI,cAAc,KAAK,KAAK,EAAE;GAC5B,MAAM,UAAoB,EAAE;AAC5B,UAAO,IAAI,MAAM,QAAQ;IACvB,MAAM,UAAU,MAAM,GAAI,MAAM,cAAc;AAC9C,QAAI,SAAS;AACX,aAAQ,KAAK,QAAQ,GAAI;AACzB;UAEA;;AAIJ,OAAI,QAAQ,SAAS,GAAG;IACtB,MAAM,aAAa,QAAQ,GAAI,MAAM,SAAS;AAC9C,QAAI,YAAY;KACd,MAAM,eAAe,QAAQ,MAAM,EAAE,CAAC,QAAQ,MAAM,MAAM,GAAG;AAC7D,YAAO,KAAK;MACV,MAAM;MACN,WAAW,WAAW;MACtB,OAAO;MACR,CAAC;AACF;;;AAGJ,UAAO,KAAK;IAAE,MAAM;IAAc,OAAO;IAAS,CAAC;AACnD;;AAIF,MAAI,MAAM,KAAK,KAAK,EAAE;GACpB,MAAM,QAAkB,EAAE;AAC1B,UAAO,IAAI,MAAM,QAAQ;IACvB,MAAM,UAAU,MAAM,GAAI,MAAM,MAAM;AACtC,QAAI,SAAS;AACX,WAAM,KAAK,QAAQ,GAAI;AACvB;UAEA;;AAGJ,UAAO,KAAK;IAAE,MAAM;IAAM;IAAO,CAAC;AAClC;;EAIF,MAAM,UAAU,KAAK,MAAM,MAAM;AACjC,MAAI,SAAS;GACX,MAAM,QAAQ,OAAO,QAAQ,GAAG;GAChC,MAAM,QAAkB,EAAE;AAC1B,UAAO,IAAI,MAAM,QAAQ;IACvB,MAAM,QAAQ,MAAM,GAAI,MAAM,MAAM;AACpC,QAAI,OAAO;AACT,WAAM,KAAK,MAAM,GAAI;AACrB;UAEA;;AAGJ,UAAO,KAAK;IAAE,MAAM;IAAM;IAAO;IAAO,CAAC;AACzC;;AAIF,MAAI,aAAa,KAAK,KAAK,IAAI,IAAI,IAAI,MAAM,UAAU,aAAa,KAAK,MAAM,IAAI,GAAI,EAAE;GACvF,MAAM,UAAU,WAAW,KAAK;GAChC,MAAM,aAAa,gBAAgB,MAAM,IAAI,GAAI;AACjD,QAAK;GACL,MAAM,OAAmB,EAAE;AAC3B,UAAO,IAAI,MAAM,UAAU,aAAa,KAAK,MAAM,GAAI,EAAE;AACvD,SAAK,KAAK,WAAW,MAAM,GAAI,CAAC;AAChC;;AAEF,UAAO,KAAK;IAAE,MAAM;IAAS;IAAS;IAAY;IAAM,CAAC;AACzD;;EAIF,MAAM,YAAsB,EAAE;AAC9B,SAAO,IAAI,MAAM,QAAQ;GACvB,MAAM,IAAI,MAAM;AAChB,OACE,EAAE,MAAM,KAAK,MACb,WAAW,KAAK,EAAE,IAClB,MAAM,KAAK,EAAE,IACb,cAAc,KAAK,EAAE,IACrB,MAAM,KAAK,EAAE,IACb,MAAM,KAAK,EAAE,IACb,cAAc,KAAK,EAAE,IACpB,aAAa,KAAK,EAAE,IAAI,IAAI,IAAI,MAAM,UAAU,aAAa,KAAK,MAAM,IAAI,GAAI,CAEjF;AAEF,aAAU,KAAK,EAAE;AACjB;;AAEF,MAAI,UAAU,SAAS,EACrB,QAAO,KAAK;GAAE,MAAM;GAAa,OAAO;GAAW,CAAC;;AAIxD,QAAO;;;;;AAMT,SAAS,WAAW,KAAuB;AACzC,QAAO,IACJ,MAAM,GAAG,GAAG,CACZ,MAAM,IAAI,CACV,KAAK,SAAS,KAAK,MAAM,CAAC;;;;;AAM/B,SAAS,gBAAgB,QAAiD;AACxE,QAAO,OACJ,MAAM,GAAG,GAAG,CACZ,MAAM,IAAI,CACV,KAAK,SAAS;EACb,MAAM,UAAU,KAAK,MAAM;AAC3B,MAAI,QAAQ,WAAW,IAAI,IAAI,QAAQ,SAAS,IAAI,CAAE,QAAO;AAC7D,MAAI,QAAQ,SAAS,IAAI,CAAE,QAAO;AAClC,SAAO;GACP;;;;;AAMN,SAAS,UAAU,MAAc,OAAe,WAAgD;CAC9F,MAAM,wCAA0B,KAAK;CACrC,MAAM,QAAQ,KAAK,IAAI,GAAG,QAAQ,YAAY;AAC9C,KAAI,cAAc,QAAS,QAAO,IAAI,OAAO,MAAM,GAAG;AACtD,KAAI,cAAc,UAAU;EAC1B,MAAM,OAAO,KAAK,MAAM,QAAQ,EAAE;AAClC,SAAO,IAAI,OAAO,KAAK,GAAG,OAAO,IAAI,OAAO,QAAQ,KAAK;;AAE3D,QAAO,OAAO,IAAI,OAAO,MAAM;;;;;AAMjC,MAAM,cAGF;CACF,MAAM;EAAE,MAAM;EAAK,OAAO;EAAQ,SAAS,OAAO;EAAM;CACxD,KAAK;EAAE,MAAM;EAAM,OAAO;EAAO,SAAS,OAAO;EAAO;CACxD,WAAW;EAAE,MAAM;EAAK,OAAO;EAAa,SAAS,OAAO;EAAS;CACrE,SAAS;EAAE,MAAM;EAAK,OAAO;EAAW,SAAS,OAAO;EAAQ;CAChE,SAAS;EAAE,MAAM;EAAM,OAAO;EAAW,SAAS,OAAO;EAAK;CAC/D;;;;AAKD,SAAS,YAAY,OAAsB;AACzC,SAAQ,MAAM,MAAd;EACE,KAAK,UAEH,QAAO,OAAO,MAAM,OAAO,KAAK,aAAa,MAAM,QAAQ,CAAC,CAAC;EAG/D,KAAK,KACH,QAAO,OAAO,IAAI,IAAI,OAAO,GAAG,CAAC;EAGnC,KAAK,cAAc;GACjB,MAAM,SAAS,OAAO,IAAI,KAAK;AAC/B,UAAO,MAAM,MAAM,KAAK,SAAS,GAAG,SAAS,aAAa,KAAK,GAAG,CAAC,KAAK,KAAK;;EAG/E,KAAK,SAAS;GACZ,MAAM,EAAE,MAAM,OAAO,YAAY,YAAY,MAAM;GACnD,MAAM,SAAS,QAAQ,OAAO,KAAK,IAAI,CAAC,GAAG;GAC3C,MAAM,SAAS,GAAG,SAAS,QAAQ,KAAK,CAAC,GAAG,QAAQ,MAAM;AAC1D,OAAI,MAAM,MAAM,WAAW,EACzB,QAAO;AAGT,UAAO,GAAG,OAAO,IADJ,MAAM,MAAM,KAAK,SAAS,GAAG,SAAS,aAAa,KAAK,GAAG,CAAC,KAAK,KAAK;;EAIrF,KAAK,KACH,QAAO,MAAM,MAAM,KAAK,SAAS,GAAG,OAAO,IAAI,IAAI,CAAC,GAAG,aAAa,KAAK,GAAG,CAAC,KAAK,KAAK;EAGzF,KAAK,MAAM;GACT,MAAM,SAAS,MAAM,QAAQ,MAAM,MAAM,SAAS;GAClD,MAAM,QAAQ,OAAO,OAAO,CAAC;AAC7B,UAAO,MAAM,MACV,KAAK,MAAM,MAAM;IAChB,MAAM,MAAM,OAAO,MAAM,QAAQ,EAAE,CAAC,SAAS,OAAO,IAAI;AACxD,WAAO,GAAG,OAAO,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,aAAa,KAAK;KACrD,CACD,KAAK,KAAK;;EAGf,KAAK,SAAS;GACZ,MAAM,WAAW,MAAM,QAAQ;GAE/B,MAAM,kBAAkB,MAAM,QAAQ,KAAK,MAAM,aAAa,EAAE,CAAC;GACjE,MAAM,eAAe,MAAM,KAAK,KAAK,QACnC,MAAM,KAAK,EAAE,QAAQ,UAAU,GAAG,GAAG,MAAM,aAAa,IAAI,MAAM,GAAG,CAAC,CACvE;GAED,MAAM,YAAY,gBAAgB,KAAK,GAAG,MAAM;IAC9C,MAAM,wCAA0B,EAAE;IAClC,MAAM,aAAa,aAAa,KAAK,kCAAoB,IAAI,GAAI,CAAC;AAClE,WAAO,KAAK,IAAI,aAAa,GAAG,WAAW;KAC3C;GACF,MAAM,OAAO,OAAO,IAAI,IAAI;GAE5B,MAAM,YAAY,OAAO,IAAI,KAAK,UAAU,KAAK,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,IAAI;GACtF,MAAM,YAAY,OAAO,IAAI,KAAK,UAAU,KAAK,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,IAAI;GACtF,MAAM,YAAY,OAAO,IAAI,KAAK,UAAU,KAAK,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,IAAI;AAatF,UAAO;IAAC;IARU,GAAG,KAAK,GAHN,gBAAgB,KAAK,GAAG,MAC1C,OAAO,KAAK,UAAU,GAAG,UAAU,IAAK,MAAM,WAAW,MAAM,OAAO,CAAC,CACxE,CACwC,KAAK,IAAI,KAAK,GAAG,CAAC,GAAG;IAQhC;IAAW,GANxB,aAAa,KAAK,QAAQ;AAIzC,YAAO,GAAG,KAAK,GAHD,IAAI,KAAK,MAAM,MAC3B,UAAU,MAAM,UAAU,IAAK,MAAM,WAAW,MAAM,OAAO,CAC9D,CACuB,KAAK,IAAI,KAAK,GAAG,CAAC,GAAG;MAC7C;IACoD;IAAU,CAAC,KAAK,KAAK;;EAG7E,KAAK,OAEH,QAAO,MAAM,MAAM,KAAK,SAAS,KAAK,OAAO,OAAO,KAAK,GAAG,CAAC,KAAK,KAAK;EAGzE,KAAK,YAGH,QAAO,aADM,MAAM,MAAM,KAAK,IAAI,CACT;;;;;;;;;AC7a/B,MAAM,6BAAkE;CACtE,MAAM;CACN,SAAS;CACT,SAAS;CACV;;;;AA+BD,SAAS,oBAAoB,MAAuB;AAClD,QAAO,CAAC,KAAK,WAAW,KAAK;;AAG/B,SAAS,4BACP,aAC2D;AAC3D,QAAO,OAAO,QAAQ,YAAY,CAAC,QAAQ,CAAC,UAAU,oBAAoB,KAAK,CAAC;;;;;AAMlF,SAAS,qBAAqB,SAAqB,SAAkC;AACnF,KAAI,SAAS,YAAY,QAAQ,eAAe,QAAQ,YAAY,SAAS,EAE3E,QAAO,QAAQ,YAAY,KAAK,IAAI;AAEtC,QAAO,QAAQ,QAAQ;;;;;AAMzB,SAAS,sBAAsB,SAAqB,SAAkC;AACpF,KAAI,SAAS,YAAY,QAAQ,eAAe,QAAQ,YAAY,SAAS,EAE3E,QAAO,GAAG,QAAQ,SAAS,GAAG,QAAQ,YAAY,KAAK,IAAI;AAE7D,QAAO,QAAQ,QAAQ;;;;;AAMzB,SAAgB,gBAAgB,SAAqB,SAAkC;CACrF,MAAM,QAAkB,EAAE;CAC1B,MAAM,OAAO,sBAAsB,SAAS,QAAQ;AAEpD,OAAM,KAAK,OAAO,YAAY,KAAK,CAAC;CAEpC,MAAM,YAAYC,4CAAmB,QAAQ;AAC7C,KAAI,WAAW;EACb,MAAM,cAAc,UAAU,OAAO,QAAQ,MAAM,EAAE,WAAW;AAIhE,MAHgB,UAAU,OAAO,QAAQ,MAAM,CAAC,EAAE,WAAW,CAGjD,SAAS,EACnB,OAAM,KAAK,OAAO,YAAY,YAAY,CAAC;AAI7C,MAAI,QAAQ,eAAe,4BAA4B,QAAQ,YAAY,CAAC,SAAS,EACnF,OAAM,KAAK,OAAO,YAAY,YAAY,CAAC;AAI7C,OAAK,MAAM,OAAO,YAChB,KAAI,IAAI,SACN,OAAM,KAAK,OAAO,OAAO,IAAI,IAAI,KAAK,GAAG,CAAC;MAE1C,OAAM,KAAK,OAAO,YAAY,IAAI,IAAI,KAAK,GAAG,CAAC;YAK/C,QAAQ,eAAe,4BAA4B,QAAQ,YAAY,CAAC,SAAS,EACnF,OAAM,KAAK,OAAO,YAAY,YAAY,CAAC;AAI/C,QAAO,MAAM,KAAK,IAAI;;;;;AAMxB,SAAgB,cACd,SACA,eAA0C,EAAE,EAC5C,SACQ;CACR,MAAM,QAAkB,EAAE;CAC1B,MAAM,OAA4C;EAChD,MAAM,aAAa,QAAQ,2BAA2B;EACtD,SAAS,aAAa,WAAW,2BAA2B;EAC5D,SAAS,aAAa,WAAW,2BAA2B;EAC7D;CAED,MAAM,YAAYA,4CAAmB,QAAQ;CAG7C,MAAM,kBACJ,WAAW,OAAO,MAAM,MAAM,EAAE,UAAU,OAAO,EAAE,yBAAyB,KAAK,IAAI;CACvF,MAAM,kBACJ,WAAW,OAAO,MAAM,MAAM,EAAE,UAAU,OAAO,EAAE,yBAAyB,KAAK,IAAI;AAGvF,KAAI,gBAEF,OAAM,KAAK,aAAa,OAAO,OAAO,SAAS,EAAE,KAAK,KAAK,CAAC;KAE5D,OAAM,KAAK,aAAa,GAAG,OAAO,OAAO,KAAK,CAAC,IAAI,OAAO,OAAO,SAAS,IAAI,KAAK,KAAK,CAAC;AAG3F,KAAI,gBAEF,OAAM,KAAK,aAAa,OAAO,OAAO,aAAa,EAAE,KAAK,QAAQ,CAAC;KAEnE,OAAM,KACJ,aAAa,GAAG,OAAO,OAAO,KAAK,CAAC,IAAI,OAAO,OAAO,aAAa,IAAI,KAAK,QAAQ,CACrF;AAIH,KAAI,SAAS,YACX,OAAM,KAAK,aAAa,OAAO,OAAO,YAAY,EAAE,KAAK,QAAQ,CAAC;AAGpE,KAAI,CAAC,UACH,QAAO,MAAM,KAAK,KAAK;AAIzB,KAAI,UAAU,eAAe,wBAAwB,UAAU,cAC7D,QAAO,gCAAgC,WAAW,SAAS,MAAM;AAInE,KAAI,UAAU,eAAe,WAAW,UAAU,aAChD,QAAO,mBAAmB,WAAW,SAAS,MAAM;AAItD,KAAI,UAAU,eAAe,SAAS,UAAU,aAC9C,QAAO,mBAAmB,WAAW,SAAS,MAAM;CAItD,MAAM,UAAU,UAAU,OAAO,QAAQ,MAAM,CAAC,EAAE,WAAW;AAC7D,MAAK,MAAM,OAAO,SAAS;EACzB,MAAM,QAAQ,YAAY,IAAI;EAC9B,IAAI,OAAO,IAAI,eAAe;AAG9B,MAAI,IAAI,iBAAiB,OACvB,SAAQ,IAAI,OAAO,aAAa,aAAa,KAAK,UAAU,IAAI,aAAa,CAAC,GAAG;AAInF,MAAI,IAAI,SACN,SAAQ,IAAI,OAAO,SAAS,aAAa;EAI3C,MAAM,UAAU,cAAc,IAAI,IAAI;AACtC,MAAI,QACF,SAAQ,IAAI;AAGd,QAAM,KAAK,aAAa,OAAO,KAAK,CAAC;;AAGvC,QAAO,MAAM,KAAK,KAAK;;;;;AAMzB,SAAS,gCACP,WACA,UACA,OACQ;CACR,MAAM,gBAAgB,UAAU;CAChC,MAAM,WAAW,UAAU,YAAY,EAAE;CAGzC,MAAM,qBAAqB,UAAU,OAAO,MAAM,MAAM,EAAE,SAAS,cAAc;AACjF,KAAI,oBAAoB;EACtB,MAAM,gBAAgB,SAAS,KAAK,MAAM,EAAE,mBAAmB,CAAC,KAAK,IAAI;EACzE,MAAM,QAAQ,GAAG,OAAO,OAAO,KAAK,gBAAgB,CAAC,GAAG,OAAO,YAAY,IAAI,cAAc,GAAG;EAEhG,MAAM,cACJ,UAAU,eAAe,mBAAmB,eAAe;AAC7D,QAAM,KAAK,aAAa,OAAO,YAAY,CAAC;;CAI9C,MAAM,+BAAe,IAAI,KAAa;CACtC,MAAM,gCAAgB,IAAI,KAAa;AAEvC,MAAK,MAAM,WAAW,SACpB,MAAK,MAAM,SAAS,QAAQ,OAC1B,eAAc,IAAI,MAAM,KAAK;AAIjC,MAAK,MAAM,aAAa,eAAe;AACrC,MAAI,cAAc,cAAe;AAGjC,MADsB,SAAS,OAAO,MAAM,EAAE,OAAO,MAAM,MAAM,EAAE,SAAS,UAAU,CAAC,CAErF,cAAa,IAAI,UAAU;;AAK/B,MAAK,MAAM,aAAa,cAAc;EACpC,MAAM,QAAQ,UAAU,OAAO,MAAM,MAAM,EAAE,SAAS,UAAU;AAChE,MAAI,SAAS,CAAC,MAAM,YAAY;GAC9B,MAAM,QAAQ,YAAY,MAAM;GAChC,IAAI,OAAO,MAAM,eAAe;AAChC,OAAI,MAAM,iBAAiB,OACzB,SAAQ,IAAI,OAAO,aAAa,aAAa,KAAK,UAAU,MAAM,aAAa,CAAC,GAAG;GAErF,MAAM,UAAU,cAAc,MAAM,IAAI;AACxC,OAAI,QACF,SAAQ,IAAI;AAEd,SAAM,KAAK,aAAa,OAAO,KAAK,CAAC;;;AAKzC,MAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,gBAAgB,QAAQ,OAAO,QAClC,MAAM,EAAE,SAAS,iBAAiB,CAAC,aAAa,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE,WACpE;AAED,MAAI,cAAc,SAAS,GAAG;AAC5B,SAAM,KAAK,GAAG;GAEd,MAAM,eAAe,QAAQ,cACzB,GAAG,OAAO,IAAI,OAAO,CAAC,GAAG,OAAO,OAAO,cAAc,CAAC,GAAG,OAAO,KAAK,QAAQ,mBAAmB,CAAC,IAAI,QAAQ,gBAC7G,GAAG,OAAO,IAAI,OAAO,CAAC,GAAG,OAAO,OAAO,cAAc,CAAC,GAAG,OAAO,KAAK,QAAQ,mBAAmB,CAAC;AACrG,SAAM,KAAK,aAAa;AAExB,QAAK,MAAM,SAAS,eAAe;IACjC,MAAM,QAAQ,YAAY,MAAM;IAChC,IAAI,OAAO,MAAM,eAAe;AAChC,QAAI,MAAM,iBAAiB,OACzB,SAAQ,IAAI,OAAO,aAAa,aAAa,KAAK,UAAU,MAAM,aAAa,CAAC,GAAG;AAErF,QAAI,MAAM,SACR,SAAQ,IAAI,OAAO,SAAS,aAAa;IAE3C,MAAM,UAAU,cAAc,MAAM,IAAI;AACxC,QAAI,QACF,SAAQ,IAAI;AAEd,UAAM,KAAK,aAAa,KAAK,SAAS,KAAK,CAAC;;;;AAKlD,QAAO,MAAM,KAAK,KAAK;;;;;AAMzB,SAAS,mBACP,WACA,UACA,OACQ;CACR,MAAM,eAAe,UAAU,gBAAgB,EAAE;CAGjD,MAAM,+BAAe,IAAI,KAAa;CACtC,MAAM,gCAAgB,IAAI,KAAa;AAEvC,MAAK,MAAM,UAAU,aACnB,MAAK,MAAM,SAAS,OAAO,OACzB,eAAc,IAAI,MAAM,KAAK;AAIjC,MAAK,MAAM,aAAa,cAEtB,KADqB,aAAa,OAAO,MAAM,EAAE,OAAO,MAAM,MAAM,EAAE,SAAS,UAAU,CAAC,CAExF,cAAa,IAAI,UAAU;AAK/B,MAAK,MAAM,aAAa,cAAc;EACpC,MAAM,QAAQ,UAAU,OAAO,MAAM,MAAM,EAAE,SAAS,UAAU;AAChE,MAAI,SAAS,CAAC,MAAM,YAAY;GAC9B,MAAM,QAAQ,YAAY,MAAM;GAChC,IAAI,OAAO,MAAM,eAAe;AAChC,OAAI,MAAM,iBAAiB,OACzB,SAAQ,IAAI,OAAO,aAAa,aAAa,KAAK,UAAU,MAAM,aAAa,CAAC,GAAG;GAErF,MAAM,UAAU,cAAc,MAAM,IAAI;AACxC,OAAI,QACF,SAAQ,IAAI;AAEd,SAAM,KAAK,aAAa,OAAO,KAAK,CAAC;;;AAKzC,MAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;EAC5C,MAAM,SAAS,aAAa;AAC5B,MAAI,CAAC,OAAQ;EAEb,MAAM,eAAe,OAAO,OAAO,QAAQ,MAAM,CAAC,aAAa,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE,WAAW;AAE5F,MAAI,aAAa,SAAS,GAAG;AAC3B,SAAM,KAAK,GAAG;GAEd,MAAM,QAAQ,OAAO,eAAe,WAAW,IAAI;AACnD,SAAM,KAAK,KAAK,OAAO,KAAK,GAAG,MAAM,GAAG,GAAG;AAE3C,QAAK,MAAM,SAAS,cAAc;IAChC,MAAM,QAAQ,YAAY,MAAM;IAChC,IAAI,OAAO,MAAM,eAAe;AAChC,QAAI,MAAM,iBAAiB,OACzB,SAAQ,IAAI,OAAO,aAAa,aAAa,KAAK,UAAU,MAAM,aAAa,CAAC,GAAG;AAErF,QAAI,MAAM,SACR,SAAQ,IAAI,OAAO,SAAS,aAAa;IAE3C,MAAM,UAAU,cAAc,MAAM,IAAI;AACxC,QAAI,QACF,SAAQ,IAAI;AAEd,UAAM,KAAK,aAAa,KAAK,SAAS,KAAK,CAAC;;;;AAKlD,QAAO,MAAM,KAAK,KAAK;;;;;;AAOzB,SAAS,YAAY,KAAgC;CACnD,MAAM,QAAkB,EAAE;AAE1B,KAAI,IAAI,MACN,OAAM,KAAK,OAAO,OAAO,IAAI,IAAI,QAAQ,CAAC;CAI5C,IAAI,WAAW,OAAO,OAAO,KAAK,IAAI,UAAU;AAGhD,KAAI,IAAI,SAAS,WAAW;EAC1B,MAAM,cAAc,IAAI,eAAe,IAAI,QAAQ,aAAa;AAChE,cAAY,IAAI,OAAO,YAAY,IAAI,YAAY,GAAG;;AAGxD,OAAM,KAAK,SAAS;AAEpB,QAAO,MAAM,KAAK,KAAK;;;;;AAMzB,SAAS,cAAc,KAA4C;AACjE,KAAI,CAAC,IAAK,QAAO;CAEjB,MAAM,WAAW,MAAM,QAAQ,IAAI,GAAG,MAAM,CAAC,IAAI;AACjD,QAAO,OAAO,IAAI,SAAS,SAAS,KAAK,KAAK,CAAC,GAAG;;;;;AAMpD,SAAS,UAAU,KAAqB;AAEtC,QAAO,IAAI,QAAQ,mBAAmB,GAAG;;;;;AAM3C,SAAS,aAAa,KAAa,OAAuB;CACxD,MAAM,eAAe,UAAU,IAAI,CAAC;CACpC,MAAM,UAAU,KAAK,IAAI,GAAG,QAAQ,aAAa;AACjD,QAAO,MAAM,IAAI,OAAO,QAAQ;;;;;;AAOlC,SAAS,aACP,OACA,aACA,SAAS,GACT,mBAAmB,GACX;CACR,MAAM,YAAY;CAClB,MAAM,YAAY,KAAK,OAAO,OAAO;CACrC,MAAM,mBAAmB,UAAU,MAAM,CAAC;CAC1C,MAAM,qBAAqB,YAAY,SAAS,IAAI;AAGpD,KAAI,oBAAoB,mBAEtB,QAAO,GAAG,UAAU,IAAI,MAAM,IADX,IAAI,OAAO,qBAAqB,IAAI,SAAS,EAAE,GACnB;AAIjD,QAAO,GAAG,UAAU,IADA,aAAa,OAAO,mBAAmB,GACrB;;;;;AAMxC,SAAS,+BAA+B,SAAqB,QAA0B;CACrF,MAAM,QAAkB,EAAE;CAC1B,MAAM,YAAYA,4CAAmB,QAAQ;AAE7C,KAAI,WAAW;EACb,MAAM,UAAU,UAAU,OAAO,QAAQ,MAAM,CAAC,EAAE,WAAW;AAC7D,OAAK,MAAM,OAAO,SAAS;GACzB,MAAM,QAAQ,YAAY,IAAI;GAC9B,IAAI,OAAO,IAAI,eAAe;AAC9B,OAAI,IAAI,iBAAiB,OACvB,SAAQ,IAAI,OAAO,aAAa,aAAa,KAAK,UAAU,IAAI,aAAa,CAAC,GAAG;GAEnF,MAAM,UAAU,cAAc,IAAI,IAAI;AACtC,OAAI,QACF,SAAQ,IAAI;AAEd,SAAM,KAAK,aAAa,OAAO,MAAM,QAAQ,EAAE,CAAC;;;AAIpD,QAAO;;;;;AAMT,SAAS,6BACP,aACA,YACA,YACU;CACV,MAAM,QAAkB,EAAE;AAE1B,MAAK,MAAM,CAAC,MAAM,WAAW,4BAA4B,YAAY,EAAE;EAErE,MAAM,MAAM,OAAO,WAAW,aAAa,OAAO;EAClD,MAAM,WAAW,aAAa,GAAG,WAAW,GAAG,SAAS;EACxD,MAAM,OAAO,KAAK,eAAe;AAGjC,QAAM,KAAK,aAAa,OAAO,QAAQ,SAAS,EAAE,MAAM,WAAW,CAAC;AAEpE,MAAI,KAAK;GAEP,MAAM,cAAc,+BAA+B,KAAK,aAAa,EAAE;AACvE,SAAM,KAAK,GAAG,YAAY;GAG1B,MAAM,2BAA2B,IAAI,cACjC,OAAO,YAAY,4BAA4B,IAAI,YAAY,CAAC,GAChE;AACJ,OAAI,4BAA4B,OAAO,KAAK,yBAAyB,CAAC,SAAS,GAAG;IAChF,MAAM,cAAc,6BAClB,0BACA,UACA,WACD;AACD,UAAM,KAAK,GAAG,YAAY;;;;AAKhC,QAAO;;;;;;;;;AAUT,SAAgB,aAAa,SAAqB,SAA8B;CAC9E,MAAM,WAAqB,EAAE;CAC7B,MAAM,UAAU,QAAQ;CAGxB,MAAM,cAAc,qBAAqB,SAAS,QAAQ;AAC1D,KAAI,aAAa;EACf,IAAI,SAAS,OAAO,YAAY,YAAY;AAE5C,MAAI,SAAS,YAAY,QAAQ,eAAe,QAAQ,YAAY,SAAS,EAE3E,KAAI,QAAQ,YACV,WAAU,IAAI,OAAO,QAAQ,IAAI,QAAQ,SAAS,IAAI,QAAQ,YAAY,GAAG;MAE7E,WAAU,IAAI,OAAO,QAAQ,IAAI,QAAQ,SAAS,GAAG;WAE9C,SAAS,YAElB,WAAU,IAAI,OAAO,QAAQ,IAAI,QAAQ,cAAc;AAEzD,WAAS,KAAK,OAAO;;AAIvB,KAAI,QAAQ,YACV,UAAS,KAAK,QAAQ,YAAY;AAIpC,UAAS,KAAK,GAAG,OAAO,cAAc,SAAS,CAAC,GAAG,gBAAgB,SAAS,QAAQ,GAAG;CAGvF,MAAM,cAAc,cAAc,SAAS,QAAQ,cAAc,QAAQ;AACzE,KAAI,YACF,UAAS,KAAK,GAAG,OAAO,cAAc,WAAW,CAAC,IAAI,cAAc;AAItE,KACE,QAAQ,oBAAoB,SAC5B,QAAQ,eACR,4BAA4B,QAAQ,YAAY,CAAC,SAAS,GAC1D;EAEA,MAAM,cAAc,SAAS,aAAa,KAAK,IAAI,IAAI;EAEvD,MAAM,qBAAqB,OAAO,YAAY,4BAA4B,QAAQ,YAAY,CAAC;AAE/F,MAAI,QAAQ,uBAAuB;GAEjC,MAAM,WAAW,6BAA6B,oBAAoB,aAAa,EAAE;AACjF,YAAS,KAAK,GAAG,OAAO,cAAc,YAAY,CAAC,IAAI,SAAS,KAAK,KAAK,GAAG;SACxE;GAEL,MAAM,WAAqB,EAAE;AAC7B,QAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,mBAAmB,EAAE;IAG/D,MAAM,QADM,OAAO,WAAW,aAAa,EAAE,aAAa,QAAW,GAAG,QACvD,eAAe;IAEhC,MAAM,WAAW,cAAc,GAAG,YAAY,GAAG,SAAS;AAC1D,aAAS,KAAK,aAAa,OAAO,QAAQ,SAAS,EAAE,KAAK,CAAC;;AAE7D,YAAS,KAAK,GAAG,OAAO,cAAc,YAAY,CAAC,IAAI,SAAS,KAAK,KAAK,GAAG;;;AAKjF,KAAI,QAAQ,YAAY,QAAQ,SAAS,SAAS,GAAG;EACnD,MAAM,eAAe,sBAAsB,QAAQ,UAAU,QAAQ;AACrE,WAAS,KAAK,GAAG,OAAO,cAAc,YAAY,CAAC,IAAI,eAAe;;AAIxE,KAAI,QAAQ,OAAO;EAEjB,MAAM,WADW,eAAe,QAAQ,MAAM,CAE3C,MAAM,KAAK,CACX,KAAK,SAAU,SAAS,KAAK,KAAK,KAAK,OAAQ,CAC/C,KAAK,KAAK;AACb,WAAS,KAAK,GAAG,OAAO,cAAc,SAAS,CAAC,IAAI,WAAW;;AAGjE,QAAO,KAAK,SAAS,KAAK,OAAO,CAAC;;;;;AAMpC,SAAS,sBAAsB,UAAqB,SAAkC;CACpF,MAAM,QAAkB,EAAE;CAC1B,MAAM,YAAY,SAAS,WAAW,GAAG,QAAQ,SAAS,KAAK;CAC/D,MAAM,UAAU,SAAS,aAAa,KAAK,IAAI,IAAI;CACnD,MAAM,aAAa,UAAU,GAAG,YAAY,QAAQ,KAAK;AAEzD,MAAK,MAAM,WAAW,UAAU;AAE9B,QAAM,KAAK,KAAK,OAAO,IAAI,QAAQ,KAAK,GAAG;AAE3C,QAAM,KAAK,OAAO,OAAO,IAAI,IAAI,CAAC,GAAG,aAAa,QAAQ,MAAM;AAEhE,MAAI,QAAQ,OACV,MAAK,MAAM,QAAQ,QAAQ,OAAO,MAAM,KAAK,CAC3C,OAAM,KAAK,OAAO,OAAO;AAG7B,QAAM,KAAK,GAAG;;AAIhB,KAAI,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,OAAO,GAClD,OAAM,KAAK;AAGb,QAAO,MAAM,KAAK,KAAK;;;;;;;;ACnpBzB,IAAa,wBAAb,cAA2C,MAAM;CAC/C,YAAY,SAAiB;AAC3B,QAAM,QAAQ;AACd,OAAK,OAAO;;;;;;AAOhB,IAAa,qBAAb,cAAwC,MAAM;CAC5C,YAAY,SAAiB;AAC3B,QAAM,QAAQ;AACd,OAAK,OAAO;;;;;;AAOhB,IAAa,sBAAb,cAAyC,MAAM;CAC7C,YAAY,SAAiB;AAC3B,QAAM,QAAQ;AACd,OAAK,OAAO;;;;;;AAOhB,IAAa,sBAAb,cAAyC,MAAM;CAC7C,YAAY,SAAiB;AAC3B,QAAM,QAAQ;AACd,OAAK,OAAO;;;;;;;;;ACahB,SAAS,qBACP,WACA,aAC0B;CAC1B,MAAM,SAAmC,EAAE;CAC3C,MAAM,4BAAY,IAAI,KAAqB;AAE3C,MAAK,MAAM,SAAS,UAAU,QAAQ;AACpC,MAAI,UAAU,IAAI,MAAM,KAAK,CAC3B,QAAO,KAAK;GACV;GACA,MAAM;GACN,SAAS,yBAAyB,MAAM,KAAK;GAC7C,OAAO,MAAM;GACd,CAAC;AAEJ,YAAU,IAAI,MAAM,MAAM,MAAM,KAAK;;AAEvC,QAAO;;;;;AAMT,SAAS,sBACP,WACA,aAC0B;CAC1B,MAAM,SAAmC,EAAE;CAC3C,MAAM,8BAAc,IAAI,KAAqB;CAC7C,MAAM,aAAa,IAAI,IAAI,UAAU,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC;AAE/D,MAAK,MAAM,SAAS,UAAU,QAAQ;AACpC,MAAI,CAAC,MAAM,MAAO;AAGlB,MAAI,WAAW,IAAI,MAAM,MAAM,CAC7B,QAAO,KAAK;GACV;GACA,MAAM;GACN,SAAS,UAAU,MAAM,MAAM,eAAe,MAAM,KAAK,wCAAwC,MAAM,MAAM;GAC7G,OAAO,MAAM;GACd,CAAC;EAIJ,MAAM,gBAAgB,YAAY,IAAI,MAAM,MAAM;AAClD,MAAI,cACF,QAAO,KAAK;GACV;GACA,MAAM;GACN,SAAS,oBAAoB,MAAM,MAAM,oBAAoB,cAAc,SAAS,MAAM,KAAK;GAC/F,OAAO,MAAM;GACd,CAAC;AAEJ,cAAY,IAAI,MAAM,OAAO,MAAM,KAAK;;AAE1C,QAAO;;;;;AAMT,SAAS,sBACP,WACA,aAC0B;CAC1B,MAAM,SAAmC,EAAE;CAC3C,MAAM,mBAAmB,UAAU,OAAO,QAAQ,MAAM,EAAE,WAAW;CAErE,IAAI,uBAAsC;CAC1C,IAAI,0BAAyC;AAE7C,MAAK,MAAM,SAAS,kBAAkB;AAEpC,MAAI,yBAAyB,KAC3B,QAAO,KAAK;GACV;GACA,MAAM;GACN,SAAS,wBAAwB,MAAM,KAAK,6CAA6C,qBAAqB;GAC9G,OAAO,MAAM;GACd,CAAC;AAIJ,MAAI,MAAM,SAAS,WAAW,4BAA4B,KACxD,QAAO,KAAK;GACV;GACA,MAAM;GACN,SAAS,qBAAqB,MAAM,KAAK,6CAA6C,wBAAwB;GAC9G,OAAO,MAAM;GACd,CAAC;AAIJ,MAAI,4BAA4B,QAAQ,MAAM,SAC5C,QAAO,KAAK;GACV;GACA,MAAM;GACN,SAAS,wBAAwB,MAAM,KAAK,uCAAuC,wBAAwB;GAC3G,OAAO,MAAM;GACd,CAAC;AAGJ,MAAI,MAAM,SAAS,QACjB,wBAAuB,MAAM;AAE/B,MAAI,CAAC,MAAM,SACT,2BAA0B,MAAM;;AAGpC,QAAO;;;;;AAMT,SAAS,qBACP,WACA,aAC0B;CAC1B,MAAM,SAAmC,EAAE;AAE3C,MAAK,MAAM,SAAS,UAAU,OAC5B,MAAK,MAAM,UAAU,OAAO,MAAM,UAAU,QAAQ,MAAM,yBAAyB,KACjF,QAAO,KAAK;EACV;EACA,MAAM;EACN,SAAS,UAAU,MAAM,MAAM,sBAAsB,MAAM,UAAU,MAAM,SAAS,WAAW;EAC/F,OAAO,MAAM;EACd,CAAC;AAGN,QAAO;;;;;;;;AAaT,SAAgB,wBAAwB,WAAkC;CACxE,MAAM,SAAS,qBAAqB,WAAW,EAAE,CAAC;AAClD,KAAI,OAAO,SAAS,EAElB,OAAM,IAAI,oBACR,yBAFY,OAAO,IAAI,SAAS,UAED,iDAChC;;;;;;;;;;AAYL,SAAgB,yBAAyB,WAAkC;CACzE,MAAM,SAAS,sBAAsB,WAAW,EAAE,CAAC;AACnD,KAAI,OAAO,SAAS,GAAG;EACrB,MAAM,MAAM,OAAO;AACnB,QAAM,IAAI,oBAAoB,IAAI,QAAQ;;;;;;;;;;;;;;;AAgB9C,SAAgB,yBAAyB,WAAkC;CACzE,MAAM,SAAS,sBAAsB,WAAW,EAAE,CAAC;AACnD,KAAI,OAAO,SAAS,GAAG;EACrB,MAAM,MAAM,OAAO;AACnB,QAAM,IAAI,sBAAsB,IAAI,QAAQ;;;;;;;;;;;;;;;;AAiBhD,SAAgB,wBACd,WACA,iBACM;CACN,MAAM,SAAS,qBAAqB,WAAW,EAAE,CAAC;AAClD,KAAI,OAAO,SAAS,GAAG;EAErB,MAAM,QADM,OAAO,GACD,SAAS;EAC3B,MAAM,QAAQ,UAAU,OAAO,MAAM,MAAM,EAAE,SAAS,MAAM,EAAE,SAAS;AACvE,QAAM,IAAI,mBACR,UAAU,MAAM,sBAAsB,UAAU,MAAM,SAAS,WAAW,oCACrC,MAAM,uCAAuC,MAAM,IACzF;;;;;;AAWL,SAAS,oBACP,WACA,iBACA,aAC0B;AAC1B,QAAO;EACL,GAAG,qBAAqB,WAAW,YAAY;EAC/C,GAAG,sBAAsB,WAAW,YAAY;EAChD,GAAG,sBAAsB,WAAW,YAAY;EAChD,GAAG,qBAAqB,WAAW,YAAY;EAChD;;;;;;;;;;;;;;;;;;;;AAqBH,eAAsB,gBACpB,SACA,UAAkC,EAAE,EACF;CAClC,MAAM,cAAc,QAAQ,eAAe,CAAC,QAAQ,KAAK;CACzD,MAAM,SAAmC,EAAE;CAC3C,MAAM,iBAAiB,QAAQ,cAAc,OAAO,KAAK,QAAQ,YAAY,CAAC,SAAS,IAAI;AAG3F,KAAI,QAAQ,MAAM;EAChB,MAAM,YAAYC,uCAAc,QAAQ,KAAK;AAC7C,SAAO,KAAK,GAAG,oBAAoB,WAAW,gBAAgB,YAAY,CAAC;;AAI7E,KAAI,QAAQ,YACV,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,QAAQ,YAAY,EAAE;EAEhE,MAAM,YAAY,MAAM,gBADD,MAAMC,6CAAmB,OAAO,EACC,EACtD,aAAa,CAAC,GAAG,aAAa,KAAK,EACpC,CAAC;AACF,MAAI,CAAC,UAAU,MACb,QAAO,KAAK,GAAG,UAAU,OAAO;;AAKtC,KAAI,OAAO,WAAW,EACpB,QAAO,EAAE,OAAO,MAAM;AAGxB,QAAO;EAAE,OAAO;EAAO;EAAQ;;;;;;;;AASjC,SAAgB,8BAA8B,QAA0C;AACtF,KAAI,OAAO,WAAW,EAAG,QAAO;CAEhC,MAAM,QAAkB,CAAC,6BAA6B;AACtD,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,OAAO,MAAM,YAAY,KAAK,MAAM;AAC1C,QAAM,KAAK,QAAQ,KAAK,IAAI,MAAM,UAAU;;AAE9C,QAAO,MAAM,KAAK,KAAK;;;;;;;;;;;;;;;;;;;AC5TzB,SAAgB,UAAU,MAAgB,UAAyB,EAAE,EAAc;CACjF,MAAM,EAAE,2BAAW,IAAI,KAAK,EAAE,+BAAe,IAAI,KAAK,EAAE,6BAAa,IAAI,KAAK,KAAK;CAEnF,MAAM,SAAqB;EACzB,SAAS,EAAE;EACX,aAAa,EAAE;EACf,MAAM,EAAE;EACT;CAED,IAAI,IAAI;CACR,IAAI,cAAc;CAElB,MAAM,aAAa,MAAc,UAAmB;EAElD,MAAM,eAAe,SAAS,IAAI,KAAK,IAAI;AAE3C,MAAI,WAAW,IAAI,aAAa,EAAE;GAEhC,MAAM,WAAW,OAAO,QAAQ;AAChC,OAAI,MAAM,QAAQ,SAAS,CACzB,UAAS,KAAK,MAAM;YACX,aAAa,OACtB,QAAO,QAAQ,gBAAgB,CAAC,UAAU,MAAM;OAEhD,QAAO,QAAQ,gBAAgB,CAAC,MAAM;QAGxC,QAAO,QAAQ,gBAAgB;;AAInC,QAAO,IAAI,KAAK,QAAQ;EACtB,MAAM,MAAM,KAAK;AAGjB,MAAI,aAAa;AACf,UAAO,KAAK,KAAK,IAAI;AACrB;AACA;;AAIF,MAAI,QAAQ,MAAM;AAChB,iBAAc;AACd;AACA;;AAIF,MAAI,IAAI,WAAW,KAAK,EAAE;GACxB,MAAM,gBAAgB,IAAI,MAAM,EAAE;AAGlC,OAAI,cAAc,WAAW,MAAM,EAAE;IACnC,MAAM,WAAW,cAAc,MAAM,EAAE;IACvC,MAAM,eAAe,SAAS,IAAI,SAAS,IAAI;AAC/C,QAAI,aAAa,IAAI,aAAa,EAAE;AAClC,eAAU,UAAU,MAAM;AAC1B;AACA;;;GAIJ,MAAM,UAAU,cAAc,QAAQ,IAAI;AAC1C,OAAI,YAAY,IAAI;AAIlB,cAFa,cAAc,MAAM,GAAG,QAAQ,EAC9B,cAAc,MAAM,UAAU,EAAE,CACxB;AACtB;UACK;IAEL,MAAM,OAAO;IACb,MAAM,eAAe,SAAS,IAAI,KAAK,IAAI;AAE3C,QAAI,aAAa,IAAI,aAAa,EAAE;AAElC,eAAU,MAAM,KAAK;AACrB;WACK;KAEL,MAAM,UAAU,KAAK,IAAI;AACzB,SAAI,YAAY,UAAa,CAAC,QAAQ,WAAW,IAAI,EAAE;AACrD,gBAAU,MAAM,QAAQ;AACxB,WAAK;YACA;AAEL,gBAAU,MAAM,KAAK;AACrB;;;;AAIN;;AAIF,MAAI,IAAI,WAAW,IAAI,IAAI,IAAI,SAAS,KAAK,CAAC,IAAI,WAAW,KAAK,EAAE;GAClE,MAAM,cAAc,IAAI,MAAM,EAAE;GAEhC,MAAM,UAAU,YAAY,QAAQ,IAAI;AACxC,OAAI,YAAY,IAAI;AAIlB,cAFa,YAAY,MAAM,GAAG,QAAQ,EAC5B,YAAY,MAAM,UAAU,EAAE,CACtB;AACtB;cACS,YAAY,WAAW,GAAG;IAEnC,MAAM,OAAO;IACb,MAAM,eAAe,SAAS,IAAI,KAAK,IAAI;AAE3C,QAAI,aAAa,IAAI,aAAa,EAAE;AAClC,eAAU,MAAM,KAAK;AACrB;WACK;KAEL,MAAM,UAAU,KAAK,IAAI;AACzB,SAAI,YAAY,UAAa,CAAC,QAAQ,WAAW,IAAI,EAAE;AACrD,gBAAU,MAAM,QAAQ;AACxB,WAAK;YACA;AACL,gBAAU,MAAM,KAAK;AACrB;;;UAGC;AAGL,SAAK,MAAM,QAAQ,YACjB,WAAU,MAAM,KAAK;AAEvB;;AAEF;;AAIF,SAAO,YAAY,KAAK,IAAI;AAC5B;;AAGF,QAAO;;;;;AAMT,SAAgB,mBAAmB,WAA2C;CAC5E,MAAM,2BAAW,IAAI,KAAqB;CAC1C,MAAM,+BAAe,IAAI,KAAa;CACtC,MAAM,6BAAa,IAAI,KAAa;AAEpC,MAAK,MAAM,SAAS,UAAU,QAAQ;AAGpC,MAAI,MAAM,YAAY,MAAM,KAC1B,UAAS,IAAI,MAAM,SAAS,MAAM,KAAK;AAGzC,MAAI,MAAM,MACR,UAAS,IAAI,MAAM,OAAO,MAAM,KAAK;AAGvC,MAAI,MAAM,SAAS,UACjB,cAAa,IAAI,MAAM,KAAK;AAG9B,MAAI,MAAM,SAAS,QACjB,YAAW,IAAI,MAAM,KAAK;;AAI9B,QAAO;EAAE;EAAU;EAAc;EAAY;;;;;AAM/C,SAAgB,qBACd,QACA,WACyB;CACzB,MAAM,SAAkC,EAAE,GAAG,OAAO,SAAS;CAG7D,MAAM,mBAAmB,UAAU,OAAO,QAAQ,MAAM,EAAE,WAAW;CAGrE,MAAM,iBACJ,OAAO,KAAK,SAAS,IAAI,CAAC,GAAG,OAAO,aAAa,GAAG,OAAO,KAAK,GAAG,OAAO;CAE5E,IAAI,kBAAkB;AACtB,MAAK,MAAM,SAAS,kBAAkB;AACpC,MAAI,mBAAmB,eAAe,OACpC;AAGF,MAAI,MAAM,SAAS,SAAS;AAE1B,UAAO,MAAM,QAAQ,eAAe,MAAM,gBAAgB;AAC1D;SACK;AACL,UAAO,MAAM,QAAQ,eAAe;AACpC;;;AAIJ,QAAO;;;;;;;;;;;;;ACrMT,SAAgB,UACd,MACA,SACA,UAA4B,EAAE,EACjB;CAGb,MAAM,kBAAkB,QAAQ,cAAc,OAAO,KAAK,QAAQ,YAAY,GAAG,EAAE;CACnF,MAAM,iBAAiB,gBAAgB,SAAS;AAEhD,KAAI,kBAAkB,KAAK,SAAS,GAAG;EACrC,MAAM,WAAW,KAAK;AAEtB,MAAI,YAAY,CAAC,SAAS,WAAW,IAAI,IAAI,gBAAgB,SAAS,SAAS,CAC7E,QAAO;GACL,eAAe;GACf,kBAAkB;GAClB,kBAAkB;GAClB,YAAY;GACZ,eAAe,KAAK,MAAM,EAAE;GAC5B,SAAS,EAAE;GACX,aAAa,EAAE;GACf,cAAc,EAAE;GACjB;;CAML,IAAI;AACJ,KAAI,QAAQ,MAAM;AAChB,cAAYC,uCAAc,QAAQ,KAAK;AAEvC,MAAI,CAAC,QAAQ,gBAAgB;AAC3B,2BAAwB,UAAU;AAClC,4BAAyB,UAAU;AACnC,4BAAyB,UAAU;AACnC,2BAAwB,WAAW,eAAe;;;CAMtD,MAAM,kBACJ,WAAW,OAAO,MAAM,MAAM,EAAE,UAAU,OAAO,EAAE,yBAAyB,KAAK,IAAI;CACvF,MAAM,kBACJ,WAAW,OAAO,MAAM,MAAM,EAAE,UAAU,OAAO,EAAE,yBAAyB,KAAK,IAAI;CACvF,MAAM,mBAAmB,KAAK,SAAS,aAAa,IAAK,CAAC,mBAAmB,KAAK,SAAS,KAAK;CAChG,MAAM,gBACJ,CAAC,qBAAqB,KAAK,SAAS,SAAS,IAAK,CAAC,mBAAmB,KAAK,SAAS,KAAK;CAC3F,MAAM,mBAAmB,KAAK,SAAS,YAAY;AAEnD,KAAI,iBAAiB,oBAAoB,iBACvC,QAAO;EACL;EACA;EACA;EACA,YAAY;EACZ,eAAe,EAAE;EACjB,SAAS,EAAE;EACX,aAAa,EAAE;EACf,cAAc,EAAE;EACjB;AAIH,KAAI,CAAC,UACH,QAAO;EACL,eAAe;EACf,kBAAkB;EAClB,kBAAkB;EAClB,YAAY;EACZ,eAAe,EAAE;EACjB,SAAS,EAAE;EACX,aAAa,EAAE;EACf,cAAc,EAAE;EACjB;CAOH,MAAM,SAAS,UAAU,MAHH,mBAAmB,UAAU,CAGN;CAG7C,MAAM,UAAU,qBAAqB,QAAQ,UAAU;AAGvD,MAAK,MAAM,SAAS,UAAU,OAC5B,KAAI,MAAM,OAAO,QAAQ,MAAM,UAAU,QAAW;EAElD,MAAM,WAAW,MAAM,QAAQ,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,MAAM,IAAI;AAGnE,OAAK,MAAM,WAAW,UAAU;GAC9B,MAAM,WAAW,QAAQ,IAAI;AAC7B,OAAI,aAAa,QAAW;AAC1B,YAAQ,MAAM,QAAQ;AACtB;;;;CAOR,MAAM,aAAa,IAAI,IAAI,UAAU,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC;CAC/D,MAAM,gBAAgB,IAAI,IAAI,UAAU,OAAO,KAAK,MAAM,EAAE,QAAQ,CAAC;CACrE,MAAM,eAAe,IAAI,IAAI,UAAU,OAAO,QAAQ,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,EAAE,MAAO,CAAC;CAC1F,MAAM,eAAyB,EAAE;AAEjC,MAAK,MAAM,OAAO,OAAO,KAAK,OAAO,QAAQ,CAC3C,KAAI,CAAC,WAAW,IAAI,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAC3E,cAAa,KAAK,IAAI;AAI1B,QAAO;EACL,eAAe;EACf,kBAAkB;EAClB,kBAAkB;EAClB,YAAY;EACZ,eAAe,EAAE;EACjB;EACA,aAAa,OAAO;EACpB;EACA,iBAAiB;EAClB;;;;;;;;AC3KH,SAAS,oBAAoB,GAAW,GAAmB;CACzD,MAAM,SAAqB,EAAE;AAE7B,MAAK,IAAI,IAAI,GAAG,KAAK,EAAE,QAAQ,IAC7B,QAAO,KAAK,CAAC,EAAE;AAGjB,MAAK,IAAI,IAAI,GAAG,KAAK,EAAE,QAAQ,IAC7B,QAAO,GAAI,KAAK;AAGlB,MAAK,IAAI,IAAI,GAAG,KAAK,EAAE,QAAQ,IAC7B,MAAK,IAAI,IAAI,GAAG,KAAK,EAAE,QAAQ,IAC7B,KAAI,EAAE,OAAO,IAAI,EAAE,KAAK,EAAE,OAAO,IAAI,EAAE,CACrC,QAAO,GAAI,KAAK,OAAO,IAAI,GAAI,IAAI;KAEnC,QAAO,GAAI,KAAK,KAAK,IACnB,OAAO,IAAI,GAAI,IAAI,KAAM,GACzB,OAAO,GAAI,IAAI,KAAM,GACrB,OAAO,IAAI,GAAI,KAAM,EACtB;AAKP,QAAO,OAAO,EAAE,QAAS,EAAE;;;;;AAM7B,SAAS,YAAY,QAAgB,YAAgC;CACnE,MAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,SAAS,EAAE,CAAC;AAE5D,QAAO,WACJ,KAAK,eAAe;EACnB;EACA,UAAU,oBAAoB,OAAO,aAAa,EAAE,UAAU,aAAa,CAAC;EAC7E,EAAE,CACF,QAAQ,EAAE,eAAe,YAAY,UAAU,CAC/C,MAAM,GAAG,MAAM,EAAE,WAAW,EAAE,SAAS,CACvC,KAAK,EAAE,gBAAgB,UAAU,CACjC,MAAM,GAAG,EAAE;;;;;;;;AAShB,SAAgBC,yBAAuB,QAAmC;AACxE,KAAI,OAAO,WAAW,EACpB,QAAO;CAGT,MAAM,QAAkB,CAAC,OAAO,MAAM,qBAAqB,CAAC;AAE5D,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,OAAO,MAAM,KAAK,KAAK,IAAI;AACjC,QAAM,KAAK,KAAK,QAAQ,OAAO,GAAG,OAAO,KAAK,KAAK,CAAC,IAAI,MAAM,UAAU;;AAG1E,QAAO,MAAM,KAAK,KAAK;;;;;;;;;AAUzB,SAAgB,kBAAkB,MAAc,YAA8B;CAE5E,MAAM,UAAU,YADC,KAAK,QAAQ,WAAW,GAAG,EACN,WAAW;CAEjD,IAAI,UAAU,GAAG,OAAO,MAAM,kBAAkB,CAAC,GAAG,OAAO,KAAK,KAAK;AAErE,KAAI,QAAQ,SAAS,GAAG;AACtB,aAAW,OAAO,OAAO,KAAK,gBAAgB;AAC9C,OAAK,MAAM,cAAc,QACvB,YAAW,OAAO,QAAQ,MAAM,GAAG,OAAO,OAAO,KAAK,aAAa;;AAIvE,QAAO;;;;;;;;;AAUT,SAAgB,yBAAyB,MAAc,YAA8B;CAEnF,MAAM,UAAU,YADC,KAAK,QAAQ,WAAW,GAAG,EACN,WAAW;CAEjD,IAAI,UAAU,GAAG,OAAO,QAAQ,2BAA2B,CAAC,GAAG,OAAO,KAAK,KAAK;AAEhF,KAAI,QAAQ,SAAS,GAAG;AACtB,aAAW,OAAO,OAAO,KAAK,gBAAgB;AAC9C,OAAK,MAAM,cAAc,QACvB,YAAW,OAAO,QAAQ,MAAM,GAAG,OAAO,OAAO,KAAK,aAAa;;AAIvE,QAAO;;;;;;;;;AAUT,SAAgB,mBAAmB,OAAc,OAAwB;AACvE,KAAI,SAAS,MAAM,MACjB,QAAO,GAAG,OAAO,MAAM,SAAS,CAAC,GAAG,MAAM,QAAQ,MAAM,OAAO,IAAI,MAAM,MAAM;AAGjF,QAAO,GAAG,OAAO,MAAM,SAAS,CAAC,GAAG,MAAM;;;;;;;;;AAU5C,SAAgB,wBAAwB,YAAoB,kBAAoC;CAC9F,MAAM,UAAU,YAAY,YAAY,iBAAiB;CAEzD,IAAI,UAAU,GAAG,OAAO,MAAM,mBAAmB,CAAC,GAAG,OAAO,KAAK,WAAW;AAE5E,KAAI,QAAQ,SAAS,GAAG;AACtB,aAAW,OAAO,OAAO,KAAK,gBAAgB;AAC9C,OAAK,MAAM,cAAc,QACvB,YAAW,OAAO,QAAQ,MAAM,GAAG,OAAO,QAAQ,WAAW;;AAIjE,QAAO;;;;;;;;AC3HT,SAAS,gBAAgB,OAAsC;AAC7D,QAAO,MAAM,OAAO,KAAK,WAAW;EAClC,MAAM,MAAM,KAAK,IAAI,OAAO;EAC5B,SAAS,MAAM;EACf,MAAM,MAAM;EACZ,UAAU,cAAc,QAAQ,MAAM,WAAW;EACjD,UAAU,cAAc,QAAQ,OAAO,MAAM,SAAS,GAAG;EAC1D,EAAE;;;;;;;;;AAUL,SAAgB,aACd,SACA,QAC8B;CAC9B,MAAM,SAAS,OAAO,UAAU,QAAQ;AAExC,KAAI,OAAO,QACT,QAAO;EACL,SAAS;EACT,MAAM,OAAO;EACd;AAGH,QAAO;EACL,SAAS;EACT,QAAQ,gBAAgB,OAAO,MAAM;EACtC;;;;;AAMH,SAAgB,uBAAuB,QAAmC;AACxE,QAAO,OACJ,KAAK,MAAM;AAEV,SAAO,GADM,EAAE,KAAK,SAAS,IAAI,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC,MAAM,KAC1C,EAAE;GACnB,CACD,KAAK,KAAK;;;;;;;;;;;;AChDf,MAAM,gBAAwB;CAC5B,MAAM,YAAoB,QAAQ,IAAI,QAAQ;CAC9C,QAAQ,YAAoB,QAAQ,MAAM,QAAQ;CACnD;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCD,eAAsB,WACpB,SACA,MACA,UAA6B,EAAE,EACF;AAC7B,QAAO,mBAAmB,SAAS,MAAM;EACvC,GAAG;EACH,eAAe;EACf,gBAAgB,QAAQ;EACxB,QAAQ,QAAQ;EACjB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;AA0BJ,eAAsB,QAAQ,SAAqB,UAAuB,EAAE,EAAkB;CAC5F,MAAM,SAAS,MAAM,mBAAmB,SAAS,QAAQ,KAAK,MAAM,EAAE,EAAE;EACtE,OAAO,QAAQ;EACf,aAAa,QAAQ;EACrB,gBAAgB,QAAQ;EACxB,eAAe;EACf,QAAQ,QAAQ;EAChB,UAAU;GACR,aAAa,EAAE;GACf,UAAU,QAAQ;GAClB,aAAa,QAAQ;GACtB;EACF,CAAC;AAEF,SAAQ,KAAK,OAAO,SAAS;;;;;AAM/B,eAAe,mBACb,SACA,MACA,UAAkC,EAAE,EACP;CAE7B,MAAM,SAAS,QAAQ,UAAU;CAGjC,MAAM,UAA0B,QAAQ,YAAY;EAClD,aAAa,EAAE;EACf,UAAU,QAAQ;EACnB;CAID,MAAM,YADoB,QAAQ,eAAe,QACXC,8CAAoB,GAAG;AAC7D,YAAW,OAAO;CAGlB,MAAM,uBAAsC;AAG1C,SAAOC,oCAFc,QAAQ,iBAAiBC,qCAAW,EACnC,WAAW,SAAS,IAAIA,qCAAW,CACZ;;AAG/C,KAAI;EAEF,MAAM,cAAc,UAAU,MAAM,SAAS,EAAE,gBAAgB,QAAQ,gBAAgB,CAAC;AAGxF,MAAI,YAAY,iBAAiB,YAAY,kBAAkB;GAE7D,IAAI,uBAAuB;GAC3B,MAAM,cAAcC,0CAAgB,QAAQ;AAC5C,OAAI,YAAY,SAAS,GAAG;IAE1B,MAAM,kBAAkB,KAAK,MAAM,QAAQ,CAAC,IAAI,WAAW,IAAI,CAAC;AAChE,QAAI,mBAAmB,CAAC,YAAY,SAAS,gBAAgB,EAAE;AAC7D,YAAO,MAAM,wBAAwB,iBAAiB,YAAY,CAAC;AACnE,YAAO,MAAM,GAAG;AAChB,4BAAuB;;;GAI3B,MAAM,OAAO,aAAa,SAAS;IACjC,iBAAiB,QAAQ,mBAAmB;IAC5C,uBAAuB,YAAY,oBAAoB,QAAQ;IAC/D;IACD,CAAC;AACF,UAAO,IAAI,KAAK;AAChB,cAAW,MAAM;AACjB,OAAI,qBACF,QAAO;IACL,SAAS;IACT,uBAAO,IAAI,MAAM,uBAAuB,KAAK,MAAM,QAAQ,CAAC,IAAI,WAAW,IAAI,CAAC,GAAG;IACnF,UAAU;IACV,MAAM,gBAAgB;IACvB;AAEH,UAAO;IAAE,SAAS;IAAM,QAAQ;IAAW,UAAU;IAAG,MAAM,gBAAgB;IAAE;;AAIlF,MAAI,YAAY,kBAAkB;GAEhC,MAAM,UAAU,QAAQ;AACxB,OAAI,QACF,QAAO,IAAI,QAAQ;AAErB,cAAW,MAAM;AACjB,UAAO;IAAE,SAAS;IAAM,QAAQ;IAAW,UAAU;IAAG,MAAM,gBAAgB;IAAE;;AAIlF,MAAI,YAAY,YAAY;GAC1B,MAAM,SAAS,MAAMC,4CAAkB,SAAS,YAAY,WAAW;AACvE,OAAI,QAAQ;IAEV,MAAM,aAA6B;KACjC,aAAa,CAAC,GAAI,QAAQ,eAAe,EAAE,EAAG,YAAY,WAAW;KACrE,UAAU,QAAQ;KAClB,aAAa,QAAQ;KACtB;AAED,eAAW,MAAM;AACjB,WAAO,mBAA4B,QAAQ,YAAY,eAAe;KACpE,GAAG;KACH,UAAU;KACV,eAAe,gBAAgB;KAChC,CAAC;;;AAMN,MADgBD,0CAAgB,QAAQ,CAC5B,SAAS,KAAK,CAAC,YAAY,cAAc,CAAC,QAAQ,KAAK;GACjE,MAAM,OAAO,aAAa,SAAS;IACjC,iBAAiB,QAAQ,mBAAmB;IAC5C;IACD,CAAC;AACF,UAAO,IAAI,KAAK;AAChB,cAAW,MAAM;AACjB,UAAO;IAAE,SAAS;IAAM,QAAQ;IAAW,UAAU;IAAG,MAAM,gBAAgB;IAAE;;AAIlF,MAAI,YAAY,aAAa,SAAS,GAAG;GACvC,MAAM,kBAAkB,YAAY,iBAAiB,mBAAmB;GACxE,MAAM,aAAa,YAAY,iBAAiB,OAAO,KAAK,MAAM,EAAE,KAAK,IAAI,EAAE;AAE/E,OAAI,oBAAoB,UAAU;AAEhC,SAAK,MAAM,QAAQ,YAAY,aAC7B,QAAO,MAAM,kBAAkB,MAAM,WAAW,CAAC;AAEnD,eAAW,MAAM;AACjB,WAAO;KACL,SAAS;KACT,uBAAO,IAAI,MAAM,kBAAkB,YAAY,aAAa,KAAK,KAAK,GAAG;KACzE,UAAU;KACV,MAAM,gBAAgB;KACvB;cACQ,oBAAoB,QAE7B,MAAK,MAAM,QAAQ,YAAY,aAC7B,QAAO,MAAM,yBAAyB,MAAM,WAAW,CAAC;;AAQ9D,MAAI,CAAC,QAAQ,MAAM;AAGjB,cAAW,MAAM;AAMjB,UALe,MAAM,iBAAiB,SAAS,EAAE,EAA2B;IAC1E,eAAe,QAAQ;IACvB,aAAa,QAAQ;IACrB,cAAc,gBAAgB;IAC/B,CAAC;;EAIJ,MAAM,mBAAmB,aAAa,YAAY,SAAS,QAAQ,KAAK;AAExE,MAAI,CAAC,iBAAiB,SAAS;AAC7B,UAAO,MAAME,yBAAuB,iBAAiB,OAAO,CAAC;AAC7D,cAAW,MAAM;AACjB,UAAO;IACL,SAAS;IACT,OAAO,IAAI,MAAMA,yBAAuB,iBAAiB,OAAO,CAAC;IACjE,UAAU;IACV,MAAM,gBAAgB;IACvB;;AAKH,aAAW,MAAM;AAOjB,SANe,MAAM,iBAAiB,SAAS,iBAAiB,MAAM;GACpE,eAAe,QAAQ;GACvB,aAAa,QAAQ;GACrB,cAAc,gBAAgB;GAC/B,CAAC;UAGK,OAAO;EACd,MAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;AACrE,SAAO,MAAM,mBAAmB,KAAK,QAAQ,SAAS,MAAM,CAAC;AAC7D,aAAW,MAAM;AACjB,SAAO;GACL,SAAS;GACT,OAAO;GACP,UAAU;GACV,MAAM,gBAAgB;GACvB"}
@@ -2,6 +2,7 @@ import { n as getExtractedFields, t as extractFields } from "./schema-extractor-
2
2
  import { a as emptyLogs, i as createLogCollector, n as resolveLazyCommand, o as mergeLogs, r as resolveSubcommand, t as listSubCommands } from "./subcommand-router-DtCeT_O9.js";
3
3
  import { z } from "zod";
4
4
  import { styleText } from "node:util";
5
+ import stringWidth from "string-width";
5
6
 
6
7
  //#region \0rolldown/runtime.js
7
8
  var __defProp = Object.defineProperty;
@@ -420,13 +421,14 @@ function parseAlignments(sepRow) {
420
421
  * Pad a string to a given width with the specified alignment.
421
422
  */
422
423
  function alignText(text, width, alignment) {
423
- if (alignment === "right") return text.padStart(width);
424
+ const visualWidth = stringWidth(text);
425
+ const total = Math.max(0, width - visualWidth);
426
+ if (alignment === "right") return " ".repeat(total) + text;
424
427
  if (alignment === "center") {
425
- const total = width - text.length;
426
428
  const left = Math.floor(total / 2);
427
429
  return " ".repeat(left) + text + " ".repeat(total - left);
428
430
  }
429
- return text.padEnd(width);
431
+ return text + " ".repeat(total);
430
432
  }
431
433
  /**
432
434
  * Style configuration for GitHub-style alert blocks.
@@ -487,9 +489,12 @@ function renderBlock(block) {
487
489
  }
488
490
  case "table": {
489
491
  const colCount = block.headers.length;
490
- const colWidths = block.headers.map((h, i) => {
491
- const cellLengths = block.rows.map((row) => (row[i] ?? "").length);
492
- return Math.max(h.length, ...cellLengths);
492
+ const renderedHeaders = block.headers.map((h) => renderInline(h));
493
+ const renderedRows = block.rows.map((row) => Array.from({ length: colCount }, (_, i) => renderInline(row[i] ?? "")));
494
+ const colWidths = renderedHeaders.map((h, i) => {
495
+ const headerWidth = stringWidth(h);
496
+ const cellWidths = renderedRows.map((row) => stringWidth(row[i]));
497
+ return Math.max(headerWidth, ...cellWidths);
493
498
  });
494
499
  const pipe = styles.dim("│");
495
500
  const topBorder = styles.dim(`┌─${colWidths.map((w) => "─".repeat(w)).join("─┬─")}─┐`);
@@ -497,10 +502,10 @@ function renderBlock(block) {
497
502
  const botBorder = styles.dim(`└─${colWidths.map((w) => "─".repeat(w)).join("─┴─")}─┘`);
498
503
  return [
499
504
  topBorder,
500
- `${pipe} ${block.headers.map((h, i) => styles.bold(alignText(h, colWidths[i], block.alignments[i] ?? "left"))).join(` ${pipe} `)} ${pipe}`,
505
+ `${pipe} ${renderedHeaders.map((h, i) => styles.bold(alignText(h, colWidths[i], block.alignments[i] ?? "left"))).join(` ${pipe} `)} ${pipe}`,
501
506
  midBorder,
502
- ...block.rows.map((row) => {
503
- return `${pipe} ${Array.from({ length: colCount }, (_, i) => renderInline(alignText(row[i] ?? "", colWidths[i], block.alignments[i] ?? "left"))).join(` ${pipe} `)} ${pipe}`;
507
+ ...renderedRows.map((row) => {
508
+ return `${pipe} ${row.map((cell, i) => alignText(cell, colWidths[i], block.alignments[i] ?? "left")).join(` ${pipe} `)} ${pipe}`;
504
509
  }),
505
510
  botBorder
506
511
  ].join("\n");
@@ -1708,4 +1713,4 @@ async function runCommandInternal(command, argv, options = {}) {
1708
1713
 
1709
1714
  //#endregion
1710
1715
  export { symbols as C, styles as S, renderInline as _, parseArgv as a, logger as b, validateDuplicateAliases as c, validateReservedAliases as d, DuplicateAliasError as f, generateHelp as g, ReservedAliasError as h, formatValidationErrors as i, validateDuplicateFields as l, PositionalConfigError as m, runMain as n, formatCommandValidationErrors as o, DuplicateFieldError as p, runner_exports as r, validateCommand as s, runCommand as t, validatePositionalConfig as u, renderMarkdown as v, setColorEnabled as x, isColorEnabled as y };
1711
- //# sourceMappingURL=runner-ElQbBn1U.js.map
1716
+ //# sourceMappingURL=runner-LJRI4haB.js.map