fuzzi-cli 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types/brand.ts","../src/lib/credentials.ts","../src/lib/config.ts","../src/lib/logger.ts","../src/lib/api-client.ts","../src/terminal/capabilities.ts","../src/terminal/theme.ts","../src/terminal/table.ts","../src/terminal/strings.ts","../src/terminal/width.ts","../src/terminal/layout.ts","../src/lib/theme.ts","../src/commands/report.ts","../src/commands/whatif.ts","../src/commands/compare.ts","../src/cli/program.ts","../src/commands/auth.ts","../src/lib/browser-auth.ts","../src/lib/output.ts","../src/commands/scan.ts","../src/lib/errors.ts","../src/lib/risk.ts","../src/lib/project-config.ts","../src/terminal/progress.ts","../src/lib/retry.ts","../src/commands/scans.ts","../src/commands/status.ts","../src/commands/config.ts","../src/cli/exit.ts","../src/shell/prompt-loop.ts","../src/lib/assets.ts","../src/shell/home-screen.ts","../src/shell/ascii-mark.ts","../src/components/Panel.ts","../src/shell/slash-commands.ts","../src/commands/keys.ts","../src/terminal/empty-state.ts","../src/terminal/interactive.ts","../src/shell/help-screen.ts","../src/shell/registry.ts","../src/shell/command-palette.ts","../src/shell/session.ts","../src/terminal/banner.ts","../src/shell/completer.ts","../src/shell/auth-gate.ts","../src/cli/profile.ts","../src/cli/bootstrap.ts","../src/index.ts"],"sourcesContent":["/** Locked Fuzzi CLI design tokens (dark-first terminal). */\nexport const BRAND = {\n accent: \"#4FC3A1\",\n accentDim: \"#3A9A7E\",\n bg: \"#0A0C10\",\n surface: \"#12151B\",\n surfaceHover: \"#181C24\",\n borderSubtle: \"#232832\",\n borderStrong: \"#313846\",\n textPrimary: \"#E8EAED\",\n textSecondary: \"#9AA3B2\",\n textTertiary: \"#5C6470\",\n success: \"#22C55E\",\n warning: \"#F59E0B\",\n danger: \"#EF4444\",\n critical: \"#A855F7\",\n} as const;\n\nexport const RISK_COLORS: Record<string, string> = {\n LOW: BRAND.success,\n MEDIUM: BRAND.warning,\n HIGH: BRAND.danger,\n CRITICAL: BRAND.critical,\n};\n\nexport const VERSION = \"0.1.4\";\n\n/** Production web app (Vercel) */\nexport const APP_ORIGIN = \"https://fuzzi-ten.vercel.app\";\n\n/** Default API base — override with FUZZI_API_URL */\nexport const DEFAULT_API_URL = `${APP_ORIGIN}/api`;\n\nexport const SETTINGS_API_KEYS_URL = `${APP_ORIGIN}/settings/api-keys`;\nexport const CLI_AUTH_URL = `${APP_ORIGIN}/cli-auth`;\nexport const APP_HOST = \"fuzzi-ten.vercel.app\";\n","import { mkdir, readFile, writeFile, chmod, unlink } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { Credentials } from \"../types/api.js\";\n\nconst FUZZI_DIR = join(homedir(), \".fuzzi\");\nconst CREDENTIALS_PATH = join(FUZZI_DIR, \"credentials\");\nconst LEGACY_CREDENTIALS_PATH = join(FUZZI_DIR, \"credentials.json\");\n\nexport function fuzziDir(): string {\n return FUZZI_DIR;\n}\n\nexport function credentialsPath(): string {\n return CREDENTIALS_PATH;\n}\n\nasync function ensureDir(): Promise<void> {\n await mkdir(FUZZI_DIR, { recursive: true, mode: 0o700 });\n}\n\nfunction normalizeCredentials(raw: Record<string, unknown>): Credentials {\n if (raw.api_key && typeof raw.api_key === \"string\") {\n return {\n api_key: raw.api_key,\n auth_method: \"api_key\",\n key_prefix: (raw.key_prefix as string) || raw.api_key.slice(0, 12) + \"...\",\n key_expires_at: raw.key_expires_at as string | undefined,\n email: raw.email as string | undefined,\n full_name: raw.full_name as string | undefined,\n saved_at: (raw.saved_at as string) || new Date().toISOString(),\n };\n }\n if (raw.access_token && typeof raw.access_token === \"string\") {\n return {\n api_key: raw.access_token,\n auth_method: \"api_key\",\n key_prefix: raw.access_token.slice(0, 12) + \"...\",\n email: raw.email as string | undefined,\n full_name: raw.full_name as string | undefined,\n saved_at: (raw.saved_at as string) || new Date().toISOString(),\n };\n }\n throw new Error(\"Invalid credentials file\");\n}\n\nexport async function loadCredentials(): Promise<Credentials | null> {\n for (const path of [CREDENTIALS_PATH, LEGACY_CREDENTIALS_PATH]) {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n if (!parsed || Object.keys(parsed).length === 0) return null;\n return normalizeCredentials(parsed);\n } catch {\n /* try next path */\n }\n }\n return null;\n}\n\nexport async function saveCredentials(creds: Credentials): Promise<void> {\n await ensureDir();\n await writeFile(CREDENTIALS_PATH, JSON.stringify(creds, null, 2), { mode: 0o600 });\n try {\n await chmod(CREDENTIALS_PATH, 0o600);\n } catch {\n /* windows */\n }\n}\n\nexport async function clearCredentials(): Promise<void> {\n for (const path of [CREDENTIALS_PATH, LEGACY_CREDENTIALS_PATH]) {\n try {\n await unlink(path);\n } catch {\n /* ok */\n }\n }\n}\n\nexport function maskApiKey(key: string): string {\n if (key.length <= 16) return key.slice(0, 8) + \"...\";\n return key.slice(0, 12) + \"...\";\n}\n\nexport function isValidApiKeyFormat(key: string): boolean {\n return /^fz_live_[A-Za-z0-9_-]{20,}$/.test(key.trim());\n}\n","import { mkdir, readFile, writeFile, chmod } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { CliConfig } from \"../types/api.js\";\nimport { DEFAULT_API_URL } from \"../types/brand.js\";\nimport { fuzziDir } from \"./credentials.js\";\n\nconst CONFIG_PATH = join(homedir(), \".fuzzi\", \"config\");\nconst LEGACY_CONFIG_PATH = join(homedir(), \".fuzzi\", \"config.json\");\n\nexport { fuzziDir };\n\nasync function ensureDir(): Promise<void> {\n await mkdir(fuzziDir(), { recursive: true, mode: 0o700 });\n}\n\nexport async function loadConfig(): Promise<CliConfig> {\n for (const path of [CONFIG_PATH, LEGACY_CONFIG_PATH]) {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<CliConfig>;\n return {\n api_url: process.env.FUZZI_API_URL || parsed.api_url || DEFAULT_API_URL,\n default_env: parsed.default_env,\n default_format: parsed.default_format,\n ...parsed,\n };\n } catch {\n /* try next */\n }\n }\n return { api_url: process.env.FUZZI_API_URL || DEFAULT_API_URL };\n}\n\nexport async function saveConfig(config: CliConfig): Promise<void> {\n await ensureDir();\n await writeFile(CONFIG_PATH, JSON.stringify(config, null, 2), { mode: 0o600 });\n try {\n await chmod(CONFIG_PATH, 0o600);\n } catch {\n /* windows */\n }\n}\n\nexport async function setConfigValue(key: string, value: string): Promise<void> {\n const config = await loadConfig();\n if (key === \"api_url\") config.api_url = value;\n else if (key === \"default_env\") config.default_env = value as CliConfig[\"default_env\"];\n else if (key === \"default_format\") config.default_format = value as CliConfig[\"default_format\"];\n else (config as unknown as Record<string, string>)[key] = value;\n await saveConfig(config);\n}\n\nexport async function getConfigValue(key: string): Promise<string | undefined> {\n const config = await loadConfig();\n return (config as unknown as Record<string, string | undefined>)[key];\n}\n\nexport async function listConfigEntries(): Promise<Record<string, string>> {\n const config = await loadConfig();\n const entries: Record<string, string> = {};\n for (const [k, v] of Object.entries(config)) {\n if (v !== undefined) entries[k] = String(v);\n }\n return entries;\n}\n","type Level = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nconst LEVELS: Record<Level, number> = { debug: 0, info: 1, warn: 2, error: 3 };\n\nfunction currentLevel(): Level {\n if (process.env.FUZZI_DEBUG === \"1\" || process.env.FUZZI_DEBUG === \"true\") return \"debug\";\n if (process.env.FUZZI_LOG_LEVEL) return process.env.FUZZI_LOG_LEVEL as Level;\n return \"warn\";\n}\n\nfunction shouldLog(level: Level): boolean {\n return LEVELS[level] >= LEVELS[currentLevel()];\n}\n\nfunction stamp(): string {\n return new Date().toISOString();\n}\n\nexport const log = {\n debug(...args: unknown[]) {\n if (shouldLog(\"debug\")) console.error(`[fuzzi ${stamp()}]`, ...args);\n },\n info(...args: unknown[]) {\n if (shouldLog(\"info\")) console.error(`[fuzzi ${stamp()}]`, ...args);\n },\n warn(...args: unknown[]) {\n if (shouldLog(\"warn\")) console.error(`[fuzzi ${stamp()}]`, ...args);\n },\n error(...args: unknown[]) {\n if (shouldLog(\"error\")) console.error(`[fuzzi ${stamp()}]`, ...args);\n },\n};\n\nexport function isDebugMode(): boolean {\n return currentLevel() === \"debug\";\n}\n","import type { Credentials, CliConfig } from \"../types/api.js\";\nimport { loadConfig } from \"./config.js\";\nimport { loadCredentials } from \"./credentials.js\";\nimport { log } from \"./logger.js\";\nimport { APP_HOST, SETTINGS_API_KEYS_URL } from \"../types/brand.js\";\n\nexport class ApiError extends Error {\n exitCode?: number;\n\n constructor(\n message: string,\n public status: number,\n public code?: string,\n public body?: unknown,\n exitCode?: number,\n ) {\n super(message);\n this.name = \"ApiError\";\n this.exitCode = exitCode;\n }\n}\n\nfunction mapErrorMessage(status: number, body: { error?: string; code?: string; message?: string }): string {\n const code = body.code?.toLowerCase();\n const msg = body.error || body.message || \"\";\n\n if (status === 401) {\n if (code === \"key_revoked\" || msg.toLowerCase().includes(\"revoked\")) {\n return \"API key has been revoked. Please log in again.\";\n }\n if (code === \"key_expired\" || msg.toLowerCase().includes(\"expired\")) {\n return `API key has expired. Generate a new one at ${SETTINGS_API_KEYS_URL}`;\n }\n return `Invalid API key. Generate a new one at ${SETTINGS_API_KEYS_URL}`;\n }\n if (status === 403 && (code === \"ssrf\" || msg.toLowerCase().includes(\"private ip\"))) {\n return \"This URL is not allowed (private IP address detected). Please scan a public-facing URL.\";\n }\n if (status === 400 && msg.toLowerCase().includes(\"url\")) {\n return \"Invalid URL. Please provide a valid URL starting with http:// or https://\";\n }\n if (status === 429) {\n return msg || \"Rate limit exceeded.\";\n }\n if (msg.toLowerCase().startsWith(\"scan failed\")) {\n return msg;\n }\n if (msg) return msg;\n return `Request failed with status ${status}`;\n}\n\nexport class FuzziApiClient {\n constructor(\n private baseUrl: string,\n private token?: string,\n ) {}\n\n static async create(): Promise<FuzziApiClient> {\n const config = await loadConfig();\n const creds = await loadCredentials();\n return new FuzziApiClient(config.api_url.replace(/\\/$/, \"\"), creds?.api_key);\n }\n\n get base(): string {\n return this.baseUrl;\n }\n\n setToken(token: string): void {\n this.token = token;\n }\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = { \"Content-Type\": \"application/json\", Accept: \"application/json\" };\n if (this.token) h.Authorization = `Bearer ${this.token}`;\n return h;\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path.startsWith(\"/\") ? path : `/${path}`}`;\n log.debug(`${method} ${url}`);\n let res: Response;\n try {\n res = await fetch(url, {\n method,\n headers: this.headers(),\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n } catch {\n throw new ApiError(\n `Could not connect to ${APP_HOST}. Check your internet connection or try again later.`,\n 0,\n \"network_error\",\n undefined,\n 2,\n );\n }\n\n let data: unknown;\n const text = await res.text();\n try {\n data = text ? JSON.parse(text) : {};\n } catch {\n data = { error: text };\n }\n\n if (!res.ok) {\n const errBody = data as { error?: string; code?: string; message?: string };\n let message = mapErrorMessage(res.status, errBody);\n\n if (res.status === 429) {\n const retryAfter = res.headers.get(\"Retry-After\");\n const seconds = retryAfter ? parseInt(retryAfter, 10) : 60;\n message = `Rate limit exceeded. Retry after ${seconds} seconds.`;\n }\n\n if (res.status >= 500) {\n message = `Scan failed: ${errBody.error || errBody.message || res.statusText}`;\n }\n\n throw new ApiError(message, res.status, errBody.code, data, 2);\n }\n return data as T;\n }\n\n get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(\"PATCH\", path, body);\n }\n\n delete<T>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n\n async validateToken(): Promise<boolean> {\n try {\n await this.get(\"/me\");\n return true;\n } catch {\n return false;\n }\n }\n\n async download(path: string): Promise<{ data: Buffer; contentType: string }> {\n const url = `${this.baseUrl}${path.startsWith(\"/\") ? path : `/${path}`}`;\n let res: Response;\n try {\n res = await fetch(url, { headers: this.headers() });\n } catch {\n throw new ApiError(\n `Could not connect to ${APP_HOST}. Check your internet connection or try again later.`,\n 0,\n \"network_error\",\n undefined,\n 2,\n );\n }\n if (!res.ok) {\n const text = await res.text();\n let errBody: { error?: string; code?: string } = {};\n try {\n errBody = JSON.parse(text);\n } catch {\n errBody = { error: text };\n }\n throw new ApiError(mapErrorMessage(res.status, errBody), res.status, errBody.code, errBody, 2);\n }\n const buf = Buffer.from(await res.arrayBuffer());\n return { data: buf, contentType: res.headers.get(\"content-type\") || \"application/octet-stream\" };\n }\n}\n\nexport async function getAuthenticatedClient(): Promise<FuzziApiClient> {\n const client = await FuzziApiClient.create();\n if (!client[\"token\"]) {\n throw new ApiError(\"Not authenticated. Run: fuzzi auth login\", 401, \"not_authenticated\", undefined, 2);\n }\n return client;\n}\n\nexport async function getConfig(): Promise<CliConfig> {\n return loadConfig();\n}\n\nexport async function getCredentials(): Promise<Credentials | null> {\n return loadCredentials();\n}\n","import { stdout } from \"node:process\";\n\nexport interface TerminalCapabilities {\n width: number;\n trueColor: boolean;\n interactive: boolean;\n}\n\nlet cached: TerminalCapabilities | null = null;\n\nexport function getCapabilities(): TerminalCapabilities {\n if (cached) return cached;\n const cols = stdout.columns ?? 80;\n const term = process.env.TERM ?? \"\";\n const colorterm = process.env.COLORTERM ?? \"\";\n const trueColor =\n colorterm.includes(\"truecolor\") ||\n colorterm.includes(\"24bit\") ||\n term.includes(\"truecolor\") ||\n (!!process.env.FORCE_COLOR && process.env.FORCE_COLOR !== \"0\");\n\n cached = {\n width: Math.max(60, cols),\n trueColor,\n interactive: stdout.isTTY === true,\n };\n return cached;\n}\n\nexport function resetCapabilities(): void {\n cached = null;\n}\n","import chalk, { type ChalkInstance } from \"chalk\";\nimport { BRAND, RISK_COLORS } from \"../types/brand.js\";\nimport { getCapabilities } from \"./capabilities.js\";\n\nfunction color(hex: string, fallback: ChalkInstance): ChalkInstance {\n return getCapabilities().trueColor ? chalk.hex(hex) : fallback;\n}\n\nexport const accent = color(BRAND.accent, chalk.cyan);\nexport const accentBold = accent.bold;\nexport const primary = color(BRAND.textPrimary, chalk.white);\nexport const primaryBold = primary.bold;\nexport const muted = color(BRAND.textSecondary, chalk.gray);\nexport const dimText = color(BRAND.textTertiary, chalk.dim);\nexport const border = color(BRAND.borderSubtle, chalk.gray);\nexport const bold = chalk.bold;\nexport const dim = chalk.dim;\n\nexport function riskColor(level: string | null | undefined): (s: string) => string {\n if (!level) return muted;\n const key = level.toUpperCase();\n const hex = RISK_COLORS[key] || BRAND.textSecondary;\n const fallbacks: Record<string, ChalkInstance> = {\n LOW: chalk.green,\n MEDIUM: chalk.yellow,\n HIGH: chalk.red,\n CRITICAL: chalk.magenta,\n };\n return color(hex, fallbacks[key] ?? chalk.gray).bold;\n}\n\nexport function scoreBold(n: number | null | undefined): string {\n if (n == null) return muted(\"—\");\n return chalk.bold(String(n));\n}\n\nexport function header(text: string): string {\n return primaryBold(text);\n}\n\nexport function error(text: string): string {\n return color(BRAND.danger, chalk.red)(text);\n}\n\nexport function success(text: string): string {\n return color(BRAND.success, chalk.green)(text);\n}\n\nexport function warn(text: string): string {\n return color(BRAND.warning, chalk.yellow)(text);\n}\n\nexport function info(text: string): string {\n return color(BRAND.accent, chalk.cyan)(text);\n}\n\nexport const italic = chalk.italic;\n\nexport function riskBadge(level: string): string {\n const tag = level.toUpperCase().padEnd(8);\n return riskColor(level)(tag);\n}\n\nexport function cmd(text: string): string {\n return accent(text);\n}\n","import Table from \"cli-table3\";\nimport { muted } from \"./theme.js\";\n\nconst BOX_CHARS: Record<string, string> = {\n mid: \"─\",\n \"left-mid\": \"├\",\n \"mid-mid\": \"┼\",\n \"right-mid\": \"┤\",\n};\n\nexport function createTable(headers: string[], rows: string[][]): string {\n const table = new Table({\n head: headers.map((h) => muted(h)),\n style: { head: [], border: [] },\n chars: BOX_CHARS,\n });\n for (const row of rows) table.push(row);\n return table.toString();\n}\n","export function truncate(s: string, max: number): string {\n if (s.length <= max) return s;\n return s.slice(0, max - 1) + \"…\";\n}\n\nexport function padEndVisible(s: string, width: number): string {\n const plain = s.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n const pad = Math.max(0, width - plain.length);\n return s + \" \".repeat(pad);\n}\n\nexport function formatTimestamp(iso: string | null | undefined): string {\n if (!iso) return \"—\";\n const d = new Date(iso);\n const p = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;\n}\n\nexport function hostnameFromUrl(url: string): string {\n try {\n return new URL(url).hostname;\n } catch {\n return url;\n }\n}\n","import { stdout } from \"node:process\";\nimport { getCapabilities, resetCapabilities } from \"./capabilities.js\";\n\nexport function terminalWidth(): number {\n resetCapabilities();\n return Math.max(64, (stdout.columns ?? 80) - 2);\n}\n\nexport function contentWidth(): number {\n return terminalWidth() - 4;\n}\n","import boxen from \"boxen\";\nimport { BRAND } from \"../types/brand.js\";\nimport { accentBold, dim, muted } from \"./theme.js\";\nimport { getCapabilities } from \"./capabilities.js\";\nimport { padEndVisible } from \"./strings.js\";\nimport { terminalWidth, contentWidth } from \"./width.js\";\n\nexport interface PanelOptions {\n title?: string;\n padding?: number;\n marginBottom?: number;\n fullWidth?: boolean;\n borderStyle?: \"round\" | \"single\" | \"classic\" | \"bold\";\n}\n\nexport function panel(content: string, opts: PanelOptions = {}): string {\n const width = opts.fullWidth !== false ? terminalWidth() : undefined;\n return boxen(content, {\n title: opts.title ? accentBold(opts.title) : undefined,\n padding: opts.padding ?? 1,\n margin: { top: 0, bottom: opts.marginBottom ?? 1, left: 0, right: 0 },\n borderStyle: opts.borderStyle ?? \"classic\",\n borderColor: getCapabilities().trueColor ? BRAND.accent : undefined,\n titleAlignment: \"left\",\n width,\n });\n}\n\nexport function centerInColumn(text: string, colWidth: number): string {\n return text\n .split(\"\\n\")\n .map((line) => {\n const plain = line.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n const pad = Math.max(0, Math.floor((colWidth - plain.length) / 2));\n return \" \".repeat(pad) + line;\n })\n .join(\"\\n\");\n}\n\nexport interface SplitHomeOptions {\n title: string;\n left: string;\n rightTop: string;\n rightBottom: string;\n leftRatio?: number;\n}\n\n/** Claude Code-style two-column home with horizontal split on the right. */\nexport function splitHomePanel(opts: SplitHomeOptions): string {\n const total = contentWidth();\n const leftW = Math.max(28, Math.floor(total * (opts.leftRatio ?? 0.34)));\n const rightW = total - leftW - 3;\n\n const leftLines = opts.left.split(\"\\n\");\n const rightTop = opts.rightTop.split(\"\\n\");\n const rightDiv = dim(\"─\".repeat(Math.max(10, rightW)));\n const rightBottom = opts.rightBottom.split(\"\\n\");\n const rightLines = [...rightTop, \"\", rightDiv, \"\", ...rightBottom];\n\n const rows = Math.max(leftLines.length, rightLines.length);\n const sep = dim(\"│\");\n const body: string[] = [\"\"];\n\n for (let i = 0; i < rows; i++) {\n const l = padEndVisible(leftLines[i] ?? \"\", leftW);\n const r = rightLines[i] ?? \"\";\n body.push(`${l} ${sep} ${r}`);\n }\n body.push(\"\");\n\n return panel(body.join(\"\\n\"), { title: opts.title, marginBottom: 0, borderStyle: \"classic\" });\n}\n\nexport function columns(left: string, right: string, leftWidth?: number): string {\n const total = contentWidth();\n const split = leftWidth ?? Math.floor(total * 0.48);\n const leftLines = left.split(\"\\n\");\n const rightLines = right.split(\"\\n\");\n const rows = Math.max(leftLines.length, rightLines.length);\n const out: string[] = [];\n for (let i = 0; i < rows; i++) {\n const l = padEndVisible(leftLines[i] ?? \"\", split);\n const r = rightLines[i] ?? \"\";\n out.push(`${l} ${r}`);\n }\n return out.join(\"\\n\");\n}\n\nexport function divider(char = \"─\", width?: number): string {\n const w = width ?? contentWidth();\n return dim(char.repeat(Math.max(20, w)));\n}\n\nexport function statusBar(parts: string[]): string {\n return dim(parts.filter(Boolean).join(\" · \"));\n}\n\nexport function keyValue(rows: Array<[string, string]>, indent = 2): string {\n const pad = \" \".repeat(indent);\n const maxKey = Math.max(...rows.map(([k]) => k.length), 4);\n return rows.map(([k, v]) => `${pad}${muted(k.padEnd(maxKey))} ${v}`).join(\"\\n\");\n}\n\nexport function centerBlock(text: string, width = contentWidth()): string {\n return centerInColumn(text, width);\n}\n","export * from \"../terminal/theme.js\";\n","import { writeFile } from \"node:fs/promises\";\nimport { FuzziApiClient } from \"../lib/api-client.js\";\n\nexport async function runReportCommand(\n client: FuzziApiClient,\n scanId: string,\n format: \"pdf\" | \"csv\" | \"json\",\n outputPath?: string,\n): Promise<string> {\n const { data, contentType } = await client.download(`/scan/${scanId}/report?format=${format}`);\n\n const ext = format === \"pdf\" ? \"pdf\" : format === \"csv\" ? \"csv\" : \"json\";\n const path = outputPath || `fuzzi-report-${scanId.slice(0, 8)}.${ext}`;\n\n await writeFile(path, data);\n return `Report saved to ${path} (${contentType})`;\n}\n","import { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport type { OutputFormat } from \"../lib/output.js\";\nimport { riskColor, scoreBold } from \"../lib/theme.js\";\n\nexport async function runWhatIfCommand(\n scanId: string,\n overrides: Record<string, number>,\n format: OutputFormat = \"table\",\n): Promise<string> {\n const client = await getAuthenticatedClient();\n const data = await client.post<{\n original: { risk_level: string; overall_score: number };\n simulated: { risk_level: string; overall_score: number };\n summary: string;\n overall_score_delta: number;\n }>(\"/whatif\", { scan_id: scanId, overrides });\n\n if (format === \"json\") return JSON.stringify(data, null, 2);\n return [\n `Original: ${riskColor(data.original.risk_level)(data.original.risk_level)} (${scoreBold(data.original.overall_score)})`,\n `Simulated: ${riskColor(data.simulated.risk_level)(data.simulated.risk_level)} (${scoreBold(data.simulated.overall_score)})`,\n `Delta: ${data.overall_score_delta > 0 ? \"+\" : \"\"}${data.overall_score_delta}`,\n data.summary,\n ].join(\"\\n\");\n}\n","import { createTable } from \"../terminal/table.js\";\nimport { riskColor, scoreBold } from \"../terminal/theme.js\";\nimport { panel } from \"../terminal/layout.js\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport type { CompareResponse } from \"../types/api.js\";\nimport type { OutputFormat } from \"../lib/output.js\";\n\nexport async function runCompareCommand(\n scanA: string,\n scanB: string,\n format: OutputFormat = \"table\",\n): Promise<string> {\n const client = await getAuthenticatedClient();\n const data = await client.post<CompareResponse>(\"/compare\", {\n scan_a_id: scanA,\n scan_b_id: scanB,\n });\n\n if (format === \"json\") return JSON.stringify(data, null, 2);\n\n const summary = [\n `Scan A ${data.scan_a.target_url}`,\n ` ${riskColor(data.scan_a.risk_level || \"\")(data.scan_a.risk_level || \"—\")} ${scoreBold(data.scan_a.overall_score)}`,\n `Scan B ${data.scan_b.target_url}`,\n ` ${riskColor(data.scan_b.risk_level || \"\")(data.scan_b.risk_level || \"—\")} ${scoreBold(data.scan_b.overall_score)}`,\n `Delta ${data.score_delta > 0 ? \"+\" : \"\"}${data.score_delta}`,\n data.summary,\n ].join(\"\\n\");\n\n let body = panel(summary, { title: \"Compare\" });\n\n if (data.factor_changes?.length) {\n const rows = data.factor_changes.map((f) => [f.name.replace(/_/g, \" \"), String(f.delta)]);\n body += \"\\n\\n\" + createTable([\"Factor\", \"Delta\"], rows);\n }\n\n return body;\n}\n","import { Command } from \"commander\";\nimport { cwd } from \"node:process\";\nimport { VERSION } from \"../types/brand.js\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport { runAuthLogin, runAuthLogout } from \"../commands/auth.js\";\nimport { runScanCommand } from \"../commands/scan.js\";\nimport { runScansListCommand, runScanGetCommand } from \"../commands/scans.js\";\nimport { runStatusCommand } from \"../commands/status.js\";\nimport { runConfigGet, runConfigSet, runConfigList } from \"../commands/config.js\";\nimport { handleCommandError, exitWith } from \"./exit.js\";\nimport type { RiskLevel } from \"../lib/risk.js\";\nimport type { OutputFormat } from \"../lib/output.js\";\nimport { loadProjectConfig } from \"../lib/project-config.js\";\n\nexport function buildProgram(): Command {\n const program = new Command(\"fuzzi\")\n .name(\"fuzzi\")\n .description(\"Fuzzi security scanner CLI — interactive shell and scriptable commands\")\n .version(VERSION);\n\n const auth = program.command(\"auth\").description(\"Authentication\");\n\n auth\n .command(\"login\")\n .description(\"Sign in via browser (default) or API key\")\n .option(\"--browser\", \"Sign in via browser (default when interactive)\")\n .option(\"--api-key <key>\", \"Paste an API key (fz_live_...)\")\n .action(async (opts) => {\n try {\n const useApiKey = !!opts.apiKey;\n console.log(\n await runAuthLogin({\n apiKey: opts.apiKey,\n interactive: !opts.apiKey,\n browser: !useApiKey,\n apiKeyOnly: useApiKey,\n }),\n );\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n auth.command(\"logout\").description(\"Clear stored credentials\").action(async () => {\n console.log(await runAuthLogout());\n });\n\n auth.command(\"status\").description(\"Show auth status\").action(async () => {\n try {\n const client = await getAuthenticatedClient();\n console.log(await runStatusCommand(client));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n program\n .command(\"scan [url]\")\n .description(\"Scan a URL (waits for completion by default)\")\n .option(\"-t, --title <title>\", \"Scan title\")\n .option(\"-e, --env <env>\", \"production|staging|development\")\n .option(\"-w, --wait\", \"Poll until scan completes (default)\")\n .option(\"--no-wait\", \"Return immediately with scan ID\")\n .option(\"-f, --format <format>\", \"table|json|markdown\", \"table\")\n .option(\"--fail-on <level>\", \"Exit 1 if risk >= level (low|medium|high|critical)\")\n .option(\"--fail-threshold <n>\", \"Exit 1 if risk_score >= threshold (0.0-1.0)\", parseFloat)\n .action(async (urlArg, opts) => {\n try {\n const project = await loadProjectConfig(cwd());\n const url = urlArg || project?.scan?.url;\n if (!url) {\n console.error(\"Usage: fuzzi scan <url>\");\n exitWith(2);\n }\n const client = await getAuthenticatedClient();\n const result = await runScanCommand(client, {\n url,\n wait: opts.wait,\n noWait: opts.noWait,\n format: opts.format as OutputFormat,\n environment: opts.env,\n title: opts.title,\n failOn: opts.failOn as RiskLevel | undefined,\n failThreshold: opts.failThreshold,\n });\n console.log(result.output);\n exitWith(result.exitCode);\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n const scans = program.command(\"scans\").description(\"Browse scans\");\n\n scans\n .command(\"list\")\n .description(\"List recent scans\")\n .option(\"--status <status>\", \"pending|running|completed|failed\")\n .option(\"--risk-level <level>\", \"low|medium|high|critical\")\n .option(\"--limit <n>\", \"Max results\", \"20\")\n .option(\"-f, --format <format>\", \"table|json|markdown\", \"table\")\n .action(async (opts) => {\n try {\n const client = await getAuthenticatedClient();\n console.log(\n await runScansListCommand(client, opts.format as OutputFormat, {\n status: opts.status,\n riskLevel: opts.riskLevel,\n limit: parseInt(opts.limit, 10),\n }),\n );\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n scans\n .command(\"get <scan-id>\")\n .description(\"Get scan details\")\n .option(\"-f, --format <format>\", \"table|json|markdown\", \"table\")\n .action(async (scanId, opts) => {\n try {\n const client = await getAuthenticatedClient();\n console.log(await runScanGetCommand(client, scanId, opts.format as OutputFormat));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n program\n .command(\"report <scan-id>\")\n .description(\"Download a scan report\")\n .requiredOption(\"--format <format>\", \"pdf|csv|json\")\n .option(\"-o, --output <path>\", \"Output file path\")\n .action(async (scanId, opts) => {\n try {\n const { runReportCommand } = await import(\"../commands/report.js\");\n const client = await getAuthenticatedClient();\n console.log(await runReportCommand(client, scanId, opts.format, opts.output));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n program\n .command(\"whatif <scan-id>\")\n .description(\"Simulate factor overrides\")\n .option(\"--set <pair>\", \"dimension=value (repeatable)\", (v, prev: string[]) => [...prev, v], [])\n .option(\"-f, --format <format>\", \"table|json\", \"table\")\n .action(async (scanId, opts) => {\n try {\n const { runWhatIfCommand } = await import(\"../commands/whatif.js\");\n const overrides: Record<string, number> = {};\n for (const pair of opts.set as string[]) {\n const [k, val] = pair.split(\"=\");\n if (k && val) overrides[k] = parseFloat(val);\n }\n console.log(await runWhatIfCommand(scanId, overrides, opts.format as OutputFormat));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n program\n .command(\"compare <scan-a> <scan-b>\")\n .description(\"Compare two scans\")\n .option(\"-f, --format <format>\", \"table|json\", \"table\")\n .action(async (scanA, scanB, opts) => {\n try {\n const { runCompareCommand } = await import(\"../commands/compare.js\");\n console.log(await runCompareCommand(scanA, scanB, opts.format as OutputFormat));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n const config = program.command(\"config\").description(\"CLI configuration (~/.fuzzi/config)\");\n\n config.command(\"list\").action(async () => console.log(await runConfigList()));\n config.command(\"get [key]\").action(async (key) => console.log(await runConfigGet(key)));\n config\n .command(\"set <key> <value>\")\n .action(async (key, value) => console.log(await runConfigSet(key, value)));\n\n program.command(\"status\").description(\"Show account status\").action(async () => {\n try {\n const client = await getAuthenticatedClient();\n console.log(await runStatusCommand(client));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n return program;\n}\n","import { password, input, confirm } from \"@inquirer/prompts\";\nimport { saveCredentials, clearCredentials } from \"../lib/credentials.js\";\nimport { ApiError, FuzziApiClient, getAuthenticatedClient } from \"../lib/api-client.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { isValidApiKeyFormat, maskApiKey } from \"../lib/credentials.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { success, muted, accent } from \"../terminal/theme.js\";\nimport { openCliAuthPage } from \"../lib/browser-auth.js\";\nimport { SETTINGS_API_KEYS_URL } from \"../types/brand.js\";\n\nexport interface AuthLoginOptions {\n apiKey?: string;\n interactive?: boolean;\n browser?: boolean;\n apiKeyOnly?: boolean;\n}\n\nexport interface AssistedLoginResult {\n message: string;\n profile: UserProfile;\n}\n\n/**\n * Opens the web authorize page, then prompts to paste the API key shown there.\n * Matches the current fuzzi-ten.vercel.app flow (manual key handoff).\n */\nexport async function runAssistedBrowserLogin(): Promise<AssistedLoginResult> {\n await openCliAuthPage();\n console.log(\"\");\n console.log(accent(\" Browser opened — authorize Fuzzi CLI on the web page.\"));\n console.log(muted(\" Copy the API key shown, then paste it below.\"));\n console.log(\"\");\n const msg = await runApiKeyLogin({ interactive: true });\n const client = await getAuthenticatedClient();\n const profile = await client.get<UserProfile>(\"/me\");\n return { message: msg, profile };\n}\n\nexport async function runAuthLogin(opts: AuthLoginOptions = {}): Promise<string> {\n if (opts.apiKeyOnly || opts.apiKey) {\n return runApiKeyLogin(opts);\n }\n\n if (opts.browser || opts.interactive !== false) {\n const result = await runAssistedBrowserLogin();\n return result.message;\n }\n\n return runApiKeyLogin(opts);\n}\n\nexport async function runApiKeyLogin(opts: AuthLoginOptions = {}): Promise<string> {\n const config = await loadConfig();\n const client = new FuzziApiClient(config.api_url);\n\n let apiKey = opts.apiKey?.trim();\n\n if (!apiKey) {\n if (opts.interactive === false) {\n throw new ApiError(\n \"No API key provided. Run fuzzi auth login or sign in via browser.\",\n 401,\n \"missing_key\",\n undefined,\n 2,\n );\n }\n apiKey = await password({\n message: \"Paste your API key (fz_live_...):\",\n mask: \"•\",\n validate: (v) => {\n if (!v.trim()) return \"API key is required\";\n if (!isValidApiKeyFormat(v)) return \"Key must start with fz_live_\";\n return true;\n },\n });\n }\n\n apiKey = apiKey.trim();\n if (!isValidApiKeyFormat(apiKey)) {\n throw new ApiError(\n `Invalid API key format. Generate a new one at ${SETTINGS_API_KEYS_URL}`,\n 401,\n \"invalid_key_format\",\n undefined,\n 2,\n );\n }\n\n client.setToken(apiKey);\n const valid = await client.validateToken();\n if (!valid) {\n throw new ApiError(\n `Invalid API key. Generate a new one at ${SETTINGS_API_KEYS_URL}`,\n 401,\n \"invalid_token\",\n undefined,\n 2,\n );\n }\n\n const profile = await client.get<UserProfile>(\"/me\");\n await saveCredentials({\n api_key: apiKey,\n auth_method: \"api_key\",\n key_prefix: profile.key_prefix || maskApiKey(apiKey),\n key_expires_at: profile.key_expires_at || undefined,\n email: profile.email,\n full_name: profile.full_name || undefined,\n saved_at: new Date().toISOString(),\n });\n\n const name = profile.full_name || profile.email;\n return success(`Authenticated as ${name}`);\n}\n\nexport async function runAuthLogout(): Promise<string> {\n await clearCredentials();\n return muted(\"You are now logged out.\");\n}\n\nexport async function promptNewKeyName(): Promise<string> {\n return input({\n message: \"Key name:\",\n validate: (v) => (v.trim().length > 0 ? true : \"Name is required\"),\n });\n}\n\nexport async function confirmBrowserLogin(): Promise<boolean> {\n return confirm({\n message: \"Open browser to sign in?\",\n default: true,\n });\n}\n","import { randomBytes } from \"node:crypto\";\nimport { createServer } from \"node:http\";\nimport { exec } from \"node:child_process\";\nimport { loadConfig } from \"./config.js\";\nimport { saveCredentials, maskApiKey } from \"./credentials.js\";\nimport { FuzziApiClient, ApiError } from \"./api-client.js\";\nimport { APP_ORIGIN } from \"../types/brand.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { log } from \"./logger.js\";\n\nconst CALLBACK_TIMEOUT_MS = 90_000;\n\nexport interface BrowserLoginResult {\n message: string;\n profile: UserProfile;\n}\n\ninterface HandoffResponse {\n api_key: string;\n prefix?: string;\n expires_at?: string | null;\n}\n\nfunction generateState(): string {\n return randomBytes(24).toString(\"base64url\");\n}\n\nexport function openBrowser(url: string): void {\n const platform = process.platform;\n const cmd =\n platform === \"darwin\" ? `open ${JSON.stringify(url)}`\n : platform === \"win32\" ? `start \"\" ${JSON.stringify(url)}`\n : `xdg-open ${JSON.stringify(url)}`;\n exec(cmd, (err) => {\n if (err) log.warn(\"could not open browser automatically\", err.message);\n });\n}\n\nfunction apiOrigin(apiUrl: string): string {\n return apiUrl.replace(/\\/api\\/?$/, \"\") || APP_ORIGIN;\n}\n\n/** Open the web authorize page (no localhost callback required). */\nexport async function openCliAuthPage(): Promise<string> {\n const config = await loadConfig();\n const url = `${apiOrigin(config.api_url)}/cli-auth`;\n openBrowser(url);\n log.debug(\"opened cli auth page\", url);\n return url;\n}\n\nasync function saveProfileFromKey(apiKey: string, handoff?: HandoffResponse): Promise<BrowserLoginResult> {\n const config = await loadConfig();\n const client = new FuzziApiClient(config.api_url);\n client.setToken(apiKey);\n const profile = await client.get<UserProfile>(\"/me\");\n\n await saveCredentials({\n api_key: apiKey,\n auth_method: \"api_key\",\n key_prefix: handoff?.prefix || profile.key_prefix || maskApiKey(apiKey),\n key_expires_at: handoff?.expires_at || profile.key_expires_at || undefined,\n email: profile.email,\n full_name: profile.full_name || undefined,\n saved_at: new Date().toISOString(),\n });\n\n const name = profile.full_name || profile.email;\n return { message: `Signed in as ${name}`, profile };\n}\n\n/** Automatic callback flow (when web redirects to localhost). */\nexport async function runBrowserCallbackLogin(): Promise<BrowserLoginResult> {\n const config = await loadConfig();\n const state = generateState();\n\n const handoffToken = await new Promise<string>((resolve, reject) => {\n const server = createServer((req, res) => {\n try {\n const addr = server.address();\n const port = typeof addr === \"object\" && addr ? addr.port : 0;\n const url = new URL(req.url ?? \"/\", `http://127.0.0.1:${port}`);\n\n if (url.pathname !== \"/callback\") {\n res.writeHead(404);\n res.end();\n return;\n }\n\n const token = url.searchParams.get(\"token\");\n const returnedState = url.searchParams.get(\"state\");\n if (!token || returnedState !== state) {\n res.writeHead(400);\n res.end(\"Invalid callback\");\n reject(new ApiError(\"Invalid sign-in callback.\", 400, \"invalid_callback\", undefined, 2));\n return;\n }\n\n res.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(`<!DOCTYPE html><html><body style=\"font-family:system-ui;text-align:center;padding:48px\">\n <h1>Signed in to Fuzzi CLI</h1><p>Return to your terminal.</p>\n <script>setTimeout(()=>window.close(),1200)</script></body></html>`);\n clearTimeout(timer);\n server.close();\n resolve(token);\n } catch (e) {\n clearTimeout(timer);\n server.close();\n reject(e);\n }\n });\n\n const timer = setTimeout(() => {\n server.close();\n reject(new ApiError(\"callback_timeout\", 408, \"auth_timeout\", undefined, 2));\n }, CALLBACK_TIMEOUT_MS);\n\n server.listen(0, \"127.0.0.1\", () => {\n const addr = server.address();\n const port = typeof addr === \"object\" && addr ? addr.port : 0;\n const loginUrl = `${apiOrigin(config.api_url)}/cli-auth?state=${encodeURIComponent(state)}&callback_port=${port}`;\n openBrowser(loginUrl);\n log.debug(\"browser callback auth\", loginUrl);\n });\n\n server.on(\"error\", (e) => {\n clearTimeout(timer);\n reject(e);\n });\n });\n\n const client = new FuzziApiClient(config.api_url);\n const handoff = await client.post<HandoffResponse>(\"/cli/handoff\", {\n handoff_token: handoffToken,\n state,\n });\n\n if (!handoff.api_key) {\n throw new ApiError(\"Sign-in failed: no API key returned.\", 500, \"handoff_failed\", undefined, 2);\n }\n\n return saveProfileFromKey(handoff.api_key, handoff);\n}\n\n/** @deprecated alias */\nexport const runBrowserLogin = runBrowserCallbackLogin;\n","import { riskColor, accent, muted, bold, scoreBold, warn } from \"../terminal/theme.js\";\nimport { createTable } from \"../terminal/table.js\";\nimport { formatTimestamp, hostnameFromUrl, truncate } from \"../terminal/strings.js\";\nimport { panel, divider } from \"../terminal/layout.js\";\nimport type { ScanDetail, ScanSummary } from \"../types/api.js\";\n\nexport type OutputFormat = \"table\" | \"json\" | \"markdown\";\n\nexport function formatScanDate(scan: ScanDetail | ScanSummary): string {\n return formatTimestamp(\"created_at\" in scan ? scan.created_at : undefined);\n}\n\nexport function renderScanResult(scan: ScanDetail, format: OutputFormat): string {\n if (format === \"json\") return JSON.stringify(buildScanJson(scan), null, 2);\n if (format === \"markdown\") return renderScanMarkdown(scan);\n return renderScanTable(scan);\n}\n\nfunction buildScanJson(scan: ScanDetail) {\n const fr = scan.fuzzy_result;\n return {\n scan: {\n id: scan.id,\n target_url: scan.target_url,\n status: scan.status,\n risk_level: fr?.risk_level ?? null,\n risk_score: fr?.risk_score ?? null,\n overall_score: fr?.overall_score ?? null,\n },\n factors: scan.factors ?? [],\n recommendations: scan.recommendations ?? [],\n };\n}\n\nfunction levelIndicator(level: string): string {\n if (level === \"LOW\") return muted(\"ok\");\n return warn(\"!\");\n}\n\nexport function renderScanTable(scan: ScanDetail): string {\n const fr = scan.fuzzy_result;\n const rc = riskColor(fr?.risk_level);\n const lines: string[] = [];\n\n lines.push(panel([\n bold(scan.target_url),\n fr ? `${rc(\"Risk\")} ${rc(fr.risk_level)} ${muted(\"Score\")} ${scoreBold(fr.overall_score)}/100` : \"\",\n `${muted(\"Date\")} ${formatScanDate(scan)}`,\n scan.status === \"completed_inconclusive\" ? warn(\"Inconclusive — indicative only\") : \"\",\n ].filter(Boolean).join(\"\\n\"), { title: \"Scan result\" }));\n\n if (scan.factors?.length) {\n const rows = [...scan.factors]\n .sort((a, b) => a.score_100 - b.score_100)\n .map((f) => {\n const inc = f.details?.inconclusive;\n return [\n f.name.replace(/_/g, \" \"),\n inc ? muted(\"—\") : `${f.score_100}/100`,\n inc ? muted(\"n/a\") : `${riskColor(f.linguistic_value)(f.linguistic_value)} ${levelIndicator(f.linguistic_value)}`,\n ];\n });\n lines.push(\"\", createTable([\"Dimension\", \"Score\", \"Level\"], rows));\n }\n\n if (scan.recommendations?.length) {\n lines.push(\"\", accent(\"Findings\"));\n scan.recommendations.forEach((r, i) => {\n lines.push(` ${muted(String(i + 1).padStart(2))} ${riskColor(r.severity.toUpperCase())(`[${r.severity.toUpperCase()}]`)} ${r.title}`);\n });\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\nexport function renderScanMarkdown(scan: ScanDetail): string {\n const fr = scan.fuzzy_result;\n const host = hostnameFromUrl(scan.target_url);\n const lines: string[] = [`## Fuzzi Security Scan: ${host}`, \"\"];\n\n if (fr) lines.push(`**Risk Level:** ${fr.risk_level} (${fr.overall_score}/100)`, \"\");\n\n if (scan.factors?.length) {\n lines.push(\"| Dimension | Score | Level |\", \"|-----------|-------|-------|\");\n for (const f of scan.factors) {\n lines.push(`| ${f.name.replace(/_/g, \" \")} | ${f.score_100}/100 | ${f.linguistic_value} |`);\n }\n lines.push(\"\");\n }\n\n if (scan.recommendations?.length) {\n lines.push(\"### Findings\");\n scan.recommendations.forEach((r, i) => {\n lines.push(`${i + 1}. [${r.severity.toUpperCase()}] ${r.title}`);\n });\n }\n return lines.join(\"\\n\");\n}\n\nexport function renderScansList(scans: ScanSummary[], format: OutputFormat): string {\n if (format === \"json\") return JSON.stringify(scans, null, 2);\n if (format === \"markdown\") {\n if (!scans.length) return \"No scans found.\";\n const lines = [\"| URL | Status | Risk | Score | Date |\", \"|-----|--------|------|-------|------|\"];\n for (const s of scans) {\n lines.push(`| ${s.target_url} | ${s.status} | ${s.risk_level || \"—\"} | ${s.overall_score ?? \"—\"} | ${formatScanDate(s)} |`);\n }\n return lines.join(\"\\n\");\n }\n if (!scans.length) return muted(\"No scans found.\");\n\n const rows = scans.map((s) => [\n truncate(s.target_url, 40),\n s.status === \"completed_inconclusive\" ? warn(\"inconcl.\") : s.status,\n s.risk_level ? riskColor(s.risk_level)(s.risk_level) : muted(\"—\"),\n s.overall_score != null ? scoreBold(s.overall_score) : muted(\"—\"),\n muted(formatScanDate(s)),\n ]);\n return createTable([\"URL\", \"Status\", \"Risk\", \"Score\", \"Date\"], rows);\n}\n","import type { OutputFormat } from \"../lib/output.js\";\nimport { renderScanResult } from \"../lib/output.js\";\nimport { ApiError, FuzziApiClient } from \"../lib/api-client.js\";\nimport type { ScanCreateResponse, ScanDetail } from \"../types/api.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { success, muted } from \"../terminal/theme.js\";\nimport { validateUrl } from \"../lib/errors.js\";\nimport { riskMeetsThreshold, type RiskLevel } from \"../lib/risk.js\";\nimport { loadProjectConfig } from \"../lib/project-config.js\";\nimport { createProgress } from \"../terminal/progress.js\";\nimport { hostnameFromUrl } from \"../terminal/strings.js\";\nimport { withRetry } from \"../lib/retry.js\";\nimport { log } from \"../lib/logger.js\";\nimport { cwd } from \"node:process\";\n\nexport interface ScanCommandOptions {\n url: string;\n format?: OutputFormat;\n wait?: boolean;\n noWait?: boolean;\n environment?: string;\n title?: string;\n failOn?: RiskLevel;\n failThreshold?: number;\n onProgress?: (message: string) => void;\n streamProgress?: boolean;\n}\n\nexport interface ScanCommandResult {\n output: string;\n exitCode: 0 | 1 | 2;\n scan?: ScanDetail;\n}\n\nconst TERMINAL_STATUSES = new Set([\"completed\", \"completed_inconclusive\", \"failed\"]);\nconst POLL_INTERVAL_MS = 3000;\n\nexport async function pollScan(\n client: FuzziApiClient,\n scanId: string,\n onTick?: (elapsed: number, status: string) => void,\n maxWaitMs = 300_000,\n): Promise<ScanDetail> {\n const start = Date.now();\n let last = \"pending\";\n while (Date.now() - start < maxWaitMs) {\n const detail = await withRetry(() => client.get<ScanDetail>(`/scan/${scanId}`));\n last = detail.status;\n onTick?.(Math.floor((Date.now() - start) / 1000), last);\n if (TERMINAL_STATUSES.has(detail.status)) {\n if (detail.status === \"failed\") {\n throw new ApiError(\n `Scan failed: ${detail.inconclusive_message || detail.inconclusive_reason || \"unknown error\"}`,\n 500,\n \"scan_failed\",\n detail,\n 2,\n );\n }\n return detail;\n }\n await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));\n }\n throw new ApiError(`Scan timed out after ${maxWaitMs / 1000}s (last status: ${last})`, 408, \"scan_timeout\", undefined, 2);\n}\n\nfunction resolveFormat(format?: OutputFormat, projectFormat?: OutputFormat): OutputFormat {\n return format || projectFormat || \"table\";\n}\n\nfunction computeExitCode(scan: ScanDetail, opts: ScanCommandOptions): 0 | 1 | 2 {\n const fr = scan.fuzzy_result;\n if (!fr) return 0;\n if (opts.failThreshold != null && fr.risk_score >= opts.failThreshold) return 1;\n if (opts.failOn && riskMeetsThreshold(fr.risk_level, opts.failOn)) return 1;\n return 0;\n}\n\nexport async function runScanCommand(\n client: FuzziApiClient,\n opts: ScanCommandOptions,\n): Promise<ScanCommandResult> {\n const urlError = validateUrl(opts.url);\n if (urlError) throw new ApiError(urlError, 400, \"invalid_url\", undefined, 2);\n\n const projectConfig = await loadProjectConfig(cwd());\n const config = await loadConfig();\n const format = resolveFormat(opts.format, projectConfig?.output?.format || config.default_format);\n const env = opts.environment || projectConfig?.scan?.environment || config.default_env || \"production\";\n const failOn = opts.failOn || (projectConfig?.scan?.fail_on as RiskLevel | undefined);\n const shouldWait = opts.noWait ? false : opts.wait !== false;\n\n const body: Record<string, string> = { url: opts.url, environment: env };\n if (opts.title || projectConfig?.scan?.title) {\n body.title = opts.title || projectConfig?.scan?.title || \"\";\n }\n\n log.debug(\"creating scan\", { url: opts.url, env });\n const created = await withRetry(() => client.post<ScanCreateResponse>(\"/scan\", body));\n\n if (!shouldWait) {\n const output =\n format === \"json\"\n ? JSON.stringify(created, null, 2)\n : [success(\"Scan started\"), muted(`ID: ${created.scan_id}`), muted(created.message)].join(\"\\n\");\n return { output, exitCode: 0 };\n }\n\n const host = hostnameFromUrl(opts.url);\n const progress = opts.onProgress\n ? { update: opts.onProgress, stop: () => {}, succeed: () => {}, fail: () => {} }\n : createProgress(`Scanning ${host}...`, opts.streamProgress);\n\n const detail = await pollScan(client, created.scan_id, (sec, status) => {\n progress.update(`Scanning ${host}... (${sec}s) ${muted(status)}`);\n });\n\n progress.succeed(`Scan complete — ${host}`);\n\n const exitCode = computeExitCode(detail, { ...opts, failOn });\n return { output: renderScanResult(detail, format), exitCode, scan: detail };\n}\n","import { ApiError } from \"./api-client.js\";\nimport { APP_HOST } from \"../types/brand.js\";\n\nexport type ExitCode = 0 | 1 | 2;\n\nexport function formatApiError(err: unknown): string {\n if (err instanceof ApiError) {\n return err.message;\n }\n if (err instanceof Error) {\n if (err.message.includes(\"fetch failed\") || err.message.includes(\"ECONNREFUSED\")) {\n return `Could not connect to ${APP_HOST}. Check your internet connection or try again later.`;\n }\n return `An error occurred: ${err.message}. Please report this at https://github.com/fuzzi-cli/fuzzi-cli/issues`;\n }\n return `An error occurred: ${String(err)}. Please report this at https://github.com/fuzzi-cli/fuzzi-cli/issues`;\n}\n\nexport function getExitCode(err: unknown): ExitCode {\n if (err instanceof ApiError && err.exitCode !== undefined) {\n return err.exitCode as ExitCode;\n }\n return 2;\n}\n\nexport function validateUrl(url: string): string | null {\n try {\n const parsed = new URL(url);\n if (![\"http:\", \"https:\"].includes(parsed.protocol)) {\n return \"Invalid URL. Please provide a valid URL starting with http:// or https://\";\n }\n return null;\n } catch {\n return \"Invalid URL. Please provide a valid URL starting with http:// or https://\";\n }\n}\n","export type RiskLevel = \"LOW\" | \"MEDIUM\" | \"HIGH\" | \"CRITICAL\";\n\nconst RISK_ORDER: Record<RiskLevel, number> = {\n LOW: 0,\n MEDIUM: 1,\n HIGH: 2,\n CRITICAL: 3,\n};\n\nexport function normalizeRiskLevel(level: string | null | undefined): RiskLevel | null {\n if (!level) return null;\n const upper = level.toUpperCase() as RiskLevel;\n return upper in RISK_ORDER ? upper : null;\n}\n\nexport function riskMeetsThreshold(\n actual: string | null | undefined,\n threshold: RiskLevel,\n): boolean {\n const a = normalizeRiskLevel(actual);\n const t = normalizeRiskLevel(threshold);\n if (!a || !t) return false;\n return RISK_ORDER[a] >= RISK_ORDER[t];\n}\n\nexport function parseRiskLevel(value: string): RiskLevel | null {\n return normalizeRiskLevel(value);\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { existsSync } from \"node:fs\";\n\nexport interface ProjectConfig {\n scan?: {\n url?: string;\n environment?: \"production\" | \"staging\" | \"development\";\n fail_on?: string;\n title?: string;\n };\n output?: {\n format?: \"table\" | \"json\" | \"markdown\";\n };\n}\n\nfunction parseTomlSimple(raw: string): ProjectConfig {\n const config: ProjectConfig = { scan: {}, output: {} };\n let section = \"\";\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const sectionMatch = trimmed.match(/^\\[([^\\]]+)\\]$/);\n if (sectionMatch) {\n section = sectionMatch[1];\n continue;\n }\n const kv = trimmed.match(/^(\\w+)\\s*=\\s*\"?([^\"]+)\"?$/);\n if (!kv) continue;\n const [, key, value] = kv;\n if (section === \"scan\" || section === \"scan.scan\") {\n config.scan ??= {};\n if (key === \"url\") config.scan.url = value;\n else if (key === \"environment\") config.scan.environment = value as \"production\" | \"staging\" | \"development\";\n else if (key === \"fail_on\") config.scan.fail_on = value;\n else if (key === \"title\") config.scan.title = value;\n } else if (section === \"output\") {\n config.output ??= {};\n if (key === \"format\") config.output.format = value as \"table\" | \"json\" | \"markdown\";\n }\n }\n return config;\n}\n\nexport async function loadProjectConfig(cwd: string): Promise<ProjectConfig | null> {\n const fuzzirc = join(cwd, \".fuzzirc\");\n const fuzzitoml = join(cwd, \"fuzzi.toml\");\n\n if (existsSync(fuzzirc)) {\n try {\n const raw = await readFile(fuzzirc, \"utf8\");\n return JSON.parse(raw) as ProjectConfig;\n } catch {\n return null;\n }\n }\n\n if (existsSync(fuzzitoml)) {\n try {\n const raw = await readFile(fuzzitoml, \"utf8\");\n return parseTomlSimple(raw);\n } catch {\n return null;\n }\n }\n\n return null;\n}\n","import ora, { type Ora } from \"ora\";\nimport { muted } from \"./theme.js\";\nimport { getCapabilities } from \"./capabilities.js\";\n\nexport interface ProgressHandle {\n update(message: string): void;\n succeed(message?: string): void;\n fail(message?: string): void;\n stop(): void;\n}\n\nexport function createProgress(label: string, stream = false): ProgressHandle {\n if (!getCapabilities().interactive) {\n return {\n update: () => {},\n succeed: () => {},\n fail: () => {},\n stop: () => {},\n };\n }\n\n if (stream) {\n let last = \"\";\n return {\n update(message: string) {\n if (last) process.stdout.write(\"\\r\\x1b[K\");\n last = message;\n process.stdout.write(muted(message));\n },\n succeed(message?: string) {\n if (last) process.stdout.write(\"\\r\\x1b[K\");\n if (message) process.stdout.write(muted(message) + \"\\n\");\n last = \"\";\n },\n fail(message?: string) {\n if (last) process.stdout.write(\"\\r\\x1b[K\");\n if (message) process.stdout.write(muted(message) + \"\\n\");\n last = \"\";\n },\n stop() {\n if (last) process.stdout.write(\"\\r\\x1b[K\");\n last = \"\";\n },\n };\n }\n\n let spinner: Ora | null = ora({ text: label, color: \"cyan\", discardStdin: false }).start();\n return {\n update(message: string) {\n if (spinner) spinner.text = message;\n },\n succeed(message?: string) {\n if (spinner) {\n spinner.succeed(message);\n spinner = null;\n }\n },\n fail(message?: string) {\n if (spinner) {\n spinner.fail(message);\n spinner = null;\n }\n },\n stop() {\n if (spinner) {\n spinner.stop();\n spinner = null;\n }\n },\n };\n}\n\nexport async function withSteps<T>(\n steps: Array<{ title: string; run: () => Promise<T> }>,\n): Promise<T> {\n let last: T | undefined;\n for (const step of steps) {\n const p = createProgress(step.title);\n try {\n last = await step.run();\n p.succeed(step.title);\n } catch (e) {\n p.fail(step.title);\n throw e;\n }\n }\n return last as T;\n}\n","import { log } from \"./logger.js\";\n\nexport interface RetryOptions {\n maxAttempts?: number;\n baseDelayMs?: number;\n retryOn?: (error: unknown) => boolean;\n}\n\nexport async function withRetry<T>(fn: () => Promise<T>, opts: RetryOptions = {}): Promise<T> {\n const max = opts.maxAttempts ?? 3;\n const base = opts.baseDelayMs ?? 500;\n const retryOn = opts.retryOn ?? ((e: unknown) => {\n const err = e as { status?: number };\n return err.status === 429 || err.status === 502 || err.status === 503;\n });\n\n let last: unknown;\n for (let attempt = 1; attempt <= max; attempt++) {\n try {\n return await fn();\n } catch (e) {\n last = e;\n if (attempt >= max || !retryOn(e)) throw e;\n const delay = base * Math.pow(2, attempt - 1);\n log.debug(`retry ${attempt}/${max} in ${delay}ms`);\n await new Promise((r) => setTimeout(r, delay));\n }\n }\n throw last;\n}\n","import type { OutputFormat } from \"../lib/output.js\";\nimport { renderScansList } from \"../lib/output.js\";\nimport { FuzziApiClient } from \"../lib/api-client.js\";\nimport type { ScanDetail } from \"../types/api.js\";\nimport { renderScanResult } from \"../lib/output.js\";\n\nexport interface ScansListFilters {\n status?: string;\n riskLevel?: string;\n limit?: number;\n}\n\nexport async function runScansListCommand(\n client: FuzziApiClient,\n format: OutputFormat = \"table\",\n filters?: ScansListFilters,\n): Promise<string> {\n const params = new URLSearchParams({ page: \"1\", page_size: String(filters?.limit || 20) });\n if (filters?.status) params.set(\"status\", filters.status);\n if (filters?.riskLevel) params.set(\"risk_level\", filters.riskLevel);\n\n const data = await client.get<{ results: import(\"../types/api.js\").ScanSummary[] }>(\n `/scans?${params.toString()}`,\n );\n return renderScansList(data.results || [], format);\n}\n\nexport async function runScanGetCommand(\n client: FuzziApiClient,\n scanId: string,\n format: OutputFormat = \"table\",\n): Promise<string> {\n const detail = await client.get<ScanDetail>(`/scan/${scanId}`);\n return renderScanResult(detail, format);\n}\n","import { FuzziApiClient } from \"../lib/api-client.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { loadCredentials, maskApiKey } from \"../lib/credentials.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { panel, keyValue, divider } from \"../terminal/layout.js\";\nimport { muted } from \"../terminal/theme.js\";\n\nfunction daysUntil(dateStr: string): number {\n const diff = new Date(dateStr).getTime() - Date.now();\n return Math.max(0, Math.ceil(diff / (1000 * 60 * 60 * 24)));\n}\n\nexport async function runRateLimitStatus(client: FuzziApiClient): Promise<string | null> {\n try {\n const data = await client.get<{ limit?: number; remaining?: number; reset?: string }>(\"/rate-limit\");\n if (data.limit != null) {\n return `${data.remaining ?? \"?\"}/${data.limit} remaining`;\n }\n } catch {\n /* optional endpoint */\n }\n return null;\n}\n\nexport async function runStatusCommand(client: FuzziApiClient): Promise<string> {\n const creds = await loadCredentials();\n const profile = await client.get<UserProfile>(\"/me\");\n const keyExpiry = creds?.key_expires_at || profile.key_expires_at;\n const config = await loadConfig();\n const rate = await runRateLimitStatus(client);\n\n const rows: Array<[string, string]> = [\n [\"Name\", profile.full_name || profile.email.split(\"@\")[0]],\n [\"Email\", profile.email],\n [\"Organization\", profile.organization || muted(\"—\")],\n [\"Role\", profile.role],\n [\"Auth\", `API Key (${creds ? maskApiKey(creds.api_key) : \"—\"})`],\n ];\n\n if (keyExpiry) {\n const days = daysUntil(keyExpiry);\n rows.push([\"Key expires\", `${keyExpiry.slice(0, 10)} (${days}d remaining)`]);\n } else {\n rows.push([\"Key expires\", muted(\"No expiry\")]);\n }\n\n rows.push([\"API\", config.api_url]);\n if (rate) rows.push([\"Rate limit\", rate]);\n\n return [panel(keyValue(rows), { title: \"Account\" }), \"\", divider(), muted(\"Use /keys to manage API keys\")].join(\"\\n\");\n}\n\nexport { formatApiError } from \"../lib/errors.js\";\n","import { loadConfig, setConfigValue, getConfigValue, listConfigEntries } from \"../lib/config.js\";\nimport { accent, muted } from \"../lib/theme.js\";\n\nexport async function runConfigList(): Promise<string> {\n const entries = await listConfigEntries();\n const lines = Object.entries(entries).map(([k, v]) => ` ${k} = ${v}`);\n return lines.length ? [accent(\"Config (~/.fuzzi/config)\"), ...lines].join(\"\\n\") : muted(\"No config set.\");\n}\n\nexport async function runConfigGet(key?: string): Promise<string> {\n if (!key) return runConfigList();\n const value = await getConfigValue(key);\n if (value === undefined) return muted(`Config key not set: ${key}`);\n return value;\n}\n\nexport async function runConfigSet(key: string, value: string): Promise<string> {\n const allowed = [\"api_url\", \"default_env\", \"default_format\"];\n if (!allowed.includes(key)) {\n return muted(`Unknown config key: ${key}. Supported: ${allowed.join(\", \")}`);\n }\n await setConfigValue(key, value);\n return accent(\"Config updated.\");\n}\n\nexport async function runConfigShowApiUrl(): Promise<string> {\n const config = await loadConfig();\n return config.api_url;\n}\n","import { formatApiError, getExitCode } from \"../lib/errors.js\";\n\nexport function handleCommandError(e: unknown): never {\n console.error(formatApiError(e));\n process.exit(getExitCode(e));\n}\n\nexport function exitWith(code: 0 | 1 | 2): never {\n process.exit(code);\n}\n","import * as readline from \"node:readline/promises\";\nimport { stdin as input, stdout as output, cwd } from \"node:process\";\nimport { fetchHomeData, renderHomeScreen } from \"./home-screen.js\";\nimport { dispatchSlashCommand, normalizeInput } from \"./slash-commands.js\";\nimport { accent, muted } from \"../terminal/theme.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { appendHistory, loadHistory } from \"./session.js\";\nimport { buildCompleter } from \"./completer.js\";\nimport { SLASH_COMMANDS } from \"./registry.js\";\nimport { getCapabilities } from \"../terminal/capabilities.js\";\n\nexport async function runPromptLoop(initialProfile: UserProfile | null): Promise<void> {\n let profile = initialProfile;\n const workDir = cwd();\n const history = await loadHistory();\n\n const refresh = async () => {\n if (getCapabilities().interactive) {\n process.stdout.write(\"\\x1b[2J\\x1b[H\");\n }\n const data = await fetchHomeData(profile);\n console.log(renderHomeScreen(data));\n console.log(\"\");\n };\n\n await refresh();\n\n const rl = readline.createInterface({\n input,\n output,\n terminal: true,\n completer: buildCompleter(SLASH_COMMANDS, history),\n historySize: 300,\n });\n\n rl.on(\"SIGINT\", () => {\n console.log(muted(\"\\nGoodbye!\"));\n rl.close();\n process.exit(0);\n });\n\n const prompt = () => process.stdout.write(accent(\"> \"));\n\n prompt();\n\n for await (const line of rl) {\n await appendHistory(line);\n history.push(line.trim());\n\n const sink = {\n write: (text: string) => console.log(text),\n error: (text: string) => console.error(text),\n clearLine: () => process.stdout.write(\"\\r\\x1b[K\"),\n };\n\n const normalized = normalizeInput(line);\n const result = await dispatchSlashCommand(normalized, {\n cwd: workDir,\n profile,\n sink,\n refresh,\n });\n\n if (result.profile) profile = result.profile;\n if (result.exit) {\n console.log(muted(\"Goodbye!\"));\n rl.close();\n break;\n }\n if (result.redraw) await refresh();\n\n prompt();\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { existsSync } from \"node:fs\";\n\n/** Resolve assets dir for both dev (src/) and production (dist/) layouts. */\nexport function assetsDir(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n join(here, \"..\", \"assets\"), // dist/lib → dist/../assets = package/assets\n join(here, \"..\", \"..\", \"assets\"), // src/lib → package/assets\n join(here, \"assets\"), // bundled flat fallback\n ];\n for (const p of candidates) {\n if (existsSync(join(p, \"changelog.json\"))) return p;\n }\n return candidates[0];\n}\n\nexport async function readAsset(name: string): Promise<string> {\n return readFile(join(assetsDir(), name), \"utf8\");\n}\n","import { readAsset } from \"../lib/assets.js\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport { runRateLimitStatus } from \"../commands/status.js\";\nimport { renderFuzziMark } from \"./ascii-mark.js\";\nimport { VERSION, SETTINGS_API_KEYS_URL } from \"../types/brand.js\";\nimport {\n accent,\n accentBold,\n cmd,\n muted,\n primary,\n primaryBold,\n success,\n} from \"../terminal/theme.js\";\nimport { contentWidth, terminalWidth } from \"../terminal/width.js\";\nimport {\n topBanner,\n tripleColumnPanel,\n stackedPanels,\n tipPanel,\n besideMark,\n popularCommand,\n type ColumnSpec,\n} from \"../components/Panel.js\";\nimport type { ChangelogEntry, UserProfile } from \"../types/api.js\";\n\nexport interface HomeScreenStats {\n rateHour: string | null;\n usageMonth: string | null;\n}\n\nexport interface HomeScreenData {\n profile: UserProfile | null;\n changelog: ChangelogEntry[];\n stats: HomeScreenStats | null;\n}\n\nfunction daysUntil(dateStr: string): number {\n const diff = new Date(dateStr).getTime() - Date.now();\n return Math.max(0, Math.ceil(diff / (1000 * 60 * 60 * 24)));\n}\n\nfunction formatKeyExpiry(dateStr: string | null | undefined): string | null {\n if (!dateStr) return null;\n const days = daysUntil(dateStr);\n return `Key expires: ${days} days remaining`;\n}\n\nfunction formatKeyExpiryDate(dateStr: string | null | undefined): string | null {\n if (!dateStr) return null;\n return `(${dateStr.slice(0, 10)})`;\n}\n\nexport async function fetchHomeData(profile: UserProfile | null): Promise<HomeScreenData> {\n let changelog: ChangelogEntry[] = [];\n try {\n changelog = JSON.parse(await readAsset(\"changelog.json\")) as ChangelogEntry[];\n } catch {\n changelog = [];\n }\n\n let stats: HomeScreenStats | null = null;\n if (profile) {\n try {\n const client = await getAuthenticatedClient();\n const rateRaw = await runRateLimitStatus(client);\n let rateHour: string | null = null;\n if (rateRaw) {\n const m = rateRaw.match(/(\\d+)\\/(\\d+)/);\n if (m) {\n const remaining = Number(m[1]);\n const limit = Number(m[2]);\n const used = limit - remaining;\n rateHour = `${used}/${limit} scans this hour`;\n } else {\n rateHour = rateRaw;\n }\n }\n\n const used = profile.scans_used_this_month ?? profile.total_scans;\n const limit = profile.monthly_scan_limit;\n const usageMonth =\n used != null && limit != null\n ? `${used}/${limit} scans this month`\n : used != null\n ? `${used} scans total`\n : null;\n\n stats = { rateHour, usageMonth };\n } catch {\n stats = null;\n }\n }\n\n return { profile, changelog, stats };\n}\n\nfunction renderAccountColumn(data: HomeScreenData): string[] {\n const mark = accent(renderFuzziMark()).split(\"\\n\");\n\n if (data.profile) {\n const p = data.profile;\n const name = p.full_name || p.email.split(\"@\")[0];\n const keyExpiry = formatKeyExpiry(p.key_expires_at ?? undefined);\n const keyDate = formatKeyExpiryDate(p.key_expires_at ?? undefined);\n\n const textBlock: string[] = [\n primaryBold(`Welcome back, ${name}!`),\n primary(p.email),\n \"\",\n muted(`Organization: ${p.organization || \"—\"}`),\n muted(`Role: ${p.role}`),\n ];\n\n const beside = besideMark(mark, textBlock, 14, 4);\n const lines = [\"\", ...beside, \"\"];\n\n lines.push(success(\"● Connected\"));\n lines.push(muted(\"Status: Ready\"));\n\n if (data.stats?.rateHour) lines.push(muted(`Rate limit: ${data.stats.rateHour}`));\n if (data.stats?.usageMonth) lines.push(muted(`Usage: ${data.stats.usageMonth}`));\n\n if (keyExpiry) {\n lines.push(\"\");\n lines.push(muted(keyExpiry));\n if (keyDate) lines.push(muted(keyDate));\n }\n\n return lines;\n }\n\n const textBlock = [\n primaryBold(\"Welcome to Fuzzi!\"),\n muted(\"Not connected\"),\n \"\",\n muted(\"Press Enter to sign in\"),\n muted(\"or run /auth-key\"),\n ];\n\n return [\"\", ...besideMark(mark, textBlock, 14, 4), \"\"];\n}\n\nfunction renderQuickStartColumn(data: HomeScreenData): string[] {\n const lines = [\n \"\",\n muted(\"Type \") + cmd(\"/help\") + muted(\" for all\"),\n muted(\"commands.\"),\n \"\",\n primaryBold(\"Popular commands:\"),\n \"\",\n popularCommand(\"/scan\", \"Start a security scan\", 12),\n popularCommand(\"/scans\", \"Browse recent scans\", 12),\n popularCommand(\"/status\", \"Show account info\", 12),\n ];\n\n if (data.profile) {\n lines.push(\n popularCommand(\"/keys\", \"Manage API keys\", 12),\n popularCommand(\"/config\", \"CLI settings\", 12),\n );\n } else {\n lines.push(\n popularCommand(\"/auth\", \"Browser sign-in\", 12),\n popularCommand(\"/auth-key\", \"Paste API key\", 12),\n );\n }\n\n return lines;\n}\n\nfunction renderWhatsNewColumn(data: HomeScreenData): string[] {\n const lines = [\"\"];\n const highlights = data.changelog[0]?.highlights ?? [\n \"Confidence gating added\",\n \"Netflix-style false positives fixed\",\n \"CLI shell interface\",\n ];\n\n for (const h of highlights.slice(0, 4)) {\n const text = h.replace(/^✓\\s*/, \"\");\n lines.push(success(\"✓ \") + primary(text));\n }\n\n lines.push(\"\");\n lines.push(muted(\"Run \") + cmd(\"/changelog\") + muted(\" for more details.\"));\n\n return lines;\n}\n\nfunction renderTip(data: HomeScreenData): string {\n if (data.profile) {\n return muted(\"Tip: Run \") + cmd(\"/scan <url>\") + muted(\" to scan a target, or \") + cmd(\"/palette\") + muted(\" to find commands.\");\n }\n return (\n muted(\"Not logged in? Run \") +\n cmd(\"/auth-key\") +\n muted(\" to paste an API key from settings, or press Enter to sign in via browser.\")\n );\n}\n\nexport function renderHomeScreen(data: HomeScreenData): string {\n const width = contentWidth();\n const cols: [ColumnSpec, ColumnSpec, ColumnSpec] = [\n { title: \"Account\", lines: renderAccountColumn(data) },\n { title: \"Quick Start\", lines: renderQuickStartColumn(data) },\n { title: \"What's New\", lines: renderWhatsNewColumn(data) },\n ];\n\n const main =\n terminalWidth() >= 100\n ? tripleColumnPanel(cols, width)\n : stackedPanels(cols, width);\n\n return [topBanner(`Fuzzi CLI v${VERSION}`, width), \"\", main, \"\", tipPanel(renderTip(data), width)].join(\n \"\\n\",\n );\n}\n\nexport function renderChangelog(entries: ChangelogEntry[]): string {\n if (!entries.length) return muted(\"No changelog entries.\");\n return entries\n .map((e) => {\n const lines = [\n accentBold(`v${e.version}`) + muted(` — ${e.date}`),\n ...e.highlights.map((h) => success(\"✓ \") + primary(h.replace(/^✓\\s*/, \"\"))),\n ];\n return lines.join(\"\\n\");\n })\n .join(\"\\n\\n\");\n}\n\n/** Auth gate uses the same shell layout before login completes. */\nexport function renderAuthGateScreen(): string {\n return renderHomeScreen({\n profile: null,\n changelog: [],\n stats: null,\n });\n}\n\nexport { SETTINGS_API_KEYS_URL };\n","/** Teal diamond shield mascot — 8 lines, pair with accent(). */\nexport function renderFuzziMark(): string {\n return [\n \" ╔════╗\",\n \" ║ ◆ ║\",\n \" ╚═╦══╝\",\n \" ╔═╩═╗\",\n \" ║ ◆ ║\",\n \" ╚═══╝\",\n ].join(\"\\n\");\n}\n","import { border, cmd, muted } from \"../terminal/theme.js\";\nimport { padEndVisible } from \"../terminal/strings.js\";\nimport { contentWidth } from \"../terminal/width.js\";\n\nexport function visibleLen(s: string): number {\n return s.replace(/\\x1b\\[[0-9;]*m/g, \"\").length;\n}\n\n/** Heavy double-line top banner: ┏━━ Fuzzi CLI v0.1.3 ━━┓ */\nexport function topBanner(title: string, width = contentWidth()): string {\n const inner = ` ${title} `;\n const dashes = Math.max(0, width - 2 - visibleLen(inner));\n const left = Math.floor(dashes / 2);\n const right = dashes - left;\n return [\n border(`┏${\"━\".repeat(left)}${inner}${\"━\".repeat(right)}┓`),\n border(`┗${\"━\".repeat(width - 2)}┛`),\n ].join(\"\\n\");\n}\n\nexport interface ColumnSpec {\n title: string;\n lines: string[];\n}\n\nfunction titleSegment(title: string, width: number): string {\n const prefix = `─ ${title} `;\n const dashes = Math.max(0, width - visibleLen(prefix));\n return prefix + \"─\".repeat(dashes);\n}\n\n/** Three-column panel with shared top/bottom borders. */\nexport function tripleColumnPanel(\n cols: [ColumnSpec, ColumnSpec, ColumnSpec],\n totalWidth = contentWidth(),\n): string {\n const sep = 1;\n const inner = totalWidth - 2;\n const ratios = [0.44, 0.28, 0.28];\n const raw = ratios.map((r) => Math.floor(inner * r));\n const used = raw.reduce((a, b) => a + b, 0) + 2 * sep;\n raw[0] += inner - used;\n\n const widths = raw;\n const top =\n border(\"┌\") +\n titleSegment(cols[0].title, widths[0]) +\n border(\"┬\") +\n titleSegment(cols[1].title, widths[1]) +\n border(\"┬\") +\n titleSegment(cols[2].title, widths[2]) +\n border(\"┐\");\n\n const maxRows = Math.max(...cols.map((c) => c.lines.length), 1);\n const body: string[] = [top];\n\n for (let i = 0; i < maxRows; i++) {\n const cells = cols.map((c, idx) => padEndVisible(c.lines[i] ?? \"\", widths[idx]));\n body.push(\n border(\"│\") +\n cells[0] +\n border(\"│\") +\n cells[1] +\n border(\"│\") +\n cells[2] +\n border(\"│\"),\n );\n }\n\n const bottom =\n border(\"└\") +\n border(\"─\".repeat(widths[0])) +\n border(\"┴\") +\n border(\"─\".repeat(widths[1])) +\n border(\"┴\") +\n border(\"─\".repeat(widths[2])) +\n border(\"┘\");\n\n body.push(bottom);\n return body.join(\"\\n\");\n}\n\n/** Stacked single-column panels for narrow terminals. */\nexport function stackedPanels(cols: ColumnSpec[], width = contentWidth()): string {\n return cols\n .map((col) => singlePanel(col.title, col.lines, width))\n .join(\"\\n\\n\");\n}\n\nexport function singlePanel(title: string, lines: string[], width = contentWidth()): string {\n const inner = width - 2;\n const prefix = `─ ${title} `;\n const dashes = Math.max(0, inner - visibleLen(prefix));\n const top = border(`┌${prefix}${\"─\".repeat(dashes)}┐`);\n const bottom = border(`└${\"─\".repeat(inner)}┘`);\n const body = lines.map((l) => border(\"│\") + padEndVisible(l, inner) + border(\"│\"));\n return [top, ...body, bottom].join(\"\\n\");\n}\n\nexport function tipPanel(text: string, width = contentWidth()): string {\n const inner = width - 2;\n const prefix = \"─ Tip \";\n const dashes = Math.max(0, inner - visibleLen(prefix));\n const top = border(`┌${prefix}${\"─\".repeat(dashes)}┐`);\n const bottom = border(`└${\"─\".repeat(inner)}┘`);\n return [top, border(\"│\") + padEndVisible(text, inner) + border(\"│\"), bottom].join(\"\\n\");\n}\n\n/** Place mark art beside text lines (Account column layout). */\nexport function besideMark(mark: string[], text: string[], markCol = 14, gap = 2): string[] {\n const rows = Math.max(mark.length, text.length);\n const out: string[] = [];\n for (let i = 0; i < rows; i++) {\n const m = padEndVisible(mark[i] ?? \"\", markCol);\n const t = text[i] ?? \"\";\n out.push(m + \" \".repeat(gap) + t);\n }\n return out;\n}\n\nexport function popularCommand(command: string, desc: string, cmdWidth = 14): string {\n return padEndVisible(cmd(command), cmdWidth) + muted(desc);\n}\n","import { confirm, input } from \"@inquirer/prompts\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport { runScanCommand } from \"../commands/scan.js\";\nimport { runScansListCommand } from \"../commands/scans.js\";\nimport { runStatusCommand, runRateLimitStatus } from \"../commands/status.js\";\nimport { runAssistedBrowserLogin, runApiKeyLogin, promptNewKeyName } from \"../commands/auth.js\";\nimport { runKeysListCommand, runKeyRevoke, pickKeyForRevoke } from \"../commands/keys.js\";\nimport { runConfigSet } from \"../commands/config.js\";\nimport { formatApiError } from \"../lib/errors.js\";\nimport { readAsset } from \"../lib/assets.js\";\nimport { renderChangelog } from \"./home-screen.js\";\nimport { renderHelpScreen, renderHistoryScreen } from \"./help-screen.js\";\nimport { openCommandPalette, pickFromList } from \"./command-palette.js\";\nimport { findCommand } from \"./registry.js\";\nimport { loadHistory } from \"./session.js\";\nimport { accent, muted, success, error as errStyle } from \"../terminal/theme.js\";\nimport { emptyState } from \"../terminal/empty-state.js\";\nimport { errorBox, successBox } from \"../terminal/banner.js\";\nimport { truncate, formatTimestamp } from \"../terminal/strings.js\";\nimport type { UserProfile, ScanSummary, ScanDetail } from \"../types/api.js\";\nimport type { OutputSink } from \"../terminal/sink.js\";\nimport { renderScanResult } from \"../lib/output.js\";\n\nexport interface SlashContext {\n cwd: string;\n profile: UserProfile | null;\n sink: OutputSink;\n refresh: () => Promise<void>;\n}\n\nexport interface SlashResult {\n exit?: boolean;\n redraw?: boolean;\n profile?: UserProfile | null;\n}\n\n/** Map bare CLI-style input to slash commands. */\nexport function normalizeInput(line: string): string {\n let t = line.trim();\n if (!t || t.startsWith(\"/\")) return t;\n\n if (t.toLowerCase().startsWith(\"fuzzi \")) t = t.slice(6).trim();\n\n const lower = t.toLowerCase();\n const aliases: Record<string, string> = {\n \"auth login\": \"/auth\",\n auth: \"/auth\",\n login: \"/auth\",\n \"auth-key\": \"/auth-key\",\n logout: \"/exit\",\n help: \"/help\",\n exit: \"/exit\",\n quit: \"/exit\",\n clear: \"/clear\",\n changelog: \"/changelog\",\n status: \"/status\",\n scans: \"/scans\",\n keys: \"/keys\",\n palette: \"/palette\",\n };\n if (aliases[lower]) return aliases[lower];\n\n if (lower.startsWith(\"scan \")) return `/scan ${t.slice(5).trim()}`;\n if (lower.startsWith(\"config set \")) {\n const parts = t.slice(11).trim().split(/\\s+/);\n if (parts.length >= 2) return `/config ${parts[0]}=${parts.slice(1).join(\" \")}`;\n }\n if (lower.startsWith(\"config \")) return `/config ${t.slice(7).trim().replace(/\\s+/, \"=\")}`;\n\n // Bare hostname → scan\n if (!t.includes(\" \") && t.includes(\".\")) return `/scan ${t}`;\n\n return t;\n}\n\nfunction normalizeScanUrl(url: string): string {\n const u = url.trim();\n if (!/^https?:\\/\\//i.test(u)) return `https://${u}`;\n return u;\n}\n\nexport async function dispatchSlashCommand(line: string, ctx: SlashContext): Promise<SlashResult> {\n const trimmed = line.trim();\n if (!trimmed) return {};\n if (trimmed === \"/exit\" || trimmed === \"/quit\") return { exit: true };\n\n const [cmd, ...rest] = trimmed.split(/\\s+/);\n const arg = rest.join(\" \").trim();\n\n if (!cmd.startsWith(\"/\")) {\n ctx.sink.write(\n errorBox(\n `Not a shell command: ${trimmed}`,\n `Use slash commands here — e.g. ${accent(\"/auth\")} not \"fuzzi auth login\"\\n${accent(\"/help\")} lists everything`,\n ),\n );\n return {};\n }\n\n if (!findCommand(cmd) && cmd.startsWith(\"/\")) {\n ctx.sink.write(errorBox(`Unknown command: ${cmd}`, \"Type /help or /palette\"));\n return {};\n }\n\n try {\n switch (cmd.toLowerCase()) {\n case \"/help\":\n ctx.sink.write(renderHelpScreen());\n break;\n\n case \"/palette\":\n case \"/commands\": {\n const picked = await openCommandPalette();\n if (picked) return dispatchSlashCommand(picked, ctx);\n break;\n }\n\n case \"/clear\":\n return { redraw: true };\n\n case \"/history\": {\n const hist = await loadHistory();\n ctx.sink.write(renderHistoryScreen(hist));\n break;\n }\n\n case \"/scan\": {\n if (!arg) {\n ctx.sink.write(errStyle(\"Usage: /scan <url>\"));\n break;\n }\n const client = await getAuthenticatedClient();\n const progress = createStreamProgress(ctx.sink);\n const result = await runScanCommand(client, {\n url: normalizeScanUrl(arg),\n wait: true,\n onProgress: progress.update,\n streamProgress: true,\n });\n progress.stop();\n ctx.sink.write(result.output);\n break;\n }\n\n case \"/status\": {\n const client = await getAuthenticatedClient();\n const status = await runStatusCommand(client);\n const rate = await runRateLimitStatus(client);\n ctx.sink.write(rate ? `${status}\\n\\n${muted(\"Rate limit\")} ${rate}` : status);\n break;\n }\n\n case \"/scans\":\n await runScansInteractive(ctx);\n break;\n\n case \"/keys\":\n await runKeysInteractive(ctx);\n break;\n\n case \"/config\": {\n if (!arg.includes(\"=\")) {\n ctx.sink.write(errStyle(\"Usage: /config key=value\"));\n break;\n }\n const [k, ...vParts] = arg.split(\"=\");\n ctx.sink.write(await runConfigSet(k.trim(), vParts.join(\"=\").trim()));\n break;\n }\n\n case \"/changelog\": {\n const raw = await readAsset(\"changelog.json\");\n ctx.sink.write(renderChangelog(JSON.parse(raw)));\n break;\n }\n\n case \"/compare\": {\n const [a, b] = arg.split(/\\s+/);\n if (!a || !b) {\n ctx.sink.write(errStyle(\"Usage: /compare <scan-a> <scan-b>\"));\n break;\n }\n const { runCompareCommand } = await import(\"../commands/compare.js\");\n ctx.sink.write(await runCompareCommand(a, b, \"table\"));\n break;\n }\n\n case \"/whatif\": {\n if (!arg) {\n ctx.sink.write(errStyle(\"Usage: /whatif <scan-id>\"));\n break;\n }\n const { runWhatIfCommand } = await import(\"../commands/whatif.js\");\n ctx.sink.write(await runWhatIfCommand(arg, {}, \"table\"));\n break;\n }\n\n case \"/report\": {\n if (!arg) {\n ctx.sink.write(errStyle(\"Usage: /report <scan-id>\"));\n break;\n }\n const { runReportCommand } = await import(\"../commands/report.js\");\n const client = await getAuthenticatedClient();\n ctx.sink.write(await runReportCommand(client, arg, \"json\"));\n break;\n }\n\n case \"/login\":\n case \"/auth\": {\n const result = await runAssistedBrowserLogin();\n ctx.sink.write(result.message);\n return { profile: result.profile, redraw: true };\n }\n\n case \"/auth-key\": {\n ctx.sink.write(await runApiKeyLogin({ interactive: true }));\n const client = await getAuthenticatedClient();\n return { profile: await client.get<UserProfile>(\"/me\"), redraw: true };\n }\n\n default:\n ctx.sink.write(errorBox(`Unknown command: ${cmd}`, \"Type /help\"));\n }\n } catch (e) {\n ctx.sink.error(formatApiError(e));\n }\n return {};\n}\n\nfunction createStreamProgress(sink: OutputSink) {\n let last = \"\";\n return {\n update(msg: string) {\n if (last) sink.clearLine?.();\n last = msg;\n process.stdout.write(muted(msg));\n },\n stop() {\n if (last) sink.clearLine?.();\n last = \"\";\n },\n };\n}\n\nasync function runScansInteractive(ctx: SlashContext): Promise<void> {\n const client = await getAuthenticatedClient();\n\n while (true) {\n const list = await runScansListCommand(client, \"table\", { limit: 20 });\n const data = await client.get<{ results: ScanSummary[] }>(\"/scans?page=1&page_size=20\");\n const scans = data.results || [];\n\n if (!scans.length) {\n ctx.sink.write(emptyState(\"No scans yet\", \"Run /scan <url> to create your first scan\", \"/scan https://example.com\"));\n return;\n }\n\n ctx.sink.write(list);\n ctx.sink.write(\"\");\n\n const scanId = await pickFromList(\n \"Select a scan (Esc to go back)\",\n scans.map((s) => ({\n name: `${truncate(s.target_url, 32)} ${s.risk_level ?? s.status} ${s.overall_score ?? \"—\"} ${formatTimestamp(s.created_at)}`,\n value: s.id,\n })),\n );\n if (!scanId) return;\n\n const detail = await client.get<ScanDetail>(`/scan/${scanId}`);\n ctx.sink.write(renderScanResult(detail, \"table\"));\n\n const cont = await input({\n message: muted(\"Enter = back to list · q = exit\"),\n default: \"\",\n }).catch(() => \"q\");\n if (cont.toLowerCase() === \"q\") return;\n }\n}\n\nasync function runKeysInteractive(ctx: SlashContext): Promise<void> {\n const client = await getAuthenticatedClient();\n ctx.sink.write(await runKeysListCommand(client));\n ctx.sink.write(muted(\"\\nActions: [r] revoke [n] new key [Enter] back\"));\n\n const action = await input({ message: \"Action\", default: \"\" }).catch(() => \"\");\n\n if (action.toLowerCase() === \"r\") {\n const keyId = await pickKeyForRevoke(client);\n if (!keyId) return;\n const ok = await confirm({ message: \"Revoke this API key?\", default: false }).catch(() => false);\n if (ok) ctx.sink.write(successBox(await runKeyRevoke(client, keyId)));\n } else if (action.toLowerCase() === \"n\") {\n const name = await promptNewKeyName();\n const created = await client.post<{ key: string; name: string; prefix: string }>(\"/keys\", { name });\n ctx.sink.write(success(`Created: ${created.name} (${created.prefix})`));\n ctx.sink.write(accent(\"Save this key — it won't be shown again:\"));\n ctx.sink.write(created.key);\n }\n}\n","import { createTable } from \"../terminal/table.js\";\nimport { muted, success } from \"../terminal/theme.js\";\nimport { emptyState } from \"../terminal/empty-state.js\";\nimport { SETTINGS_API_KEYS_URL } from \"../types/brand.js\";\nimport type { ApiKey } from \"../types/api.js\";\nimport type { FuzziApiClient } from \"../lib/api-client.js\";\nimport { pickFromList } from \"../terminal/interactive.js\";\n\nexport async function runKeysListCommand(client: FuzziApiClient): Promise<string> {\n const data = await client.get<{ results: ApiKey[] }>(\"/keys\");\n const keys = data.results || [];\n if (!keys.length) {\n return emptyState(\"No API keys\", `Create one at ${SETTINGS_API_KEYS_URL}`, \"[n] new key in this view\");\n }\n\n const rows = keys.map((k) => [\n k.name,\n k.prefix,\n k.scopes?.join(\", \") || muted(\"—\"),\n k.revoked ? muted(\"Revoked\") : k.active ? success(\"Active\") : muted(\"Inactive\"),\n k.last_used_at ? new Date(k.last_used_at).toLocaleDateString() : muted(\"Never\"),\n ]);\n\n return createTable([\"Name\", \"Prefix\", \"Scopes\", \"Status\", \"Last Used\"], rows);\n}\n\nexport async function runKeyRevoke(client: FuzziApiClient, keyId: string): Promise<string> {\n await client.delete(`/keys/${keyId}`);\n return \"API key revoked.\";\n}\n\nexport async function pickKeyForRevoke(client: FuzziApiClient): Promise<string | null> {\n const data = await client.get<{ results: ApiKey[] }>(\"/keys\");\n const active = (data.results || []).filter((k) => !k.revoked && k.active);\n return pickFromList(\n \"Select a key to revoke\",\n active.map((k) => ({ name: `${k.name} (${k.prefix})`, value: k.id })),\n );\n}\n","import { muted, accent } from \"./theme.js\";\n\nexport function emptyState(title: string, hint: string, action?: string): string {\n const lines = [\"\", muted(title), muted(hint)];\n if (action) lines.push(\"\", accent(action));\n return lines.join(\"\\n\");\n}\n","import { select, search } from \"@inquirer/prompts\";\nimport { accent, muted } from \"./theme.js\";\n\nexport async function pickFromList<T extends { name: string; value: string }>(\n message: string,\n items: T[],\n): Promise<string | null> {\n if (!items.length) return null;\n try {\n return await select({ message, choices: items });\n } catch {\n return null;\n }\n}\n\nexport async function searchPalette(\n message: string,\n choices: Array<{ name: string; value: string; description?: string }>,\n): Promise<string | null> {\n try {\n return await search({\n message,\n source: async (input) => {\n if (!input) return choices;\n const q = input.toLowerCase();\n return choices.filter((c) => c.value.includes(q) || c.description?.includes(q));\n },\n });\n } catch {\n return null;\n }\n}\n\nexport function formatChoice(name: string, description: string): string {\n return `${accent(name)}${muted(\" — \" + description)}`;\n}\n","import { panel, columns, divider, keyValue } from \"../terminal/layout.js\";\nimport { accent, accentBold, muted, dim } from \"../terminal/theme.js\";\nimport { SLASH_COMMANDS } from \"./registry.js\";\n\nexport function renderHelpScreen(): string {\n const visible = SLASH_COMMANDS.filter((c) => !c.hidden);\n const left = visible\n .slice(0, Math.ceil(visible.length / 2))\n .map((c) => `${accent(c.name.padEnd(12))} ${muted(c.description)}`)\n .join(\"\\n\");\n const right = visible\n .slice(Math.ceil(visible.length / 2))\n .map((c) => `${accent(c.name.padEnd(12))} ${muted(c.description)}`)\n .join(\"\\n\");\n\n const script = [\n muted(\"Scriptable commands\"),\n ` fuzzi scan <url> [--format json|markdown] [--fail-on critical]`,\n ` fuzzi scans list | get <id> · fuzzi auth login | status`,\n ` fuzzi config set default_env staging`,\n ].join(\"\\n\");\n\n return [\n panel(columns(left, right), { title: \"Commands\" }),\n \"\",\n script,\n \"\",\n divider(),\n dim(\"Tips: Tab to complete · /palette to search · Ctrl+C to exit\"),\n ].join(\"\\n\");\n}\n\nexport function renderHistoryScreen(entries: string[]): string {\n if (!entries.length) return muted(\"No command history yet.\");\n const body = entries\n .slice(-15)\n .reverse()\n .map((e, i) => `${dim(String(i + 1).padStart(2))} ${e}`)\n .join(\"\\n\");\n return panel(body, { title: \"Recent commands\" });\n}\n","export interface SlashCommandDef {\n name: string;\n description: string;\n usage?: string;\n aliases?: string[];\n requiresAuth?: boolean;\n hidden?: boolean;\n}\n\nexport const SLASH_COMMANDS: SlashCommandDef[] = [\n { name: \"/scan\", description: \"Run a security scan on a URL\", usage: \"/scan <url>\", requiresAuth: true },\n { name: \"/scans\", description: \"Browse recent scans\", requiresAuth: true },\n { name: \"/status\", description: \"Show auth status and rate limits\", requiresAuth: true },\n { name: \"/keys\", description: \"Manage API keys\", requiresAuth: true },\n { name: \"/config\", description: \"Set CLI configuration\", usage: \"/config key=value\" },\n { name: \"/compare\", description: \"Compare two scans\", usage: \"/compare <id-a> <id-b>\", requiresAuth: true },\n { name: \"/whatif\", description: \"Simulate factor overrides\", usage: \"/whatif <id>\", requiresAuth: true },\n { name: \"/report\", description: \"Download scan report\", usage: \"/report <id>\", requiresAuth: true },\n { name: \"/palette\", description: \"Open command palette\", aliases: [\"/commands\"] },\n { name: \"/changelog\", description: \"View release notes\" },\n { name: \"/help\", description: \"Show all commands\" },\n { name: \"/auth\", description: \"Sign in via browser\", aliases: [\"/login\"] },\n { name: \"/auth-key\", description: \"Paste an API key instead\", usage: \"/auth-key\" },\n { name: \"/clear\", description: \"Clear screen and refresh home\" },\n { name: \"/history\", description: \"Show recent commands\" },\n { name: \"/exit\", description: \"Exit the shell\", aliases: [\"/quit\"] },\n];\n\nexport function findCommand(input: string): SlashCommandDef | undefined {\n const cmd = input.trim().split(/\\s/)[0].toLowerCase();\n return SLASH_COMMANDS.find(\n (c) => c.name === cmd || c.aliases?.some((a) => a === cmd),\n );\n}\n\nexport function suggestCommands(partial: string): SlashCommandDef[] {\n const p = partial.toLowerCase();\n if (!p.startsWith(\"/\")) return SLASH_COMMANDS.filter((c) => !c.hidden);\n return SLASH_COMMANDS.filter((c) => c.name.startsWith(p) || c.aliases?.some((a) => a.startsWith(p)));\n}\n","import { searchPalette, formatChoice } from \"../terminal/interactive.js\";\nimport { SLASH_COMMANDS } from \"./registry.js\";\n\nexport async function openCommandPalette(): Promise<string | null> {\n const choices = SLASH_COMMANDS.filter((c) => !c.hidden).map((c) => ({\n name: formatChoice(c.name, c.description),\n value: c.name,\n description: c.usage,\n }));\n return searchPalette(\"Command palette\", choices);\n}\n\nexport { pickFromList } from \"../terminal/interactive.js\";\n","import { mkdir, readFile, writeFile, appendFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { fuzziDir } from \"../lib/credentials.js\";\n\nconst HISTORY_PATH = join(fuzziDir(), \"history\");\nconst MAX_ENTRIES = 200;\n\nexport async function loadHistory(): Promise<string[]> {\n try {\n const raw = await readFile(HISTORY_PATH, \"utf8\");\n return raw.split(\"\\n\").filter(Boolean).slice(-MAX_ENTRIES);\n } catch {\n return [];\n }\n}\n\nexport async function appendHistory(line: string): Promise<void> {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) return;\n await mkdir(fuzziDir(), { recursive: true, mode: 0o700 });\n await appendFile(HISTORY_PATH, trimmed + \"\\n\", \"utf8\");\n}\n\nexport async function clearHistory(): Promise<void> {\n await writeFile(HISTORY_PATH, \"\", \"utf8\");\n}\n","import { panel } from \"./layout.js\";\nimport { error, warn, success, accentBold } from \"./theme.js\";\n\nexport function errorBox(message: string, hint?: string): string {\n const body = hint ? `${message}\\n\\n${hint}` : message;\n return panel(body, { title: \"Error\" });\n}\n\nexport function successBox(message: string): string {\n return panel(success(message), { title: \"Done\" });\n}\n\nexport function section(title: string, body: string): string {\n return [accentBold(title), body].join(\"\\n\");\n}\n\nexport function warningBox(message: string): string {\n return panel(warn(message), { title: \"Warning\" });\n}\n","import type { SlashCommandDef } from \"./registry.js\";\n\nexport function buildCompleter(commands: SlashCommandDef[], history: string[]): (line: string) => [string[], string] {\n const names = commands.map((c) => c.name);\n return (line: string): [string[], string] => {\n const trimmed = line.trimStart();\n if (!trimmed.startsWith(\"/\")) {\n if (trimmed === \"\") return [[...names, ...history.slice(-20).reverse()], line];\n return [[], line];\n }\n const hits = names.filter((n) => n.startsWith(trimmed.split(/\\s/)[0]));\n return [hits.length ? hits : names, line];\n };\n}\n","import * as readline from \"node:readline\";\nimport { stdin as input, stdout as output } from \"node:process\";\nimport { renderAuthGateScreen } from \"./home-screen.js\";\nimport { accent, muted } from \"../terminal/theme.js\";\nimport { runAssistedBrowserLogin } from \"../commands/auth.js\";\nimport { tryGetProfile } from \"../cli/profile.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { formatApiError } from \"../lib/errors.js\";\n\nfunction waitForEnter(): Promise<void> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({ input, output, terminal: true });\n output.write(accent(\"\\n> Press Enter to open browser... \"));\n rl.once(\"line\", () => {\n rl.close();\n resolve();\n });\n });\n}\n\nexport async function runAuthGate(): Promise<UserProfile | null> {\n const existing = await tryGetProfile();\n if (existing) return existing;\n\n if (!output.isTTY) return null;\n\n console.log(renderAuthGateScreen());\n await waitForEnter();\n\n try {\n const result = await runAssistedBrowserLogin();\n console.log(result.message);\n return result.profile;\n } catch (e) {\n console.log(muted(formatApiError(e)));\n console.log(muted(\"Run /auth-key to paste your API key manually.\"));\n return null;\n }\n}\n\n/** @deprecated use renderAuthGateScreen */\nexport const renderAuthGate = renderAuthGateScreen;\n","import { cwd } from \"node:process\";\nimport { loadCredentials } from \"../lib/credentials.js\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { log } from \"../lib/logger.js\";\n\nexport async function tryGetProfile(): Promise<UserProfile | null> {\n try {\n const creds = await loadCredentials();\n if (!creds?.api_key) return null;\n const client = await getAuthenticatedClient();\n return await client.get<UserProfile>(\"/me\");\n } catch (e) {\n log.debug(\"profile bootstrap failed\", e);\n return null;\n }\n}\n","import type { UserProfile } from \"../types/api.js\";\nimport { runPromptLoop } from \"../shell/prompt-loop.js\";\nimport { runAuthGate } from \"../shell/auth-gate.js\";\nimport { tryGetProfile } from \"./profile.js\";\n\nexport async function runInteractiveMode(): Promise<void> {\n let profile = await tryGetProfile();\n if (!profile) {\n profile = await runAuthGate();\n }\n await runPromptLoop(profile);\n}\n","import { buildProgram } from \"./cli/program.js\";\nimport { runInteractiveMode } from \"./cli/bootstrap.js\";\nimport { formatApiError, getExitCode } from \"./lib/errors.js\";\n\nasync function main(argv: string[]): Promise<void> {\n if (argv.length <= 2) {\n await runInteractiveMode();\n return;\n }\n await buildProgram().parseAsync(argv);\n}\n\nmain(process.argv).catch((e) => {\n console.error(formatApiError(e));\n process.exit(getExitCode(e));\n});\n"],"mappings":"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","names":["mkdir","readFile","writeFile","chmod","homedir","join","ensureDir","stdout","init_theme","writeFile","init_theme","cwd","cmd","readFile","join","cwd","output","init_theme","cwd","runReportCommand","runWhatIfCommand","runCompareCommand","input","cwd","readFile","join","existsSync","daysUntil","limit","used","textBlock","main","confirm","input","input","input","cmd","mkdir","readFile","writeFile","join","cmd","runCompareCommand","runWhatIfCommand","runReportCommand","input","confirm","cwd","input","readline","input","output","input","output"]}
1
+ {"version":3,"sources":["../src/types/brand.ts","../src/lib/credentials.ts","../src/lib/config.ts","../src/lib/logger.ts","../src/lib/api-utils.ts","../src/lib/api-client.ts","../src/terminal/capabilities.ts","../src/terminal/theme.ts","../src/terminal/table.ts","../src/terminal/strings.ts","../src/terminal/width.ts","../src/terminal/layout.ts","../src/lib/theme.ts","../src/commands/report.ts","../src/commands/whatif.ts","../src/commands/compare.ts","../src/cli/program.ts","../src/commands/auth.ts","../src/lib/browser-auth.ts","../src/lib/platform.ts","../src/terminal/interactive.ts","../src/lib/output.ts","../src/commands/scan.ts","../src/lib/errors.ts","../src/lib/risk.ts","../src/lib/project-config.ts","../src/terminal/progress.ts","../src/lib/retry.ts","../src/commands/scans.ts","../src/commands/status.ts","../src/commands/config.ts","../src/cli/exit.ts","../src/shell/prompt-loop.ts","../src/lib/assets.ts","../src/shell/home-screen.ts","../src/shell/ascii-mark.ts","../src/components/Panel.ts","../src/shell/slash-commands.ts","../src/commands/keys.ts","../src/terminal/empty-state.ts","../src/shell/help-screen.ts","../src/shell/registry.ts","../src/shell/command-palette.ts","../src/shell/session.ts","../src/terminal/banner.ts","../src/shell/completer.ts","../src/shell/auth-gate.ts","../src/cli/profile.ts","../src/cli/bootstrap.ts","../src/index.ts"],"sourcesContent":["/** Locked Fuzzi CLI design tokens (dark-first terminal). */\nexport const BRAND = {\n accent: \"#4FC3A1\",\n accentDim: \"#3A9A7E\",\n bg: \"#0A0C10\",\n surface: \"#12151B\",\n surfaceHover: \"#181C24\",\n borderSubtle: \"#232832\",\n borderStrong: \"#313846\",\n textPrimary: \"#E8EAED\",\n textSecondary: \"#9AA3B2\",\n textTertiary: \"#5C6470\",\n success: \"#22C55E\",\n warning: \"#F59E0B\",\n danger: \"#EF4444\",\n critical: \"#A855F7\",\n} as const;\n\nexport const RISK_COLORS: Record<string, string> = {\n LOW: BRAND.success,\n MEDIUM: BRAND.warning,\n HIGH: BRAND.danger,\n CRITICAL: BRAND.critical,\n};\n\nexport const VERSION = \"0.1.6\";\n\n/** Production web app (Vercel) */\nexport const APP_ORIGIN = \"https://fuzzi-ten.vercel.app\";\n\n/** Default API base — override with FUZZI_API_URL */\nexport const DEFAULT_API_URL = `${APP_ORIGIN}/api`;\n\nexport const SETTINGS_API_KEYS_URL = `${APP_ORIGIN}/settings/api-keys`;\nexport const CLI_AUTH_URL = `${APP_ORIGIN}/cli-auth`;\nexport const APP_HOST = \"fuzzi-ten.vercel.app\";\n","import { mkdir, readFile, writeFile, chmod, unlink } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { Credentials } from \"../types/api.js\";\n\nconst FUZZI_DIR = join(homedir(), \".fuzzi\");\nconst CREDENTIALS_PATH = join(FUZZI_DIR, \"credentials\");\nconst LEGACY_CREDENTIALS_PATH = join(FUZZI_DIR, \"credentials.json\");\n\nexport function fuzziDir(): string {\n return FUZZI_DIR;\n}\n\nexport function credentialsPath(): string {\n return CREDENTIALS_PATH;\n}\n\nasync function ensureDir(): Promise<void> {\n await mkdir(FUZZI_DIR, {\n recursive: true,\n ...(process.platform === \"win32\" ? {} : { mode: 0o700 }),\n });\n}\n\nfunction normalizeCredentials(raw: Record<string, unknown>): Credentials {\n if (raw.api_key && typeof raw.api_key === \"string\") {\n return {\n api_key: raw.api_key,\n auth_method: \"api_key\",\n key_prefix: (raw.key_prefix as string) || raw.api_key.slice(0, 12) + \"...\",\n key_expires_at: raw.key_expires_at as string | undefined,\n email: raw.email as string | undefined,\n full_name: raw.full_name as string | undefined,\n saved_at: (raw.saved_at as string) || new Date().toISOString(),\n };\n }\n if (raw.access_token && typeof raw.access_token === \"string\") {\n return {\n api_key: raw.access_token,\n auth_method: \"api_key\",\n key_prefix: raw.access_token.slice(0, 12) + \"...\",\n email: raw.email as string | undefined,\n full_name: raw.full_name as string | undefined,\n saved_at: (raw.saved_at as string) || new Date().toISOString(),\n };\n }\n throw new Error(\"Invalid credentials file\");\n}\n\nexport async function loadCredentials(): Promise<Credentials | null> {\n for (const path of [CREDENTIALS_PATH, LEGACY_CREDENTIALS_PATH]) {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n if (!parsed || Object.keys(parsed).length === 0) return null;\n return normalizeCredentials(parsed);\n } catch {\n /* try next path */\n }\n }\n return null;\n}\n\nexport async function saveCredentials(creds: Credentials): Promise<void> {\n await ensureDir();\n await writeFile(CREDENTIALS_PATH, JSON.stringify(creds, null, 2), { mode: 0o600 });\n try {\n await chmod(CREDENTIALS_PATH, 0o600);\n } catch {\n /* windows */\n }\n}\n\nexport async function clearCredentials(): Promise<void> {\n for (const path of [CREDENTIALS_PATH, LEGACY_CREDENTIALS_PATH]) {\n try {\n await unlink(path);\n } catch {\n /* ok */\n }\n }\n}\n\nexport function maskApiKey(key: string): string {\n if (key.length <= 16) return key.slice(0, 8) + \"...\";\n return key.slice(0, 12) + \"...\";\n}\n\nexport function isValidApiKeyFormat(key: string): boolean {\n return /^fz_live_[A-Za-z0-9_-]{20,}$/.test(key.trim());\n}\n","import { mkdir, readFile, writeFile, chmod } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { CliConfig } from \"../types/api.js\";\nimport { DEFAULT_API_URL } from \"../types/brand.js\";\nimport { fuzziDir } from \"./credentials.js\";\n\nconst CONFIG_PATH = join(homedir(), \".fuzzi\", \"config\");\nconst LEGACY_CONFIG_PATH = join(homedir(), \".fuzzi\", \"config.json\");\n\nexport { fuzziDir };\n\nasync function ensureDir(): Promise<void> {\n await mkdir(fuzziDir(), {\n recursive: true,\n ...(process.platform === \"win32\" ? {} : { mode: 0o700 }),\n });\n}\n\nexport async function loadConfig(): Promise<CliConfig> {\n for (const path of [CONFIG_PATH, LEGACY_CONFIG_PATH]) {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<CliConfig>;\n return {\n api_url: process.env.FUZZI_API_URL || parsed.api_url || DEFAULT_API_URL,\n default_env: parsed.default_env,\n default_format: parsed.default_format,\n ...parsed,\n };\n } catch {\n /* try next */\n }\n }\n return { api_url: process.env.FUZZI_API_URL || DEFAULT_API_URL };\n}\n\nexport async function saveConfig(config: CliConfig): Promise<void> {\n await ensureDir();\n await writeFile(CONFIG_PATH, JSON.stringify(config, null, 2), { mode: 0o600 });\n try {\n await chmod(CONFIG_PATH, 0o600);\n } catch {\n /* windows */\n }\n}\n\nexport async function setConfigValue(key: string, value: string): Promise<void> {\n const config = await loadConfig();\n if (key === \"api_url\") config.api_url = value;\n else if (key === \"default_env\") config.default_env = value as CliConfig[\"default_env\"];\n else if (key === \"default_format\") config.default_format = value as CliConfig[\"default_format\"];\n else (config as unknown as Record<string, string>)[key] = value;\n await saveConfig(config);\n}\n\nexport async function getConfigValue(key: string): Promise<string | undefined> {\n const config = await loadConfig();\n return (config as unknown as Record<string, string | undefined>)[key];\n}\n\nexport async function listConfigEntries(): Promise<Record<string, string>> {\n const config = await loadConfig();\n const entries: Record<string, string> = {};\n for (const [k, v] of Object.entries(config)) {\n if (v !== undefined) entries[k] = String(v);\n }\n return entries;\n}\n","type Level = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nconst LEVELS: Record<Level, number> = { debug: 0, info: 1, warn: 2, error: 3 };\n\nfunction currentLevel(): Level {\n if (process.env.FUZZI_DEBUG === \"1\" || process.env.FUZZI_DEBUG === \"true\") return \"debug\";\n if (process.env.FUZZI_LOG_LEVEL) return process.env.FUZZI_LOG_LEVEL as Level;\n return \"warn\";\n}\n\nfunction shouldLog(level: Level): boolean {\n return LEVELS[level] >= LEVELS[currentLevel()];\n}\n\nfunction stamp(): string {\n return new Date().toISOString();\n}\n\nexport const log = {\n debug(...args: unknown[]) {\n if (shouldLog(\"debug\")) console.error(`[fuzzi ${stamp()}]`, ...args);\n },\n info(...args: unknown[]) {\n if (shouldLog(\"info\")) console.error(`[fuzzi ${stamp()}]`, ...args);\n },\n warn(...args: unknown[]) {\n if (shouldLog(\"warn\")) console.error(`[fuzzi ${stamp()}]`, ...args);\n },\n error(...args: unknown[]) {\n if (shouldLog(\"error\")) console.error(`[fuzzi ${stamp()}]`, ...args);\n },\n};\n\nexport function isDebugMode(): boolean {\n return currentLevel() === \"debug\";\n}\n","/** Coerce API error bodies (string, array, object) into a single string. */\nexport function errorText(value: unknown): string {\n if (value == null) return \"\";\n if (typeof value === \"string\") return value;\n if (Array.isArray(value)) return value.map(errorText).filter(Boolean).join(\"; \");\n if (typeof value === \"object\") {\n const o = value as Record<string, unknown>;\n if (typeof o.detail === \"string\") return o.detail;\n if (Array.isArray(o.detail)) return o.detail.map(errorText).join(\"; \");\n if (typeof o.message === \"string\") return o.message;\n if (typeof o.error === \"string\") return o.error;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n return String(value);\n}\n\n/** Normalize list endpoints that may return an array or { results: [] }. */\nexport function asList<T>(data: T[] | { results?: T[]; data?: T[] } | null | undefined): T[] {\n if (!data) return [];\n if (Array.isArray(data)) return data;\n return data.results ?? data.data ?? [];\n}\n","import type { Credentials, CliConfig } from \"../types/api.js\";\nimport { loadConfig } from \"./config.js\";\nimport { loadCredentials } from \"./credentials.js\";\nimport { log } from \"./logger.js\";\nimport { APP_HOST, SETTINGS_API_KEYS_URL } from \"../types/brand.js\";\nimport { errorText } from \"./api-utils.js\";\n\nexport class ApiError extends Error {\n exitCode?: number;\n\n constructor(\n message: string,\n public status: number,\n public code?: string,\n public body?: unknown,\n exitCode?: number,\n ) {\n super(message);\n this.name = \"ApiError\";\n this.exitCode = exitCode;\n }\n}\n\nfunction mapErrorMessage(status: number, body: { error?: unknown; code?: string; message?: unknown; detail?: unknown }): string {\n const code = typeof body.code === \"string\" ? body.code.toLowerCase() : \"\";\n const msg = errorText(body.error ?? body.message ?? body.detail);\n\n if (status === 401) {\n if (code === \"key_revoked\" || msg.toLowerCase().includes(\"revoked\")) {\n return \"API key has been revoked. Please log in again.\";\n }\n if (code === \"key_expired\" || msg.toLowerCase().includes(\"expired\")) {\n return `API key has expired. Generate a new one at ${SETTINGS_API_KEYS_URL}`;\n }\n return msg || `Invalid API key. Generate a new one at ${SETTINGS_API_KEYS_URL}`;\n }\n if (status === 403 && (code === \"ssrf\" || msg.toLowerCase().includes(\"private ip\"))) {\n return \"This URL is not allowed (private IP address detected). Please scan a public-facing URL.\";\n }\n if (status === 400 && msg.toLowerCase().includes(\"url\")) {\n return \"Invalid URL. Please provide a valid URL starting with http:// or https://\";\n }\n if (status === 429) {\n return msg || \"Rate limit exceeded.\";\n }\n if (msg.toLowerCase().startsWith(\"scan failed\")) {\n return msg;\n }\n if (msg) return msg;\n return `Request failed with status ${status}`;\n}\n\nexport class FuzziApiClient {\n constructor(\n private baseUrl: string,\n private token?: string,\n ) {}\n\n static async create(): Promise<FuzziApiClient> {\n const config = await loadConfig();\n const creds = await loadCredentials();\n return new FuzziApiClient(config.api_url.replace(/\\/$/, \"\"), creds?.api_key);\n }\n\n get base(): string {\n return this.baseUrl;\n }\n\n setToken(token: string): void {\n this.token = token;\n }\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = { \"Content-Type\": \"application/json\", Accept: \"application/json\" };\n if (this.token) h.Authorization = `Bearer ${this.token}`;\n return h;\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path.startsWith(\"/\") ? path : `/${path}`}`;\n log.debug(`${method} ${url}`);\n let res: Response;\n try {\n res = await fetch(url, {\n method,\n headers: this.headers(),\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n } catch {\n throw new ApiError(\n `Could not connect to ${APP_HOST}. Check your internet connection or try again later.`,\n 0,\n \"network_error\",\n undefined,\n 2,\n );\n }\n\n let data: unknown;\n const text = await res.text();\n try {\n data = text ? JSON.parse(text) : {};\n } catch {\n data = { error: text };\n }\n\n if (!res.ok) {\n const errBody = data as { error?: unknown; code?: string; message?: unknown; detail?: unknown };\n let message = mapErrorMessage(res.status, errBody);\n\n if (res.status === 429) {\n const retryAfter = res.headers.get(\"Retry-After\");\n const seconds = retryAfter ? parseInt(retryAfter, 10) : 60;\n message = `Rate limit exceeded. Retry after ${seconds} seconds.`;\n }\n\n if (res.status >= 500) {\n message = `Request failed: ${errorText(errBody.error ?? errBody.message ?? errBody.detail) || res.statusText}`;\n }\n\n throw new ApiError(message, res.status, errBody.code, data, 2);\n }\n return data as T;\n }\n\n get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(\"PATCH\", path, body);\n }\n\n delete<T>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n\n async validateToken(): Promise<boolean> {\n try {\n await this.get(\"/me\");\n return true;\n } catch {\n return false;\n }\n }\n\n async download(path: string): Promise<{ data: Buffer; contentType: string }> {\n const url = `${this.baseUrl}${path.startsWith(\"/\") ? path : `/${path}`}`;\n let res: Response;\n try {\n res = await fetch(url, { headers: this.headers() });\n } catch {\n throw new ApiError(\n `Could not connect to ${APP_HOST}. Check your internet connection or try again later.`,\n 0,\n \"network_error\",\n undefined,\n 2,\n );\n }\n if (!res.ok) {\n const text = await res.text();\n let errBody: { error?: unknown; code?: string; message?: unknown; detail?: unknown } = {};\n try {\n errBody = JSON.parse(text);\n } catch {\n errBody = { error: text };\n }\n throw new ApiError(mapErrorMessage(res.status, errBody), res.status, errBody.code, errBody, 2);\n }\n const buf = Buffer.from(await res.arrayBuffer());\n return { data: buf, contentType: res.headers.get(\"content-type\") || \"application/octet-stream\" };\n }\n}\n\nexport async function getAuthenticatedClient(): Promise<FuzziApiClient> {\n const client = await FuzziApiClient.create();\n if (!client[\"token\"]) {\n throw new ApiError(\"Not authenticated. Run: fuzzi auth login\", 401, \"not_authenticated\", undefined, 2);\n }\n return client;\n}\n\nexport async function getConfig(): Promise<CliConfig> {\n return loadConfig();\n}\n\nexport async function getCredentials(): Promise<Credentials | null> {\n return loadCredentials();\n}\n","import { stdout } from \"node:process\";\n\nexport interface TerminalCapabilities {\n width: number;\n trueColor: boolean;\n interactive: boolean;\n}\n\nlet cached: TerminalCapabilities | null = null;\n\nexport function getCapabilities(): TerminalCapabilities {\n if (cached) return cached;\n const cols = stdout.columns ?? 80;\n const term = process.env.TERM ?? \"\";\n const colorterm = process.env.COLORTERM ?? \"\";\n const onWindows = process.platform === \"win32\";\n const trueColor =\n colorterm.includes(\"truecolor\") ||\n colorterm.includes(\"24bit\") ||\n term.includes(\"truecolor\") ||\n (!!process.env.FORCE_COLOR && process.env.FORCE_COLOR !== \"0\") ||\n (onWindows && stdout.isTTY === true) ||\n !!process.env.WT_SESSION ||\n !!process.env.TERM_PROGRAM;\n\n cached = {\n width: Math.max(60, cols),\n trueColor,\n interactive: stdout.isTTY === true,\n };\n return cached;\n}\n\nexport function resetCapabilities(): void {\n cached = null;\n}\n","import chalk, { type ChalkInstance } from \"chalk\";\nimport { BRAND, RISK_COLORS } from \"../types/brand.js\";\nimport { getCapabilities } from \"./capabilities.js\";\n\nfunction color(hex: string, fallback: ChalkInstance): ChalkInstance {\n return getCapabilities().trueColor ? chalk.hex(hex) : fallback;\n}\n\nexport const accent = color(BRAND.accent, chalk.cyan);\nexport const accentBold = accent.bold;\nexport const primary = color(BRAND.textPrimary, chalk.white);\nexport const primaryBold = primary.bold;\nexport const muted = color(BRAND.textSecondary, chalk.gray);\nexport const dimText = color(BRAND.textTertiary, chalk.dim);\nexport const border = color(BRAND.borderSubtle, chalk.gray);\nexport const bold = chalk.bold;\nexport const dim = chalk.dim;\n\nexport function riskColor(level: string | null | undefined): (s: string) => string {\n if (!level) return muted;\n const key = level.toUpperCase();\n const hex = RISK_COLORS[key] || BRAND.textSecondary;\n const fallbacks: Record<string, ChalkInstance> = {\n LOW: chalk.green,\n MEDIUM: chalk.yellow,\n HIGH: chalk.red,\n CRITICAL: chalk.magenta,\n };\n return color(hex, fallbacks[key] ?? chalk.gray).bold;\n}\n\nexport function scoreBold(n: number | null | undefined): string {\n if (n == null) return muted(\"—\");\n return chalk.bold(String(n));\n}\n\nexport function header(text: string): string {\n return primaryBold(text);\n}\n\nexport function error(text: string): string {\n return color(BRAND.danger, chalk.red)(text);\n}\n\nexport function success(text: string): string {\n return color(BRAND.success, chalk.green)(text);\n}\n\nexport function warn(text: string): string {\n return color(BRAND.warning, chalk.yellow)(text);\n}\n\nexport function info(text: string): string {\n return color(BRAND.accent, chalk.cyan)(text);\n}\n\nexport const italic = chalk.italic;\n\nexport function riskBadge(level: string): string {\n const tag = level.toUpperCase().padEnd(8);\n return riskColor(level)(tag);\n}\n\nexport function cmd(text: string): string {\n return accent(text);\n}\n","import Table from \"cli-table3\";\nimport { muted } from \"./theme.js\";\n\nconst BOX_CHARS: Record<string, string> = {\n mid: \"─\",\n \"left-mid\": \"├\",\n \"mid-mid\": \"┼\",\n \"right-mid\": \"┤\",\n};\n\nexport function createTable(headers: string[], rows: string[][]): string {\n const table = new Table({\n head: headers.map((h) => muted(h)),\n style: { head: [], border: [] },\n chars: BOX_CHARS,\n });\n for (const row of rows) table.push(row);\n return table.toString();\n}\n","export function truncate(s: string, max: number): string {\n if (s.length <= max) return s;\n return s.slice(0, max - 1) + \"…\";\n}\n\nexport function padEndVisible(s: string, width: number): string {\n const plain = s.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n const pad = Math.max(0, width - plain.length);\n return s + \" \".repeat(pad);\n}\n\nexport function formatTimestamp(iso: string | null | undefined): string {\n if (!iso) return \"—\";\n const d = new Date(iso);\n const p = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;\n}\n\nexport function hostnameFromUrl(url: string): string {\n try {\n return new URL(url).hostname;\n } catch {\n return url;\n }\n}\n","import { stdout } from \"node:process\";\nimport { getCapabilities, resetCapabilities } from \"./capabilities.js\";\n\nexport function terminalWidth(): number {\n resetCapabilities();\n return Math.max(64, (stdout.columns ?? 80) - 2);\n}\n\nexport function contentWidth(): number {\n return terminalWidth() - 4;\n}\n","import boxen from \"boxen\";\nimport { BRAND } from \"../types/brand.js\";\nimport { accentBold, dim, muted } from \"./theme.js\";\nimport { getCapabilities } from \"./capabilities.js\";\nimport { padEndVisible } from \"./strings.js\";\nimport { terminalWidth, contentWidth } from \"./width.js\";\n\nexport interface PanelOptions {\n title?: string;\n padding?: number;\n marginBottom?: number;\n fullWidth?: boolean;\n borderStyle?: \"round\" | \"single\" | \"classic\" | \"bold\";\n}\n\nexport function panel(content: string, opts: PanelOptions = {}): string {\n const width = opts.fullWidth !== false ? terminalWidth() : undefined;\n return boxen(content, {\n title: opts.title ? accentBold(opts.title) : undefined,\n padding: opts.padding ?? 1,\n margin: { top: 0, bottom: opts.marginBottom ?? 1, left: 0, right: 0 },\n borderStyle: opts.borderStyle ?? \"classic\",\n borderColor: getCapabilities().trueColor ? BRAND.accent : undefined,\n titleAlignment: \"left\",\n width,\n });\n}\n\nexport function centerInColumn(text: string, colWidth: number): string {\n return text\n .split(\"\\n\")\n .map((line) => {\n const plain = line.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n const pad = Math.max(0, Math.floor((colWidth - plain.length) / 2));\n return \" \".repeat(pad) + line;\n })\n .join(\"\\n\");\n}\n\nexport interface SplitHomeOptions {\n title: string;\n left: string;\n rightTop: string;\n rightBottom: string;\n leftRatio?: number;\n}\n\n/** Claude Code-style two-column home with horizontal split on the right. */\nexport function splitHomePanel(opts: SplitHomeOptions): string {\n const total = contentWidth();\n const leftW = Math.max(28, Math.floor(total * (opts.leftRatio ?? 0.34)));\n const rightW = total - leftW - 3;\n\n const leftLines = opts.left.split(\"\\n\");\n const rightTop = opts.rightTop.split(\"\\n\");\n const rightDiv = dim(\"─\".repeat(Math.max(10, rightW)));\n const rightBottom = opts.rightBottom.split(\"\\n\");\n const rightLines = [...rightTop, \"\", rightDiv, \"\", ...rightBottom];\n\n const rows = Math.max(leftLines.length, rightLines.length);\n const sep = dim(\"│\");\n const body: string[] = [\"\"];\n\n for (let i = 0; i < rows; i++) {\n const l = padEndVisible(leftLines[i] ?? \"\", leftW);\n const r = rightLines[i] ?? \"\";\n body.push(`${l} ${sep} ${r}`);\n }\n body.push(\"\");\n\n return panel(body.join(\"\\n\"), { title: opts.title, marginBottom: 0, borderStyle: \"classic\" });\n}\n\nexport function columns(left: string, right: string, leftWidth?: number): string {\n const total = contentWidth();\n const split = leftWidth ?? Math.floor(total * 0.48);\n const leftLines = left.split(\"\\n\");\n const rightLines = right.split(\"\\n\");\n const rows = Math.max(leftLines.length, rightLines.length);\n const out: string[] = [];\n for (let i = 0; i < rows; i++) {\n const l = padEndVisible(leftLines[i] ?? \"\", split);\n const r = rightLines[i] ?? \"\";\n out.push(`${l} ${r}`);\n }\n return out.join(\"\\n\");\n}\n\nexport function divider(char = \"─\", width?: number): string {\n const w = width ?? contentWidth();\n return dim(char.repeat(Math.max(20, w)));\n}\n\nexport function statusBar(parts: string[]): string {\n return dim(parts.filter(Boolean).join(\" · \"));\n}\n\nexport function keyValue(rows: Array<[string, string]>, indent = 2): string {\n const pad = \" \".repeat(indent);\n const maxKey = Math.max(...rows.map(([k]) => k.length), 4);\n return rows.map(([k, v]) => `${pad}${muted(k.padEnd(maxKey))} ${v}`).join(\"\\n\");\n}\n\nexport function centerBlock(text: string, width = contentWidth()): string {\n return centerInColumn(text, width);\n}\n","export * from \"../terminal/theme.js\";\n","import { writeFile } from \"node:fs/promises\";\nimport { FuzziApiClient } from \"../lib/api-client.js\";\n\nexport async function runReportCommand(\n client: FuzziApiClient,\n scanId: string,\n format: \"pdf\" | \"csv\" | \"json\",\n outputPath?: string,\n): Promise<string> {\n const { data, contentType } = await client.download(`/scan/${scanId}/report?format=${format}`);\n\n const ext = format === \"pdf\" ? \"pdf\" : format === \"csv\" ? \"csv\" : \"json\";\n const path = outputPath || `fuzzi-report-${scanId.slice(0, 8)}.${ext}`;\n\n await writeFile(path, data);\n return `Report saved to ${path} (${contentType})`;\n}\n","import { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport type { OutputFormat } from \"../lib/output.js\";\nimport { riskColor, scoreBold } from \"../lib/theme.js\";\n\nexport async function runWhatIfCommand(\n scanId: string,\n overrides: Record<string, number>,\n format: OutputFormat = \"table\",\n): Promise<string> {\n const client = await getAuthenticatedClient();\n const data = await client.post<{\n original: { risk_level: string; overall_score: number };\n simulated: { risk_level: string; overall_score: number };\n summary: string;\n overall_score_delta: number;\n }>(\"/whatif\", { scan_id: scanId, overrides });\n\n if (format === \"json\") return JSON.stringify(data, null, 2);\n return [\n `Original: ${riskColor(data.original.risk_level)(data.original.risk_level)} (${scoreBold(data.original.overall_score)})`,\n `Simulated: ${riskColor(data.simulated.risk_level)(data.simulated.risk_level)} (${scoreBold(data.simulated.overall_score)})`,\n `Delta: ${data.overall_score_delta > 0 ? \"+\" : \"\"}${data.overall_score_delta}`,\n data.summary,\n ].join(\"\\n\");\n}\n","import { createTable } from \"../terminal/table.js\";\nimport { riskColor, scoreBold } from \"../terminal/theme.js\";\nimport { panel } from \"../terminal/layout.js\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport type { CompareResponse } from \"../types/api.js\";\nimport type { OutputFormat } from \"../lib/output.js\";\n\nexport async function runCompareCommand(\n scanA: string,\n scanB: string,\n format: OutputFormat = \"table\",\n): Promise<string> {\n const client = await getAuthenticatedClient();\n const data = await client.post<CompareResponse>(\"/compare\", {\n scan_a_id: scanA,\n scan_b_id: scanB,\n });\n\n if (format === \"json\") return JSON.stringify(data, null, 2);\n\n const summary = [\n `Scan A ${data.scan_a.target_url}`,\n ` ${riskColor(data.scan_a.risk_level || \"\")(data.scan_a.risk_level || \"—\")} ${scoreBold(data.scan_a.overall_score)}`,\n `Scan B ${data.scan_b.target_url}`,\n ` ${riskColor(data.scan_b.risk_level || \"\")(data.scan_b.risk_level || \"—\")} ${scoreBold(data.scan_b.overall_score)}`,\n `Delta ${data.score_delta > 0 ? \"+\" : \"\"}${data.score_delta}`,\n data.summary,\n ].join(\"\\n\");\n\n let body = panel(summary, { title: \"Compare\" });\n\n if (data.factor_changes?.length) {\n const rows = data.factor_changes.map((f) => [f.name.replace(/_/g, \" \"), String(f.delta)]);\n body += \"\\n\\n\" + createTable([\"Factor\", \"Delta\"], rows);\n }\n\n return body;\n}\n","import { Command } from \"commander\";\nimport { cwd } from \"node:process\";\nimport { VERSION } from \"../types/brand.js\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport { runAuthLogin, runAuthLogout } from \"../commands/auth.js\";\nimport { runScanCommand } from \"../commands/scan.js\";\nimport { runScansListCommand, runScanGetCommand } from \"../commands/scans.js\";\nimport { runStatusCommand } from \"../commands/status.js\";\nimport { runConfigGet, runConfigSet, runConfigList } from \"../commands/config.js\";\nimport { handleCommandError, exitWith } from \"./exit.js\";\nimport type { RiskLevel } from \"../lib/risk.js\";\nimport type { OutputFormat } from \"../lib/output.js\";\nimport { loadProjectConfig } from \"../lib/project-config.js\";\n\nexport function buildProgram(): Command {\n const program = new Command(\"fuzzi\")\n .name(\"fuzzi\")\n .description(\"Fuzzi security scanner CLI — interactive shell and scriptable commands\")\n .version(VERSION);\n\n const auth = program.command(\"auth\").description(\"Authentication\");\n\n auth\n .command(\"login\")\n .description(\"Sign in via browser (default) or API key\")\n .option(\"--browser\", \"Sign in via browser (default when interactive)\")\n .option(\"--api-key <key>\", \"Paste an API key (fz_live_...)\")\n .action(async (opts) => {\n try {\n const useApiKey = !!opts.apiKey;\n console.log(\n await runAuthLogin({\n apiKey: opts.apiKey,\n interactive: !opts.apiKey,\n browser: !useApiKey,\n apiKeyOnly: useApiKey,\n }),\n );\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n auth.command(\"logout\").description(\"Clear stored credentials\").action(async () => {\n console.log(await runAuthLogout());\n });\n\n auth.command(\"status\").description(\"Show auth status\").action(async () => {\n try {\n const client = await getAuthenticatedClient();\n console.log(await runStatusCommand(client));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n program\n .command(\"scan [url]\")\n .description(\"Scan a URL (waits for completion by default)\")\n .option(\"-t, --title <title>\", \"Scan title\")\n .option(\"-e, --env <env>\", \"production|staging|development\")\n .option(\"-w, --wait\", \"Poll until scan completes (default)\")\n .option(\"--no-wait\", \"Return immediately with scan ID\")\n .option(\"-f, --format <format>\", \"table|json|markdown\", \"table\")\n .option(\"--fail-on <level>\", \"Exit 1 if risk >= level (low|medium|high|critical)\")\n .option(\"--fail-threshold <n>\", \"Exit 1 if risk_score >= threshold (0.0-1.0)\", parseFloat)\n .action(async (urlArg, opts) => {\n try {\n const project = await loadProjectConfig(cwd());\n const url = urlArg || project?.scan?.url;\n if (!url) {\n console.error(\"Usage: fuzzi scan <url>\");\n exitWith(2);\n }\n const client = await getAuthenticatedClient();\n const result = await runScanCommand(client, {\n url,\n wait: opts.wait,\n noWait: opts.noWait,\n format: opts.format as OutputFormat,\n environment: opts.env,\n title: opts.title,\n failOn: opts.failOn as RiskLevel | undefined,\n failThreshold: opts.failThreshold,\n });\n console.log(result.output);\n exitWith(result.exitCode);\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n const scans = program.command(\"scans\").description(\"Browse scans\");\n\n scans\n .command(\"list\")\n .description(\"List recent scans\")\n .option(\"--status <status>\", \"pending|running|completed|failed\")\n .option(\"--risk-level <level>\", \"low|medium|high|critical\")\n .option(\"--limit <n>\", \"Max results\", \"20\")\n .option(\"-f, --format <format>\", \"table|json|markdown\", \"table\")\n .action(async (opts) => {\n try {\n const client = await getAuthenticatedClient();\n console.log(\n await runScansListCommand(client, opts.format as OutputFormat, {\n status: opts.status,\n riskLevel: opts.riskLevel,\n limit: parseInt(opts.limit, 10),\n }),\n );\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n scans\n .command(\"get <scan-id>\")\n .description(\"Get scan details\")\n .option(\"-f, --format <format>\", \"table|json|markdown\", \"table\")\n .action(async (scanId, opts) => {\n try {\n const client = await getAuthenticatedClient();\n console.log(await runScanGetCommand(client, scanId, opts.format as OutputFormat));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n program\n .command(\"report <scan-id>\")\n .description(\"Download a scan report\")\n .requiredOption(\"--format <format>\", \"pdf|csv|json\")\n .option(\"-o, --output <path>\", \"Output file path\")\n .action(async (scanId, opts) => {\n try {\n const { runReportCommand } = await import(\"../commands/report.js\");\n const client = await getAuthenticatedClient();\n console.log(await runReportCommand(client, scanId, opts.format, opts.output));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n program\n .command(\"whatif <scan-id>\")\n .description(\"Simulate factor overrides\")\n .option(\"--set <pair>\", \"dimension=value (repeatable)\", (v, prev: string[]) => [...prev, v], [])\n .option(\"-f, --format <format>\", \"table|json\", \"table\")\n .action(async (scanId, opts) => {\n try {\n const { runWhatIfCommand } = await import(\"../commands/whatif.js\");\n const overrides: Record<string, number> = {};\n for (const pair of opts.set as string[]) {\n const [k, val] = pair.split(\"=\");\n if (k && val) overrides[k] = parseFloat(val);\n }\n console.log(await runWhatIfCommand(scanId, overrides, opts.format as OutputFormat));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n program\n .command(\"compare <scan-a> <scan-b>\")\n .description(\"Compare two scans\")\n .option(\"-f, --format <format>\", \"table|json\", \"table\")\n .action(async (scanA, scanB, opts) => {\n try {\n const { runCompareCommand } = await import(\"../commands/compare.js\");\n console.log(await runCompareCommand(scanA, scanB, opts.format as OutputFormat));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n const config = program.command(\"config\").description(\"CLI configuration (~/.fuzzi/config)\");\n\n config.command(\"list\").action(async () => console.log(await runConfigList()));\n config.command(\"get [key]\").action(async (key) => console.log(await runConfigGet(key)));\n config\n .command(\"set <key> <value>\")\n .action(async (key, value) => console.log(await runConfigSet(key, value)));\n\n program.command(\"status\").description(\"Show account status\").action(async () => {\n try {\n const client = await getAuthenticatedClient();\n console.log(await runStatusCommand(client));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n return program;\n}\n","import { password, input, confirm } from \"@inquirer/prompts\";\nimport { saveCredentials, clearCredentials } from \"../lib/credentials.js\";\nimport { ApiError, FuzziApiClient, getAuthenticatedClient } from \"../lib/api-client.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { isValidApiKeyFormat, maskApiKey } from \"../lib/credentials.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { success, muted, accent } from \"../terminal/theme.js\";\nimport { openCliAuthPage } from \"../lib/browser-auth.js\";\nimport { SETTINGS_API_KEYS_URL } from \"../types/brand.js\";\nimport { runInteractive } from \"../terminal/interactive.js\";\n\nexport interface AuthLoginOptions {\n apiKey?: string;\n interactive?: boolean;\n browser?: boolean;\n apiKeyOnly?: boolean;\n}\n\nexport interface AssistedLoginResult {\n message: string;\n profile: UserProfile;\n}\n\n/**\n * Opens the web authorize page, then prompts to paste the API key shown there.\n * Matches the current fuzzi-ten.vercel.app flow (manual key handoff).\n */\nexport async function runAssistedBrowserLogin(): Promise<AssistedLoginResult> {\n await openCliAuthPage();\n console.log(\"\");\n console.log(accent(\" Browser opened — authorize Fuzzi CLI on the web page.\"));\n console.log(muted(\" Copy the API key shown, then paste it below.\"));\n console.log(\"\");\n const msg = await runApiKeyLogin({ interactive: true });\n const client = await getAuthenticatedClient();\n const profile = await client.get<UserProfile>(\"/me\");\n return { message: msg, profile };\n}\n\nexport async function runAuthLogin(opts: AuthLoginOptions = {}): Promise<string> {\n if (opts.apiKeyOnly || opts.apiKey) {\n return runApiKeyLogin(opts);\n }\n\n if (opts.browser || opts.interactive !== false) {\n const result = await runAssistedBrowserLogin();\n return result.message;\n }\n\n return runApiKeyLogin(opts);\n}\n\nexport async function runApiKeyLogin(opts: AuthLoginOptions = {}): Promise<string> {\n const config = await loadConfig();\n const client = new FuzziApiClient(config.api_url);\n\n let apiKey = opts.apiKey?.trim();\n\n if (!apiKey) {\n if (opts.interactive === false) {\n throw new ApiError(\n \"No API key provided. Run fuzzi auth login or sign in via browser.\",\n 401,\n \"missing_key\",\n undefined,\n 2,\n );\n }\n apiKey = await runInteractive(() =>\n password({\n message: \"Paste your API key (fz_live_...):\",\n mask: \"•\",\n validate: (v) => {\n if (!v.trim()) return \"API key is required\";\n if (!isValidApiKeyFormat(v)) return \"Key must start with fz_live_\";\n return true;\n },\n }),\n );\n }\n\n apiKey = apiKey.trim();\n if (!isValidApiKeyFormat(apiKey)) {\n throw new ApiError(\n `Invalid API key format. Generate a new one at ${SETTINGS_API_KEYS_URL}`,\n 401,\n \"invalid_key_format\",\n undefined,\n 2,\n );\n }\n\n client.setToken(apiKey);\n const valid = await client.validateToken();\n if (!valid) {\n throw new ApiError(\n `Invalid API key. Generate a new one at ${SETTINGS_API_KEYS_URL}`,\n 401,\n \"invalid_token\",\n undefined,\n 2,\n );\n }\n\n const profile = await client.get<UserProfile>(\"/me\");\n await saveCredentials({\n api_key: apiKey,\n auth_method: \"api_key\",\n key_prefix: profile.key_prefix || maskApiKey(apiKey),\n key_expires_at: profile.key_expires_at || undefined,\n email: profile.email,\n full_name: profile.full_name || undefined,\n saved_at: new Date().toISOString(),\n });\n\n const name = profile.full_name || profile.email;\n return success(`Authenticated as ${name}`);\n}\n\nexport async function runAuthLogout(): Promise<string> {\n await clearCredentials();\n return muted(\"You are now logged out.\");\n}\n\nexport async function promptNewKeyName(): Promise<string> {\n return input({\n message: \"Key name:\",\n validate: (v) => (v.trim().length > 0 ? true : \"Name is required\"),\n });\n}\n\nexport async function confirmBrowserLogin(): Promise<boolean> {\n return confirm({\n message: \"Open browser to sign in?\",\n default: true,\n });\n}\n","import { randomBytes } from \"node:crypto\";\nimport { createServer } from \"node:http\";\nimport { loadConfig } from \"./config.js\";\nimport { saveCredentials, maskApiKey } from \"./credentials.js\";\nimport { FuzziApiClient, ApiError } from \"./api-client.js\";\nimport { APP_ORIGIN } from \"../types/brand.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { log } from \"./logger.js\";\nimport { openBrowser } from \"./platform.js\";\n\nconst CALLBACK_TIMEOUT_MS = 90_000;\n\nexport interface BrowserLoginResult {\n message: string;\n profile: UserProfile;\n}\n\ninterface HandoffResponse {\n api_key: string;\n prefix?: string;\n expires_at?: string | null;\n}\n\nfunction generateState(): string {\n return randomBytes(24).toString(\"base64url\");\n}\n\nfunction apiOrigin(apiUrl: string): string {\n return apiUrl.replace(/\\/api\\/?$/, \"\") || APP_ORIGIN;\n}\n\nexport { openBrowser } from \"./platform.js\";\n\n/** Open the web authorize page (no localhost callback required). */\nexport async function openCliAuthPage(): Promise<string> {\n const config = await loadConfig();\n const url = `${apiOrigin(config.api_url)}/cli-auth`;\n openBrowser(url);\n log.debug(\"opened cli auth page\", url);\n return url;\n}\n\nasync function saveProfileFromKey(apiKey: string, handoff?: HandoffResponse): Promise<BrowserLoginResult> {\n const config = await loadConfig();\n const client = new FuzziApiClient(config.api_url);\n client.setToken(apiKey);\n const profile = await client.get<UserProfile>(\"/me\");\n\n await saveCredentials({\n api_key: apiKey,\n auth_method: \"api_key\",\n key_prefix: handoff?.prefix || profile.key_prefix || maskApiKey(apiKey),\n key_expires_at: handoff?.expires_at || profile.key_expires_at || undefined,\n email: profile.email,\n full_name: profile.full_name || undefined,\n saved_at: new Date().toISOString(),\n });\n\n const name = profile.full_name || profile.email;\n return { message: `Signed in as ${name}`, profile };\n}\n\n/** Automatic callback flow (when web redirects to localhost). */\nexport async function runBrowserCallbackLogin(): Promise<BrowserLoginResult> {\n const config = await loadConfig();\n const state = generateState();\n\n const handoffToken = await new Promise<string>((resolve, reject) => {\n const server = createServer((req, res) => {\n try {\n const addr = server.address();\n const port = typeof addr === \"object\" && addr ? addr.port : 0;\n const url = new URL(req.url ?? \"/\", `http://127.0.0.1:${port}`);\n\n if (url.pathname !== \"/callback\") {\n res.writeHead(404);\n res.end();\n return;\n }\n\n const token = url.searchParams.get(\"token\");\n const returnedState = url.searchParams.get(\"state\");\n if (!token || returnedState !== state) {\n res.writeHead(400);\n res.end(\"Invalid callback\");\n reject(new ApiError(\"Invalid sign-in callback.\", 400, \"invalid_callback\", undefined, 2));\n return;\n }\n\n res.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(`<!DOCTYPE html><html><body style=\"font-family:system-ui;text-align:center;padding:48px\">\n <h1>Signed in to Fuzzi CLI</h1><p>Return to your terminal.</p>\n <script>setTimeout(()=>window.close(),1200)</script></body></html>`);\n clearTimeout(timer);\n server.close();\n resolve(token);\n } catch (e) {\n clearTimeout(timer);\n server.close();\n reject(e);\n }\n });\n\n const timer = setTimeout(() => {\n server.close();\n reject(new ApiError(\"callback_timeout\", 408, \"auth_timeout\", undefined, 2));\n }, CALLBACK_TIMEOUT_MS);\n\n server.listen(0, \"127.0.0.1\", () => {\n const addr = server.address();\n const port = typeof addr === \"object\" && addr ? addr.port : 0;\n const loginUrl = `${apiOrigin(config.api_url)}/cli-auth?state=${encodeURIComponent(state)}&callback_port=${port}`;\n openBrowser(loginUrl);\n log.debug(\"browser callback auth\", loginUrl);\n });\n\n server.on(\"error\", (e) => {\n clearTimeout(timer);\n reject(e);\n });\n });\n\n const client = new FuzziApiClient(config.api_url);\n const handoff = await client.post<HandoffResponse>(\"/cli/handoff\", {\n handoff_token: handoffToken,\n state,\n });\n\n if (!handoff.api_key) {\n throw new ApiError(\"Sign-in failed: no API key returned.\", 500, \"handoff_failed\", undefined, 2);\n }\n\n return saveProfileFromKey(handoff.api_key, handoff);\n}\n\n/** @deprecated alias */\nexport const runBrowserLogin = runBrowserCallbackLogin;\n","import { spawn } from \"node:child_process\";\nimport { stdout, stderr } from \"node:process\";\n\n/** Enable ANSI colors and UTF-8 on Windows consoles (Windows Terminal, PowerShell, cmd). */\nexport function configurePlatform(): void {\n if (process.platform !== \"win32\") return;\n\n try {\n if (stdout.isTTY) enableWindowsVtMode(stdout);\n if (stderr.isTTY) enableWindowsVtMode(stderr);\n } catch {\n /* best effort */\n }\n}\n\nfunction enableWindowsVtMode(stream: NodeJS.WriteStream): void {\n const handle = (stream as NodeJS.WriteStream & { _handle?: { setMode?: (mode: number) => void; mode?: number } })\n ._handle;\n if (!handle?.setMode || handle.mode == null) return;\n // ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004\n handle.setMode(handle.mode | 0x0004);\n}\n\n/** Open a URL in the user's default browser (cross-platform). */\nexport function openBrowser(url: string): void {\n const platform = process.platform;\n\n if (platform === \"win32\") {\n // `start` is a cmd builtin — must run through cmd.exe\n spawn(\"cmd\", [\"/c\", \"start\", \"\", url], {\n detached: true,\n stdio: \"ignore\",\n windowsHide: true,\n }).unref();\n return;\n }\n\n if (platform === \"darwin\") {\n spawn(\"open\", [url], { detached: true, stdio: \"ignore\" }).unref();\n return;\n }\n\n spawn(\"xdg-open\", [url], { detached: true, stdio: \"ignore\" }).unref();\n}\n\nexport function isWindows(): boolean {\n return process.platform === \"win32\";\n}\n","import { select, search } from \"@inquirer/prompts\";\nimport { accent, muted } from \"./theme.js\";\n\nlet pauseHook: (() => void) | null = null;\nlet resumeHook: (() => void) | null = null;\n\nexport function setReadlineHooks(pause: () => void, resume: () => void): void {\n pauseHook = pause;\n resumeHook = resume;\n}\n\n/** Pause readline while @inquirer prompts run (prevents broken `> >` prompt). */\nexport async function runInteractive<T>(fn: () => Promise<T>): Promise<T> {\n return withReadlinePaused(fn);\n}\n\nasync function withReadlinePaused<T>(fn: () => Promise<T>): Promise<T> {\n pauseHook?.();\n try {\n return await fn();\n } finally {\n resumeHook?.();\n }\n}\n\nexport async function pickFromList<T extends { name: string; value: string }>(\n message: string,\n items: T[],\n): Promise<string | null> {\n if (!items.length) return null;\n try {\n return await withReadlinePaused(() => select({ message, choices: items }));\n } catch {\n return null;\n }\n}\n\nexport async function searchPalette(\n message: string,\n choices: Array<{ name: string; value: string; description?: string }>,\n): Promise<string | null> {\n try {\n return await withReadlinePaused(() =>\n search({\n message,\n source: async (input) => {\n if (!input) return choices;\n const q = input.toLowerCase();\n return choices.filter(\n (c) =>\n c.value.toLowerCase().includes(q) ||\n String(c.description ?? \"\").toLowerCase().includes(q),\n );\n },\n }),\n );\n } catch {\n return null;\n }\n}\n\nexport function formatChoice(name: string, description: string): string {\n return `${accent(name)}${muted(\" — \" + description)}`;\n}\n","import { riskColor, accent, muted, bold, scoreBold, warn } from \"../terminal/theme.js\";\nimport { createTable } from \"../terminal/table.js\";\nimport { formatTimestamp, hostnameFromUrl, truncate } from \"../terminal/strings.js\";\nimport { panel, divider } from \"../terminal/layout.js\";\nimport type { ScanDetail, ScanSummary } from \"../types/api.js\";\n\nexport type OutputFormat = \"table\" | \"json\" | \"markdown\";\n\nexport function formatScanDate(scan: ScanDetail | ScanSummary): string {\n return formatTimestamp(\"created_at\" in scan ? scan.created_at : undefined);\n}\n\nexport function renderScanResult(scan: ScanDetail, format: OutputFormat): string {\n if (format === \"json\") return JSON.stringify(buildScanJson(scan), null, 2);\n if (format === \"markdown\") return renderScanMarkdown(scan);\n return renderScanTable(scan);\n}\n\nfunction buildScanJson(scan: ScanDetail) {\n const fr = scan.fuzzy_result;\n return {\n scan: {\n id: scan.id,\n target_url: scan.target_url,\n status: scan.status,\n risk_level: fr?.risk_level ?? null,\n risk_score: fr?.risk_score ?? null,\n overall_score: fr?.overall_score ?? null,\n },\n factors: scan.factors ?? [],\n recommendations: scan.recommendations ?? [],\n };\n}\n\nfunction levelIndicator(level: string): string {\n if (level === \"LOW\") return muted(\"ok\");\n return warn(\"!\");\n}\n\nexport function renderScanTable(scan: ScanDetail): string {\n const fr = scan.fuzzy_result;\n const rc = riskColor(fr?.risk_level);\n const lines: string[] = [];\n\n lines.push(panel([\n bold(scan.target_url),\n fr ? `${rc(\"Risk\")} ${rc(fr.risk_level)} ${muted(\"Score\")} ${scoreBold(fr.overall_score)}/100` : \"\",\n `${muted(\"Date\")} ${formatScanDate(scan)}`,\n scan.status === \"completed_inconclusive\" ? warn(\"Inconclusive — indicative only\") : \"\",\n ].filter(Boolean).join(\"\\n\"), { title: \"Scan result\" }));\n\n if (scan.factors?.length) {\n const rows = [...scan.factors]\n .sort((a, b) => a.score_100 - b.score_100)\n .map((f) => {\n const inc = f.details?.inconclusive;\n return [\n f.name.replace(/_/g, \" \"),\n inc ? muted(\"—\") : `${f.score_100}/100`,\n inc ? muted(\"n/a\") : `${riskColor(f.linguistic_value)(f.linguistic_value)} ${levelIndicator(f.linguistic_value)}`,\n ];\n });\n lines.push(\"\", createTable([\"Dimension\", \"Score\", \"Level\"], rows));\n }\n\n if (scan.recommendations?.length) {\n lines.push(\"\", accent(\"Findings\"));\n scan.recommendations.forEach((r, i) => {\n lines.push(` ${muted(String(i + 1).padStart(2))} ${riskColor(r.severity.toUpperCase())(`[${r.severity.toUpperCase()}]`)} ${r.title}`);\n });\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\nexport function renderScanMarkdown(scan: ScanDetail): string {\n const fr = scan.fuzzy_result;\n const host = hostnameFromUrl(scan.target_url);\n const lines: string[] = [`## Fuzzi Security Scan: ${host}`, \"\"];\n\n if (fr) lines.push(`**Risk Level:** ${fr.risk_level} (${fr.overall_score}/100)`, \"\");\n\n if (scan.factors?.length) {\n lines.push(\"| Dimension | Score | Level |\", \"|-----------|-------|-------|\");\n for (const f of scan.factors) {\n lines.push(`| ${f.name.replace(/_/g, \" \")} | ${f.score_100}/100 | ${f.linguistic_value} |`);\n }\n lines.push(\"\");\n }\n\n if (scan.recommendations?.length) {\n lines.push(\"### Findings\");\n scan.recommendations.forEach((r, i) => {\n lines.push(`${i + 1}. [${r.severity.toUpperCase()}] ${r.title}`);\n });\n }\n return lines.join(\"\\n\");\n}\n\nexport function renderScansList(scans: ScanSummary[], format: OutputFormat): string {\n if (format === \"json\") return JSON.stringify(scans, null, 2);\n if (format === \"markdown\") {\n if (!scans.length) return \"No scans found.\";\n const lines = [\"| URL | Status | Risk | Score | Date |\", \"|-----|--------|------|-------|------|\"];\n for (const s of scans) {\n lines.push(`| ${s.target_url} | ${s.status} | ${s.risk_level || \"—\"} | ${s.overall_score ?? \"—\"} | ${formatScanDate(s)} |`);\n }\n return lines.join(\"\\n\");\n }\n if (!scans.length) return muted(\"No scans found.\");\n\n const rows = scans.map((s) => [\n truncate(s.target_url, 40),\n s.status === \"completed_inconclusive\" ? warn(\"inconcl.\") : s.status,\n s.risk_level ? riskColor(s.risk_level)(s.risk_level) : muted(\"—\"),\n s.overall_score != null ? scoreBold(s.overall_score) : muted(\"—\"),\n muted(formatScanDate(s)),\n ]);\n return createTable([\"URL\", \"Status\", \"Risk\", \"Score\", \"Date\"], rows);\n}\n","import type { OutputFormat } from \"../lib/output.js\";\nimport { renderScanResult } from \"../lib/output.js\";\nimport { ApiError, FuzziApiClient } from \"../lib/api-client.js\";\nimport type { ScanCreateResponse, ScanDetail } from \"../types/api.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { success, muted } from \"../terminal/theme.js\";\nimport { validateUrl } from \"../lib/errors.js\";\nimport { riskMeetsThreshold, type RiskLevel } from \"../lib/risk.js\";\nimport { loadProjectConfig } from \"../lib/project-config.js\";\nimport { createProgress } from \"../terminal/progress.js\";\nimport { hostnameFromUrl } from \"../terminal/strings.js\";\nimport { withRetry } from \"../lib/retry.js\";\nimport { log } from \"../lib/logger.js\";\nimport { cwd } from \"node:process\";\n\nexport interface ScanCommandOptions {\n url: string;\n format?: OutputFormat;\n wait?: boolean;\n noWait?: boolean;\n environment?: string;\n title?: string;\n failOn?: RiskLevel;\n failThreshold?: number;\n onProgress?: (message: string) => void;\n streamProgress?: boolean;\n}\n\nexport interface ScanCommandResult {\n output: string;\n exitCode: 0 | 1 | 2;\n scan?: ScanDetail;\n}\n\nconst TERMINAL_STATUSES = new Set([\"completed\", \"completed_inconclusive\", \"failed\"]);\nconst POLL_INTERVAL_MS = 3000;\n\nexport async function pollScan(\n client: FuzziApiClient,\n scanId: string,\n onTick?: (elapsed: number, status: string) => void,\n maxWaitMs = 300_000,\n): Promise<ScanDetail> {\n const start = Date.now();\n let last = \"pending\";\n while (Date.now() - start < maxWaitMs) {\n const detail = await withRetry(() => client.get<ScanDetail>(`/scan/${scanId}`));\n last = detail.status;\n onTick?.(Math.floor((Date.now() - start) / 1000), last);\n if (TERMINAL_STATUSES.has(detail.status)) {\n if (detail.status === \"failed\") {\n throw new ApiError(\n `Scan failed: ${detail.inconclusive_message || detail.inconclusive_reason || \"unknown error\"}`,\n 500,\n \"scan_failed\",\n detail,\n 2,\n );\n }\n return detail;\n }\n await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));\n }\n throw new ApiError(`Scan timed out after ${maxWaitMs / 1000}s (last status: ${last})`, 408, \"scan_timeout\", undefined, 2);\n}\n\nfunction resolveFormat(format?: OutputFormat, projectFormat?: OutputFormat): OutputFormat {\n return format || projectFormat || \"table\";\n}\n\nfunction computeExitCode(scan: ScanDetail, opts: ScanCommandOptions): 0 | 1 | 2 {\n const fr = scan.fuzzy_result;\n if (!fr) return 0;\n if (opts.failThreshold != null && fr.risk_score >= opts.failThreshold) return 1;\n if (opts.failOn && riskMeetsThreshold(fr.risk_level, opts.failOn)) return 1;\n return 0;\n}\n\nexport async function runScanCommand(\n client: FuzziApiClient,\n opts: ScanCommandOptions,\n): Promise<ScanCommandResult> {\n const urlError = validateUrl(opts.url);\n if (urlError) throw new ApiError(urlError, 400, \"invalid_url\", undefined, 2);\n\n const projectConfig = await loadProjectConfig(cwd());\n const config = await loadConfig();\n const format = resolveFormat(opts.format, projectConfig?.output?.format || config.default_format);\n const env = opts.environment || projectConfig?.scan?.environment || config.default_env || \"production\";\n const failOn = opts.failOn || (projectConfig?.scan?.fail_on as RiskLevel | undefined);\n const shouldWait = opts.noWait ? false : opts.wait !== false;\n\n const body: Record<string, string> = { url: opts.url, environment: env };\n if (opts.title || projectConfig?.scan?.title) {\n body.title = opts.title || projectConfig?.scan?.title || \"\";\n }\n\n log.debug(\"creating scan\", { url: opts.url, env });\n const created = await withRetry(() => client.post<ScanCreateResponse>(\"/scan\", body));\n\n if (!shouldWait) {\n const output =\n format === \"json\"\n ? JSON.stringify(created, null, 2)\n : [success(\"Scan started\"), muted(`ID: ${created.scan_id}`), muted(created.message)].join(\"\\n\");\n return { output, exitCode: 0 };\n }\n\n const host = hostnameFromUrl(opts.url);\n const progress = opts.onProgress\n ? { update: opts.onProgress, stop: () => {}, succeed: () => {}, fail: () => {} }\n : createProgress(`Scanning ${host}...`, opts.streamProgress);\n\n const detail = await pollScan(client, created.scan_id, (sec, status) => {\n progress.update(`Scanning ${host}... (${sec}s) ${muted(status)}`);\n });\n\n progress.succeed(`Scan complete — ${host}`);\n\n const exitCode = computeExitCode(detail, { ...opts, failOn });\n return { output: renderScanResult(detail, format), exitCode, scan: detail };\n}\n","import { ApiError } from \"./api-client.js\";\nimport { APP_HOST } from \"../types/brand.js\";\n\nexport type ExitCode = 0 | 1 | 2;\n\nexport function formatApiError(err: unknown): string {\n if (err instanceof ApiError) {\n return err.message;\n }\n if (err instanceof Error) {\n if (err.message.includes(\"fetch failed\") || err.message.includes(\"ECONNREFUSED\")) {\n return `Could not connect to ${APP_HOST}. Check your internet connection or try again later.`;\n }\n return `An error occurred: ${err.message}. Please report this at https://github.com/fuzzi-cli/fuzzi-cli/issues`;\n }\n return `An error occurred: ${String(err)}. Please report this at https://github.com/fuzzi-cli/fuzzi-cli/issues`;\n}\n\nexport function getExitCode(err: unknown): ExitCode {\n if (err instanceof ApiError && err.exitCode !== undefined) {\n return err.exitCode as ExitCode;\n }\n return 2;\n}\n\nexport function validateUrl(url: string): string | null {\n try {\n const parsed = new URL(url);\n if (![\"http:\", \"https:\"].includes(parsed.protocol)) {\n return \"Invalid URL. Please provide a valid URL starting with http:// or https://\";\n }\n return null;\n } catch {\n return \"Invalid URL. Please provide a valid URL starting with http:// or https://\";\n }\n}\n","export type RiskLevel = \"LOW\" | \"MEDIUM\" | \"HIGH\" | \"CRITICAL\";\n\nconst RISK_ORDER: Record<RiskLevel, number> = {\n LOW: 0,\n MEDIUM: 1,\n HIGH: 2,\n CRITICAL: 3,\n};\n\nexport function normalizeRiskLevel(level: string | null | undefined): RiskLevel | null {\n if (!level) return null;\n const upper = level.toUpperCase() as RiskLevel;\n return upper in RISK_ORDER ? upper : null;\n}\n\nexport function riskMeetsThreshold(\n actual: string | null | undefined,\n threshold: RiskLevel,\n): boolean {\n const a = normalizeRiskLevel(actual);\n const t = normalizeRiskLevel(threshold);\n if (!a || !t) return false;\n return RISK_ORDER[a] >= RISK_ORDER[t];\n}\n\nexport function parseRiskLevel(value: string): RiskLevel | null {\n return normalizeRiskLevel(value);\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { existsSync } from \"node:fs\";\n\nexport interface ProjectConfig {\n scan?: {\n url?: string;\n environment?: \"production\" | \"staging\" | \"development\";\n fail_on?: string;\n title?: string;\n };\n output?: {\n format?: \"table\" | \"json\" | \"markdown\";\n };\n}\n\nfunction parseTomlSimple(raw: string): ProjectConfig {\n const config: ProjectConfig = { scan: {}, output: {} };\n let section = \"\";\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const sectionMatch = trimmed.match(/^\\[([^\\]]+)\\]$/);\n if (sectionMatch) {\n section = sectionMatch[1];\n continue;\n }\n const kv = trimmed.match(/^(\\w+)\\s*=\\s*\"?([^\"]+)\"?$/);\n if (!kv) continue;\n const [, key, value] = kv;\n if (section === \"scan\" || section === \"scan.scan\") {\n config.scan ??= {};\n if (key === \"url\") config.scan.url = value;\n else if (key === \"environment\") config.scan.environment = value as \"production\" | \"staging\" | \"development\";\n else if (key === \"fail_on\") config.scan.fail_on = value;\n else if (key === \"title\") config.scan.title = value;\n } else if (section === \"output\") {\n config.output ??= {};\n if (key === \"format\") config.output.format = value as \"table\" | \"json\" | \"markdown\";\n }\n }\n return config;\n}\n\nexport async function loadProjectConfig(cwd: string): Promise<ProjectConfig | null> {\n const fuzzirc = join(cwd, \".fuzzirc\");\n const fuzzitoml = join(cwd, \"fuzzi.toml\");\n\n if (existsSync(fuzzirc)) {\n try {\n const raw = await readFile(fuzzirc, \"utf8\");\n return JSON.parse(raw) as ProjectConfig;\n } catch {\n return null;\n }\n }\n\n if (existsSync(fuzzitoml)) {\n try {\n const raw = await readFile(fuzzitoml, \"utf8\");\n return parseTomlSimple(raw);\n } catch {\n return null;\n }\n }\n\n return null;\n}\n","import ora, { type Ora } from \"ora\";\nimport { muted } from \"./theme.js\";\nimport { getCapabilities } from \"./capabilities.js\";\n\nexport interface ProgressHandle {\n update(message: string): void;\n succeed(message?: string): void;\n fail(message?: string): void;\n stop(): void;\n}\n\nexport function createProgress(label: string, stream = false): ProgressHandle {\n if (!getCapabilities().interactive) {\n return {\n update: () => {},\n succeed: () => {},\n fail: () => {},\n stop: () => {},\n };\n }\n\n if (stream) {\n let last = \"\";\n return {\n update(message: string) {\n if (last) process.stdout.write(\"\\r\\x1b[K\");\n last = message;\n process.stdout.write(muted(message));\n },\n succeed(message?: string) {\n if (last) process.stdout.write(\"\\r\\x1b[K\");\n if (message) process.stdout.write(muted(message) + \"\\n\");\n last = \"\";\n },\n fail(message?: string) {\n if (last) process.stdout.write(\"\\r\\x1b[K\");\n if (message) process.stdout.write(muted(message) + \"\\n\");\n last = \"\";\n },\n stop() {\n if (last) process.stdout.write(\"\\r\\x1b[K\");\n last = \"\";\n },\n };\n }\n\n let spinner: Ora | null = ora({\n text: label,\n color: \"cyan\",\n discardStdin: false,\n isEnabled: getCapabilities().interactive,\n }).start();\n return {\n update(message: string) {\n if (spinner) spinner.text = message;\n },\n succeed(message?: string) {\n if (spinner) {\n spinner.succeed(message);\n spinner = null;\n }\n },\n fail(message?: string) {\n if (spinner) {\n spinner.fail(message);\n spinner = null;\n }\n },\n stop() {\n if (spinner) {\n spinner.stop();\n spinner = null;\n }\n },\n };\n}\n\nexport async function withSpinner<T>(label: string, fn: () => Promise<T>): Promise<T> {\n const p = createProgress(label);\n try {\n const result = await fn();\n p.stop();\n return result;\n } catch (e) {\n p.fail();\n throw e;\n }\n}\n\nexport async function withSteps<T>(\n steps: Array<{ title: string; run: () => Promise<T> }>,\n): Promise<T> {\n let last: T | undefined;\n for (const step of steps) {\n const p = createProgress(step.title);\n try {\n last = await step.run();\n p.succeed(step.title);\n } catch (e) {\n p.fail(step.title);\n throw e;\n }\n }\n return last as T;\n}\n","import { log } from \"./logger.js\";\n\nexport interface RetryOptions {\n maxAttempts?: number;\n baseDelayMs?: number;\n retryOn?: (error: unknown) => boolean;\n}\n\nexport async function withRetry<T>(fn: () => Promise<T>, opts: RetryOptions = {}): Promise<T> {\n const max = opts.maxAttempts ?? 3;\n const base = opts.baseDelayMs ?? 500;\n const retryOn = opts.retryOn ?? ((e: unknown) => {\n const err = e as { status?: number };\n return err.status === 429 || err.status === 502 || err.status === 503;\n });\n\n let last: unknown;\n for (let attempt = 1; attempt <= max; attempt++) {\n try {\n return await fn();\n } catch (e) {\n last = e;\n if (attempt >= max || !retryOn(e)) throw e;\n const delay = base * Math.pow(2, attempt - 1);\n log.debug(`retry ${attempt}/${max} in ${delay}ms`);\n await new Promise((r) => setTimeout(r, delay));\n }\n }\n throw last;\n}\n","import type { OutputFormat } from \"../lib/output.js\";\nimport { renderScansList } from \"../lib/output.js\";\nimport { FuzziApiClient } from \"../lib/api-client.js\";\nimport type { ScanDetail, ScanSummary } from \"../types/api.js\";\nimport { renderScanResult } from \"../lib/output.js\";\nimport { asList } from \"../lib/api-utils.js\";\n\nexport interface ScansListFilters {\n status?: string;\n riskLevel?: string;\n limit?: number;\n}\n\nexport async function runScansListCommand(\n client: FuzziApiClient,\n format: OutputFormat = \"table\",\n filters?: ScansListFilters,\n): Promise<string> {\n const params = new URLSearchParams({ page: \"1\", page_size: String(filters?.limit || 20) });\n if (filters?.status) params.set(\"status\", filters.status);\n if (filters?.riskLevel) params.set(\"risk_level\", filters.riskLevel);\n\n const data = await client.get<ScanSummary[] | { results: ScanSummary[] }>(\n `/scans?${params.toString()}`,\n );\n return renderScansList(asList(data), format);\n}\n\nexport async function runScanGetCommand(\n client: FuzziApiClient,\n scanId: string,\n format: OutputFormat = \"table\",\n): Promise<string> {\n const detail = await client.get<ScanDetail>(`/scan/${scanId}`);\n return renderScanResult(detail, format);\n}\n","import { FuzziApiClient } from \"../lib/api-client.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { loadCredentials, maskApiKey } from \"../lib/credentials.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { panel, keyValue, divider } from \"../terminal/layout.js\";\nimport { muted } from \"../terminal/theme.js\";\n\nfunction daysUntil(dateStr: string): number {\n const diff = new Date(dateStr).getTime() - Date.now();\n return Math.max(0, Math.ceil(diff / (1000 * 60 * 60 * 24)));\n}\n\nexport async function runRateLimitStatus(client: FuzziApiClient): Promise<string | null> {\n try {\n const data = await client.get<{ limit?: number; remaining?: number; reset?: string }>(\"/rate-limit\");\n if (data.limit != null) {\n return `${data.remaining ?? \"?\"}/${data.limit} remaining`;\n }\n } catch {\n /* optional endpoint */\n }\n return null;\n}\n\nexport async function runStatusCommand(client: FuzziApiClient): Promise<string> {\n const creds = await loadCredentials();\n const profile = await client.get<UserProfile>(\"/me\");\n const keyExpiry = creds?.key_expires_at || profile.key_expires_at;\n const config = await loadConfig();\n const rate = await runRateLimitStatus(client);\n\n const rows: Array<[string, string]> = [\n [\"Name\", profile.full_name || profile.email.split(\"@\")[0]],\n [\"Email\", profile.email],\n [\"Organization\", profile.organization || muted(\"—\")],\n [\"Role\", profile.role],\n [\"Auth\", `API Key (${creds ? maskApiKey(creds.api_key) : \"—\"})`],\n ];\n\n if (keyExpiry) {\n const days = daysUntil(keyExpiry);\n rows.push([\"Key expires\", `${keyExpiry.slice(0, 10)} (${days}d remaining)`]);\n } else {\n rows.push([\"Key expires\", muted(\"No expiry\")]);\n }\n\n rows.push([\"API\", config.api_url]);\n if (rate) rows.push([\"Rate limit\", rate]);\n\n return [panel(keyValue(rows), { title: \"Account\" }), \"\", divider(), muted(\"Use /keys to manage API keys\")].join(\"\\n\");\n}\n\nexport { formatApiError } from \"../lib/errors.js\";\n","import { loadConfig, setConfigValue, getConfigValue, listConfigEntries } from \"../lib/config.js\";\nimport { accent, muted } from \"../lib/theme.js\";\n\nexport async function runConfigList(): Promise<string> {\n const entries = await listConfigEntries();\n const lines = Object.entries(entries).map(([k, v]) => ` ${k} = ${v}`);\n return lines.length ? [accent(\"Config (~/.fuzzi/config)\"), ...lines].join(\"\\n\") : muted(\"No config set.\");\n}\n\nexport async function runConfigGet(key?: string): Promise<string> {\n if (!key) return runConfigList();\n const value = await getConfigValue(key);\n if (value === undefined) return muted(`Config key not set: ${key}`);\n return value;\n}\n\nexport async function runConfigSet(key: string, value: string): Promise<string> {\n const allowed = [\"api_url\", \"default_env\", \"default_format\"];\n if (!allowed.includes(key)) {\n return muted(`Unknown config key: ${key}. Supported: ${allowed.join(\", \")}`);\n }\n await setConfigValue(key, value);\n return accent(\"Config updated.\");\n}\n\nexport async function runConfigShowApiUrl(): Promise<string> {\n const config = await loadConfig();\n return config.api_url;\n}\n","import { formatApiError, getExitCode } from \"../lib/errors.js\";\n\nexport function handleCommandError(e: unknown): never {\n console.error(formatApiError(e));\n process.exit(getExitCode(e));\n}\n\nexport function exitWith(code: 0 | 1 | 2): never {\n process.exit(code);\n}\n","import * as readline from \"node:readline/promises\";\nimport { stdin as input, stdout as output, cwd } from \"node:process\";\nimport { fetchHomeData, renderHomeScreen } from \"./home-screen.js\";\nimport { dispatchSlashCommand, normalizeInput } from \"./slash-commands.js\";\nimport { accent, muted } from \"../terminal/theme.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { appendHistory, loadHistory } from \"./session.js\";\nimport { buildCompleter } from \"./completer.js\";\nimport { SLASH_COMMANDS } from \"./registry.js\";\nimport { getCapabilities } from \"../terminal/capabilities.js\";\nimport { setReadlineHooks } from \"../terminal/interactive.js\";\n\nexport async function runPromptLoop(initialProfile: UserProfile | null): Promise<void> {\n let profile = initialProfile;\n const workDir = cwd();\n const history = await loadHistory();\n\n const refresh = async () => {\n if (getCapabilities().interactive) {\n process.stdout.write(\"\\x1b[2J\\x1b[H\");\n }\n const data = await fetchHomeData(profile);\n console.log(renderHomeScreen(data));\n console.log(\"\");\n };\n\n await refresh();\n\n const rl = readline.createInterface({\n input,\n output,\n terminal: true,\n completer: buildCompleter(SLASH_COMMANDS, history),\n historySize: 300,\n });\n\n rl.on(\"SIGINT\", () => {\n console.log(muted(\"\\nGoodbye!\"));\n rl.close();\n process.exit(0);\n });\n\n setReadlineHooks(\n () => rl.pause(),\n () => {\n process.stdout.write(\"\\n\");\n rl.resume();\n },\n );\n\n const prompt = () => process.stdout.write(accent(\"> \"));\n\n prompt();\n\n for await (const line of rl) {\n await appendHistory(line);\n history.push(line.trim());\n\n const sink = {\n write: (text: string) => console.log(text),\n error: (text: string) => console.error(text),\n clearLine: () => process.stdout.write(\"\\r\\x1b[K\"),\n };\n\n const normalized = normalizeInput(line);\n const result = await dispatchSlashCommand(normalized, {\n cwd: workDir,\n profile,\n sink,\n refresh,\n });\n\n if (result.profile) profile = result.profile;\n if (result.exit) {\n console.log(muted(\"Goodbye!\"));\n rl.close();\n break;\n }\n if (result.redraw) await refresh();\n\n prompt();\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { existsSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\n\n/** Resolve assets dir for dev, production, and global npm installs on all OSes. */\nexport function assetsDir(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n join(here, \"..\", \"assets\"), // dist/index.js or dist/lib → package/assets\n join(here, \"..\", \"..\", \"assets\"), // src/lib → package/assets\n join(here, \"assets\"),\n ];\n\n // When bundled as dist/index.js, walk up to package root\n try {\n const req = createRequire(import.meta.url);\n const pkgRoot = dirname(req.resolve(\"fuzzi-cli/package.json\"));\n candidates.unshift(join(pkgRoot, \"assets\"));\n } catch {\n /* not resolvable via package name — local dev paths above are enough */\n }\n\n for (const p of candidates) {\n if (existsSync(join(p, \"changelog.json\"))) return p;\n }\n return candidates[0];\n}\n\nexport function assetPath(name: string): string {\n return join(assetsDir(), name);\n}\n\nexport async function readAsset(name: string): Promise<string> {\n return readFile(assetPath(name), \"utf8\");\n}\n\n/** Resolve path for dynamic import on Windows (needs file:// URL). */\nexport function pathToImportUrl(path: string): string {\n return pathToFileURL(path).href;\n}\n","import { readAsset } from \"../lib/assets.js\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport { runRateLimitStatus } from \"../commands/status.js\";\nimport { renderFuzziMark } from \"./ascii-mark.js\";\nimport { VERSION, SETTINGS_API_KEYS_URL } from \"../types/brand.js\";\nimport {\n accent,\n accentBold,\n cmd,\n muted,\n primary,\n primaryBold,\n success,\n} from \"../terminal/theme.js\";\nimport { contentWidth, terminalWidth } from \"../terminal/width.js\";\nimport {\n topBanner,\n tripleColumnPanel,\n stackedPanels,\n tipPanel,\n besideMark,\n popularCommand,\n type ColumnSpec,\n} from \"../components/Panel.js\";\nimport type { ChangelogEntry, UserProfile } from \"../types/api.js\";\n\nexport interface HomeScreenStats {\n rateHour: string | null;\n usageMonth: string | null;\n}\n\nexport interface HomeScreenData {\n profile: UserProfile | null;\n changelog: ChangelogEntry[];\n stats: HomeScreenStats | null;\n}\n\nfunction daysUntil(dateStr: string): number {\n const diff = new Date(dateStr).getTime() - Date.now();\n return Math.max(0, Math.ceil(diff / (1000 * 60 * 60 * 24)));\n}\n\nfunction formatKeyExpiry(dateStr: string | null | undefined): string | null {\n if (!dateStr) return null;\n const days = daysUntil(dateStr);\n return `Key expires: ${days} days remaining`;\n}\n\nfunction formatKeyExpiryDate(dateStr: string | null | undefined): string | null {\n if (!dateStr) return null;\n return `(${dateStr.slice(0, 10)})`;\n}\n\nexport async function fetchHomeData(profile: UserProfile | null): Promise<HomeScreenData> {\n let changelog: ChangelogEntry[] = [];\n try {\n changelog = JSON.parse(await readAsset(\"changelog.json\")) as ChangelogEntry[];\n } catch {\n changelog = [];\n }\n\n let stats: HomeScreenStats | null = null;\n if (profile) {\n try {\n const client = await getAuthenticatedClient();\n const rateRaw = await runRateLimitStatus(client);\n let rateHour: string | null = null;\n if (rateRaw) {\n const m = rateRaw.match(/(\\d+)\\/(\\d+)/);\n if (m) {\n const remaining = Number(m[1]);\n const limit = Number(m[2]);\n const used = limit - remaining;\n rateHour = `${used}/${limit} scans this hour`;\n } else {\n rateHour = rateRaw;\n }\n }\n\n const used = profile.scans_used_this_month ?? profile.total_scans;\n const limit = profile.monthly_scan_limit;\n const usageMonth =\n used != null && limit != null\n ? `${used}/${limit} scans this month`\n : used != null\n ? `${used} scans total`\n : null;\n\n stats = { rateHour, usageMonth };\n } catch {\n stats = null;\n }\n }\n\n return { profile, changelog, stats };\n}\n\nfunction renderAccountColumn(data: HomeScreenData): string[] {\n const mark = accent(renderFuzziMark()).split(\"\\n\");\n\n if (data.profile) {\n const p = data.profile;\n const name = p.full_name || p.email.split(\"@\")[0];\n const keyExpiry = formatKeyExpiry(p.key_expires_at ?? undefined);\n const keyDate = formatKeyExpiryDate(p.key_expires_at ?? undefined);\n\n const textBlock: string[] = [\n primaryBold(`Welcome back, ${name}!`),\n primary(p.email),\n \"\",\n muted(`Organization: ${p.organization || \"—\"}`),\n muted(`Role: ${p.role}`),\n ];\n\n const beside = besideMark(mark, textBlock, 14, 4);\n const lines = [\"\", ...beside, \"\"];\n\n lines.push(success(\"● Connected\"));\n lines.push(muted(\"Status: Ready\"));\n\n if (data.stats?.rateHour) lines.push(muted(`Rate limit: ${data.stats.rateHour}`));\n if (data.stats?.usageMonth) lines.push(muted(`Usage: ${data.stats.usageMonth}`));\n\n if (keyExpiry) {\n lines.push(\"\");\n lines.push(muted(keyExpiry));\n if (keyDate) lines.push(muted(keyDate));\n }\n\n return lines;\n }\n\n const textBlock = [\n primaryBold(\"Welcome to Fuzzi!\"),\n muted(\"Not connected\"),\n \"\",\n muted(\"Press Enter to sign in\"),\n muted(\"or run /auth-key\"),\n ];\n\n return [\"\", ...besideMark(mark, textBlock, 14, 4), \"\"];\n}\n\nfunction renderQuickStartColumn(data: HomeScreenData): string[] {\n const lines = [\n \"\",\n muted(\"Type \") + cmd(\"/help\") + muted(\" for all\"),\n muted(\"commands.\"),\n \"\",\n primaryBold(\"Popular commands:\"),\n \"\",\n popularCommand(\"/scan\", \"Start a security scan\", 12),\n popularCommand(\"/scans\", \"Browse recent scans\", 12),\n popularCommand(\"/status\", \"Show account info\", 12),\n ];\n\n if (data.profile) {\n lines.push(\n popularCommand(\"/keys\", \"Manage API keys\", 12),\n popularCommand(\"/config\", \"CLI settings\", 12),\n );\n } else {\n lines.push(\n popularCommand(\"/auth\", \"Browser sign-in\", 12),\n popularCommand(\"/auth-key\", \"Paste API key\", 12),\n );\n }\n\n return lines;\n}\n\nfunction renderWhatsNewColumn(data: HomeScreenData): string[] {\n const lines = [\"\"];\n const highlights = data.changelog[0]?.highlights ?? [\n \"Confidence gating added\",\n \"Netflix-style false positives fixed\",\n \"CLI shell interface\",\n ];\n\n for (const h of highlights.slice(0, 4)) {\n const text = h.replace(/^✓\\s*/, \"\");\n lines.push(success(\"✓ \") + primary(text));\n }\n\n lines.push(\"\");\n lines.push(muted(\"Run \") + cmd(\"/changelog\") + muted(\" for more details.\"));\n\n return lines;\n}\n\nfunction renderTip(data: HomeScreenData): string {\n if (data.profile) {\n return muted(\"Tip: Run \") + cmd(\"/scan <url>\") + muted(\" to scan a target, or \") + cmd(\"/palette\") + muted(\" to find commands.\");\n }\n return (\n muted(\"Not logged in? Run \") +\n cmd(\"/auth-key\") +\n muted(\" to paste an API key from settings, or press Enter to sign in via browser.\")\n );\n}\n\nexport function renderHomeScreen(data: HomeScreenData): string {\n const width = contentWidth();\n const cols: [ColumnSpec, ColumnSpec, ColumnSpec] = [\n { title: \"Account\", lines: renderAccountColumn(data) },\n { title: \"Quick Start\", lines: renderQuickStartColumn(data) },\n { title: \"What's New\", lines: renderWhatsNewColumn(data) },\n ];\n\n const main =\n terminalWidth() >= 100\n ? tripleColumnPanel(cols, width)\n : stackedPanels(cols, width);\n\n return [topBanner(`Fuzzi CLI v${VERSION}`, width), \"\", main, \"\", tipPanel(renderTip(data), width)].join(\n \"\\n\",\n );\n}\n\nexport function renderChangelog(entries: ChangelogEntry[]): string {\n if (!entries.length) return muted(\"No changelog entries.\");\n return entries\n .map((e) => {\n const lines = [\n accentBold(`v${e.version}`) + muted(` — ${e.date}`),\n ...e.highlights.map((h) => success(\"✓ \") + primary(h.replace(/^✓\\s*/, \"\"))),\n ];\n return lines.join(\"\\n\");\n })\n .join(\"\\n\\n\");\n}\n\n/** Auth gate uses the same shell layout before login completes. */\nexport function renderAuthGateScreen(): string {\n return renderHomeScreen({\n profile: null,\n changelog: [],\n stats: null,\n });\n}\n\nexport { SETTINGS_API_KEYS_URL };\n","/** Teal diamond shield mascot — 8 lines, pair with accent(). */\nexport function renderFuzziMark(): string {\n return [\n \" ╔════╗\",\n \" ║ ◆ ║\",\n \" ╚═╦══╝\",\n \" ╔═╩═╗\",\n \" ║ ◆ ║\",\n \" ╚═══╝\",\n ].join(\"\\n\");\n}\n","import { border, cmd, muted } from \"../terminal/theme.js\";\nimport { padEndVisible } from \"../terminal/strings.js\";\nimport { contentWidth } from \"../terminal/width.js\";\n\nexport function visibleLen(s: string): number {\n return s.replace(/\\x1b\\[[0-9;]*m/g, \"\").length;\n}\n\nfunction padCell(content: string, width: number): string {\n const inner = width - 2;\n return \" \" + padEndVisible(content, inner) + \" \";\n}\n\n/** Heavy double-line top banner: ┏━━ Fuzzi CLI v0.1.3 ━━┓ */\nexport function topBanner(title: string, width = contentWidth()): string {\n const inner = ` ${title} `;\n const dashes = Math.max(0, width - 2 - visibleLen(inner));\n const left = Math.floor(dashes / 2);\n const right = dashes - left;\n return [\n border(`┏${\"━\".repeat(left)}${inner}${\"━\".repeat(right)}┓`),\n border(`┗${\"━\".repeat(width - 2)}┛`),\n ].join(\"\\n\");\n}\n\nexport interface ColumnSpec {\n title: string;\n lines: string[];\n}\n\nfunction titleSegment(title: string, width: number): string {\n const prefix = `─ ${title} `;\n const dashes = Math.max(0, width - visibleLen(prefix));\n return prefix + \"─\".repeat(dashes);\n}\n\n/** Three-column panel with shared top/bottom borders. */\nexport function tripleColumnPanel(\n cols: [ColumnSpec, ColumnSpec, ColumnSpec],\n totalWidth = contentWidth(),\n): string {\n const sep = 1;\n const inner = totalWidth - 2;\n const ratios = [0.44, 0.28, 0.28];\n const raw = ratios.map((r) => Math.floor(inner * r));\n const used = raw.reduce((a, b) => a + b, 0) + 2 * sep;\n raw[0] += inner - used;\n\n const widths = raw;\n const top =\n border(\"┌\") +\n titleSegment(cols[0].title, widths[0]) +\n border(\"┬\") +\n titleSegment(cols[1].title, widths[1]) +\n border(\"┬\") +\n titleSegment(cols[2].title, widths[2]) +\n border(\"┐\");\n\n const maxRows = Math.max(...cols.map((c) => c.lines.length), 1);\n const body: string[] = [top];\n\n for (let i = 0; i < maxRows; i++) {\n const cells = cols.map((c, idx) => padCell(c.lines[i] ?? \"\", widths[idx]));\n body.push(\n border(\"│\") +\n cells[0] +\n border(\"│\") +\n cells[1] +\n border(\"│\") +\n cells[2] +\n border(\"│\"),\n );\n }\n\n const bottom =\n border(\"└\") +\n border(\"─\".repeat(widths[0])) +\n border(\"┴\") +\n border(\"─\".repeat(widths[1])) +\n border(\"┴\") +\n border(\"─\".repeat(widths[2])) +\n border(\"┘\");\n\n body.push(bottom);\n return body.join(\"\\n\");\n}\n\n/** Stacked single-column panels for narrow terminals. */\nexport function stackedPanels(cols: ColumnSpec[], width = contentWidth()): string {\n return cols\n .map((col) => singlePanel(col.title, col.lines, width))\n .join(\"\\n\\n\");\n}\n\nexport function singlePanel(title: string, lines: string[], width = contentWidth()): string {\n const inner = width - 2;\n const prefix = `─ ${title} `;\n const dashes = Math.max(0, inner - visibleLen(prefix));\n const top = border(`┌${prefix}${\"─\".repeat(dashes)}┐`);\n const bottom = border(`└${\"─\".repeat(inner)}┘`);\n const body = lines.map((l) => border(\"│\") + padCell(l, inner + 2) + border(\"│\"));\n return [top, ...body, bottom].join(\"\\n\");\n}\n\nexport function tipPanel(text: string, width = contentWidth()): string {\n const inner = width - 2;\n const prefix = \"─ Tip \";\n const dashes = Math.max(0, inner - visibleLen(prefix));\n const top = border(`┌${prefix}${\"─\".repeat(dashes)}┐`);\n const bottom = border(`└${\"─\".repeat(inner)}┘`);\n return [top, border(\"│\") + padCell(text, inner + 2) + border(\"│\"), bottom].join(\"\\n\");\n}\n\n/** Place mark art beside text lines (Account column layout). */\nexport function besideMark(mark: string[], text: string[], markCol = 18, gap = 3): string[] {\n const rows = Math.max(mark.length, text.length);\n const out: string[] = [];\n for (let i = 0; i < rows; i++) {\n const m = padEndVisible(mark[i] ?? \"\", markCol);\n const t = text[i] ?? \"\";\n out.push(m + \" \".repeat(gap) + t);\n }\n return out;\n}\n\nexport function popularCommand(command: string, desc: string, cmdWidth = 14): string {\n return padEndVisible(cmd(command), cmdWidth) + muted(desc);\n}\n","import { confirm, input } from \"@inquirer/prompts\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport { runScanCommand } from \"../commands/scan.js\";\nimport { runScansListCommand } from \"../commands/scans.js\";\nimport { runStatusCommand, runRateLimitStatus } from \"../commands/status.js\";\nimport { runAssistedBrowserLogin, runApiKeyLogin, promptNewKeyName } from \"../commands/auth.js\";\nimport { runKeysListCommand, runKeyRevoke, pickKeyForRevoke } from \"../commands/keys.js\";\nimport { runConfigSet } from \"../commands/config.js\";\nimport { formatApiError } from \"../lib/errors.js\";\nimport { asList } from \"../lib/api-utils.js\";\nimport { readAsset } from \"../lib/assets.js\";\nimport { renderChangelog } from \"./home-screen.js\";\nimport { renderHelpScreen, renderHistoryScreen } from \"./help-screen.js\";\nimport { openCommandPalette } from \"./command-palette.js\";\nimport { pickFromList, runInteractive } from \"../terminal/interactive.js\";\nimport { findCommand } from \"./registry.js\";\nimport { loadHistory } from \"./session.js\";\nimport { accent, muted, success, error as errStyle } from \"../terminal/theme.js\";\nimport { emptyState } from \"../terminal/empty-state.js\";\nimport { errorBox, successBox } from \"../terminal/banner.js\";\nimport { truncate, formatTimestamp } from \"../terminal/strings.js\";\nimport { withSpinner } from \"../terminal/progress.js\";\nimport type { UserProfile, ScanSummary, ScanDetail } from \"../types/api.js\";\nimport type { OutputSink } from \"../terminal/sink.js\";\nimport { renderScanResult } from \"../lib/output.js\";\n\nexport interface SlashContext {\n cwd: string;\n profile: UserProfile | null;\n sink: OutputSink;\n refresh: () => Promise<void>;\n}\n\nexport interface SlashResult {\n exit?: boolean;\n redraw?: boolean;\n profile?: UserProfile | null;\n}\n\n/** Map bare CLI-style input to slash commands. */\nexport function normalizeInput(line: string): string {\n let t = line.trim();\n if (!t || t.startsWith(\"/\")) return t;\n\n if (t.toLowerCase().startsWith(\"fuzzi \")) t = t.slice(6).trim();\n\n const lower = t.toLowerCase();\n const aliases: Record<string, string> = {\n \"auth login\": \"/auth\",\n auth: \"/auth\",\n login: \"/auth\",\n \"auth-key\": \"/auth-key\",\n logout: \"/exit\",\n help: \"/help\",\n exit: \"/exit\",\n quit: \"/exit\",\n clear: \"/clear\",\n changelog: \"/changelog\",\n status: \"/status\",\n scans: \"/scans\",\n keys: \"/keys\",\n palette: \"/palette\",\n };\n if (aliases[lower]) return aliases[lower];\n\n if (lower.startsWith(\"scan \")) return `/scan ${t.slice(5).trim()}`;\n if (lower.startsWith(\"config set \")) {\n const parts = t.slice(11).trim().split(/\\s+/);\n if (parts.length >= 2) return `/config ${parts[0]}=${parts.slice(1).join(\" \")}`;\n }\n if (lower.startsWith(\"config \")) return `/config ${t.slice(7).trim().replace(/\\s+/, \"=\")}`;\n\n // Bare hostname → scan\n if (!t.includes(\" \") && t.includes(\".\")) return `/scan ${t}`;\n\n return t;\n}\n\nfunction normalizeScanUrl(url: string): string {\n const u = url.trim();\n if (!/^https?:\\/\\//i.test(u)) return `https://${u}`;\n return u;\n}\n\nconst SPINNER_LABELS: Record<string, string> = {\n \"/scan\": \"Scanning target...\",\n \"/status\": \"Loading account status...\",\n \"/scans\": \"Loading scans...\",\n \"/keys\": \"Loading API keys...\",\n \"/config\": \"Updating configuration...\",\n \"/compare\": \"Comparing scans...\",\n \"/whatif\": \"Running simulation...\",\n \"/report\": \"Fetching report...\",\n \"/auth\": \"Signing in...\",\n \"/auth-key\": \"Validating API key...\",\n \"/login\": \"Signing in...\",\n \"/changelog\": \"Loading changelog...\",\n \"/history\": \"Loading history...\",\n \"/palette\": \"Opening command palette...\",\n \"/commands\": \"Opening command palette...\",\n};\n\nfunction spinnerLabel(cmd: string): string | null {\n return SPINNER_LABELS[cmd.toLowerCase()] ?? null;\n}\n\nasync function executeSlashCommand(cmd: string, arg: string, ctx: SlashContext): Promise<SlashResult> {\n switch (cmd.toLowerCase()) {\n case \"/help\":\n ctx.sink.write(renderHelpScreen());\n break;\n\n case \"/palette\":\n case \"/commands\": {\n const picked = await openCommandPalette();\n if (picked) return dispatchSlashCommand(picked, ctx);\n break;\n }\n\n case \"/clear\":\n return { redraw: true };\n\n case \"/history\": {\n const hist = await loadHistory();\n ctx.sink.write(renderHistoryScreen(hist));\n break;\n }\n\n case \"/scan\": {\n if (!arg) {\n ctx.sink.write(errStyle(\"Usage: /scan <url>\"));\n break;\n }\n const client = await getAuthenticatedClient();\n const progress = createStreamProgress(ctx.sink);\n const result = await runScanCommand(client, {\n url: normalizeScanUrl(arg),\n wait: true,\n onProgress: progress.update,\n streamProgress: true,\n });\n progress.stop();\n ctx.sink.write(result.output);\n break;\n }\n\n case \"/status\": {\n const client = await getAuthenticatedClient();\n const status = await runStatusCommand(client);\n const rate = await runRateLimitStatus(client);\n ctx.sink.write(rate ? `${status}\\n\\n${muted(\"Rate limit\")} ${rate}` : status);\n break;\n }\n\n case \"/scans\":\n await runScansInteractive(ctx);\n break;\n\n case \"/keys\":\n await runKeysInteractive(ctx);\n break;\n\n case \"/config\": {\n if (!arg.includes(\"=\")) {\n ctx.sink.write(errStyle(\"Usage: /config key=value\"));\n break;\n }\n const [k, ...vParts] = arg.split(\"=\");\n ctx.sink.write(await runConfigSet(k.trim(), vParts.join(\"=\").trim()));\n break;\n }\n\n case \"/changelog\": {\n const raw = await readAsset(\"changelog.json\");\n ctx.sink.write(renderChangelog(JSON.parse(raw)));\n break;\n }\n\n case \"/compare\": {\n const [a, b] = arg.split(/\\s+/);\n if (!a || !b) {\n ctx.sink.write(errStyle(\"Usage: /compare <scan-a> <scan-b>\"));\n break;\n }\n const { runCompareCommand } = await import(\"../commands/compare.js\");\n ctx.sink.write(await runCompareCommand(a, b, \"table\"));\n break;\n }\n\n case \"/whatif\": {\n if (!arg) {\n ctx.sink.write(errStyle(\"Usage: /whatif <scan-id>\"));\n break;\n }\n const { runWhatIfCommand } = await import(\"../commands/whatif.js\");\n ctx.sink.write(await runWhatIfCommand(arg, {}, \"table\"));\n break;\n }\n\n case \"/report\": {\n if (!arg) {\n ctx.sink.write(errStyle(\"Usage: /report <scan-id>\"));\n break;\n }\n const { runReportCommand } = await import(\"../commands/report.js\");\n const client = await getAuthenticatedClient();\n ctx.sink.write(await runReportCommand(client, arg, \"json\"));\n break;\n }\n\n case \"/login\":\n case \"/auth\": {\n const result = await runAssistedBrowserLogin();\n ctx.sink.write(result.message);\n return { profile: result.profile, redraw: true };\n }\n\n case \"/auth-key\": {\n ctx.sink.write(await runApiKeyLogin({ interactive: true }));\n const client = await getAuthenticatedClient();\n return { profile: await client.get<UserProfile>(\"/me\"), redraw: true };\n }\n\n default:\n ctx.sink.write(errorBox(`Unknown command: ${cmd}`, \"Type /help\"));\n }\n return {};\n}\n\nexport async function dispatchSlashCommand(line: string, ctx: SlashContext): Promise<SlashResult> {\n const trimmed = line.trim();\n if (!trimmed) return {};\n if (trimmed === \"/exit\" || trimmed === \"/quit\") return { exit: true };\n\n const [cmd, ...rest] = trimmed.split(/\\s+/);\n const arg = rest.join(\" \").trim();\n\n if (!cmd.startsWith(\"/\")) {\n ctx.sink.write(\n errorBox(\n `Not a shell command: ${trimmed}`,\n `Use slash commands here — e.g. ${accent(\"/auth\")} not \"fuzzi auth login\"\\n${accent(\"/help\")} lists everything`,\n ),\n );\n return {};\n }\n\n if (!findCommand(cmd) && cmd.startsWith(\"/\")) {\n ctx.sink.write(errorBox(`Unknown command: ${cmd}`, \"Type /help or /palette\"));\n return {};\n }\n\n try {\n const label = spinnerLabel(cmd);\n if (label) {\n return await withSpinner(label, () => executeSlashCommand(cmd, arg, ctx));\n }\n return await executeSlashCommand(cmd, arg, ctx);\n } catch (e) {\n ctx.sink.error(formatApiError(e));\n }\n return {};\n}\n\nfunction createStreamProgress(sink: OutputSink) {\n let last = \"\";\n return {\n update(msg: string) {\n if (last) sink.clearLine?.();\n last = msg;\n process.stdout.write(muted(msg));\n },\n stop() {\n if (last) sink.clearLine?.();\n last = \"\";\n },\n };\n}\n\nasync function runScansInteractive(ctx: SlashContext): Promise<void> {\n const client = await getAuthenticatedClient();\n\n while (true) {\n const list = await runScansListCommand(client, \"table\", { limit: 20 });\n const data = await client.get<ScanSummary[] | { results: ScanSummary[] }>(\"/scans?page=1&page_size=20\");\n const scans = asList(data);\n\n if (!scans.length) {\n ctx.sink.write(emptyState(\"No scans yet\", \"Run /scan <url> to create your first scan\", \"/scan https://example.com\"));\n return;\n }\n\n ctx.sink.write(list);\n ctx.sink.write(\"\");\n\n const scanId = await pickFromList(\n \"Select a scan (Esc to go back)\",\n scans.map((s) => ({\n name: `${truncate(s.target_url, 32)} ${s.risk_level ?? s.status} ${s.overall_score ?? \"—\"} ${formatTimestamp(s.created_at)}`,\n value: s.id,\n })),\n );\n if (!scanId) return;\n\n const detail = await client.get<ScanDetail>(`/scan/${scanId}`);\n ctx.sink.write(renderScanResult(detail, \"table\"));\n\n const cont = await runInteractive(() =>\n input({\n message: muted(\"Enter = back to list · q = exit\"),\n default: \"\",\n }),\n ).catch(() => \"q\");\n if (cont.toLowerCase() === \"q\") return;\n }\n}\n\nasync function runKeysInteractive(ctx: SlashContext): Promise<void> {\n const client = await getAuthenticatedClient();\n ctx.sink.write(await runKeysListCommand(client));\n ctx.sink.write(muted(\"\\nActions: [r] revoke [n] new key [Enter] back\"));\n\n const action = await runInteractive(() => input({ message: \"Action\", default: \"\" })).catch(() => \"\");\n\n if (action.toLowerCase() === \"r\") {\n const keyId = await pickKeyForRevoke(client);\n if (!keyId) return;\n const ok = await runInteractive(() =>\n confirm({ message: \"Revoke this API key?\", default: false }),\n ).catch(() => false);\n if (ok) ctx.sink.write(successBox(await runKeyRevoke(client, keyId)));\n } else if (action.toLowerCase() === \"n\") {\n const name = await runInteractive(() => promptNewKeyName());\n const created = await client.post<{ key: string; name: string; prefix: string }>(\"/keys\", { name });\n ctx.sink.write(success(`Created: ${created.name} (${created.prefix})`));\n ctx.sink.write(accent(\"Save this key — it won't be shown again:\"));\n ctx.sink.write(created.key);\n }\n}\n","import { createTable } from \"../terminal/table.js\";\nimport { muted, success } from \"../terminal/theme.js\";\nimport { emptyState } from \"../terminal/empty-state.js\";\nimport { SETTINGS_API_KEYS_URL } from \"../types/brand.js\";\nimport type { ApiKey } from \"../types/api.js\";\nimport type { FuzziApiClient } from \"../lib/api-client.js\";\nimport { asList } from \"../lib/api-utils.js\";\nimport { pickFromList } from \"../terminal/interactive.js\";\n\nexport async function runKeysListCommand(client: FuzziApiClient): Promise<string> {\n const data = await client.get<ApiKey[] | { results: ApiKey[] }>(\"/keys\");\n const keys = asList(data);\n if (!keys.length) {\n return emptyState(\"No API keys\", `Create one at ${SETTINGS_API_KEYS_URL}`, \"[n] new key in this view\");\n }\n\n const rows = keys.map((k) => [\n k.name,\n k.prefix,\n k.scopes && Array.isArray(k.scopes) ? k.scopes.join(\", \") : muted(\"—\"),\n k.revoked ? muted(\"Revoked\") : k.active ? success(\"Active\") : muted(\"Inactive\"),\n k.last_used_at ? new Date(k.last_used_at).toLocaleDateString() : muted(\"Never\"),\n ]);\n\n return createTable([\"Name\", \"Prefix\", \"Scopes\", \"Status\", \"Last Used\"], rows);\n}\n\nexport async function runKeyRevoke(client: FuzziApiClient, keyId: string): Promise<string> {\n await client.delete(`/keys/${keyId}`);\n return \"API key revoked.\";\n}\n\nexport async function pickKeyForRevoke(client: FuzziApiClient): Promise<string | null> {\n const data = await client.get<ApiKey[] | { results: ApiKey[] }>(\"/keys\");\n const active = asList(data).filter((k) => !k.revoked && k.active);\n return pickFromList(\n \"Select a key to revoke\",\n active.map((k) => ({ name: `${k.name} (${k.prefix})`, value: k.id })),\n );\n}\n","import { muted, accent } from \"./theme.js\";\n\nexport function emptyState(title: string, hint: string, action?: string): string {\n const lines = [\"\", muted(title), muted(hint)];\n if (action) lines.push(\"\", accent(action));\n return lines.join(\"\\n\");\n}\n","import { panel, columns, divider, keyValue } from \"../terminal/layout.js\";\nimport { accent, accentBold, muted, dim } from \"../terminal/theme.js\";\nimport { SLASH_COMMANDS } from \"./registry.js\";\n\nexport function renderHelpScreen(): string {\n const visible = SLASH_COMMANDS.filter((c) => !c.hidden);\n const left = visible\n .slice(0, Math.ceil(visible.length / 2))\n .map((c) => `${accent(c.name.padEnd(12))} ${muted(c.description)}`)\n .join(\"\\n\");\n const right = visible\n .slice(Math.ceil(visible.length / 2))\n .map((c) => `${accent(c.name.padEnd(12))} ${muted(c.description)}`)\n .join(\"\\n\");\n\n const script = [\n muted(\"Scriptable commands\"),\n ` fuzzi scan <url> [--format json|markdown] [--fail-on critical]`,\n ` fuzzi scans list | get <id> · fuzzi auth login | status`,\n ` fuzzi config set default_env staging`,\n ].join(\"\\n\");\n\n return [\n panel(columns(left, right), { title: \"Commands\" }),\n \"\",\n script,\n \"\",\n divider(),\n dim(\"Tips: Tab to complete · /palette to search · Ctrl+C to exit\"),\n ].join(\"\\n\");\n}\n\nexport function renderHistoryScreen(entries: string[]): string {\n if (!entries.length) return muted(\"No command history yet.\");\n const body = entries\n .slice(-15)\n .reverse()\n .map((e, i) => `${dim(String(i + 1).padStart(2))} ${e}`)\n .join(\"\\n\");\n return panel(body, { title: \"Recent commands\" });\n}\n","export interface SlashCommandDef {\n name: string;\n description: string;\n usage?: string;\n aliases?: string[];\n requiresAuth?: boolean;\n hidden?: boolean;\n}\n\nexport const SLASH_COMMANDS: SlashCommandDef[] = [\n { name: \"/scan\", description: \"Run a security scan on a URL\", usage: \"/scan <url>\", requiresAuth: true },\n { name: \"/scans\", description: \"Browse recent scans\", requiresAuth: true },\n { name: \"/status\", description: \"Show auth status and rate limits\", requiresAuth: true },\n { name: \"/keys\", description: \"Manage API keys\", requiresAuth: true },\n { name: \"/config\", description: \"Set CLI configuration\", usage: \"/config key=value\" },\n { name: \"/compare\", description: \"Compare two scans\", usage: \"/compare <id-a> <id-b>\", requiresAuth: true },\n { name: \"/whatif\", description: \"Simulate factor overrides\", usage: \"/whatif <id>\", requiresAuth: true },\n { name: \"/report\", description: \"Download scan report\", usage: \"/report <id>\", requiresAuth: true },\n { name: \"/palette\", description: \"Open command palette\", aliases: [\"/commands\"] },\n { name: \"/changelog\", description: \"View release notes\" },\n { name: \"/help\", description: \"Show all commands\" },\n { name: \"/auth\", description: \"Sign in via browser\", aliases: [\"/login\"] },\n { name: \"/auth-key\", description: \"Paste an API key instead\", usage: \"/auth-key\" },\n { name: \"/clear\", description: \"Clear screen and refresh home\" },\n { name: \"/history\", description: \"Show recent commands\" },\n { name: \"/exit\", description: \"Exit the shell\", aliases: [\"/quit\"] },\n];\n\nexport function findCommand(input: string): SlashCommandDef | undefined {\n const cmd = input.trim().split(/\\s/)[0].toLowerCase();\n return SLASH_COMMANDS.find(\n (c) => c.name === cmd || c.aliases?.some((a) => a === cmd),\n );\n}\n\nexport function suggestCommands(partial: string): SlashCommandDef[] {\n const p = partial.toLowerCase();\n if (!p.startsWith(\"/\")) return SLASH_COMMANDS.filter((c) => !c.hidden);\n return SLASH_COMMANDS.filter((c) => c.name.startsWith(p) || c.aliases?.some((a) => a.startsWith(p)));\n}\n","import { searchPalette, formatChoice } from \"../terminal/interactive.js\";\nimport { SLASH_COMMANDS } from \"./registry.js\";\n\nexport async function openCommandPalette(): Promise<string | null> {\n const choices = SLASH_COMMANDS.filter((c) => !c.hidden).map((c) => ({\n name: formatChoice(c.name, c.description),\n value: c.name,\n description: c.usage,\n }));\n return searchPalette(\"Command palette\", choices);\n}\n\nexport { pickFromList } from \"../terminal/interactive.js\";\n","import { mkdir, readFile, writeFile, appendFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { fuzziDir } from \"../lib/credentials.js\";\n\nconst HISTORY_PATH = join(fuzziDir(), \"history\");\nconst MAX_ENTRIES = 200;\n\nexport async function loadHistory(): Promise<string[]> {\n try {\n const raw = await readFile(HISTORY_PATH, \"utf8\");\n return raw.split(\"\\n\").filter(Boolean).slice(-MAX_ENTRIES);\n } catch {\n return [];\n }\n}\n\nexport async function appendHistory(line: string): Promise<void> {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) return;\n await mkdir(fuzziDir(), {\n recursive: true,\n ...(process.platform === \"win32\" ? {} : { mode: 0o700 }),\n });\n await appendFile(HISTORY_PATH, trimmed + \"\\n\", \"utf8\");\n}\n\nexport async function clearHistory(): Promise<void> {\n await writeFile(HISTORY_PATH, \"\", \"utf8\");\n}\n","import { panel } from \"./layout.js\";\nimport { error, warn, success, accentBold } from \"./theme.js\";\n\nexport function errorBox(message: string, hint?: string): string {\n const body = hint ? `${message}\\n\\n${hint}` : message;\n return panel(body, { title: \"Error\" });\n}\n\nexport function successBox(message: string): string {\n return panel(success(message), { title: \"Done\" });\n}\n\nexport function section(title: string, body: string): string {\n return [accentBold(title), body].join(\"\\n\");\n}\n\nexport function warningBox(message: string): string {\n return panel(warn(message), { title: \"Warning\" });\n}\n","import type { SlashCommandDef } from \"./registry.js\";\n\nexport function buildCompleter(commands: SlashCommandDef[], history: string[]): (line: string) => [string[], string] {\n const names = commands.map((c) => c.name);\n return (line: string): [string[], string] => {\n const trimmed = line.trimStart();\n if (!trimmed.startsWith(\"/\")) {\n if (trimmed === \"\") return [[...names, ...history.slice(-20).reverse()], line];\n return [[], line];\n }\n const hits = names.filter((n) => n.startsWith(trimmed.split(/\\s/)[0]));\n return [hits.length ? hits : names, line];\n };\n}\n","import * as readline from \"node:readline\";\nimport { stdin as input, stdout as output } from \"node:process\";\nimport { renderAuthGateScreen } from \"./home-screen.js\";\nimport { accent, muted } from \"../terminal/theme.js\";\nimport { runAssistedBrowserLogin } from \"../commands/auth.js\";\nimport { tryGetProfile } from \"../cli/profile.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { formatApiError } from \"../lib/errors.js\";\n\nfunction waitForEnter(): Promise<void> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({ input, output, terminal: true });\n output.write(accent(\"\\n> Press Enter to open browser... \"));\n rl.once(\"line\", () => {\n rl.close();\n resolve();\n });\n });\n}\n\nexport async function runAuthGate(): Promise<UserProfile | null> {\n const existing = await tryGetProfile();\n if (existing) return existing;\n\n if (!output.isTTY) return null;\n\n console.log(renderAuthGateScreen());\n await waitForEnter();\n\n try {\n const result = await runAssistedBrowserLogin();\n console.log(result.message);\n return result.profile;\n } catch (e) {\n console.log(muted(formatApiError(e)));\n console.log(muted(\"Run /auth-key to paste your API key manually.\"));\n return null;\n }\n}\n\n/** @deprecated use renderAuthGateScreen */\nexport const renderAuthGate = renderAuthGateScreen;\n","import { loadCredentials, clearCredentials } from \"../lib/credentials.js\";\nimport { FuzziApiClient, ApiError } from \"../lib/api-client.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { log } from \"../lib/logger.js\";\n\nfunction profileFromCredentials(creds: NonNullable<Awaited<ReturnType<typeof loadCredentials>>>): UserProfile {\n return {\n id: \"local\",\n email: creds.email || \"user@local\",\n full_name: creds.full_name || null,\n role: \"analyst\",\n organization: \"—\",\n key_expires_at: creds.key_expires_at ?? null,\n key_prefix: creds.key_prefix ?? null,\n };\n}\n\nexport async function tryGetProfile(): Promise<UserProfile | null> {\n const creds = await loadCredentials();\n if (!creds?.api_key) return null;\n\n try {\n const client = await FuzziApiClient.create();\n const profile = await client.get<UserProfile>(\"/me\");\n return profile;\n } catch (e) {\n if (e instanceof ApiError && e.status === 401) {\n log.debug(\"stored credentials invalid, clearing\");\n await clearCredentials();\n return null;\n }\n log.debug(\"profile bootstrap failed, using cached credentials\", e);\n return profileFromCredentials(creds);\n }\n}\n\nexport async function refreshProfile(): Promise<UserProfile | null> {\n const creds = await loadCredentials();\n if (!creds?.api_key) return null;\n try {\n const client = await FuzziApiClient.create();\n return await client.get<UserProfile>(\"/me\");\n } catch {\n return profileFromCredentials(creds);\n }\n}\n","import type { UserProfile } from \"../types/api.js\";\nimport { runPromptLoop } from \"../shell/prompt-loop.js\";\nimport { runAuthGate } from \"../shell/auth-gate.js\";\nimport { tryGetProfile } from \"./profile.js\";\n\nexport async function runInteractiveMode(): Promise<void> {\n let profile = await tryGetProfile();\n if (!profile) {\n profile = await runAuthGate();\n }\n await runPromptLoop(profile);\n}\n","import { buildProgram } from \"./cli/program.js\";\nimport { runInteractiveMode } from \"./cli/bootstrap.js\";\nimport { formatApiError, getExitCode } from \"./lib/errors.js\";\nimport { configurePlatform } from \"./lib/platform.js\";\n\nconfigurePlatform();\n\nasync function main(argv: string[]): Promise<void> {\n if (argv.length <= 2) {\n await runInteractiveMode();\n return;\n }\n await buildProgram().parseAsync(argv);\n}\n\nmain(process.argv).catch((e) => {\n console.error(formatApiError(e));\n process.exit(getExitCode(e));\n});\n"],"mappings":";;;;;;;;;;;;AAAA,IACa,OAiBA,aAOA,SAGA,YAGA,iBAEA,uBACA,cACA;AAnCb;AAAA;AAAA;AACO,IAAM,QAAQ;AAAA,MACnB,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc;AAAA,MACd,aAAa;AAAA,MACb,eAAe;AAAA,MACf,cAAc;AAAA,MACd,SAAS;AAAA,MACT,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ;AAEO,IAAM,cAAsC;AAAA,MACjD,KAAK,MAAM;AAAA,MACX,QAAQ,MAAM;AAAA,MACd,MAAM,MAAM;AAAA,MACZ,UAAU,MAAM;AAAA,IAClB;AAEO,IAAM,UAAU;AAGhB,IAAM,aAAa;AAGnB,IAAM,kBAAkB,GAAG,UAAU;AAErC,IAAM,wBAAwB,GAAG,UAAU;AAC3C,IAAM,eAAe,GAAG,UAAU;AAClC,IAAM,WAAW;AAAA;AAAA;;;ACnCxB,SAAS,OAAO,UAAU,WAAW,OAAO,cAAc;AAC1D,SAAS,eAAe;AACxB,SAAS,YAAY;AAOd,SAAS,WAAmB;AACjC,SAAO;AACT;AAMA,eAAe,YAA2B;AACxC,QAAM,MAAM,WAAW;AAAA,IACrB,WAAW;AAAA,IACX,GAAI,QAAQ,aAAa,UAAU,CAAC,IAAI,EAAE,MAAM,IAAM;AAAA,EACxD,CAAC;AACH;AAEA,SAAS,qBAAqB,KAA2C;AACvE,MAAI,IAAI,WAAW,OAAO,IAAI,YAAY,UAAU;AAClD,WAAO;AAAA,MACL,SAAS,IAAI;AAAA,MACb,aAAa;AAAA,MACb,YAAa,IAAI,cAAyB,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI;AAAA,MACrE,gBAAgB,IAAI;AAAA,MACpB,OAAO,IAAI;AAAA,MACX,WAAW,IAAI;AAAA,MACf,UAAW,IAAI,aAAuB,oBAAI,KAAK,GAAE,YAAY;AAAA,IAC/D;AAAA,EACF;AACA,MAAI,IAAI,gBAAgB,OAAO,IAAI,iBAAiB,UAAU;AAC5D,WAAO;AAAA,MACL,SAAS,IAAI;AAAA,MACb,aAAa;AAAA,MACb,YAAY,IAAI,aAAa,MAAM,GAAG,EAAE,IAAI;AAAA,MAC5C,OAAO,IAAI;AAAA,MACX,WAAW,IAAI;AAAA,MACf,UAAW,IAAI,aAAuB,oBAAI,KAAK,GAAE,YAAY;AAAA,IAC/D;AAAA,EACF;AACA,QAAM,IAAI,MAAM,0BAA0B;AAC5C;AAEA,eAAsB,kBAA+C;AACnE,aAAW,QAAQ,CAAC,kBAAkB,uBAAuB,GAAG;AAC9D,QAAI;AACF,YAAM,MAAM,MAAM,SAAS,MAAM,MAAM;AACvC,YAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,UAAI,CAAC,UAAU,OAAO,KAAK,MAAM,EAAE,WAAW,EAAG,QAAO;AACxD,aAAO,qBAAqB,MAAM;AAAA,IACpC,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,gBAAgB,OAAmC;AACvE,QAAM,UAAU;AAChB,QAAM,UAAU,kBAAkB,KAAK,UAAU,OAAO,MAAM,CAAC,GAAG,EAAE,MAAM,IAAM,CAAC;AACjF,MAAI;AACF,UAAM,MAAM,kBAAkB,GAAK;AAAA,EACrC,QAAQ;AAAA,EAER;AACF;AAEA,eAAsB,mBAAkC;AACtD,aAAW,QAAQ,CAAC,kBAAkB,uBAAuB,GAAG;AAC9D,QAAI;AACF,YAAM,OAAO,IAAI;AAAA,IACnB,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAEO,SAAS,WAAW,KAAqB;AAC9C,MAAI,IAAI,UAAU,GAAI,QAAO,IAAI,MAAM,GAAG,CAAC,IAAI;AAC/C,SAAO,IAAI,MAAM,GAAG,EAAE,IAAI;AAC5B;AAEO,SAAS,oBAAoB,KAAsB;AACxD,SAAO,+BAA+B,KAAK,IAAI,KAAK,CAAC;AACvD;AA1FA,IAKM,WACA,kBACA;AAPN;AAAA;AAAA;AAKA,IAAM,YAAY,KAAK,QAAQ,GAAG,QAAQ;AAC1C,IAAM,mBAAmB,KAAK,WAAW,aAAa;AACtD,IAAM,0BAA0B,KAAK,WAAW,kBAAkB;AAAA;AAAA;;;ACPlE,SAAS,SAAAA,QAAO,YAAAC,WAAU,aAAAC,YAAW,SAAAC,cAAa;AAClD,SAAS,WAAAC,gBAAe;AACxB,SAAS,QAAAC,aAAY;AAUrB,eAAeC,aAA2B;AACxC,QAAMN,OAAM,SAAS,GAAG;AAAA,IACtB,WAAW;AAAA,IACX,GAAI,QAAQ,aAAa,UAAU,CAAC,IAAI,EAAE,MAAM,IAAM;AAAA,EACxD,CAAC;AACH;AAEA,eAAsB,aAAiC;AACrD,aAAW,QAAQ,CAAC,aAAa,kBAAkB,GAAG;AACpD,QAAI;AACF,YAAM,MAAM,MAAMC,UAAS,MAAM,MAAM;AACvC,YAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,aAAO;AAAA,QACL,SAAS,QAAQ,IAAI,iBAAiB,OAAO,WAAW;AAAA,QACxD,aAAa,OAAO;AAAA,QACpB,gBAAgB,OAAO;AAAA,QACvB,GAAG;AAAA,MACL;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO,EAAE,SAAS,QAAQ,IAAI,iBAAiB,gBAAgB;AACjE;AAEA,eAAsB,WAAW,QAAkC;AACjE,QAAMK,WAAU;AAChB,QAAMJ,WAAU,aAAa,KAAK,UAAU,QAAQ,MAAM,CAAC,GAAG,EAAE,MAAM,IAAM,CAAC;AAC7E,MAAI;AACF,UAAMC,OAAM,aAAa,GAAK;AAAA,EAChC,QAAQ;AAAA,EAER;AACF;AAEA,eAAsB,eAAe,KAAa,OAA8B;AAC9E,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,QAAQ,UAAW,QAAO,UAAU;AAAA,WAC/B,QAAQ,cAAe,QAAO,cAAc;AAAA,WAC5C,QAAQ,iBAAkB,QAAO,iBAAiB;AAAA,MACtD,CAAC,OAA6C,GAAG,IAAI;AAC1D,QAAM,WAAW,MAAM;AACzB;AAEA,eAAsB,eAAe,KAA0C;AAC7E,QAAM,SAAS,MAAM,WAAW;AAChC,SAAQ,OAAyD,GAAG;AACtE;AAEA,eAAsB,oBAAqD;AACzE,QAAM,SAAS,MAAM,WAAW;AAChC,QAAM,UAAkC,CAAC;AACzC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,QAAI,MAAM,OAAW,SAAQ,CAAC,IAAI,OAAO,CAAC;AAAA,EAC5C;AACA,SAAO;AACT;AApEA,IAOM,aACA;AARN;AAAA;AAAA;AAIA;AACA;AAEA,IAAM,cAAcE,MAAKD,SAAQ,GAAG,UAAU,QAAQ;AACtD,IAAM,qBAAqBC,MAAKD,SAAQ,GAAG,UAAU,aAAa;AAAA;AAAA;;;ACJlE,SAAS,eAAsB;AAC7B,MAAI,QAAQ,IAAI,gBAAgB,OAAO,QAAQ,IAAI,gBAAgB,OAAQ,QAAO;AAClF,MAAI,QAAQ,IAAI,gBAAiB,QAAO,QAAQ,IAAI;AACpD,SAAO;AACT;AAEA,SAAS,UAAU,OAAuB;AACxC,SAAO,OAAO,KAAK,KAAK,OAAO,aAAa,CAAC;AAC/C;AAEA,SAAS,QAAgB;AACvB,UAAO,oBAAI,KAAK,GAAE,YAAY;AAChC;AAhBA,IAEM,QAgBO;AAlBb;AAAA;AAAA;AAEA,IAAM,SAAgC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE;AAgBtE,IAAM,MAAM;AAAA,MACjB,SAAS,MAAiB;AACxB,YAAI,UAAU,OAAO,EAAG,SAAQ,MAAM,UAAU,MAAM,CAAC,KAAK,GAAG,IAAI;AAAA,MACrE;AAAA,MACA,QAAQ,MAAiB;AACvB,YAAI,UAAU,MAAM,EAAG,SAAQ,MAAM,UAAU,MAAM,CAAC,KAAK,GAAG,IAAI;AAAA,MACpE;AAAA,MACA,QAAQ,MAAiB;AACvB,YAAI,UAAU,MAAM,EAAG,SAAQ,MAAM,UAAU,MAAM,CAAC,KAAK,GAAG,IAAI;AAAA,MACpE;AAAA,MACA,SAAS,MAAiB;AACxB,YAAI,UAAU,OAAO,EAAG,SAAQ,MAAM,UAAU,MAAM,CAAC,KAAK,GAAG,IAAI;AAAA,MACrE;AAAA,IACF;AAAA;AAAA;;;AC9BO,SAAS,UAAU,OAAwB;AAChD,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AAC/E,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI;AACV,QAAI,OAAO,EAAE,WAAW,SAAU,QAAO,EAAE;AAC3C,QAAI,MAAM,QAAQ,EAAE,MAAM,EAAG,QAAO,EAAE,OAAO,IAAI,SAAS,EAAE,KAAK,IAAI;AACrE,QAAI,OAAO,EAAE,YAAY,SAAU,QAAO,EAAE;AAC5C,QAAI,OAAO,EAAE,UAAU,SAAU,QAAO,EAAE;AAC1C,QAAI;AACF,aAAO,KAAK,UAAU,KAAK;AAAA,IAC7B,QAAQ;AACN,aAAO,OAAO,KAAK;AAAA,IACrB;AAAA,EACF;AACA,SAAO,OAAO,KAAK;AACrB;AAGO,SAAS,OAAU,MAAmE;AAC3F,MAAI,CAAC,KAAM,QAAO,CAAC;AACnB,MAAI,MAAM,QAAQ,IAAI,EAAG,QAAO;AAChC,SAAO,KAAK,WAAW,KAAK,QAAQ,CAAC;AACvC;AAzBA;AAAA;AAAA;AAAA;AAAA;;;ACuBA,SAAS,gBAAgB,QAAgB,MAAuF;AAC9H,QAAM,OAAO,OAAO,KAAK,SAAS,WAAW,KAAK,KAAK,YAAY,IAAI;AACvE,QAAM,MAAM,UAAU,KAAK,SAAS,KAAK,WAAW,KAAK,MAAM;AAE/D,MAAI,WAAW,KAAK;AAClB,QAAI,SAAS,iBAAiB,IAAI,YAAY,EAAE,SAAS,SAAS,GAAG;AACnE,aAAO;AAAA,IACT;AACA,QAAI,SAAS,iBAAiB,IAAI,YAAY,EAAE,SAAS,SAAS,GAAG;AACnE,aAAO,8CAA8C,qBAAqB;AAAA,IAC5E;AACA,WAAO,OAAO,0CAA0C,qBAAqB;AAAA,EAC/E;AACA,MAAI,WAAW,QAAQ,SAAS,UAAU,IAAI,YAAY,EAAE,SAAS,YAAY,IAAI;AACnF,WAAO;AAAA,EACT;AACA,MAAI,WAAW,OAAO,IAAI,YAAY,EAAE,SAAS,KAAK,GAAG;AACvD,WAAO;AAAA,EACT;AACA,MAAI,WAAW,KAAK;AAClB,WAAO,OAAO;AAAA,EAChB;AACA,MAAI,IAAI,YAAY,EAAE,WAAW,aAAa,GAAG;AAC/C,WAAO;AAAA,EACT;AACA,MAAI,IAAK,QAAO;AAChB,SAAO,8BAA8B,MAAM;AAC7C;AAiIA,eAAsB,yBAAkD;AACtE,QAAM,SAAS,MAAM,eAAe,OAAO;AAC3C,MAAI,CAAC,OAAO,OAAO,GAAG;AACpB,UAAM,IAAI,SAAS,4CAA4C,KAAK,qBAAqB,QAAW,CAAC;AAAA,EACvG;AACA,SAAO;AACT;AAzLA,IAOa,UA6CA;AApDb;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEO,IAAM,WAAN,cAAuB,MAAM;AAAA,MAGlC,YACE,SACO,QACA,MACA,MACP,UACA;AACA,cAAM,OAAO;AALN;AACA;AACA;AAIP,aAAK,OAAO;AACZ,aAAK,WAAW;AAAA,MAClB;AAAA,MARS;AAAA,MACA;AAAA,MACA;AAAA,MANT;AAAA,IAaF;AA+BO,IAAM,iBAAN,MAAM,gBAAe;AAAA,MAC1B,YACU,SACA,OACR;AAFQ;AACA;AAAA,MACP;AAAA,MAFO;AAAA,MACA;AAAA,MAGV,aAAa,SAAkC;AAC7C,cAAM,SAAS,MAAM,WAAW;AAChC,cAAM,QAAQ,MAAM,gBAAgB;AACpC,eAAO,IAAI,gBAAe,OAAO,QAAQ,QAAQ,OAAO,EAAE,GAAG,OAAO,OAAO;AAAA,MAC7E;AAAA,MAEA,IAAI,OAAe;AACjB,eAAO,KAAK;AAAA,MACd;AAAA,MAEA,SAAS,OAAqB;AAC5B,aAAK,QAAQ;AAAA,MACf;AAAA,MAEQ,UAAkC;AACxC,cAAM,IAA4B,EAAE,gBAAgB,oBAAoB,QAAQ,mBAAmB;AACnG,YAAI,KAAK,MAAO,GAAE,gBAAgB,UAAU,KAAK,KAAK;AACtD,eAAO;AAAA,MACT;AAAA,MAEA,MAAM,QAAW,QAAgB,MAAc,MAA4B;AACzE,cAAM,MAAM,GAAG,KAAK,OAAO,GAAG,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI,EAAE;AACtE,YAAI,MAAM,GAAG,MAAM,IAAI,GAAG,EAAE;AAC5B,YAAI;AACJ,YAAI;AACF,gBAAM,MAAM,MAAM,KAAK;AAAA,YACrB;AAAA,YACA,SAAS,KAAK,QAAQ;AAAA,YACtB,MAAM,SAAS,SAAY,KAAK,UAAU,IAAI,IAAI;AAAA,UACpD,CAAC;AAAA,QACH,QAAQ;AACN,gBAAM,IAAI;AAAA,YACR,wBAAwB,QAAQ;AAAA,YAChC;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAEA,YAAI;AACJ,cAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,YAAI;AACF,iBAAO,OAAO,KAAK,MAAM,IAAI,IAAI,CAAC;AAAA,QACpC,QAAQ;AACN,iBAAO,EAAE,OAAO,KAAK;AAAA,QACvB;AAEA,YAAI,CAAC,IAAI,IAAI;AACX,gBAAM,UAAU;AAChB,cAAI,UAAU,gBAAgB,IAAI,QAAQ,OAAO;AAEjD,cAAI,IAAI,WAAW,KAAK;AACtB,kBAAM,aAAa,IAAI,QAAQ,IAAI,aAAa;AAChD,kBAAM,UAAU,aAAa,SAAS,YAAY,EAAE,IAAI;AACxD,sBAAU,oCAAoC,OAAO;AAAA,UACvD;AAEA,cAAI,IAAI,UAAU,KAAK;AACrB,sBAAU,mBAAmB,UAAU,QAAQ,SAAS,QAAQ,WAAW,QAAQ,MAAM,KAAK,IAAI,UAAU;AAAA,UAC9G;AAEA,gBAAM,IAAI,SAAS,SAAS,IAAI,QAAQ,QAAQ,MAAM,MAAM,CAAC;AAAA,QAC/D;AACA,eAAO;AAAA,MACT;AAAA,MAEA,IAAO,MAA0B;AAC/B,eAAO,KAAK,QAAW,OAAO,IAAI;AAAA,MACpC;AAAA,MAEA,KAAQ,MAAc,MAA4B;AAChD,eAAO,KAAK,QAAW,QAAQ,MAAM,IAAI;AAAA,MAC3C;AAAA,MAEA,MAAS,MAAc,MAA4B;AACjD,eAAO,KAAK,QAAW,SAAS,MAAM,IAAI;AAAA,MAC5C;AAAA,MAEA,OAAU,MAA0B;AAClC,eAAO,KAAK,QAAW,UAAU,IAAI;AAAA,MACvC;AAAA,MAEA,MAAM,gBAAkC;AACtC,YAAI;AACF,gBAAM,KAAK,IAAI,KAAK;AACpB,iBAAO;AAAA,QACT,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,MAEA,MAAM,SAAS,MAA8D;AAC3E,cAAM,MAAM,GAAG,KAAK,OAAO,GAAG,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI,EAAE;AACtE,YAAI;AACJ,YAAI;AACF,gBAAM,MAAM,MAAM,KAAK,EAAE,SAAS,KAAK,QAAQ,EAAE,CAAC;AAAA,QACpD,QAAQ;AACN,gBAAM,IAAI;AAAA,YACR,wBAAwB,QAAQ;AAAA,YAChC;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,YAAI,CAAC,IAAI,IAAI;AACX,gBAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,cAAI,UAAmF,CAAC;AACxF,cAAI;AACF,sBAAU,KAAK,MAAM,IAAI;AAAA,UAC3B,QAAQ;AACN,sBAAU,EAAE,OAAO,KAAK;AAAA,UAC1B;AACA,gBAAM,IAAI,SAAS,gBAAgB,IAAI,QAAQ,OAAO,GAAG,IAAI,QAAQ,QAAQ,MAAM,SAAS,CAAC;AAAA,QAC/F;AACA,cAAM,MAAM,OAAO,KAAK,MAAM,IAAI,YAAY,CAAC;AAC/C,eAAO,EAAE,MAAM,KAAK,aAAa,IAAI,QAAQ,IAAI,cAAc,KAAK,2BAA2B;AAAA,MACjG;AAAA,IACF;AAAA;AAAA;;;ACjLA,SAAS,cAAc;AAUhB,SAAS,kBAAwC;AACtD,MAAI,OAAQ,QAAO;AACnB,QAAM,OAAO,OAAO,WAAW;AAC/B,QAAM,OAAO,QAAQ,IAAI,QAAQ;AACjC,QAAM,YAAY,QAAQ,IAAI,aAAa;AAC3C,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,YACJ,UAAU,SAAS,WAAW,KAC9B,UAAU,SAAS,OAAO,KAC1B,KAAK,SAAS,WAAW,KACxB,CAAC,CAAC,QAAQ,IAAI,eAAe,QAAQ,IAAI,gBAAgB,OACzD,aAAa,OAAO,UAAU,QAC/B,CAAC,CAAC,QAAQ,IAAI,cACd,CAAC,CAAC,QAAQ,IAAI;AAEhB,WAAS;AAAA,IACP,OAAO,KAAK,IAAI,IAAI,IAAI;AAAA,IACxB;AAAA,IACA,aAAa,OAAO,UAAU;AAAA,EAChC;AACA,SAAO;AACT;AAEO,SAAS,oBAA0B;AACxC,WAAS;AACX;AAnCA,IAQI;AARJ;AAAA;AAAA;AAQA,IAAI,SAAsC;AAAA;AAAA;;;ACR1C,OAAO,WAAmC;AAI1C,SAAS,MAAM,KAAa,UAAwC;AAClE,SAAO,gBAAgB,EAAE,YAAY,MAAM,IAAI,GAAG,IAAI;AACxD;AAYO,SAAS,UAAU,OAAyD;AACjF,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,MAAM,MAAM,YAAY;AAC9B,QAAM,MAAM,YAAY,GAAG,KAAK,MAAM;AACtC,QAAM,YAA2C;AAAA,IAC/C,KAAK,MAAM;AAAA,IACX,QAAQ,MAAM;AAAA,IACd,MAAM,MAAM;AAAA,IACZ,UAAU,MAAM;AAAA,EAClB;AACA,SAAO,MAAM,KAAK,UAAU,GAAG,KAAK,MAAM,IAAI,EAAE;AAClD;AAEO,SAAS,UAAU,GAAsC;AAC9D,MAAI,KAAK,KAAM,QAAO,MAAM,QAAG;AAC/B,SAAO,MAAM,KAAK,OAAO,CAAC,CAAC;AAC7B;AAMO,SAAS,MAAM,MAAsB;AAC1C,SAAO,MAAM,MAAM,QAAQ,MAAM,GAAG,EAAE,IAAI;AAC5C;AAEO,SAAS,QAAQ,MAAsB;AAC5C,SAAO,MAAM,MAAM,SAAS,MAAM,KAAK,EAAE,IAAI;AAC/C;AAEO,SAAS,KAAK,MAAsB;AACzC,SAAO,MAAM,MAAM,SAAS,MAAM,MAAM,EAAE,IAAI;AAChD;AAaO,SAAS,IAAI,MAAsB;AACxC,SAAO,OAAO,IAAI;AACpB;AAjEA,IAQa,QACA,YACA,SACA,aACA,OACA,SACA,QACA,MACA,KAwCA;AAxDb;AAAA;AAAA;AACA;AACA;AAMO,IAAM,SAAS,MAAM,MAAM,QAAQ,MAAM,IAAI;AAC7C,IAAM,aAAa,OAAO;AAC1B,IAAM,UAAU,MAAM,MAAM,aAAa,MAAM,KAAK;AACpD,IAAM,cAAc,QAAQ;AAC5B,IAAM,QAAQ,MAAM,MAAM,eAAe,MAAM,IAAI;AACnD,IAAM,UAAU,MAAM,MAAM,cAAc,MAAM,GAAG;AACnD,IAAM,SAAS,MAAM,MAAM,cAAc,MAAM,IAAI;AACnD,IAAM,OAAO,MAAM;AACnB,IAAM,MAAM,MAAM;AAwClB,IAAM,SAAS,MAAM;AAAA;AAAA;;;ACxD5B,OAAO,WAAW;AAUX,SAAS,YAAY,SAAmB,MAA0B;AACvE,QAAM,QAAQ,IAAI,MAAM;AAAA,IACtB,MAAM,QAAQ,IAAI,CAAC,MAAM,MAAM,CAAC,CAAC;AAAA,IACjC,OAAO,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,EAAE;AAAA,IAC9B,OAAO;AAAA,EACT,CAAC;AACD,aAAW,OAAO,KAAM,OAAM,KAAK,GAAG;AACtC,SAAO,MAAM,SAAS;AACxB;AAlBA,IAGM;AAHN;AAAA;AAAA;AACA;AAEA,IAAM,YAAoC;AAAA,MACxC,KAAK;AAAA,MACL,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,aAAa;AAAA,IACf;AAAA;AAAA;;;ACRO,SAAS,SAAS,GAAW,KAAqB;AACvD,MAAI,EAAE,UAAU,IAAK,QAAO;AAC5B,SAAO,EAAE,MAAM,GAAG,MAAM,CAAC,IAAI;AAC/B;AAEO,SAAS,cAAc,GAAW,OAAuB;AAC9D,QAAM,QAAQ,EAAE,QAAQ,mBAAmB,EAAE;AAC7C,QAAM,MAAM,KAAK,IAAI,GAAG,QAAQ,MAAM,MAAM;AAC5C,SAAO,IAAI,IAAI,OAAO,GAAG;AAC3B;AAEO,SAAS,gBAAgB,KAAwC;AACtE,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,IAAI,IAAI,KAAK,GAAG;AACtB,QAAM,IAAI,CAAC,MAAc,OAAO,CAAC,EAAE,SAAS,GAAG,GAAG;AAClD,SAAO,GAAG,EAAE,YAAY,CAAC,IAAI,EAAE,EAAE,SAAS,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC;AACjI;AAEO,SAAS,gBAAgB,KAAqB;AACnD,MAAI;AACF,WAAO,IAAI,IAAI,GAAG,EAAE;AAAA,EACtB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAxBA;AAAA;AAAA;AAAA;AAAA;;;ACAA,SAAS,UAAAG,eAAc;AAGhB,SAAS,gBAAwB;AACtC,oBAAkB;AAClB,SAAO,KAAK,IAAI,KAAKA,QAAO,WAAW,MAAM,CAAC;AAChD;AAEO,SAAS,eAAuB;AACrC,SAAO,cAAc,IAAI;AAC3B;AAVA;AAAA;AAAA;AACA;AAAA;AAAA;;;ACDA,OAAO,WAAW;AAeX,SAAS,MAAM,SAAiB,OAAqB,CAAC,GAAW;AACtE,QAAM,QAAQ,KAAK,cAAc,QAAQ,cAAc,IAAI;AAC3D,SAAO,MAAM,SAAS;AAAA,IACpB,OAAO,KAAK,QAAQ,WAAW,KAAK,KAAK,IAAI;AAAA,IAC7C,SAAS,KAAK,WAAW;AAAA,IACzB,QAAQ,EAAE,KAAK,GAAG,QAAQ,KAAK,gBAAgB,GAAG,MAAM,GAAG,OAAO,EAAE;AAAA,IACpE,aAAa,KAAK,eAAe;AAAA,IACjC,aAAa,gBAAgB,EAAE,YAAY,MAAM,SAAS;AAAA,IAC1D,gBAAgB;AAAA,IAChB;AAAA,EACF,CAAC;AACH;AA+CO,SAAS,QAAQ,MAAc,OAAe,WAA4B;AAC/E,QAAM,QAAQ,aAAa;AAC3B,QAAM,QAAQ,aAAa,KAAK,MAAM,QAAQ,IAAI;AAClD,QAAM,YAAY,KAAK,MAAM,IAAI;AACjC,QAAM,aAAa,MAAM,MAAM,IAAI;AACnC,QAAM,OAAO,KAAK,IAAI,UAAU,QAAQ,WAAW,MAAM;AACzD,QAAM,MAAgB,CAAC;AACvB,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,UAAM,IAAI,cAAc,UAAU,CAAC,KAAK,IAAI,KAAK;AACjD,UAAM,IAAI,WAAW,CAAC,KAAK;AAC3B,QAAI,KAAK,GAAG,CAAC,KAAK,CAAC,EAAE;AAAA,EACvB;AACA,SAAO,IAAI,KAAK,IAAI;AACtB;AAEO,SAAS,QAAQ,OAAO,UAAK,OAAwB;AAC1D,QAAM,IAAI,SAAS,aAAa;AAChC,SAAO,IAAI,KAAK,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC;AACzC;AAMO,SAAS,SAAS,MAA+B,SAAS,GAAW;AAC1E,QAAM,MAAM,IAAI,OAAO,MAAM;AAC7B,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC;AACzD,SAAO,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,GAAG,GAAG,MAAM,EAAE,OAAO,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI;AACjF;AArGA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;;;ACLA,IAAAC,cAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA,SAAS,aAAAC,kBAAiB;AAG1B,eAAsB,iBACpB,QACA,QACA,QACA,YACiB;AACjB,QAAM,EAAE,MAAM,YAAY,IAAI,MAAM,OAAO,SAAS,SAAS,MAAM,kBAAkB,MAAM,EAAE;AAE7F,QAAM,MAAM,WAAW,QAAQ,QAAQ,WAAW,QAAQ,QAAQ;AAClE,QAAM,OAAO,cAAc,gBAAgB,OAAO,MAAM,GAAG,CAAC,CAAC,IAAI,GAAG;AAEpE,QAAMA,WAAU,MAAM,IAAI;AAC1B,SAAO,mBAAmB,IAAI,KAAK,WAAW;AAChD;AAhBA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAIA,eAAsB,iBACpB,QACA,WACA,SAAuB,SACN;AACjB,QAAM,SAAS,MAAM,uBAAuB;AAC5C,QAAM,OAAO,MAAM,OAAO,KAKvB,WAAW,EAAE,SAAS,QAAQ,UAAU,CAAC;AAE5C,MAAI,WAAW,OAAQ,QAAO,KAAK,UAAU,MAAM,MAAM,CAAC;AAC1D,SAAO;AAAA,IACL,cAAc,UAAU,KAAK,SAAS,UAAU,EAAE,KAAK,SAAS,UAAU,CAAC,KAAK,UAAU,KAAK,SAAS,aAAa,CAAC;AAAA,IACtH,cAAc,UAAU,KAAK,UAAU,UAAU,EAAE,KAAK,UAAU,UAAU,CAAC,KAAK,UAAU,KAAK,UAAU,aAAa,CAAC;AAAA,IACzH,cAAc,KAAK,sBAAsB,IAAI,MAAM,EAAE,GAAG,KAAK,mBAAmB;AAAA,IAChF,KAAK;AAAA,EACP,EAAE,KAAK,IAAI;AACb;AAxBA;AAAA;AAAA;AAAA;AAEA,IAAAC;AAAA;AAAA;;;ACFA;AAAA;AAAA;AAAA;AAOA,eAAsB,kBACpB,OACA,OACA,SAAuB,SACN;AACjB,QAAM,SAAS,MAAM,uBAAuB;AAC5C,QAAM,OAAO,MAAM,OAAO,KAAsB,YAAY;AAAA,IAC1D,WAAW;AAAA,IACX,WAAW;AAAA,EACb,CAAC;AAED,MAAI,WAAW,OAAQ,QAAO,KAAK,UAAU,MAAM,MAAM,CAAC;AAE1D,QAAM,UAAU;AAAA,IACd,WAAW,KAAK,OAAO,UAAU;AAAA,IACjC,WAAW,UAAU,KAAK,OAAO,cAAc,EAAE,EAAE,KAAK,OAAO,cAAc,QAAG,CAAC,KAAK,UAAU,KAAK,OAAO,aAAa,CAAC;AAAA,IAC1H,WAAW,KAAK,OAAO,UAAU;AAAA,IACjC,WAAW,UAAU,KAAK,OAAO,cAAc,EAAE,EAAE,KAAK,OAAO,cAAc,QAAG,CAAC,KAAK,UAAU,KAAK,OAAO,aAAa,CAAC;AAAA,IAC1H,WAAW,KAAK,cAAc,IAAI,MAAM,EAAE,GAAG,KAAK,WAAW;AAAA,IAC7D,KAAK;AAAA,EACP,EAAE,KAAK,IAAI;AAEX,MAAI,OAAO,MAAM,SAAS,EAAE,OAAO,UAAU,CAAC;AAE9C,MAAI,KAAK,gBAAgB,QAAQ;AAC/B,UAAM,OAAO,KAAK,eAAe,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,QAAQ,MAAM,GAAG,GAAG,OAAO,EAAE,KAAK,CAAC,CAAC;AACxF,YAAQ,SAAS,YAAY,CAAC,UAAU,OAAO,GAAG,IAAI;AAAA,EACxD;AAEA,SAAO;AACT;AArCA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AAAA;;;ACDA;AACA;AAHA,SAAS,eAAe;AACxB,SAAS,OAAAC,YAAW;;;ACApB;AACA;AAEA;AACA;AACA;AANA,SAAS,UAAU,OAAO,eAAe;;;ACEzC;AACA;AACA;AACA;AAEA;AAPA,SAAS,mBAAmB;AAC5B,SAAS,oBAAoB;;;ACD7B,SAAS,aAAa;AACtB,SAAS,UAAAC,SAAQ,cAAc;AAGxB,SAAS,oBAA0B;AACxC,MAAI,QAAQ,aAAa,QAAS;AAElC,MAAI;AACF,QAAIA,QAAO,MAAO,qBAAoBA,OAAM;AAC5C,QAAI,OAAO,MAAO,qBAAoB,MAAM;AAAA,EAC9C,QAAQ;AAAA,EAER;AACF;AAEA,SAAS,oBAAoB,QAAkC;AAC7D,QAAM,SAAU,OACb;AACH,MAAI,CAAC,QAAQ,WAAW,OAAO,QAAQ,KAAM;AAE7C,SAAO,QAAQ,OAAO,OAAO,CAAM;AACrC;AAGO,SAAS,YAAY,KAAmB;AAC7C,QAAM,WAAW,QAAQ;AAEzB,MAAI,aAAa,SAAS;AAExB,UAAM,OAAO,CAAC,MAAM,SAAS,IAAI,GAAG,GAAG;AAAA,MACrC,UAAU;AAAA,MACV,OAAO;AAAA,MACP,aAAa;AAAA,IACf,CAAC,EAAE,MAAM;AACT;AAAA,EACF;AAEA,MAAI,aAAa,UAAU;AACzB,UAAM,QAAQ,CAAC,GAAG,GAAG,EAAE,UAAU,MAAM,OAAO,SAAS,CAAC,EAAE,MAAM;AAChE;AAAA,EACF;AAEA,QAAM,YAAY,CAAC,GAAG,GAAG,EAAE,UAAU,MAAM,OAAO,SAAS,CAAC,EAAE,MAAM;AACtE;;;ADhBA,SAAS,UAAU,QAAwB;AACzC,SAAO,OAAO,QAAQ,aAAa,EAAE,KAAK;AAC5C;AAKA,eAAsB,kBAAmC;AACvD,QAAM,SAAS,MAAM,WAAW;AAChC,QAAM,MAAM,GAAG,UAAU,OAAO,OAAO,CAAC;AACxC,cAAY,GAAG;AACf,MAAI,MAAM,wBAAwB,GAAG;AACrC,SAAO;AACT;;;ADhCA;;;AGPA;AADA,SAAS,QAAQ,cAAc;AAG/B,IAAI,YAAiC;AACrC,IAAI,aAAkC;AAE/B,SAAS,iBAAiB,OAAmB,QAA0B;AAC5E,cAAY;AACZ,eAAa;AACf;AAGA,eAAsB,eAAkB,IAAkC;AACxE,SAAO,mBAAmB,EAAE;AAC9B;AAEA,eAAe,mBAAsB,IAAkC;AACrE,cAAY;AACZ,MAAI;AACF,WAAO,MAAM,GAAG;AAAA,EAClB,UAAE;AACA,iBAAa;AAAA,EACf;AACF;AAEA,eAAsB,aACpB,SACA,OACwB;AACxB,MAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,MAAI;AACF,WAAO,MAAM,mBAAmB,MAAM,OAAO,EAAE,SAAS,SAAS,MAAM,CAAC,CAAC;AAAA,EAC3E,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,cACpB,SACA,SACwB;AACxB,MAAI;AACF,WAAO,MAAM;AAAA,MAAmB,MAC9B,OAAO;AAAA,QACL;AAAA,QACA,QAAQ,OAAOC,WAAU;AACvB,cAAI,CAACA,OAAO,QAAO;AACnB,gBAAM,IAAIA,OAAM,YAAY;AAC5B,iBAAO,QAAQ;AAAA,YACb,CAAC,MACC,EAAE,MAAM,YAAY,EAAE,SAAS,CAAC,KAChC,OAAO,EAAE,eAAe,EAAE,EAAE,YAAY,EAAE,SAAS,CAAC;AAAA,UACxD;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,aAAa,MAAc,aAA6B;AACtE,SAAO,GAAG,OAAO,IAAI,CAAC,GAAG,MAAM,aAAQ,WAAW,CAAC;AACrD;;;AHpCA,eAAsB,0BAAwD;AAC5E,QAAM,gBAAgB;AACtB,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAO,8DAAyD,CAAC;AAC7E,UAAQ,IAAI,MAAM,gDAAgD,CAAC;AACnE,UAAQ,IAAI,EAAE;AACd,QAAM,MAAM,MAAM,eAAe,EAAE,aAAa,KAAK,CAAC;AACtD,QAAM,SAAS,MAAM,uBAAuB;AAC5C,QAAM,UAAU,MAAM,OAAO,IAAiB,KAAK;AACnD,SAAO,EAAE,SAAS,KAAK,QAAQ;AACjC;AAEA,eAAsB,aAAa,OAAyB,CAAC,GAAoB;AAC/E,MAAI,KAAK,cAAc,KAAK,QAAQ;AAClC,WAAO,eAAe,IAAI;AAAA,EAC5B;AAEA,MAAI,KAAK,WAAW,KAAK,gBAAgB,OAAO;AAC9C,UAAM,SAAS,MAAM,wBAAwB;AAC7C,WAAO,OAAO;AAAA,EAChB;AAEA,SAAO,eAAe,IAAI;AAC5B;AAEA,eAAsB,eAAe,OAAyB,CAAC,GAAoB;AACjF,QAAM,SAAS,MAAM,WAAW;AAChC,QAAM,SAAS,IAAI,eAAe,OAAO,OAAO;AAEhD,MAAI,SAAS,KAAK,QAAQ,KAAK;AAE/B,MAAI,CAAC,QAAQ;AACX,QAAI,KAAK,gBAAgB,OAAO;AAC9B,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,aAAS,MAAM;AAAA,MAAe,MAC5B,SAAS;AAAA,QACP,SAAS;AAAA,QACT,MAAM;AAAA,QACN,UAAU,CAAC,MAAM;AACf,cAAI,CAAC,EAAE,KAAK,EAAG,QAAO;AACtB,cAAI,CAAC,oBAAoB,CAAC,EAAG,QAAO;AACpC,iBAAO;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,OAAO,KAAK;AACrB,MAAI,CAAC,oBAAoB,MAAM,GAAG;AAChC,UAAM,IAAI;AAAA,MACR,iDAAiD,qBAAqB;AAAA,MACtE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,SAAS,MAAM;AACtB,QAAM,QAAQ,MAAM,OAAO,cAAc;AACzC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI;AAAA,MACR,0CAA0C,qBAAqB;AAAA,MAC/D;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,MAAM,OAAO,IAAiB,KAAK;AACnD,QAAM,gBAAgB;AAAA,IACpB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,YAAY,QAAQ,cAAc,WAAW,MAAM;AAAA,IACnD,gBAAgB,QAAQ,kBAAkB;AAAA,IAC1C,OAAO,QAAQ;AAAA,IACf,WAAW,QAAQ,aAAa;AAAA,IAChC,WAAU,oBAAI,KAAK,GAAE,YAAY;AAAA,EACnC,CAAC;AAED,QAAM,OAAO,QAAQ,aAAa,QAAQ;AAC1C,SAAO,QAAQ,oBAAoB,IAAI,EAAE;AAC3C;AAEA,eAAsB,gBAAiC;AACrD,QAAM,iBAAiB;AACvB,SAAO,MAAM,yBAAyB;AACxC;AAEA,eAAsB,mBAAoC;AACxD,SAAO,MAAM;AAAA,IACX,SAAS;AAAA,IACT,UAAU,CAAC,MAAO,EAAE,KAAK,EAAE,SAAS,IAAI,OAAO;AAAA,EACjD,CAAC;AACH;;;AIjIA;AACA;AACA;AACA;AAKO,SAAS,eAAe,MAAwC;AACrE,SAAO,gBAAgB,gBAAgB,OAAO,KAAK,aAAa,MAAS;AAC3E;AAEO,SAAS,iBAAiB,MAAkB,QAA8B;AAC/E,MAAI,WAAW,OAAQ,QAAO,KAAK,UAAU,cAAc,IAAI,GAAG,MAAM,CAAC;AACzE,MAAI,WAAW,WAAY,QAAO,mBAAmB,IAAI;AACzD,SAAO,gBAAgB,IAAI;AAC7B;AAEA,SAAS,cAAc,MAAkB;AACvC,QAAM,KAAK,KAAK;AAChB,SAAO;AAAA,IACL,MAAM;AAAA,MACJ,IAAI,KAAK;AAAA,MACT,YAAY,KAAK;AAAA,MACjB,QAAQ,KAAK;AAAA,MACb,YAAY,IAAI,cAAc;AAAA,MAC9B,YAAY,IAAI,cAAc;AAAA,MAC9B,eAAe,IAAI,iBAAiB;AAAA,IACtC;AAAA,IACA,SAAS,KAAK,WAAW,CAAC;AAAA,IAC1B,iBAAiB,KAAK,mBAAmB,CAAC;AAAA,EAC5C;AACF;AAEA,SAAS,eAAe,OAAuB;AAC7C,MAAI,UAAU,MAAO,QAAO,MAAM,IAAI;AACtC,SAAO,KAAK,GAAG;AACjB;AAEO,SAAS,gBAAgB,MAA0B;AACxD,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,UAAU,IAAI,UAAU;AACnC,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,MAAM;AAAA,IACf,KAAK,KAAK,UAAU;AAAA,IACpB,KAAK,GAAG,GAAG,MAAM,CAAC,IAAI,GAAG,GAAG,UAAU,CAAC,MAAM,MAAM,OAAO,CAAC,IAAI,UAAU,GAAG,aAAa,CAAC,SAAS;AAAA,IACnG,GAAG,MAAM,MAAM,CAAC,KAAK,eAAe,IAAI,CAAC;AAAA,IACzC,KAAK,WAAW,2BAA2B,KAAK,qCAAgC,IAAI;AAAA,EACtF,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,GAAG,EAAE,OAAO,cAAc,CAAC,CAAC;AAEvD,MAAI,KAAK,SAAS,QAAQ;AACxB,UAAM,OAAO,CAAC,GAAG,KAAK,OAAO,EAC1B,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS,EACxC,IAAI,CAAC,MAAM;AACV,YAAM,MAAM,EAAE,SAAS;AACvB,aAAO;AAAA,QACL,EAAE,KAAK,QAAQ,MAAM,GAAG;AAAA,QACxB,MAAM,MAAM,QAAG,IAAI,GAAG,EAAE,SAAS;AAAA,QACjC,MAAM,MAAM,KAAK,IAAI,GAAG,UAAU,EAAE,gBAAgB,EAAE,EAAE,gBAAgB,CAAC,IAAI,eAAe,EAAE,gBAAgB,CAAC;AAAA,MACjH;AAAA,IACF,CAAC;AACH,UAAM,KAAK,IAAI,YAAY,CAAC,aAAa,SAAS,OAAO,GAAG,IAAI,CAAC;AAAA,EACnE;AAEA,MAAI,KAAK,iBAAiB,QAAQ;AAChC,UAAM,KAAK,IAAI,OAAO,UAAU,CAAC;AACjC,SAAK,gBAAgB,QAAQ,CAAC,GAAG,MAAM;AACrC,YAAM,KAAK,KAAK,MAAM,OAAO,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,SAAS,YAAY,CAAC,EAAE,IAAI,EAAE,SAAS,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE;AAAA,IACzI,CAAC;AAAA,EACH;AAEA,QAAM,KAAK,EAAE;AACb,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,mBAAmB,MAA0B;AAC3D,QAAM,KAAK,KAAK;AAChB,QAAM,OAAO,gBAAgB,KAAK,UAAU;AAC5C,QAAM,QAAkB,CAAC,2BAA2B,IAAI,IAAI,EAAE;AAE9D,MAAI,GAAI,OAAM,KAAK,mBAAmB,GAAG,UAAU,KAAK,GAAG,aAAa,SAAS,EAAE;AAEnF,MAAI,KAAK,SAAS,QAAQ;AACxB,UAAM,KAAK,iCAAiC,+BAA+B;AAC3E,eAAW,KAAK,KAAK,SAAS;AAC5B,YAAM,KAAK,KAAK,EAAE,KAAK,QAAQ,MAAM,GAAG,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,gBAAgB,IAAI;AAAA,IAC5F;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,KAAK,iBAAiB,QAAQ;AAChC,UAAM,KAAK,cAAc;AACzB,SAAK,gBAAgB,QAAQ,CAAC,GAAG,MAAM;AACrC,YAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,SAAS,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE;AAAA,IACjE,CAAC;AAAA,EACH;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,gBAAgB,OAAsB,QAA8B;AAClF,MAAI,WAAW,OAAQ,QAAO,KAAK,UAAU,OAAO,MAAM,CAAC;AAC3D,MAAI,WAAW,YAAY;AACzB,QAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,UAAM,QAAQ,CAAC,0CAA0C,wCAAwC;AACjG,eAAW,KAAK,OAAO;AACrB,YAAM,KAAK,KAAK,EAAE,UAAU,MAAM,EAAE,MAAM,MAAM,EAAE,cAAc,QAAG,MAAM,EAAE,iBAAiB,QAAG,MAAM,eAAe,CAAC,CAAC,IAAI;AAAA,IAC5H;AACA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AACA,MAAI,CAAC,MAAM,OAAQ,QAAO,MAAM,iBAAiB;AAEjD,QAAM,OAAO,MAAM,IAAI,CAAC,MAAM;AAAA,IAC5B,SAAS,EAAE,YAAY,EAAE;AAAA,IACzB,EAAE,WAAW,2BAA2B,KAAK,UAAU,IAAI,EAAE;AAAA,IAC7D,EAAE,aAAa,UAAU,EAAE,UAAU,EAAE,EAAE,UAAU,IAAI,MAAM,QAAG;AAAA,IAChE,EAAE,iBAAiB,OAAO,UAAU,EAAE,aAAa,IAAI,MAAM,QAAG;AAAA,IAChE,MAAM,eAAe,CAAC,CAAC;AAAA,EACzB,CAAC;AACD,SAAO,YAAY,CAAC,OAAO,UAAU,QAAQ,SAAS,MAAM,GAAG,IAAI;AACrE;;;ACtHA;AAEA;AACA;;;ACLA;AACA;AAIO,SAAS,eAAe,KAAsB;AACnD,MAAI,eAAe,UAAU;AAC3B,WAAO,IAAI;AAAA,EACb;AACA,MAAI,eAAe,OAAO;AACxB,QAAI,IAAI,QAAQ,SAAS,cAAc,KAAK,IAAI,QAAQ,SAAS,cAAc,GAAG;AAChF,aAAO,wBAAwB,QAAQ;AAAA,IACzC;AACA,WAAO,sBAAsB,IAAI,OAAO;AAAA,EAC1C;AACA,SAAO,sBAAsB,OAAO,GAAG,CAAC;AAC1C;AAEO,SAAS,YAAY,KAAwB;AAClD,MAAI,eAAe,YAAY,IAAI,aAAa,QAAW;AACzD,WAAO,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAEO,SAAS,YAAY,KAA4B;AACtD,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,QAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,SAAS,OAAO,QAAQ,GAAG;AAClD,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ACjCA,IAAM,aAAwC;AAAA,EAC5C,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,UAAU;AACZ;AAEO,SAAS,mBAAmB,OAAoD;AACrF,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,QAAQ,MAAM,YAAY;AAChC,SAAO,SAAS,aAAa,QAAQ;AACvC;AAEO,SAAS,mBACd,QACA,WACS;AACT,QAAM,IAAI,mBAAmB,MAAM;AACnC,QAAM,IAAI,mBAAmB,SAAS;AACtC,MAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,SAAO,WAAW,CAAC,KAAK,WAAW,CAAC;AACtC;;;ACvBA,SAAS,YAAAC,iBAAgB;AACzB,SAAS,QAAAC,aAAY;AACrB,SAAS,kBAAkB;AAc3B,SAAS,gBAAgB,KAA4B;AACnD,QAAM,SAAwB,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,EAAE;AACrD,MAAI,UAAU;AACd,aAAW,QAAQ,IAAI,MAAM,IAAI,GAAG;AAClC,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,EAAG;AACzC,UAAM,eAAe,QAAQ,MAAM,gBAAgB;AACnD,QAAI,cAAc;AAChB,gBAAU,aAAa,CAAC;AACxB;AAAA,IACF;AACA,UAAM,KAAK,QAAQ,MAAM,2BAA2B;AACpD,QAAI,CAAC,GAAI;AACT,UAAM,CAAC,EAAE,KAAK,KAAK,IAAI;AACvB,QAAI,YAAY,UAAU,YAAY,aAAa;AACjD,aAAO,SAAS,CAAC;AACjB,UAAI,QAAQ,MAAO,QAAO,KAAK,MAAM;AAAA,eAC5B,QAAQ,cAAe,QAAO,KAAK,cAAc;AAAA,eACjD,QAAQ,UAAW,QAAO,KAAK,UAAU;AAAA,eACzC,QAAQ,QAAS,QAAO,KAAK,QAAQ;AAAA,IAChD,WAAW,YAAY,UAAU;AAC/B,aAAO,WAAW,CAAC;AACnB,UAAI,QAAQ,SAAU,QAAO,OAAO,SAAS;AAAA,IAC/C;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,kBAAkBC,MAA4C;AAClF,QAAM,UAAUD,MAAKC,MAAK,UAAU;AACpC,QAAM,YAAYD,MAAKC,MAAK,YAAY;AAExC,MAAI,WAAW,OAAO,GAAG;AACvB,QAAI;AACF,YAAM,MAAM,MAAMF,UAAS,SAAS,MAAM;AAC1C,aAAO,KAAK,MAAM,GAAG;AAAA,IACvB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,WAAW,SAAS,GAAG;AACzB,QAAI;AACF,YAAM,MAAM,MAAMA,UAAS,WAAW,MAAM;AAC5C,aAAO,gBAAgB,GAAG;AAAA,IAC5B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;;;AClEA;AACA;AAFA,OAAO,SAAuB;AAWvB,SAAS,eAAe,OAAe,SAAS,OAAuB;AAC5E,MAAI,CAAC,gBAAgB,EAAE,aAAa;AAClC,WAAO;AAAA,MACL,QAAQ,MAAM;AAAA,MAAC;AAAA,MACf,SAAS,MAAM;AAAA,MAAC;AAAA,MAChB,MAAM,MAAM;AAAA,MAAC;AAAA,MACb,MAAM,MAAM;AAAA,MAAC;AAAA,IACf;AAAA,EACF;AAEA,MAAI,QAAQ;AACV,QAAI,OAAO;AACX,WAAO;AAAA,MACL,OAAO,SAAiB;AACtB,YAAI,KAAM,SAAQ,OAAO,MAAM,UAAU;AACzC,eAAO;AACP,gBAAQ,OAAO,MAAM,MAAM,OAAO,CAAC;AAAA,MACrC;AAAA,MACA,QAAQ,SAAkB;AACxB,YAAI,KAAM,SAAQ,OAAO,MAAM,UAAU;AACzC,YAAI,QAAS,SAAQ,OAAO,MAAM,MAAM,OAAO,IAAI,IAAI;AACvD,eAAO;AAAA,MACT;AAAA,MACA,KAAK,SAAkB;AACrB,YAAI,KAAM,SAAQ,OAAO,MAAM,UAAU;AACzC,YAAI,QAAS,SAAQ,OAAO,MAAM,MAAM,OAAO,IAAI,IAAI;AACvD,eAAO;AAAA,MACT;AAAA,MACA,OAAO;AACL,YAAI,KAAM,SAAQ,OAAO,MAAM,UAAU;AACzC,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEA,MAAI,UAAsB,IAAI;AAAA,IAC5B,MAAM;AAAA,IACN,OAAO;AAAA,IACP,cAAc;AAAA,IACd,WAAW,gBAAgB,EAAE;AAAA,EAC/B,CAAC,EAAE,MAAM;AACT,SAAO;AAAA,IACL,OAAO,SAAiB;AACtB,UAAI,QAAS,SAAQ,OAAO;AAAA,IAC9B;AAAA,IACA,QAAQ,SAAkB;AACxB,UAAI,SAAS;AACX,gBAAQ,QAAQ,OAAO;AACvB,kBAAU;AAAA,MACZ;AAAA,IACF;AAAA,IACA,KAAK,SAAkB;AACrB,UAAI,SAAS;AACX,gBAAQ,KAAK,OAAO;AACpB,kBAAU;AAAA,MACZ;AAAA,IACF;AAAA,IACA,OAAO;AACL,UAAI,SAAS;AACX,gBAAQ,KAAK;AACb,kBAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsB,YAAe,OAAe,IAAkC;AACpF,QAAM,IAAI,eAAe,KAAK;AAC9B,MAAI;AACF,UAAM,SAAS,MAAM,GAAG;AACxB,MAAE,KAAK;AACP,WAAO;AAAA,EACT,SAAS,GAAG;AACV,MAAE,KAAK;AACP,UAAM;AAAA,EACR;AACF;;;AJ7EA;;;AKVA;AAQA,eAAsB,UAAa,IAAsB,OAAqB,CAAC,GAAe;AAC5F,QAAM,MAAM,KAAK,eAAe;AAChC,QAAM,OAAO,KAAK,eAAe;AACjC,QAAM,UAAU,KAAK,YAAY,CAAC,MAAe;AAC/C,UAAM,MAAM;AACZ,WAAO,IAAI,WAAW,OAAO,IAAI,WAAW,OAAO,IAAI,WAAW;AAAA,EACpE;AAEA,MAAI;AACJ,WAAS,UAAU,GAAG,WAAW,KAAK,WAAW;AAC/C,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,SAAS,GAAG;AACV,aAAO;AACP,UAAI,WAAW,OAAO,CAAC,QAAQ,CAAC,EAAG,OAAM;AACzC,YAAM,QAAQ,OAAO,KAAK,IAAI,GAAG,UAAU,CAAC;AAC5C,UAAI,MAAM,SAAS,OAAO,IAAI,GAAG,OAAO,KAAK,IAAI;AACjD,YAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC;AAAA,IAC/C;AAAA,EACF;AACA,QAAM;AACR;;;ALjBA;AACA,SAAS,WAAW;AAqBpB,IAAM,oBAAoB,oBAAI,IAAI,CAAC,aAAa,0BAA0B,QAAQ,CAAC;AACnF,IAAM,mBAAmB;AAEzB,eAAsB,SACpB,QACA,QACA,QACA,YAAY,KACS;AACrB,QAAM,QAAQ,KAAK,IAAI;AACvB,MAAI,OAAO;AACX,SAAO,KAAK,IAAI,IAAI,QAAQ,WAAW;AACrC,UAAM,SAAS,MAAM,UAAU,MAAM,OAAO,IAAgB,SAAS,MAAM,EAAE,CAAC;AAC9E,WAAO,OAAO;AACd,aAAS,KAAK,OAAO,KAAK,IAAI,IAAI,SAAS,GAAI,GAAG,IAAI;AACtD,QAAI,kBAAkB,IAAI,OAAO,MAAM,GAAG;AACxC,UAAI,OAAO,WAAW,UAAU;AAC9B,cAAM,IAAI;AAAA,UACR,gBAAgB,OAAO,wBAAwB,OAAO,uBAAuB,eAAe;AAAA,UAC5F;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AACA,UAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,gBAAgB,CAAC;AAAA,EAC1D;AACA,QAAM,IAAI,SAAS,wBAAwB,YAAY,GAAI,mBAAmB,IAAI,KAAK,KAAK,gBAAgB,QAAW,CAAC;AAC1H;AAEA,SAAS,cAAc,QAAuB,eAA4C;AACxF,SAAO,UAAU,iBAAiB;AACpC;AAEA,SAAS,gBAAgB,MAAkB,MAAqC;AAC9E,QAAM,KAAK,KAAK;AAChB,MAAI,CAAC,GAAI,QAAO;AAChB,MAAI,KAAK,iBAAiB,QAAQ,GAAG,cAAc,KAAK,cAAe,QAAO;AAC9E,MAAI,KAAK,UAAU,mBAAmB,GAAG,YAAY,KAAK,MAAM,EAAG,QAAO;AAC1E,SAAO;AACT;AAEA,eAAsB,eACpB,QACA,MAC4B;AAC5B,QAAM,WAAW,YAAY,KAAK,GAAG;AACrC,MAAI,SAAU,OAAM,IAAI,SAAS,UAAU,KAAK,eAAe,QAAW,CAAC;AAE3E,QAAM,gBAAgB,MAAM,kBAAkB,IAAI,CAAC;AACnD,QAAM,SAAS,MAAM,WAAW;AAChC,QAAM,SAAS,cAAc,KAAK,QAAQ,eAAe,QAAQ,UAAU,OAAO,cAAc;AAChG,QAAM,MAAM,KAAK,eAAe,eAAe,MAAM,eAAe,OAAO,eAAe;AAC1F,QAAM,SAAS,KAAK,UAAW,eAAe,MAAM;AACpD,QAAM,aAAa,KAAK,SAAS,QAAQ,KAAK,SAAS;AAEvD,QAAM,OAA+B,EAAE,KAAK,KAAK,KAAK,aAAa,IAAI;AACvE,MAAI,KAAK,SAAS,eAAe,MAAM,OAAO;AAC5C,SAAK,QAAQ,KAAK,SAAS,eAAe,MAAM,SAAS;AAAA,EAC3D;AAEA,MAAI,MAAM,iBAAiB,EAAE,KAAK,KAAK,KAAK,IAAI,CAAC;AACjD,QAAM,UAAU,MAAM,UAAU,MAAM,OAAO,KAAyB,SAAS,IAAI,CAAC;AAEpF,MAAI,CAAC,YAAY;AACf,UAAMG,UACJ,WAAW,SACP,KAAK,UAAU,SAAS,MAAM,CAAC,IAC/B,CAAC,QAAQ,cAAc,GAAG,MAAM,OAAO,QAAQ,OAAO,EAAE,GAAG,MAAM,QAAQ,OAAO,CAAC,EAAE,KAAK,IAAI;AAClG,WAAO,EAAE,QAAAA,SAAQ,UAAU,EAAE;AAAA,EAC/B;AAEA,QAAM,OAAO,gBAAgB,KAAK,GAAG;AACrC,QAAM,WAAW,KAAK,aAClB,EAAE,QAAQ,KAAK,YAAY,MAAM,MAAM;AAAA,EAAC,GAAG,SAAS,MAAM;AAAA,EAAC,GAAG,MAAM,MAAM;AAAA,EAAC,EAAE,IAC7E,eAAe,YAAY,IAAI,OAAO,KAAK,cAAc;AAE7D,QAAM,SAAS,MAAM,SAAS,QAAQ,QAAQ,SAAS,CAAC,KAAK,WAAW;AACtE,aAAS,OAAO,YAAY,IAAI,QAAQ,GAAG,OAAO,MAAM,MAAM,CAAC,EAAE;AAAA,EACnE,CAAC;AAED,WAAS,QAAQ,wBAAmB,IAAI,EAAE;AAE1C,QAAM,WAAW,gBAAgB,QAAQ,EAAE,GAAG,MAAM,OAAO,CAAC;AAC5D,SAAO,EAAE,QAAQ,iBAAiB,QAAQ,MAAM,GAAG,UAAU,MAAM,OAAO;AAC5E;;;AMpHA;AAQA,eAAsB,oBACpB,QACA,SAAuB,SACvB,SACiB;AACjB,QAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,KAAK,WAAW,OAAO,SAAS,SAAS,EAAE,EAAE,CAAC;AACzF,MAAI,SAAS,OAAQ,QAAO,IAAI,UAAU,QAAQ,MAAM;AACxD,MAAI,SAAS,UAAW,QAAO,IAAI,cAAc,QAAQ,SAAS;AAElE,QAAM,OAAO,MAAM,OAAO;AAAA,IACxB,UAAU,OAAO,SAAS,CAAC;AAAA,EAC7B;AACA,SAAO,gBAAgB,OAAO,IAAI,GAAG,MAAM;AAC7C;AAEA,eAAsB,kBACpB,QACA,QACA,SAAuB,SACN;AACjB,QAAM,SAAS,MAAM,OAAO,IAAgB,SAAS,MAAM,EAAE;AAC7D,SAAO,iBAAiB,QAAQ,MAAM;AACxC;;;AClCA;AACA;AAEA;AACA;AAEA,SAAS,UAAU,SAAyB;AAC1C,QAAM,OAAO,IAAI,KAAK,OAAO,EAAE,QAAQ,IAAI,KAAK,IAAI;AACpD,SAAO,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,MAAO,KAAK,KAAK,GAAG,CAAC;AAC5D;AAEA,eAAsB,mBAAmB,QAAgD;AACvF,MAAI;AACF,UAAM,OAAO,MAAM,OAAO,IAA4D,aAAa;AACnG,QAAI,KAAK,SAAS,MAAM;AACtB,aAAO,GAAG,KAAK,aAAa,GAAG,IAAI,KAAK,KAAK;AAAA,IAC/C;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAEA,eAAsB,iBAAiB,QAAyC;AAC9E,QAAM,QAAQ,MAAM,gBAAgB;AACpC,QAAM,UAAU,MAAM,OAAO,IAAiB,KAAK;AACnD,QAAM,YAAY,OAAO,kBAAkB,QAAQ;AACnD,QAAM,SAAS,MAAM,WAAW;AAChC,QAAM,OAAO,MAAM,mBAAmB,MAAM;AAE5C,QAAM,OAAgC;AAAA,IACpC,CAAC,QAAQ,QAAQ,aAAa,QAAQ,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,IACzD,CAAC,SAAS,QAAQ,KAAK;AAAA,IACvB,CAAC,gBAAgB,QAAQ,gBAAgB,MAAM,QAAG,CAAC;AAAA,IACnD,CAAC,QAAQ,QAAQ,IAAI;AAAA,IACrB,CAAC,QAAQ,YAAY,QAAQ,WAAW,MAAM,OAAO,IAAI,QAAG,GAAG;AAAA,EACjE;AAEA,MAAI,WAAW;AACb,UAAM,OAAO,UAAU,SAAS;AAChC,SAAK,KAAK,CAAC,eAAe,GAAG,UAAU,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,cAAc,CAAC;AAAA,EAC7E,OAAO;AACL,SAAK,KAAK,CAAC,eAAe,MAAM,WAAW,CAAC,CAAC;AAAA,EAC/C;AAEA,OAAK,KAAK,CAAC,OAAO,OAAO,OAAO,CAAC;AACjC,MAAI,KAAM,MAAK,KAAK,CAAC,cAAc,IAAI,CAAC;AAExC,SAAO,CAAC,MAAM,SAAS,IAAI,GAAG,EAAE,OAAO,UAAU,CAAC,GAAG,IAAI,QAAQ,GAAG,MAAM,8BAA8B,CAAC,EAAE,KAAK,IAAI;AACtH;;;AClDA;AACAC;AAEA,eAAsB,gBAAiC;AACrD,QAAM,UAAU,MAAM,kBAAkB;AACxC,QAAM,QAAQ,OAAO,QAAQ,OAAO,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE;AACrE,SAAO,MAAM,SAAS,CAAC,OAAO,0BAA0B,GAAG,GAAG,KAAK,EAAE,KAAK,IAAI,IAAI,MAAM,gBAAgB;AAC1G;AAEA,eAAsB,aAAa,KAA+B;AAChE,MAAI,CAAC,IAAK,QAAO,cAAc;AAC/B,QAAM,QAAQ,MAAM,eAAe,GAAG;AACtC,MAAI,UAAU,OAAW,QAAO,MAAM,uBAAuB,GAAG,EAAE;AAClE,SAAO;AACT;AAEA,eAAsB,aAAa,KAAa,OAAgC;AAC9E,QAAM,UAAU,CAAC,WAAW,eAAe,gBAAgB;AAC3D,MAAI,CAAC,QAAQ,SAAS,GAAG,GAAG;AAC1B,WAAO,MAAM,uBAAuB,GAAG,gBAAgB,QAAQ,KAAK,IAAI,CAAC,EAAE;AAAA,EAC7E;AACA,QAAM,eAAe,KAAK,KAAK;AAC/B,SAAO,OAAO,iBAAiB;AACjC;;;ACrBO,SAAS,mBAAmB,GAAmB;AACpD,UAAQ,MAAM,eAAe,CAAC,CAAC;AAC/B,UAAQ,KAAK,YAAY,CAAC,CAAC;AAC7B;AAEO,SAAS,SAAS,MAAwB;AAC/C,UAAQ,KAAK,IAAI;AACnB;;;AfKO,SAAS,eAAwB;AACtC,QAAM,UAAU,IAAI,QAAQ,OAAO,EAChC,KAAK,OAAO,EACZ,YAAY,6EAAwE,EACpF,QAAQ,OAAO;AAElB,QAAM,OAAO,QAAQ,QAAQ,MAAM,EAAE,YAAY,gBAAgB;AAEjE,OACG,QAAQ,OAAO,EACf,YAAY,0CAA0C,EACtD,OAAO,aAAa,gDAAgD,EACpE,OAAO,mBAAmB,gCAAgC,EAC1D,OAAO,OAAO,SAAS;AACtB,QAAI;AACF,YAAM,YAAY,CAAC,CAAC,KAAK;AACzB,cAAQ;AAAA,QACN,MAAM,aAAa;AAAA,UACjB,QAAQ,KAAK;AAAA,UACb,aAAa,CAAC,KAAK;AAAA,UACnB,SAAS,CAAC;AAAA,UACV,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAAA,IACF,SAAS,GAAG;AACV,yBAAmB,CAAC;AAAA,IACtB;AAAA,EACF,CAAC;AAEH,OAAK,QAAQ,QAAQ,EAAE,YAAY,0BAA0B,EAAE,OAAO,YAAY;AAChF,YAAQ,IAAI,MAAM,cAAc,CAAC;AAAA,EACnC,CAAC;AAED,OAAK,QAAQ,QAAQ,EAAE,YAAY,kBAAkB,EAAE,OAAO,YAAY;AACxE,QAAI;AACF,YAAM,SAAS,MAAM,uBAAuB;AAC5C,cAAQ,IAAI,MAAM,iBAAiB,MAAM,CAAC;AAAA,IAC5C,SAAS,GAAG;AACV,yBAAmB,CAAC;AAAA,IACtB;AAAA,EACF,CAAC;AAED,UACG,QAAQ,YAAY,EACpB,YAAY,8CAA8C,EAC1D,OAAO,uBAAuB,YAAY,EAC1C,OAAO,mBAAmB,gCAAgC,EAC1D,OAAO,cAAc,qCAAqC,EAC1D,OAAO,aAAa,iCAAiC,EACrD,OAAO,yBAAyB,uBAAuB,OAAO,EAC9D,OAAO,qBAAqB,oDAAoD,EAChF,OAAO,wBAAwB,+CAA+C,UAAU,EACxF,OAAO,OAAO,QAAQ,SAAS;AAC9B,QAAI;AACF,YAAM,UAAU,MAAM,kBAAkBC,KAAI,CAAC;AAC7C,YAAM,MAAM,UAAU,SAAS,MAAM;AACrC,UAAI,CAAC,KAAK;AACR,gBAAQ,MAAM,yBAAyB;AACvC,iBAAS,CAAC;AAAA,MACZ;AACA,YAAM,SAAS,MAAM,uBAAuB;AAC5C,YAAM,SAAS,MAAM,eAAe,QAAQ;AAAA,QAC1C;AAAA,QACA,MAAM,KAAK;AAAA,QACX,QAAQ,KAAK;AAAA,QACb,QAAQ,KAAK;AAAA,QACb,aAAa,KAAK;AAAA,QAClB,OAAO,KAAK;AAAA,QACZ,QAAQ,KAAK;AAAA,QACb,eAAe,KAAK;AAAA,MACtB,CAAC;AACD,cAAQ,IAAI,OAAO,MAAM;AACzB,eAAS,OAAO,QAAQ;AAAA,IAC1B,SAAS,GAAG;AACV,yBAAmB,CAAC;AAAA,IACtB;AAAA,EACF,CAAC;AAEH,QAAM,QAAQ,QAAQ,QAAQ,OAAO,EAAE,YAAY,cAAc;AAEjE,QACG,QAAQ,MAAM,EACd,YAAY,mBAAmB,EAC/B,OAAO,qBAAqB,kCAAkC,EAC9D,OAAO,wBAAwB,0BAA0B,EACzD,OAAO,eAAe,eAAe,IAAI,EACzC,OAAO,yBAAyB,uBAAuB,OAAO,EAC9D,OAAO,OAAO,SAAS;AACtB,QAAI;AACF,YAAM,SAAS,MAAM,uBAAuB;AAC5C,cAAQ;AAAA,QACN,MAAM,oBAAoB,QAAQ,KAAK,QAAwB;AAAA,UAC7D,QAAQ,KAAK;AAAA,UACb,WAAW,KAAK;AAAA,UAChB,OAAO,SAAS,KAAK,OAAO,EAAE;AAAA,QAChC,CAAC;AAAA,MACH;AAAA,IACF,SAAS,GAAG;AACV,yBAAmB,CAAC;AAAA,IACtB;AAAA,EACF,CAAC;AAEH,QACG,QAAQ,eAAe,EACvB,YAAY,kBAAkB,EAC9B,OAAO,yBAAyB,uBAAuB,OAAO,EAC9D,OAAO,OAAO,QAAQ,SAAS;AAC9B,QAAI;AACF,YAAM,SAAS,MAAM,uBAAuB;AAC5C,cAAQ,IAAI,MAAM,kBAAkB,QAAQ,QAAQ,KAAK,MAAsB,CAAC;AAAA,IAClF,SAAS,GAAG;AACV,yBAAmB,CAAC;AAAA,IACtB;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,kBAAkB,EAC1B,YAAY,wBAAwB,EACpC,eAAe,qBAAqB,cAAc,EAClD,OAAO,uBAAuB,kBAAkB,EAChD,OAAO,OAAO,QAAQ,SAAS;AAC9B,QAAI;AACF,YAAM,EAAE,kBAAAC,kBAAiB,IAAI,MAAM;AACnC,YAAM,SAAS,MAAM,uBAAuB;AAC5C,cAAQ,IAAI,MAAMA,kBAAiB,QAAQ,QAAQ,KAAK,QAAQ,KAAK,MAAM,CAAC;AAAA,IAC9E,SAAS,GAAG;AACV,yBAAmB,CAAC;AAAA,IACtB;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,kBAAkB,EAC1B,YAAY,2BAA2B,EACvC,OAAO,gBAAgB,gCAAgC,CAAC,GAAG,SAAmB,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAC9F,OAAO,yBAAyB,cAAc,OAAO,EACrD,OAAO,OAAO,QAAQ,SAAS;AAC9B,QAAI;AACF,YAAM,EAAE,kBAAAC,kBAAiB,IAAI,MAAM;AACnC,YAAM,YAAoC,CAAC;AAC3C,iBAAW,QAAQ,KAAK,KAAiB;AACvC,cAAM,CAAC,GAAG,GAAG,IAAI,KAAK,MAAM,GAAG;AAC/B,YAAI,KAAK,IAAK,WAAU,CAAC,IAAI,WAAW,GAAG;AAAA,MAC7C;AACA,cAAQ,IAAI,MAAMA,kBAAiB,QAAQ,WAAW,KAAK,MAAsB,CAAC;AAAA,IACpF,SAAS,GAAG;AACV,yBAAmB,CAAC;AAAA,IACtB;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,2BAA2B,EACnC,YAAY,mBAAmB,EAC/B,OAAO,yBAAyB,cAAc,OAAO,EACrD,OAAO,OAAO,OAAO,OAAO,SAAS;AACpC,QAAI;AACF,YAAM,EAAE,mBAAAC,mBAAkB,IAAI,MAAM;AACpC,cAAQ,IAAI,MAAMA,mBAAkB,OAAO,OAAO,KAAK,MAAsB,CAAC;AAAA,IAChF,SAAS,GAAG;AACV,yBAAmB,CAAC;AAAA,IACtB;AAAA,EACF,CAAC;AAEH,QAAM,SAAS,QAAQ,QAAQ,QAAQ,EAAE,YAAY,qCAAqC;AAE1F,SAAO,QAAQ,MAAM,EAAE,OAAO,YAAY,QAAQ,IAAI,MAAM,cAAc,CAAC,CAAC;AAC5E,SAAO,QAAQ,WAAW,EAAE,OAAO,OAAO,QAAQ,QAAQ,IAAI,MAAM,aAAa,GAAG,CAAC,CAAC;AACtF,SACG,QAAQ,mBAAmB,EAC3B,OAAO,OAAO,KAAK,UAAU,QAAQ,IAAI,MAAM,aAAa,KAAK,KAAK,CAAC,CAAC;AAE3E,UAAQ,QAAQ,QAAQ,EAAE,YAAY,qBAAqB,EAAE,OAAO,YAAY;AAC9E,QAAI;AACF,YAAM,SAAS,MAAM,uBAAuB;AAC5C,cAAQ,IAAI,MAAM,iBAAiB,MAAM,CAAC;AAAA,IAC5C,SAAS,GAAG;AACV,yBAAmB,CAAC;AAAA,IACtB;AAAA,EACF,CAAC;AAED,SAAO;AACT;;;AgBlMA,YAAY,cAAc;AAC1B,SAAS,SAASC,QAAO,UAAU,QAAQ,OAAAC,YAAW;;;ACDtD,SAAS,YAAAC,iBAAgB;AACzB,SAAS,SAAS,QAAAC,aAAY;AAC9B,SAAS,eAAe,qBAAqB;AAC7C,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,qBAAqB;AAGvB,SAAS,YAAoB;AAClC,QAAM,OAAO,QAAQ,cAAc,YAAY,GAAG,CAAC;AACnD,QAAM,aAAa;AAAA,IACjBD,MAAK,MAAM,MAAM,QAAQ;AAAA;AAAA,IACzBA,MAAK,MAAM,MAAM,MAAM,QAAQ;AAAA;AAAA,IAC/BA,MAAK,MAAM,QAAQ;AAAA,EACrB;AAGA,MAAI;AACF,UAAM,MAAM,cAAc,YAAY,GAAG;AACzC,UAAM,UAAU,QAAQ,IAAI,QAAQ,wBAAwB,CAAC;AAC7D,eAAW,QAAQA,MAAK,SAAS,QAAQ,CAAC;AAAA,EAC5C,QAAQ;AAAA,EAER;AAEA,aAAW,KAAK,YAAY;AAC1B,QAAIC,YAAWD,MAAK,GAAG,gBAAgB,CAAC,EAAG,QAAO;AAAA,EACpD;AACA,SAAO,WAAW,CAAC;AACrB;AAEO,SAAS,UAAU,MAAsB;AAC9C,SAAOA,MAAK,UAAU,GAAG,IAAI;AAC/B;AAEA,eAAsB,UAAU,MAA+B;AAC7D,SAAOD,UAAS,UAAU,IAAI,GAAG,MAAM;AACzC;;;ACnCA;;;ACAO,SAAS,kBAA0B;AACxC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;;;ADNA;AACA;AASA;;;AEdA;AACA;AACA;AAEO,SAAS,WAAW,GAAmB;AAC5C,SAAO,EAAE,QAAQ,mBAAmB,EAAE,EAAE;AAC1C;AAEA,SAAS,QAAQ,SAAiB,OAAuB;AACvD,QAAM,QAAQ,QAAQ;AACtB,SAAO,MAAM,cAAc,SAAS,KAAK,IAAI;AAC/C;AAGO,SAAS,UAAU,OAAe,QAAQ,aAAa,GAAW;AACvE,QAAM,QAAQ,IAAI,KAAK;AACvB,QAAM,SAAS,KAAK,IAAI,GAAG,QAAQ,IAAI,WAAW,KAAK,CAAC;AACxD,QAAM,OAAO,KAAK,MAAM,SAAS,CAAC;AAClC,QAAM,QAAQ,SAAS;AACvB,SAAO;AAAA,IACL,OAAO,SAAI,SAAI,OAAO,IAAI,CAAC,GAAG,KAAK,GAAG,SAAI,OAAO,KAAK,CAAC,QAAG;AAAA,IAC1D,OAAO,SAAI,SAAI,OAAO,QAAQ,CAAC,CAAC,QAAG;AAAA,EACrC,EAAE,KAAK,IAAI;AACb;AAOA,SAAS,aAAa,OAAe,OAAuB;AAC1D,QAAM,SAAS,UAAK,KAAK;AACzB,QAAM,SAAS,KAAK,IAAI,GAAG,QAAQ,WAAW,MAAM,CAAC;AACrD,SAAO,SAAS,SAAI,OAAO,MAAM;AACnC;AAGO,SAAS,kBACd,MACA,aAAa,aAAa,GAClB;AACR,QAAM,MAAM;AACZ,QAAM,QAAQ,aAAa;AAC3B,QAAM,SAAS,CAAC,MAAM,MAAM,IAAI;AAChC,QAAM,MAAM,OAAO,IAAI,CAAC,MAAM,KAAK,MAAM,QAAQ,CAAC,CAAC;AACnD,QAAM,OAAO,IAAI,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI;AAClD,MAAI,CAAC,KAAK,QAAQ;AAElB,QAAM,SAAS;AACf,QAAM,MACJ,OAAO,QAAG,IACV,aAAa,KAAK,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC,IACrC,OAAO,QAAG,IACV,aAAa,KAAK,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC,IACrC,OAAO,QAAG,IACV,aAAa,KAAK,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC,IACrC,OAAO,QAAG;AAEZ,QAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM,MAAM,GAAG,CAAC;AAC9D,QAAM,OAAiB,CAAC,GAAG;AAE3B,WAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AAChC,UAAM,QAAQ,KAAK,IAAI,CAAC,GAAG,QAAQ,QAAQ,EAAE,MAAM,CAAC,KAAK,IAAI,OAAO,GAAG,CAAC,CAAC;AACzE,SAAK;AAAA,MACH,OAAO,QAAG,IACR,MAAM,CAAC,IACP,OAAO,QAAG,IACV,MAAM,CAAC,IACP,OAAO,QAAG,IACV,MAAM,CAAC,IACP,OAAO,QAAG;AAAA,IACd;AAAA,EACF;AAEA,QAAM,SACJ,OAAO,QAAG,IACV,OAAO,SAAI,OAAO,OAAO,CAAC,CAAC,CAAC,IAC5B,OAAO,QAAG,IACV,OAAO,SAAI,OAAO,OAAO,CAAC,CAAC,CAAC,IAC5B,OAAO,QAAG,IACV,OAAO,SAAI,OAAO,OAAO,CAAC,CAAC,CAAC,IAC5B,OAAO,QAAG;AAEZ,OAAK,KAAK,MAAM;AAChB,SAAO,KAAK,KAAK,IAAI;AACvB;AAGO,SAAS,cAAc,MAAoB,QAAQ,aAAa,GAAW;AAChF,SAAO,KACJ,IAAI,CAAC,QAAQ,YAAY,IAAI,OAAO,IAAI,OAAO,KAAK,CAAC,EACrD,KAAK,MAAM;AAChB;AAEO,SAAS,YAAY,OAAe,OAAiB,QAAQ,aAAa,GAAW;AAC1F,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAS,UAAK,KAAK;AACzB,QAAM,SAAS,KAAK,IAAI,GAAG,QAAQ,WAAW,MAAM,CAAC;AACrD,QAAM,MAAM,OAAO,SAAI,MAAM,GAAG,SAAI,OAAO,MAAM,CAAC,QAAG;AACrD,QAAM,SAAS,OAAO,SAAI,SAAI,OAAO,KAAK,CAAC,QAAG;AAC9C,QAAM,OAAO,MAAM,IAAI,CAAC,MAAM,OAAO,QAAG,IAAI,QAAQ,GAAG,QAAQ,CAAC,IAAI,OAAO,QAAG,CAAC;AAC/E,SAAO,CAAC,KAAK,GAAG,MAAM,MAAM,EAAE,KAAK,IAAI;AACzC;AAEO,SAAS,SAAS,MAAc,QAAQ,aAAa,GAAW;AACrE,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAS;AACf,QAAM,SAAS,KAAK,IAAI,GAAG,QAAQ,WAAW,MAAM,CAAC;AACrD,QAAM,MAAM,OAAO,SAAI,MAAM,GAAG,SAAI,OAAO,MAAM,CAAC,QAAG;AACrD,QAAM,SAAS,OAAO,SAAI,SAAI,OAAO,KAAK,CAAC,QAAG;AAC9C,SAAO,CAAC,KAAK,OAAO,QAAG,IAAI,QAAQ,MAAM,QAAQ,CAAC,IAAI,OAAO,QAAG,GAAG,MAAM,EAAE,KAAK,IAAI;AACtF;AAGO,SAAS,WAAW,MAAgB,MAAgB,UAAU,IAAI,MAAM,GAAa;AAC1F,QAAM,OAAO,KAAK,IAAI,KAAK,QAAQ,KAAK,MAAM;AAC9C,QAAM,MAAgB,CAAC;AACvB,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,UAAM,IAAI,cAAc,KAAK,CAAC,KAAK,IAAI,OAAO;AAC9C,UAAM,IAAI,KAAK,CAAC,KAAK;AACrB,QAAI,KAAK,IAAI,IAAI,OAAO,GAAG,IAAI,CAAC;AAAA,EAClC;AACA,SAAO;AACT;AAEO,SAAS,eAAe,SAAiB,MAAc,WAAW,IAAY;AACnF,SAAO,cAAc,IAAI,OAAO,GAAG,QAAQ,IAAI,MAAM,IAAI;AAC3D;;;AF1FA,SAASG,WAAU,SAAyB;AAC1C,QAAM,OAAO,IAAI,KAAK,OAAO,EAAE,QAAQ,IAAI,KAAK,IAAI;AACpD,SAAO,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,MAAO,KAAK,KAAK,GAAG,CAAC;AAC5D;AAEA,SAAS,gBAAgB,SAAmD;AAC1E,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,OAAOA,WAAU,OAAO;AAC9B,SAAO,gBAAgB,IAAI;AAC7B;AAEA,SAAS,oBAAoB,SAAmD;AAC9E,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO,IAAI,QAAQ,MAAM,GAAG,EAAE,CAAC;AACjC;AAEA,eAAsB,cAAc,SAAsD;AACxF,MAAI,YAA8B,CAAC;AACnC,MAAI;AACF,gBAAY,KAAK,MAAM,MAAM,UAAU,gBAAgB,CAAC;AAAA,EAC1D,QAAQ;AACN,gBAAY,CAAC;AAAA,EACf;AAEA,MAAI,QAAgC;AACpC,MAAI,SAAS;AACX,QAAI;AACF,YAAM,SAAS,MAAM,uBAAuB;AAC5C,YAAM,UAAU,MAAM,mBAAmB,MAAM;AAC/C,UAAI,WAA0B;AAC9B,UAAI,SAAS;AACX,cAAM,IAAI,QAAQ,MAAM,cAAc;AACtC,YAAI,GAAG;AACL,gBAAM,YAAY,OAAO,EAAE,CAAC,CAAC;AAC7B,gBAAMC,SAAQ,OAAO,EAAE,CAAC,CAAC;AACzB,gBAAMC,QAAOD,SAAQ;AACrB,qBAAW,GAAGC,KAAI,IAAID,MAAK;AAAA,QAC7B,OAAO;AACL,qBAAW;AAAA,QACb;AAAA,MACF;AAEA,YAAM,OAAO,QAAQ,yBAAyB,QAAQ;AACtD,YAAM,QAAQ,QAAQ;AACtB,YAAM,aACJ,QAAQ,QAAQ,SAAS,OACrB,GAAG,IAAI,IAAI,KAAK,sBAChB,QAAQ,OACN,GAAG,IAAI,iBACP;AAER,cAAQ,EAAE,UAAU,WAAW;AAAA,IACjC,QAAQ;AACN,cAAQ;AAAA,IACV;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,WAAW,MAAM;AACrC;AAEA,SAAS,oBAAoB,MAAgC;AAC3D,QAAM,OAAO,OAAO,gBAAgB,CAAC,EAAE,MAAM,IAAI;AAEjD,MAAI,KAAK,SAAS;AAChB,UAAM,IAAI,KAAK;AACf,UAAM,OAAO,EAAE,aAAa,EAAE,MAAM,MAAM,GAAG,EAAE,CAAC;AAChD,UAAM,YAAY,gBAAgB,EAAE,kBAAkB,MAAS;AAC/D,UAAM,UAAU,oBAAoB,EAAE,kBAAkB,MAAS;AAEjE,UAAME,aAAsB;AAAA,MAC1B,YAAY,iBAAiB,IAAI,GAAG;AAAA,MACpC,QAAQ,EAAE,KAAK;AAAA,MACf;AAAA,MACA,MAAM,iBAAiB,EAAE,gBAAgB,QAAG,EAAE;AAAA,MAC9C,MAAM,SAAS,EAAE,IAAI,EAAE;AAAA,IACzB;AAEA,UAAM,SAAS,WAAW,MAAMA,YAAW,IAAI,CAAC;AAChD,UAAM,QAAQ,CAAC,IAAI,GAAG,QAAQ,EAAE;AAEhC,UAAM,KAAK,QAAQ,kBAAa,CAAC;AACjC,UAAM,KAAK,MAAM,eAAe,CAAC;AAEjC,QAAI,KAAK,OAAO,SAAU,OAAM,KAAK,MAAM,eAAe,KAAK,MAAM,QAAQ,EAAE,CAAC;AAChF,QAAI,KAAK,OAAO,WAAY,OAAM,KAAK,MAAM,UAAU,KAAK,MAAM,UAAU,EAAE,CAAC;AAE/E,QAAI,WAAW;AACb,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,MAAM,SAAS,CAAC;AAC3B,UAAI,QAAS,OAAM,KAAK,MAAM,OAAO,CAAC;AAAA,IACxC;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,YAAY;AAAA,IAChB,YAAY,mBAAmB;AAAA,IAC/B,MAAM,eAAe;AAAA,IACrB;AAAA,IACA,MAAM,wBAAwB;AAAA,IAC9B,MAAM,kBAAkB;AAAA,EAC1B;AAEA,SAAO,CAAC,IAAI,GAAG,WAAW,MAAM,WAAW,IAAI,CAAC,GAAG,EAAE;AACvD;AAEA,SAAS,uBAAuB,MAAgC;AAC9D,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,MAAM,OAAO,IAAI,IAAI,OAAO,IAAI,MAAM,UAAU;AAAA,IAChD,MAAM,WAAW;AAAA,IACjB;AAAA,IACA,YAAY,mBAAmB;AAAA,IAC/B;AAAA,IACA,eAAe,SAAS,yBAAyB,EAAE;AAAA,IACnD,eAAe,UAAU,uBAAuB,EAAE;AAAA,IAClD,eAAe,WAAW,qBAAqB,EAAE;AAAA,EACnD;AAEA,MAAI,KAAK,SAAS;AAChB,UAAM;AAAA,MACJ,eAAe,SAAS,mBAAmB,EAAE;AAAA,MAC7C,eAAe,WAAW,gBAAgB,EAAE;AAAA,IAC9C;AAAA,EACF,OAAO;AACL,UAAM;AAAA,MACJ,eAAe,SAAS,mBAAmB,EAAE;AAAA,MAC7C,eAAe,aAAa,iBAAiB,EAAE;AAAA,IACjD;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,qBAAqB,MAAgC;AAC5D,QAAM,QAAQ,CAAC,EAAE;AACjB,QAAM,aAAa,KAAK,UAAU,CAAC,GAAG,cAAc;AAAA,IAClD;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,aAAW,KAAK,WAAW,MAAM,GAAG,CAAC,GAAG;AACtC,UAAM,OAAO,EAAE,QAAQ,SAAS,EAAE;AAClC,UAAM,KAAK,QAAQ,SAAI,IAAI,QAAQ,IAAI,CAAC;AAAA,EAC1C;AAEA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,MAAM,MAAM,IAAI,IAAI,YAAY,IAAI,MAAM,oBAAoB,CAAC;AAE1E,SAAO;AACT;AAEA,SAAS,UAAU,MAA8B;AAC/C,MAAI,KAAK,SAAS;AAChB,WAAO,MAAM,WAAW,IAAI,IAAI,aAAa,IAAI,MAAM,wBAAwB,IAAI,IAAI,UAAU,IAAI,MAAM,oBAAoB;AAAA,EACjI;AACA,SACE,MAAM,qBAAqB,IAC3B,IAAI,WAAW,IACf,MAAM,4EAA4E;AAEtF;AAEO,SAAS,iBAAiB,MAA8B;AAC7D,QAAM,QAAQ,aAAa;AAC3B,QAAM,OAA6C;AAAA,IACjD,EAAE,OAAO,WAAW,OAAO,oBAAoB,IAAI,EAAE;AAAA,IACrD,EAAE,OAAO,eAAe,OAAO,uBAAuB,IAAI,EAAE;AAAA,IAC5D,EAAE,OAAO,cAAc,OAAO,qBAAqB,IAAI,EAAE;AAAA,EAC3D;AAEA,QAAMC,QACJ,cAAc,KAAK,MACf,kBAAkB,MAAM,KAAK,IAC7B,cAAc,MAAM,KAAK;AAE/B,SAAO,CAAC,UAAU,cAAc,OAAO,IAAI,KAAK,GAAG,IAAIA,OAAM,IAAI,SAAS,UAAU,IAAI,GAAG,KAAK,CAAC,EAAE;AAAA,IACjG;AAAA,EACF;AACF;AAEO,SAAS,gBAAgB,SAAmC;AACjE,MAAI,CAAC,QAAQ,OAAQ,QAAO,MAAM,uBAAuB;AACzD,SAAO,QACJ,IAAI,CAAC,MAAM;AACV,UAAM,QAAQ;AAAA,MACZ,WAAW,IAAI,EAAE,OAAO,EAAE,IAAI,MAAM,WAAM,EAAE,IAAI,EAAE;AAAA,MAClD,GAAG,EAAE,WAAW,IAAI,CAAC,MAAM,QAAQ,SAAI,IAAI,QAAQ,EAAE,QAAQ,SAAS,EAAE,CAAC,CAAC;AAAA,IAC5E;AACA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB,CAAC,EACA,KAAK,MAAM;AAChB;AAGO,SAAS,uBAA+B;AAC7C,SAAO,iBAAiB;AAAA,IACtB,SAAS;AAAA,IACT,WAAW,CAAC;AAAA,IACZ,OAAO;AAAA,EACT,CAAC;AACH;;;AG9OA;AADA,SAAS,WAAAC,UAAS,SAAAC,cAAa;;;ACA/B;AACA;;;ACDA;AAEO,SAAS,WAAW,OAAe,MAAc,QAAyB;AAC/E,QAAM,QAAQ,CAAC,IAAI,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC;AAC5C,MAAI,OAAQ,OAAM,KAAK,IAAI,OAAO,MAAM,CAAC;AACzC,SAAO,MAAM,KAAK,IAAI;AACxB;;;ADHA;AAGA;AAGA,eAAsB,mBAAmB,QAAyC;AAChF,QAAM,OAAO,MAAM,OAAO,IAAsC,OAAO;AACvE,QAAM,OAAO,OAAO,IAAI;AACxB,MAAI,CAAC,KAAK,QAAQ;AAChB,WAAO,WAAW,eAAe,iBAAiB,qBAAqB,IAAI,0BAA0B;AAAA,EACvG;AAEA,QAAM,OAAO,KAAK,IAAI,CAAC,MAAM;AAAA,IAC3B,EAAE;AAAA,IACF,EAAE;AAAA,IACF,EAAE,UAAU,MAAM,QAAQ,EAAE,MAAM,IAAI,EAAE,OAAO,KAAK,IAAI,IAAI,MAAM,QAAG;AAAA,IACrE,EAAE,UAAU,MAAM,SAAS,IAAI,EAAE,SAAS,QAAQ,QAAQ,IAAI,MAAM,UAAU;AAAA,IAC9E,EAAE,eAAe,IAAI,KAAK,EAAE,YAAY,EAAE,mBAAmB,IAAI,MAAM,OAAO;AAAA,EAChF,CAAC;AAED,SAAO,YAAY,CAAC,QAAQ,UAAU,UAAU,UAAU,WAAW,GAAG,IAAI;AAC9E;AAEA,eAAsB,aAAa,QAAwB,OAAgC;AACzF,QAAM,OAAO,OAAO,SAAS,KAAK,EAAE;AACpC,SAAO;AACT;AAEA,eAAsB,iBAAiB,QAAgD;AACrF,QAAM,OAAO,MAAM,OAAO,IAAsC,OAAO;AACvE,QAAM,SAAS,OAAO,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,MAAM;AAChE,SAAO;AAAA,IACL;AAAA,IACA,OAAO,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,MAAM,KAAK,OAAO,EAAE,GAAG,EAAE;AAAA,EACtE;AACF;;;AD9BA;;;AGTA;AACA;;;ACQO,IAAM,iBAAoC;AAAA,EAC/C,EAAE,MAAM,SAAS,aAAa,gCAAgC,OAAO,eAAe,cAAc,KAAK;AAAA,EACvG,EAAE,MAAM,UAAU,aAAa,uBAAuB,cAAc,KAAK;AAAA,EACzE,EAAE,MAAM,WAAW,aAAa,oCAAoC,cAAc,KAAK;AAAA,EACvF,EAAE,MAAM,SAAS,aAAa,mBAAmB,cAAc,KAAK;AAAA,EACpE,EAAE,MAAM,WAAW,aAAa,yBAAyB,OAAO,oBAAoB;AAAA,EACpF,EAAE,MAAM,YAAY,aAAa,qBAAqB,OAAO,0BAA0B,cAAc,KAAK;AAAA,EAC1G,EAAE,MAAM,WAAW,aAAa,6BAA6B,OAAO,gBAAgB,cAAc,KAAK;AAAA,EACvG,EAAE,MAAM,WAAW,aAAa,wBAAwB,OAAO,gBAAgB,cAAc,KAAK;AAAA,EAClG,EAAE,MAAM,YAAY,aAAa,wBAAwB,SAAS,CAAC,WAAW,EAAE;AAAA,EAChF,EAAE,MAAM,cAAc,aAAa,qBAAqB;AAAA,EACxD,EAAE,MAAM,SAAS,aAAa,oBAAoB;AAAA,EAClD,EAAE,MAAM,SAAS,aAAa,uBAAuB,SAAS,CAAC,QAAQ,EAAE;AAAA,EACzE,EAAE,MAAM,aAAa,aAAa,4BAA4B,OAAO,YAAY;AAAA,EACjF,EAAE,MAAM,UAAU,aAAa,gCAAgC;AAAA,EAC/D,EAAE,MAAM,YAAY,aAAa,uBAAuB;AAAA,EACxD,EAAE,MAAM,SAAS,aAAa,kBAAkB,SAAS,CAAC,OAAO,EAAE;AACrE;AAEO,SAAS,YAAYC,QAA4C;AACtE,QAAMC,OAAMD,OAAM,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC,EAAE,YAAY;AACpD,SAAO,eAAe;AAAA,IACpB,CAAC,MAAM,EAAE,SAASC,QAAO,EAAE,SAAS,KAAK,CAAC,MAAM,MAAMA,IAAG;AAAA,EAC3D;AACF;;;AD7BO,SAAS,mBAA2B;AACzC,QAAM,UAAU,eAAe,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM;AACtD,QAAM,OAAO,QACV,MAAM,GAAG,KAAK,KAAK,QAAQ,SAAS,CAAC,CAAC,EACtC,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,CAAC,CAAC,IAAI,MAAM,EAAE,WAAW,CAAC,EAAE,EACjE,KAAK,IAAI;AACZ,QAAM,QAAQ,QACX,MAAM,KAAK,KAAK,QAAQ,SAAS,CAAC,CAAC,EACnC,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,CAAC,CAAC,IAAI,MAAM,EAAE,WAAW,CAAC,EAAE,EACjE,KAAK,IAAI;AAEZ,QAAM,SAAS;AAAA,IACb,MAAM,qBAAqB;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AAEX,SAAO;AAAA,IACL,MAAM,QAAQ,MAAM,KAAK,GAAG,EAAE,OAAO,WAAW,CAAC;AAAA,IACjD;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,IAAI,uEAAiE;AAAA,EACvE,EAAE,KAAK,IAAI;AACb;AAEO,SAAS,oBAAoB,SAA2B;AAC7D,MAAI,CAAC,QAAQ,OAAQ,QAAO,MAAM,yBAAyB;AAC3D,QAAM,OAAO,QACV,MAAM,GAAG,EACT,QAAQ,EACR,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,OAAO,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EACvD,KAAK,IAAI;AACZ,SAAO,MAAM,MAAM,EAAE,OAAO,kBAAkB,CAAC;AACjD;;;AErCA,eAAsB,qBAA6C;AACjE,QAAM,UAAU,eAAe,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO;AAAA,IAClE,MAAM,aAAa,EAAE,MAAM,EAAE,WAAW;AAAA,IACxC,OAAO,EAAE;AAAA,IACT,aAAa,EAAE;AAAA,EACjB,EAAE;AACF,SAAO,cAAc,mBAAmB,OAAO;AACjD;;;ACRA;AAFA,SAAS,SAAAC,QAAO,YAAAC,WAAU,aAAAC,YAAW,kBAAkB;AACvD,SAAS,QAAAC,aAAY;AAGrB,IAAM,eAAeA,MAAK,SAAS,GAAG,SAAS;AAC/C,IAAM,cAAc;AAEpB,eAAsB,cAAiC;AACrD,MAAI;AACF,UAAM,MAAM,MAAMF,UAAS,cAAc,MAAM;AAC/C,WAAO,IAAI,MAAM,IAAI,EAAE,OAAO,OAAO,EAAE,MAAM,CAAC,WAAW;AAAA,EAC3D,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,eAAsB,cAAc,MAA6B;AAC/D,QAAM,UAAU,KAAK,KAAK;AAC1B,MAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,EAAG;AACzC,QAAMD,OAAM,SAAS,GAAG;AAAA,IACtB,WAAW;AAAA,IACX,GAAI,QAAQ,aAAa,UAAU,CAAC,IAAI,EAAE,MAAM,IAAM;AAAA,EACxD,CAAC;AACD,QAAM,WAAW,cAAc,UAAU,MAAM,MAAM;AACvD;;;ANPA;;;AOjBA;AACA;AAEO,SAAS,SAAS,SAAiB,MAAuB;AAC/D,QAAM,OAAO,OAAO,GAAG,OAAO;AAAA;AAAA,EAAO,IAAI,KAAK;AAC9C,SAAO,MAAM,MAAM,EAAE,OAAO,QAAQ,CAAC;AACvC;AAEO,SAAS,WAAW,SAAyB;AAClD,SAAO,MAAM,QAAQ,OAAO,GAAG,EAAE,OAAO,OAAO,CAAC;AAClD;;;APUA;AAoBO,SAAS,eAAe,MAAsB;AACnD,MAAI,IAAI,KAAK,KAAK;AAClB,MAAI,CAAC,KAAK,EAAE,WAAW,GAAG,EAAG,QAAO;AAEpC,MAAI,EAAE,YAAY,EAAE,WAAW,QAAQ,EAAG,KAAI,EAAE,MAAM,CAAC,EAAE,KAAK;AAE9D,QAAM,QAAQ,EAAE,YAAY;AAC5B,QAAM,UAAkC;AAAA,IACtC,cAAc;AAAA,IACd,MAAM;AAAA,IACN,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AACA,MAAI,QAAQ,KAAK,EAAG,QAAO,QAAQ,KAAK;AAExC,MAAI,MAAM,WAAW,OAAO,EAAG,QAAO,SAAS,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC;AAChE,MAAI,MAAM,WAAW,aAAa,GAAG;AACnC,UAAM,QAAQ,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,KAAK;AAC5C,QAAI,MAAM,UAAU,EAAG,QAAO,WAAW,MAAM,CAAC,CAAC,IAAI,MAAM,MAAM,CAAC,EAAE,KAAK,GAAG,CAAC;AAAA,EAC/E;AACA,MAAI,MAAM,WAAW,SAAS,EAAG,QAAO,WAAW,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,QAAQ,OAAO,GAAG,CAAC;AAGxF,MAAI,CAAC,EAAE,SAAS,GAAG,KAAK,EAAE,SAAS,GAAG,EAAG,QAAO,SAAS,CAAC;AAE1D,SAAO;AACT;AAEA,SAAS,iBAAiB,KAAqB;AAC7C,QAAM,IAAI,IAAI,KAAK;AACnB,MAAI,CAAC,gBAAgB,KAAK,CAAC,EAAG,QAAO,WAAW,CAAC;AACjD,SAAO;AACT;AAEA,IAAM,iBAAyC;AAAA,EAC7C,SAAS;AAAA,EACT,WAAW;AAAA,EACX,UAAU;AAAA,EACV,SAAS;AAAA,EACT,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,WAAW;AAAA,EACX,SAAS;AAAA,EACT,aAAa;AAAA,EACb,UAAU;AAAA,EACV,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,aAAa;AACf;AAEA,SAAS,aAAaI,MAA4B;AAChD,SAAO,eAAeA,KAAI,YAAY,CAAC,KAAK;AAC9C;AAEA,eAAe,oBAAoBA,MAAa,KAAa,KAAyC;AACpG,UAAQA,KAAI,YAAY,GAAG;AAAA,IACvB,KAAK;AACH,UAAI,KAAK,MAAM,iBAAiB,CAAC;AACjC;AAAA,IAEF,KAAK;AAAA,IACL,KAAK,aAAa;AAChB,YAAM,SAAS,MAAM,mBAAmB;AACxC,UAAI,OAAQ,QAAO,qBAAqB,QAAQ,GAAG;AACnD;AAAA,IACF;AAAA,IAEA,KAAK;AACH,aAAO,EAAE,QAAQ,KAAK;AAAA,IAExB,KAAK,YAAY;AACf,YAAM,OAAO,MAAM,YAAY;AAC/B,UAAI,KAAK,MAAM,oBAAoB,IAAI,CAAC;AACxC;AAAA,IACF;AAAA,IAEA,KAAK,SAAS;AACZ,UAAI,CAAC,KAAK;AACR,YAAI,KAAK,MAAM,MAAS,oBAAoB,CAAC;AAC7C;AAAA,MACF;AACA,YAAM,SAAS,MAAM,uBAAuB;AAC5C,YAAM,WAAW,qBAAqB,IAAI,IAAI;AAC9C,YAAM,SAAS,MAAM,eAAe,QAAQ;AAAA,QAC1C,KAAK,iBAAiB,GAAG;AAAA,QACzB,MAAM;AAAA,QACN,YAAY,SAAS;AAAA,QACrB,gBAAgB;AAAA,MAClB,CAAC;AACD,eAAS,KAAK;AACd,UAAI,KAAK,MAAM,OAAO,MAAM;AAC5B;AAAA,IACF;AAAA,IAEA,KAAK,WAAW;AACd,YAAM,SAAS,MAAM,uBAAuB;AAC5C,YAAM,SAAS,MAAM,iBAAiB,MAAM;AAC5C,YAAM,OAAO,MAAM,mBAAmB,MAAM;AAC5C,UAAI,KAAK,MAAM,OAAO,GAAG,MAAM;AAAA;AAAA,EAAO,MAAM,YAAY,CAAC,KAAK,IAAI,KAAK,MAAM;AAC7E;AAAA,IACF;AAAA,IAEA,KAAK;AACH,YAAM,oBAAoB,GAAG;AAC7B;AAAA,IAEF,KAAK;AACH,YAAM,mBAAmB,GAAG;AAC5B;AAAA,IAEF,KAAK,WAAW;AACd,UAAI,CAAC,IAAI,SAAS,GAAG,GAAG;AACtB,YAAI,KAAK,MAAM,MAAS,0BAA0B,CAAC;AACnD;AAAA,MACF;AACA,YAAM,CAAC,GAAG,GAAG,MAAM,IAAI,IAAI,MAAM,GAAG;AACpC,UAAI,KAAK,MAAM,MAAM,aAAa,EAAE,KAAK,GAAG,OAAO,KAAK,GAAG,EAAE,KAAK,CAAC,CAAC;AACpE;AAAA,IACF;AAAA,IAEA,KAAK,cAAc;AACjB,YAAM,MAAM,MAAM,UAAU,gBAAgB;AAC5C,UAAI,KAAK,MAAM,gBAAgB,KAAK,MAAM,GAAG,CAAC,CAAC;AAC/C;AAAA,IACF;AAAA,IAEA,KAAK,YAAY;AACf,YAAM,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,KAAK;AAC9B,UAAI,CAAC,KAAK,CAAC,GAAG;AACZ,YAAI,KAAK,MAAM,MAAS,mCAAmC,CAAC;AAC5D;AAAA,MACF;AACA,YAAM,EAAE,mBAAAC,mBAAkB,IAAI,MAAM;AACpC,UAAI,KAAK,MAAM,MAAMA,mBAAkB,GAAG,GAAG,OAAO,CAAC;AACrD;AAAA,IACF;AAAA,IAEA,KAAK,WAAW;AACd,UAAI,CAAC,KAAK;AACR,YAAI,KAAK,MAAM,MAAS,0BAA0B,CAAC;AACnD;AAAA,MACF;AACA,YAAM,EAAE,kBAAAC,kBAAiB,IAAI,MAAM;AACnC,UAAI,KAAK,MAAM,MAAMA,kBAAiB,KAAK,CAAC,GAAG,OAAO,CAAC;AACvD;AAAA,IACF;AAAA,IAEA,KAAK,WAAW;AACd,UAAI,CAAC,KAAK;AACR,YAAI,KAAK,MAAM,MAAS,0BAA0B,CAAC;AACnD;AAAA,MACF;AACA,YAAM,EAAE,kBAAAC,kBAAiB,IAAI,MAAM;AACnC,YAAM,SAAS,MAAM,uBAAuB;AAC5C,UAAI,KAAK,MAAM,MAAMA,kBAAiB,QAAQ,KAAK,MAAM,CAAC;AAC1D;AAAA,IACF;AAAA,IAEA,KAAK;AAAA,IACL,KAAK,SAAS;AACZ,YAAM,SAAS,MAAM,wBAAwB;AAC7C,UAAI,KAAK,MAAM,OAAO,OAAO;AAC7B,aAAO,EAAE,SAAS,OAAO,SAAS,QAAQ,KAAK;AAAA,IACjD;AAAA,IAEA,KAAK,aAAa;AAChB,UAAI,KAAK,MAAM,MAAM,eAAe,EAAE,aAAa,KAAK,CAAC,CAAC;AAC1D,YAAM,SAAS,MAAM,uBAAuB;AAC5C,aAAO,EAAE,SAAS,MAAM,OAAO,IAAiB,KAAK,GAAG,QAAQ,KAAK;AAAA,IACvE;AAAA,IAEA;AACE,UAAI,KAAK,MAAM,SAAS,oBAAoBH,IAAG,IAAI,YAAY,CAAC;AAAA,EACpE;AACF,SAAO,CAAC;AACV;AAEA,eAAsB,qBAAqB,MAAc,KAAyC;AAChG,QAAM,UAAU,KAAK,KAAK;AAC1B,MAAI,CAAC,QAAS,QAAO,CAAC;AACtB,MAAI,YAAY,WAAW,YAAY,QAAS,QAAO,EAAE,MAAM,KAAK;AAEpE,QAAM,CAACA,MAAK,GAAG,IAAI,IAAI,QAAQ,MAAM,KAAK;AAC1C,QAAM,MAAM,KAAK,KAAK,GAAG,EAAE,KAAK;AAEhC,MAAI,CAACA,KAAI,WAAW,GAAG,GAAG;AACxB,QAAI,KAAK;AAAA,MACP;AAAA,QACE,wBAAwB,OAAO;AAAA,QAC/B,uCAAkC,OAAO,OAAO,CAAC;AAAA,EAA4B,OAAO,OAAO,CAAC;AAAA,MAC9F;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AAEA,MAAI,CAAC,YAAYA,IAAG,KAAKA,KAAI,WAAW,GAAG,GAAG;AAC5C,QAAI,KAAK,MAAM,SAAS,oBAAoBA,IAAG,IAAI,wBAAwB,CAAC;AAC5E,WAAO,CAAC;AAAA,EACV;AAEA,MAAI;AACF,UAAM,QAAQ,aAAaA,IAAG;AAC9B,QAAI,OAAO;AACT,aAAO,MAAM,YAAY,OAAO,MAAM,oBAAoBA,MAAK,KAAK,GAAG,CAAC;AAAA,IAC1E;AACA,WAAO,MAAM,oBAAoBA,MAAK,KAAK,GAAG;AAAA,EAChD,SAAS,GAAG;AACV,QAAI,KAAK,MAAM,eAAe,CAAC,CAAC;AAAA,EAClC;AACA,SAAO,CAAC;AACV;AAEA,SAAS,qBAAqB,MAAkB;AAC9C,MAAI,OAAO;AACX,SAAO;AAAA,IACL,OAAO,KAAa;AAClB,UAAI,KAAM,MAAK,YAAY;AAC3B,aAAO;AACP,cAAQ,OAAO,MAAM,MAAM,GAAG,CAAC;AAAA,IACjC;AAAA,IACA,OAAO;AACL,UAAI,KAAM,MAAK,YAAY;AAC3B,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,eAAe,oBAAoB,KAAkC;AACnE,QAAM,SAAS,MAAM,uBAAuB;AAE5C,SAAO,MAAM;AACX,UAAM,OAAO,MAAM,oBAAoB,QAAQ,SAAS,EAAE,OAAO,GAAG,CAAC;AACrE,UAAM,OAAO,MAAM,OAAO,IAAgD,4BAA4B;AACtG,UAAM,QAAQ,OAAO,IAAI;AAEzB,QAAI,CAAC,MAAM,QAAQ;AACjB,UAAI,KAAK,MAAM,WAAW,gBAAgB,6CAA6C,2BAA2B,CAAC;AACnH;AAAA,IACF;AAEA,QAAI,KAAK,MAAM,IAAI;AACnB,QAAI,KAAK,MAAM,EAAE;AAEjB,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA,MAAM,IAAI,CAAC,OAAO;AAAA,QAChB,MAAM,GAAG,SAAS,EAAE,YAAY,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,EAAE,iBAAiB,QAAG,KAAK,gBAAgB,EAAE,UAAU,CAAC;AAAA,QAC7H,OAAO,EAAE;AAAA,MACX,EAAE;AAAA,IACJ;AACA,QAAI,CAAC,OAAQ;AAEb,UAAM,SAAS,MAAM,OAAO,IAAgB,SAAS,MAAM,EAAE;AAC7D,QAAI,KAAK,MAAM,iBAAiB,QAAQ,OAAO,CAAC;AAEhD,UAAM,OAAO,MAAM;AAAA,MAAe,MAChCI,OAAM;AAAA,QACJ,SAAS,MAAM,sCAAmC;AAAA,QAClD,SAAS;AAAA,MACX,CAAC;AAAA,IACH,EAAE,MAAM,MAAM,GAAG;AACjB,QAAI,KAAK,YAAY,MAAM,IAAK;AAAA,EAClC;AACF;AAEA,eAAe,mBAAmB,KAAkC;AAClE,QAAM,SAAS,MAAM,uBAAuB;AAC5C,MAAI,KAAK,MAAM,MAAM,mBAAmB,MAAM,CAAC;AAC/C,MAAI,KAAK,MAAM,MAAM,kDAAkD,CAAC;AAExE,QAAM,SAAS,MAAM,eAAe,MAAMA,OAAM,EAAE,SAAS,UAAU,SAAS,GAAG,CAAC,CAAC,EAAE,MAAM,MAAM,EAAE;AAEnG,MAAI,OAAO,YAAY,MAAM,KAAK;AAChC,UAAM,QAAQ,MAAM,iBAAiB,MAAM;AAC3C,QAAI,CAAC,MAAO;AACZ,UAAM,KAAK,MAAM;AAAA,MAAe,MAC9BC,SAAQ,EAAE,SAAS,wBAAwB,SAAS,MAAM,CAAC;AAAA,IAC7D,EAAE,MAAM,MAAM,KAAK;AACnB,QAAI,GAAI,KAAI,KAAK,MAAM,WAAW,MAAM,aAAa,QAAQ,KAAK,CAAC,CAAC;AAAA,EACtE,WAAW,OAAO,YAAY,MAAM,KAAK;AACvC,UAAM,OAAO,MAAM,eAAe,MAAM,iBAAiB,CAAC;AAC1D,UAAM,UAAU,MAAM,OAAO,KAAoD,SAAS,EAAE,KAAK,CAAC;AAClG,QAAI,KAAK,MAAM,QAAQ,YAAY,QAAQ,IAAI,KAAK,QAAQ,MAAM,GAAG,CAAC;AACtE,QAAI,KAAK,MAAM,OAAO,+CAA0C,CAAC;AACjE,QAAI,KAAK,MAAM,QAAQ,GAAG;AAAA,EAC5B;AACF;;;AL9UA;;;AaFO,SAAS,eAAe,UAA6B,SAAyD;AACnH,QAAM,QAAQ,SAAS,IAAI,CAAC,MAAM,EAAE,IAAI;AACxC,SAAO,CAAC,SAAqC;AAC3C,UAAM,UAAU,KAAK,UAAU;AAC/B,QAAI,CAAC,QAAQ,WAAW,GAAG,GAAG;AAC5B,UAAI,YAAY,GAAI,QAAO,CAAC,CAAC,GAAG,OAAO,GAAG,QAAQ,MAAM,GAAG,EAAE,QAAQ,CAAC,GAAG,IAAI;AAC7E,aAAO,CAAC,CAAC,GAAG,IAAI;AAAA,IAClB;AACA,UAAM,OAAO,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;AACrE,WAAO,CAAC,KAAK,SAAS,OAAO,OAAO,IAAI;AAAA,EAC1C;AACF;;;AbJA;AAGA,eAAsB,cAAc,gBAAmD;AACrF,MAAI,UAAU;AACd,QAAM,UAAUC,KAAI;AACpB,QAAM,UAAU,MAAM,YAAY;AAElC,QAAM,UAAU,YAAY;AAC1B,QAAI,gBAAgB,EAAE,aAAa;AACjC,cAAQ,OAAO,MAAM,eAAe;AAAA,IACtC;AACA,UAAM,OAAO,MAAM,cAAc,OAAO;AACxC,YAAQ,IAAI,iBAAiB,IAAI,CAAC;AAClC,YAAQ,IAAI,EAAE;AAAA,EAChB;AAEA,QAAM,QAAQ;AAEd,QAAM,KAAc,yBAAgB;AAAA,IAClC,OAAAC;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,WAAW,eAAe,gBAAgB,OAAO;AAAA,IACjD,aAAa;AAAA,EACf,CAAC;AAED,KAAG,GAAG,UAAU,MAAM;AACpB,YAAQ,IAAI,MAAM,YAAY,CAAC;AAC/B,OAAG,MAAM;AACT,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AAED;AAAA,IACE,MAAM,GAAG,MAAM;AAAA,IACf,MAAM;AACJ,cAAQ,OAAO,MAAM,IAAI;AACzB,SAAG,OAAO;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,SAAS,MAAM,QAAQ,OAAO,MAAM,OAAO,IAAI,CAAC;AAEtD,SAAO;AAEP,mBAAiB,QAAQ,IAAI;AAC3B,UAAM,cAAc,IAAI;AACxB,YAAQ,KAAK,KAAK,KAAK,CAAC;AAExB,UAAM,OAAO;AAAA,MACX,OAAO,CAAC,SAAiB,QAAQ,IAAI,IAAI;AAAA,MACzC,OAAO,CAAC,SAAiB,QAAQ,MAAM,IAAI;AAAA,MAC3C,WAAW,MAAM,QAAQ,OAAO,MAAM,UAAU;AAAA,IAClD;AAEA,UAAM,aAAa,eAAe,IAAI;AACtC,UAAM,SAAS,MAAM,qBAAqB,YAAY;AAAA,MACpD,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,QAAI,OAAO,QAAS,WAAU,OAAO;AACrC,QAAI,OAAO,MAAM;AACf,cAAQ,IAAI,MAAM,UAAU,CAAC;AAC7B,SAAG,MAAM;AACT;AAAA,IACF;AACA,QAAI,OAAO,OAAQ,OAAM,QAAQ;AAEjC,WAAO;AAAA,EACT;AACF;;;AclFA,YAAYC,eAAc;AAC1B,SAAS,SAASC,QAAO,UAAUC,eAAc;AAEjD;;;ACHA;AACA;AAEA;AAEA,SAAS,uBAAuB,OAA8E;AAC5G,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAO,MAAM,SAAS;AAAA,IACtB,WAAW,MAAM,aAAa;AAAA,IAC9B,MAAM;AAAA,IACN,cAAc;AAAA,IACd,gBAAgB,MAAM,kBAAkB;AAAA,IACxC,YAAY,MAAM,cAAc;AAAA,EAClC;AACF;AAEA,eAAsB,gBAA6C;AACjE,QAAM,QAAQ,MAAM,gBAAgB;AACpC,MAAI,CAAC,OAAO,QAAS,QAAO;AAE5B,MAAI;AACF,UAAM,SAAS,MAAM,eAAe,OAAO;AAC3C,UAAM,UAAU,MAAM,OAAO,IAAiB,KAAK;AACnD,WAAO;AAAA,EACT,SAAS,GAAG;AACV,QAAI,aAAa,YAAY,EAAE,WAAW,KAAK;AAC7C,UAAI,MAAM,sCAAsC;AAChD,YAAM,iBAAiB;AACvB,aAAO;AAAA,IACT;AACA,QAAI,MAAM,sDAAsD,CAAC;AACjE,WAAO,uBAAuB,KAAK;AAAA,EACrC;AACF;;;ADzBA,SAAS,eAA8B;AACrC,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,KAAc,0BAAgB,EAAE,OAAAC,QAAO,QAAAC,SAAQ,UAAU,KAAK,CAAC;AACrE,IAAAA,QAAO,MAAM,OAAO,qCAAqC,CAAC;AAC1D,OAAG,KAAK,QAAQ,MAAM;AACpB,SAAG,MAAM;AACT,cAAQ;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AACH;AAEA,eAAsB,cAA2C;AAC/D,QAAM,WAAW,MAAM,cAAc;AACrC,MAAI,SAAU,QAAO;AAErB,MAAI,CAACA,QAAO,MAAO,QAAO;AAE1B,UAAQ,IAAI,qBAAqB,CAAC;AAClC,QAAM,aAAa;AAEnB,MAAI;AACF,UAAM,SAAS,MAAM,wBAAwB;AAC7C,YAAQ,IAAI,OAAO,OAAO;AAC1B,WAAO,OAAO;AAAA,EAChB,SAAS,GAAG;AACV,YAAQ,IAAI,MAAM,eAAe,CAAC,CAAC,CAAC;AACpC,YAAQ,IAAI,MAAM,+CAA+C,CAAC;AAClE,WAAO;AAAA,EACT;AACF;;;AEjCA,eAAsB,qBAAoC;AACxD,MAAI,UAAU,MAAM,cAAc;AAClC,MAAI,CAAC,SAAS;AACZ,cAAU,MAAM,YAAY;AAAA,EAC9B;AACA,QAAM,cAAc,OAAO;AAC7B;;;ACNA,kBAAkB;AAElB,eAAe,KAAK,MAA+B;AACjD,MAAI,KAAK,UAAU,GAAG;AACpB,UAAM,mBAAmB;AACzB;AAAA,EACF;AACA,QAAM,aAAa,EAAE,WAAW,IAAI;AACtC;AAEA,KAAK,QAAQ,IAAI,EAAE,MAAM,CAAC,MAAM;AAC9B,UAAQ,MAAM,eAAe,CAAC,CAAC;AAC/B,UAAQ,KAAK,YAAY,CAAC,CAAC;AAC7B,CAAC;","names":["mkdir","readFile","writeFile","chmod","homedir","join","ensureDir","stdout","init_theme","writeFile","init_theme","cwd","stdout","input","readFile","join","cwd","output","init_theme","cwd","runReportCommand","runWhatIfCommand","runCompareCommand","input","cwd","readFile","join","existsSync","daysUntil","limit","used","textBlock","main","confirm","input","input","cmd","mkdir","readFile","writeFile","join","cmd","runCompareCommand","runWhatIfCommand","runReportCommand","input","confirm","cwd","input","readline","input","output","input","output"]}