@wrongstack/tools 0.236.0 → 0.255.0

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.
Files changed (47) hide show
  1. package/dist/audit.js +591 -48
  2. package/dist/audit.js.map +1 -1
  3. package/dist/background-indexer-CJ5JiV5i.d.ts +365 -0
  4. package/dist/bash.js +135 -20
  5. package/dist/bash.js.map +1 -1
  6. package/dist/builtin.js +1840 -1109
  7. package/dist/builtin.js.map +1 -1
  8. package/dist/codebase-index/index.d.ts +53 -2
  9. package/dist/codebase-index/index.js +870 -364
  10. package/dist/codebase-index/index.js.map +1 -1
  11. package/dist/codebase-index/worker.d.ts +2 -0
  12. package/dist/codebase-index/worker.js +2326 -0
  13. package/dist/codebase-index/worker.js.map +1 -0
  14. package/dist/diff.js +2 -1
  15. package/dist/diff.js.map +1 -1
  16. package/dist/exec.js +116 -5
  17. package/dist/exec.js.map +1 -1
  18. package/dist/format.js +591 -48
  19. package/dist/format.js.map +1 -1
  20. package/dist/git.js +2 -1
  21. package/dist/git.js.map +1 -1
  22. package/dist/grep.js +2 -2
  23. package/dist/grep.js.map +1 -1
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.js +1189 -496
  26. package/dist/index.js.map +1 -1
  27. package/dist/install.js +591 -48
  28. package/dist/install.js.map +1 -1
  29. package/dist/lint.js +590 -47
  30. package/dist/lint.js.map +1 -1
  31. package/dist/logs.js +1 -1
  32. package/dist/logs.js.map +1 -1
  33. package/dist/outdated.js +1 -1
  34. package/dist/outdated.js.map +1 -1
  35. package/dist/pack.js +1840 -1109
  36. package/dist/pack.js.map +1 -1
  37. package/dist/patch.js +1 -1
  38. package/dist/patch.js.map +1 -1
  39. package/dist/replace.js +3 -2
  40. package/dist/replace.js.map +1 -1
  41. package/dist/test.d.ts +1 -0
  42. package/dist/test.js +605 -55
  43. package/dist/test.js.map +1 -1
  44. package/dist/typecheck.js +591 -48
  45. package/dist/typecheck.js.map +1 -1
  46. package/package.json +3 -3
  47. package/dist/background-indexer-CtbgPExj.d.ts +0 -228
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/codebase-index/schema.ts","../../src/codebase-index/lsp-kind.ts","../../src/codebase-index/writer.ts","../../src/codebase-index/ts-parser.ts","../../src/codebase-index/go-parser.ts","../../src/codebase-index/py-parser.ts","../../src/codebase-index/rs-parser.ts","../../src/codebase-index/json-parser.ts","../../src/codebase-index/yaml-parser.ts","../../src/codebase-index/gitignore.ts","../../src/codebase-index/background-indexer.ts","../../src/codebase-index/indexer.ts","../../src/codebase-index/codebase-index-tool.ts","../../src/codebase-index/bm25.ts","../../src/codebase-index/codebase-search-tool.ts","../../src/codebase-index/codebase-stats-tool.ts"],"names":["path","ts","parseSymbols","path2","mkdirSync","path3","os2","writeFileSync","execFileSync","expectDefined","regexParse","basename","path5","makeSymbol","fs2","path6","resolve","compileGlob","path7","stat","c","store"],"mappings":"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","file":"index.js","sourcesContent":["// ─── Symbol kind taxonomy ───────────────────────────────────────────────────────\n\n/** Language a symbol belongs to. */\nexport type SymbolLang = 'ts' | 'js' | 'tsx' | 'jsx' | 'go' | 'py' | 'rs' | 'json' | 'yaml';\n\n/** What kind of symbol this is. */\nexport type SymbolKind =\n | 'class'\n | 'interface'\n | 'enum'\n | 'type'\n | 'function'\n | 'method'\n | 'var'\n | 'const'\n | 'let'\n | 'property'\n | 'parameter'\n | 'namespace'\n | 'object' // JSON root object\n | 'literal' // scalar value in JSON/YAML\n | 'schema' // JSON Schema $ref/$schema entry\n // Rust-specific\n | 'struct'\n | 'trait'\n | 'impl'\n | 'static'\n | 'mod';\n\n/** A single indexed code symbol. */\nexport interface Symbol {\n id: number;\n lang: SymbolLang;\n kind: SymbolKind;\n name: string;\n file: string; // absolute path\n line: number; // 1-based\n col: number; // 0-based\n signature: string; // e.g. \"function foo(a: string): Promise<void>\"\n docComment: string; // JSDoc / docstring first line\n scope: string; // e.g. \"MyClass.method\" or module-level \"\"\n text: string; // concatenated searchable text: name + signature + docComment\n}\n\n/** Extracted symbols and cross-references for one file. */\nexport interface FileSymbols {\n file: string;\n lang: SymbolLang;\n symbols: Symbol[];\n refs?: Ref[] | undefined; // cross-references extracted from this file (optional for back-compat)\n mtimeMs: number;\n}\n\n/** Source file metadata tracked for incremental indexing. */\nexport interface FileMeta {\n file: string;\n lang: SymbolLang;\n mtimeMs: number;\n symbolCount: number;\n lastIndexed: number; // unix ms\n}\n\n/** Statistics about the index. */\nexport interface IndexStats {\n totalSymbols: number;\n totalFiles: number;\n byLang: Record<SymbolLang, number>;\n byKind: Record<SymbolKind, number>;\n indexPath: string;\n lastIndexed: number | null;\n sizeBytes: number;\n version: number;\n}\n\n/** Result of a search query. */\nexport interface SearchResult {\n id: number;\n name: string;\n kind: SymbolKind;\n lang: SymbolLang;\n file: string;\n line: number;\n col: number;\n signature: string;\n docComment: string;\n score: number;\n snippet: string;\n /** Original LSP SymbolKind number if the result was filtered by an LSP kind. */\n lspKind?: number | undefined;\n}\n\n/** Result of a full reindex. */\nexport interface IndexResult {\n filesIndexed: number;\n symbolsIndexed: number;\n langStats: Record<SymbolLang, number>;\n durationMs: number;\n errors: string[];\n}\n\n// ─── Cross-reference types ───────────────────────────────────────────────────\n\n/** What kind of reference this is. */\nexport type CallType = 'call' | 'type_ref' | 'inherit' | 'implement' | 'import';\n\n/** A cross-reference between two symbols (who references whom). */\nexport interface Ref {\n id?: number | undefined;\n fromId: number; // symbol that makes the reference\n toName: string; // resolved name of the referenced symbol\n toId?: number | undefined; // resolved target symbol id (filled after index resolution)\n callType: CallType; // kind of reference\n line: number; // source line where the reference occurs\n}\n\n// ─── Schema version ───────────────────────────────────────────────────────────\n\nexport const SCHEMA_VERSION = 1;\n","/**\n * LSP SymbolKind mapping utilities.\n *\n * LSP SymbolKind numbers are defined by vscode-languageserver-protocol.\n * This module maps between LSP kind numbers and the internal SymbolKind taxonomy.\n */\n\nimport type { SymbolKind } from './schema.js';\n\n/**\n * LSP SymbolKind values (1–26) as defined by vscode-languageserver-protocol.\n */\nexport enum LSPSymbolKind {\n File = 1,\n Module = 2,\n Namespace = 3,\n Package = 4,\n Class = 5,\n Method = 6,\n Property = 7,\n Field = 8,\n Constructor = 9,\n Enum = 10,\n Interface = 11,\n Function = 12,\n Variable = 13,\n Constant = 14,\n String = 15,\n Number = 16,\n Boolean = 17,\n Array = 18,\n Object = 19,\n Key = 20,\n Null = 21,\n EnumMember = 22,\n Struct = 23,\n Event = 24,\n Operator = 25,\n TypeParameter = 26,\n}\n\n/**\n * Maps an LSP kind number to the corresponding internal SymbolKind.\n * Returns null if the LSP kind has no equivalent in the internal taxonomy.\n */\nexport function lspKindToInternalKind(k: number): SymbolKind | null {\n switch (k) {\n case LSPSymbolKind.Class: return 'class';\n case LSPSymbolKind.Method: return 'method';\n case LSPSymbolKind.Property:\n case LSPSymbolKind.Field: return 'property';\n case LSPSymbolKind.Constructor: return 'class';\n case LSPSymbolKind.Enum: return 'enum';\n case LSPSymbolKind.Interface: return 'interface';\n case LSPSymbolKind.Function: return 'function';\n case LSPSymbolKind.Variable: return 'var';\n case LSPSymbolKind.Constant: return 'const';\n case LSPSymbolKind.EnumMember: return 'enum';\n case LSPSymbolKind.TypeParameter:return 'type';\n case LSPSymbolKind.Namespace: return 'namespace';\n default: return null;\n }\n}\n\n/**\n * Maps an internal SymbolKind to the corresponding LSP kind number.\n * Returns null if the internal kind has no equivalent LSP kind.\n */\nexport function internalKindToLspKind(k: SymbolKind): number | null {\n switch (k) {\n case 'class': return LSPSymbolKind.Class;\n case 'method': return LSPSymbolKind.Method;\n case 'property': return LSPSymbolKind.Property;\n case 'function': return LSPSymbolKind.Function;\n case 'var': return LSPSymbolKind.Variable;\n case 'const': return LSPSymbolKind.Constant;\n case 'let': return LSPSymbolKind.Variable;\n case 'enum': return LSPSymbolKind.Enum;\n case 'interface': return LSPSymbolKind.Interface;\n case 'namespace': return LSPSymbolKind.Namespace;\n case 'type': return LSPSymbolKind.TypeParameter;\n // parameter and other internal-only kinds have no LSP equivalent\n default: return null;\n }\n}\n\n/**\n * Returns true if `k` is a valid LSP SymbolKind number (1–26).\n */\nexport function isLspKind(k: number): boolean {\n return Number.isInteger(k) && k >= 1 && k <= 26;\n}\n","import { expectDefined } from '@wrongstack/core';\n/**\n * SQLite storage layer for the codebase index.\n *\n * Uses `node:sqlite` (synchronous API — DatabaseSync class).\n * Database file: ~/.wrongstack/projects/<hash>/codebase-index/index.db — kept\n * out of the repo so it never clutters the working tree or needs gitignoring.\n */\n\nimport { createRequire } from 'node:module';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { DatabaseSync } from 'node:sqlite';\nimport { resolveWstackPaths } from '@wrongstack/core';\nimport type { FileMeta, IndexStats, Ref, SearchResult, Symbol as IndexSymbol, SymbolKind, SymbolLang } from './schema.js';\nimport { SCHEMA_VERSION } from './schema.js';\nimport { lspKindToInternalKind } from './lsp-kind.js';\nconst DB_FILE = 'index.db';\n\n/**\n * Resolve the per-project index directory. By default it lives under the\n * global project dir (`~/.wrongstack/projects/<hash>/codebase-index`),\n * matching every other piece of per-project state. Callers may pass an\n * explicit `override` (used by tests and any wiring that already resolved the\n * path) to avoid touching the real home directory.\n */\nexport function resolveIndexDir(projectRoot: string, override?: string): string {\n return override ?? resolveWstackPaths({ projectRoot }).projectCodebaseIndex;\n}\n\n/**\n * Optional index-directory override carried on the run context's `meta` bag.\n * Production leaves it unset (the index resolves to the global per-project\n * dir); tests and bespoke wiring set `meta.codebaseIndexDir` to redirect it.\n */\nexport function codebaseIndexDirOverride(ctx: { meta?: Record<string, unknown> }): string | undefined {\n const v = ctx.meta?.['codebaseIndexDir'];\n return typeof v === 'string' ? v : undefined;\n}\n\nlet warningSilenced = false;\n/**\n * Swallow the one-time `ExperimentalWarning: SQLite ...` Node prints the first\n * time `node:sqlite` loads. Patched only once, and only filters that specific\n * warning — every other warning passes through untouched.\n */\nfunction silenceSqliteExperimentalWarning(): void {\n if (warningSilenced) return;\n warningSilenced = true;\n const original = process.emitWarning.bind(process);\n process.emitWarning = ((warning: unknown, ...rest: unknown[]): void => {\n const msg = typeof warning === 'string' ? warning : ((warning as Error)?.message ?? '');\n const name = typeof warning === 'string' ? String(rest[0] ?? '') : ((warning as Error)?.name ?? '');\n if (/sqlite/i.test(msg) && /experimental/i.test(`${name} ${msg}`)) return;\n (original as (w: unknown, ...r: unknown[]) => void)(warning, ...rest);\n }) as typeof process.emitWarning;\n}\n\nlet DatabaseSyncCtor: typeof DatabaseSync | undefined;\n/**\n * Load `node:sqlite`'s `DatabaseSync` lazily. Keeping this off the module's\n * top-level import means the codebase-index tools can be registered at CLI boot\n * without eagerly loading SQLite — so a runtime that lacks `node:sqlite` (it is\n * experimental, available since Node 22.5) only fails if the index is actually\n * used, with a clear message instead of a crash on import.\n */\nfunction loadDatabaseSync(): typeof DatabaseSync {\n if (DatabaseSyncCtor) return DatabaseSyncCtor;\n silenceSqliteExperimentalWarning();\n try {\n const req = createRequire(import.meta.url);\n DatabaseSyncCtor = (req('node:sqlite') as typeof import('node:sqlite')).DatabaseSync;\n } catch (err) {\n throw new Error(\n \"The codebase index needs Node's built-in SQLite (node:sqlite), available since Node 22.5. \" +\n `This runtime doesn't provide it: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n return DatabaseSyncCtor;\n}\n\nexport class IndexStore {\n private db: DatabaseSync;\n /** Absolute path to this project's index directory. */\n private readonly indexDir: string;\n\n constructor(projectRoot: string, opts: { indexDir?: string | undefined } = {}) {\n this.indexDir = resolveIndexDir(projectRoot, opts.indexDir);\n fs.mkdirSync(this.indexDir, { recursive: true });\n const Database = loadDatabaseSync();\n this.db = new Database(path.join(this.indexDir, DB_FILE));\n this.initSchema();\n }\n\n private initSchema(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS metadata (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n CREATE TABLE IF NOT EXISTS files (\n file TEXT PRIMARY KEY,\n lang TEXT NOT NULL,\n mtime_ms INTEGER NOT NULL,\n symbol_count INTEGER NOT NULL DEFAULT 0,\n last_indexed INTEGER NOT NULL\n );\n CREATE TABLE IF NOT EXISTS symbols (\n id INTEGER PRIMARY KEY,\n lang TEXT NOT NULL,\n kind TEXT NOT NULL,\n name TEXT NOT NULL,\n file TEXT NOT NULL,\n line INTEGER NOT NULL,\n col INTEGER NOT NULL,\n signature TEXT NOT NULL DEFAULT '',\n doc_comment TEXT NOT NULL DEFAULT '',\n scope TEXT NOT NULL DEFAULT '',\n text TEXT NOT NULL DEFAULT '',\n file_fk TEXT NOT NULL\n );\n `);\n\n this.db.exec('CREATE INDEX IF NOT EXISTS idx_s_name ON symbols(name)');\n this.db.exec('CREATE INDEX IF NOT EXISTS idx_s_kind ON symbols(kind)');\n this.db.exec('CREATE INDEX IF NOT EXISTS idx_s_lang ON symbols(lang)');\n this.db.exec('CREATE INDEX IF NOT EXISTS idx_s_file ON symbols(file)');\n\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS refs (\n id INTEGER PRIMARY KEY,\n from_id INTEGER NOT NULL,\n to_name TEXT NOT NULL,\n to_id INTEGER,\n call_type TEXT NOT NULL,\n line INTEGER NOT NULL\n );\n `);\n\n this.db.exec('CREATE INDEX IF NOT EXISTS idx_r_from ON refs(from_id)');\n this.db.exec('CREATE INDEX IF NOT EXISTS idx_r_to_id ON refs(to_id)');\n this.db.exec('CREATE INDEX IF NOT EXISTS idx_r_to_name ON refs(to_name)');\n this.db.exec('CREATE INDEX IF NOT EXISTS idx_r_call_type ON refs(call_type)');\n\n const versionRows = this.db.prepare('SELECT value FROM metadata WHERE key = ?').all('version');\n if (!versionRows.length) {\n this.db.prepare('INSERT INTO metadata(key, value) VALUES (?, ?)').run('version', String(SCHEMA_VERSION));\n }\n }\n\n // ─── Symbol CRUD ─────────────────────────────────────────────────────────────\n\n insertSymbols(symbols: IndexSymbol[], nextId: number): number {\n const stmt = this.db.prepare(\n `INSERT INTO symbols(id, lang, kind, name, file, line, col, signature, doc_comment, scope, text, file_fk)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n );\n\n let id = nextId;\n for (const s of symbols) {\n stmt.run(\n id++,\n s.lang,\n s.kind,\n s.name,\n s.file,\n s.line,\n s.col,\n s.signature,\n s.docComment,\n s.scope,\n s.text,\n s.file,\n );\n }\n return id;\n }\n\n deleteSymbolsForFile(file: string): void {\n this.db.prepare('DELETE FROM symbols WHERE file_fk = ?').run(file);\n }\n\n deleteFile(file: string): void {\n this.db.prepare('DELETE FROM files WHERE file = ?').run(file);\n }\n\n // ─── File metadata ──────────────────────────────────────────────────────────\n\n upsertFile(meta: FileMeta): void {\n this.db.prepare(\n `INSERT INTO files(file, lang, mtime_ms, symbol_count, last_indexed)\n VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(file) DO UPDATE SET\n lang = excluded.lang,\n mtime_ms = excluded.mtime_ms,\n symbol_count = excluded.symbol_count,\n last_indexed = excluded.last_indexed`,\n ).run(meta.file, meta.lang, meta.mtimeMs, meta.symbolCount, meta.lastIndexed);\n }\n\n getFileMeta(file: string): FileMeta | null {\n const rows = this.db.prepare(\n 'SELECT file, lang, mtime_ms, symbol_count, last_indexed FROM files WHERE file = ?',\n ).all(file) as { file: string; lang: string; mtime_ms: number; symbol_count: number; last_indexed: number }[];\n if (!rows.length) return null;\n const r = expectDefined(rows[0]);\n return { file: r.file, lang: r.lang as SymbolLang, mtimeMs: r.mtime_ms, symbolCount: r.symbol_count, lastIndexed: r.last_indexed };\n }\n\n getAllFileMetas(): FileMeta[] {\n return (this.db.prepare(\n 'SELECT file, lang, mtime_ms, symbol_count, last_indexed FROM files',\n ).all() as { file: string; lang: string; mtime_ms: number; symbol_count: number; last_indexed: number }[]).map(\n (r) => ({ file: r.file, lang: r.lang as SymbolLang, mtimeMs: r.mtime_ms, symbolCount: r.symbol_count, lastIndexed: r.last_indexed }),\n );\n }\n\n // ─── Search ──────────────────────────────────────────────────────────────────\n\n search(\n query: string,\n filter?: { kind?: SymbolKind | undefined; lang?: SymbolLang | undefined; file?: string | undefined; lspKind?: number | undefined },\n ): SearchResult[] {\n const conditions: string[] = [];\n const values: unknown[] = [];\n\n let effectiveKind: SymbolKind | undefined = filter?.kind;\n if (filter?.lspKind !== undefined) {\n const mapped = lspKindToInternalKind(filter.lspKind);\n if (mapped !== null) {\n effectiveKind = mapped;\n } else {\n // LSP kind was explicitly provided but has no internal mapping → no results\n return [];\n }\n }\n\n if (effectiveKind) {\n conditions.push('kind = ?');\n values.push(effectiveKind);\n }\n if (filter?.lang) {\n conditions.push('lang = ?');\n values.push(filter.lang);\n }\n if (filter?.file) {\n conditions.push('file LIKE ?');\n values.push(`%${filter.file}%`);\n }\n if (query.trim()) {\n const tokens = query.toLowerCase().split(/\\s+/).filter(Boolean);\n const tokenConds = tokens.map(() => 'text LIKE ?');\n conditions.push(`(${tokenConds.join(' OR ')})`);\n for (const t of tokens) values.push(`%${t}%`);\n }\n\n const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';\n const sql = `SELECT id, lang, kind, name, file, line, col, signature, doc_comment, text FROM symbols ${where}`;\n\n const stmt = this.db.prepare(sql);\n const rows = stmt.all(...values as (string | number)[]) as {\n id: number; lang: string; kind: string; name: string; file: string;\n line: number; col: number; signature: string; doc_comment: string; text: string;\n }[];\n\n return rows.map((r) => ({\n id: r.id,\n lang: r.lang as SymbolLang,\n kind: r.kind as SymbolKind,\n name: r.name,\n file: r.file,\n line: r.line,\n col: r.col,\n signature: r.signature,\n docComment: r.doc_comment,\n score: 0,\n snippet: '',\n lspKind: filter?.lspKind,\n }));\n }\n\n getAllIndexable(): Array<{ id: number; text: string }> {\n return (this.db.prepare('SELECT id, text FROM symbols').all() as { id: number; text: string }[]).map(\n ({ id, text }) => ({ id, text }),\n );\n }\n\n /**\n * Largest symbol id currently in the table (0 when empty). New ids must be\n * allocated from this, NOT from `COUNT(*)`: incremental reindexes delete a\n * changed file's rows, so the row count drops below the max id and a\n * count-based id would collide with a surviving row (UNIQUE constraint on\n * `symbols.id`). Ids may have gaps — that is fine.\n */\n getMaxSymbolId(): number {\n const rows = this.db.prepare('SELECT MAX(id) AS m FROM symbols').all() as { m: number | null }[];\n return rows[0]?.m ?? 0;\n }\n\n // ─── Stats ───────────────────────────────────────────────────────────────────\n\n getStats(): IndexStats {\n const sizeBytes = this.sizeBytes();\n\n const lastRows = this.db.prepare(\n \"SELECT value FROM metadata WHERE key = 'last_indexed'\",\n ).all() as { value: string }[];\n const lastIndexed = lastRows.length ? Number(lastRows[0]?.value) : null;\n\n const totalRows = this.db.prepare('SELECT COUNT(*) FROM symbols').all() as { 'COUNT(*)': number }[];\n const totalSymbols = totalRows[0] ? Number(totalRows[0]['COUNT(*)']) : 0;\n\n const fileRows = this.db.prepare('SELECT COUNT(*) FROM files').all() as { 'COUNT(*)': number }[];\n const totalFiles = fileRows[0] ? Number(fileRows[0]['COUNT(*)']) : 0;\n\n const langRows = this.db.prepare(\n 'SELECT lang, COUNT(*) FROM symbols GROUP BY lang',\n ).all() as { lang: string; 'COUNT(*)': number }[];\n const byLang = {} as Record<SymbolLang, number>;\n for (const row of langRows) byLang[row.lang as SymbolLang] = Number(row['COUNT(*)']);\n\n const kindRows = this.db.prepare(\n 'SELECT kind, COUNT(*) FROM symbols GROUP BY kind',\n ).all() as { kind: string; 'COUNT(*)': number }[];\n const byKind = {} as Record<SymbolKind, number>;\n for (const row of kindRows) byKind[row.kind as SymbolKind] = Number(row['COUNT(*)']);\n\n return {\n totalSymbols,\n totalFiles,\n byLang,\n byKind,\n indexPath: this.indexDir,\n lastIndexed,\n sizeBytes,\n version: SCHEMA_VERSION,\n };\n }\n\n setLastIndexed(ts: number): void {\n this.db.prepare(\n \"INSERT OR REPLACE INTO metadata(key, value) VALUES('last_indexed', ?)\",\n ).run(String(ts));\n }\n\n clearAll(): void {\n this.db.exec('DELETE FROM symbols');\n this.db.exec('DELETE FROM files');\n this.db.exec('DELETE FROM refs');\n }\n\n // ─── Ref CRUD ────────────────────────────────────────────────────────────────\n\n /**\n * Insert cross-references for a given source symbol id.\n * Replaces any existing refs from the same source (idempotent on re-index).\n */\n insertRefs(fromId: number, refs: Ref[]): void {\n // Delete old refs from this symbol (handles re-index)\n this.db.prepare('DELETE FROM refs WHERE from_id = ?').run(fromId);\n if (refs.length === 0) return;\n\n const stmt = this.db.prepare(\n `INSERT INTO refs(from_id, to_name, to_id, call_type, line)\n VALUES (?, ?, ?, ?, ?)`,\n );\n for (const ref of refs) {\n stmt.run(fromId, ref.toName, ref.toId ?? null, ref.callType, ref.line);\n }\n }\n\n /**\n * Delete all refs whose source symbols are in a given file.\n * Used when re-indexing a file to clear stale refs.\n */\n deleteRefsForFile(file: string): void {\n const ids = this.db.prepare(\n 'SELECT id FROM symbols WHERE file = ?',\n ).all(file) as { id: number }[];\n if (!ids.length) return;\n const placeholders = ids.map(() => '?').join(',');\n this.db.prepare(`DELETE FROM refs WHERE from_id IN (${placeholders})`).run(...ids.map((r) => r.id));\n }\n\n /**\n * Resolve `to_name` → `to_id` for all refs that have a name but no id.\n * Call this after all symbols have been inserted to fill in cross-references.\n */\n resolveRefs(): number {\n const unresolved = this.db.prepare(\n 'SELECT id, to_name FROM refs WHERE to_id IS NULL AND to_name IS NOT NULL',\n ).all() as { id: number; to_name: string }[];\n\n let resolved = 0;\n for (const row of unresolved) {\n const target = this.db.prepare('SELECT id FROM symbols WHERE name = ? LIMIT 1').all(row.to_name) as { id: number }[];\n const first = target[0];\n if (first) {\n this.db.prepare('UPDATE refs SET to_id = ? WHERE id = ?').run(first.id, row.id);\n resolved++;\n }\n }\n return resolved;\n }\n\n /**\n * Find all references TO a given symbol (who calls / uses this symbol?).\n */\n findRefsTo(symbolId: number): Ref[] {\n return (this.db.prepare(\n 'SELECT id, from_id, to_name, to_id, call_type, line FROM refs WHERE to_id = ? OR to_name = (SELECT name FROM symbols WHERE id = ?)',\n ).all(symbolId, symbolId) as { id: number; from_id: number; to_name: string; to_id: number | null; call_type: string; line: number }[]).map((r) => ({\n id: r.id, fromId: r.from_id, toName: r.to_name, toId: r.to_id ?? undefined, callType: r.call_type as Ref['callType'], line: r.line,\n }));\n }\n\n /**\n * Find all references FROM a given symbol (what does this symbol call/use?).\n */\n findRefsFrom(symbolId: number): Ref[] {\n return (this.db.prepare(\n 'SELECT id, from_id, to_name, to_id, call_type, line FROM refs WHERE from_id = ?',\n ).all(symbolId) as { id: number; from_id: number; to_name: string; to_id: number | null; call_type: string; line: number }[]).map((r) => ({\n id: r.id, fromId: r.from_id, toName: r.to_name, toId: r.to_id ?? undefined, callType: r.call_type as Ref['callType'], line: r.line,\n }));\n }\n\n private sizeBytes(): number {\n const dbPath = path.join(this.indexDir, DB_FILE);\n try {\n return fs.statSync(dbPath).size;\n } catch {\n return 0;\n }\n }\n\n close(): void {\n try { this.db.close(); } catch { /* already closed */ }\n }\n}\n","/**\n * TypeScript/JavaScript symbol extraction using the TypeScript Compiler API.\n *\n * We traverse the AST and collect:\n * - classes, interfaces, enums, type aliases → class|interface|enum|type\n * - functions and methods → function|method\n * - const/let/var declarations → const|let|var\n * - property/accessor declarations → property\n *\n * The `id` field on each Symbol is always 0 — the caller is responsible for\n * assigning unique ids during insertion.\n */\n\nimport * as ts from 'typescript';\nimport type { FileSymbols, Ref, Symbol as IndexSymbol, SymbolKind, SymbolLang } from './schema.js';\n\n// Map TypeScript SyntaxKind → our SymbolKind taxonomy\nconst KIND_MAP: Partial<Record<ts.SyntaxKind, SymbolKind>> = {\n [ts.SyntaxKind.ClassDeclaration]: 'class',\n [ts.SyntaxKind.InterfaceDeclaration]: 'interface',\n [ts.SyntaxKind.EnumDeclaration]: 'enum',\n [ts.SyntaxKind.TypeAliasDeclaration]: 'type',\n [ts.SyntaxKind.FunctionDeclaration]: 'function',\n [ts.SyntaxKind.MethodDeclaration]: 'method',\n [ts.SyntaxKind.GetAccessor]: 'property',\n [ts.SyntaxKind.SetAccessor]: 'property',\n [ts.SyntaxKind.PropertyDeclaration]: 'property',\n [ts.SyntaxKind.Parameter]: 'parameter',\n [ts.SyntaxKind.NamespaceExportDeclaration]: 'namespace',\n};\n\nfunction kindOf(node: ts.Node): SymbolKind | null {\n // VariableDeclaration needs special handling — its parent tells us whether\n // it's `const`, `let`, or `var`.\n if (ts.isVariableDeclaration(node)) {\n const parent = node.parent;\n if (ts.isVariableDeclarationList(parent)) {\n const flags = parent.flags;\n if (flags & ts.NodeFlags.Let) return 'let';\n if (flags & ts.NodeFlags.Const) return 'const';\n return 'var';\n }\n }\n\n // Namespace (module) declaration\n if (ts.isModuleDeclaration(node)) return 'namespace';\n\n return KIND_MAP[node.kind] ?? null;\n}\n\nfunction extToLang(ext: string): SymbolLang | null {\n switch (ext) {\n case '.ts': return 'ts';\n case '.tsx': return 'tsx';\n case '.js': return 'js';\n case '.jsx': return 'jsx';\n case '.go': return 'go';\n case '.py': return 'py';\n case '.rs': return 'rs';\n case '.json': return 'json';\n case '.yaml': return 'yaml';\n case '.yml': return 'yaml';\n default: return null;\n }\n}\n\nfunction getSignature(node: ts.Declaration, sourceFile: ts.SourceFile): string {\n const printer = ts.createPrinter({});\n const raw = printer.printNode(ts.EmitHint.Unspecified, node, sourceFile);\n return raw.replace(/\\s+/g, ' ').slice(0, 500);\n}\n\n/**\n * Extract the first line of a JSDoc comment preceding a node.\n * Uses `ts.getLeadingCommentRanges` which is the modern replacement for\n * the removed `ts.getJSDocComments`.\n */\nfunction getJsDoc(node: ts.Node, sourceFile: ts.SourceFile): string {\n const fullText = sourceFile.getFullText();\n const nodePos = node.getFullWidth();\n const comments = ts.getLeadingCommentRanges(fullText, nodePos);\n if (!comments) return '';\n\n for (const range of comments) {\n const commentText = fullText.slice(range.pos, range.end);\n // Only process JSDoc comments (/** ... */)\n const trimmed = commentText.trim();\n if (trimmed.startsWith('/**') && trimmed.endsWith('*/')) {\n // Strip the /** and */ delimiters and leading * on each line\n const inner = trimmed\n .slice(3, -2) // remove /** and */\n .replace(/^[ \\t]*\\*[ ]?/gm, '') // remove leading \" * \" or \" *\" on each line\n .trim();\n return inner.split('\\n')[0]?.trim().slice(0, 200) ?? '';\n }\n }\n return '';\n}\n\n/** Build the scope path from a node up to the root (for class-method scope). */\nfunction buildScope(node: ts.Node): string {\n const parts: string[] = [];\n let current: ts.Node | undefined = node.parent;\n while (current) {\n if (\n ts.isClassDeclaration(current) ||\n ts.isInterfaceDeclaration(current) ||\n ts.isEnumDeclaration(current) ||\n ts.isTypeAliasDeclaration(current)\n ) {\n parts.unshift(current.name?.text ?? 'Anon');\n } else if (\n ts.isMethodDeclaration(current) ||\n ts.isGetAccessor(current) ||\n ts.isSetAccessor(current) ||\n ts.isPropertyDeclaration(current) ||\n ts.isFunctionDeclaration(current)\n ) {\n if (current.name && ts.isIdentifier(current.name)) {\n parts.unshift(current.name.text);\n }\n }\n current = current.parent;\n }\n return parts.join('.');\n}\n\nexport interface ParseOptions {\n file: string;\n content: string;\n lang: SymbolLang;\n}\n\n/**\n * Parse a TypeScript/JavaScript source file and extract all code symbols.\n *\n * The returned `Symbol.id` field is always `0` — the caller is responsible\n * for assigning unique numeric ids during bulk insertion.\n *\n * Returns an empty array for files that can't be parsed or contain no symbols.\n */\nexport function parseSymbols(opts: ParseOptions): FileSymbols {\n const { file, content, lang } = opts;\n\n let sourceFile: ts.SourceFile;\n try {\n sourceFile = ts.createSourceFile(file, content, ts.ScriptTarget.Latest, true);\n } catch {\n return { file, lang, symbols: [], mtimeMs: Date.now() };\n }\n\n const symbols: IndexSymbol[] = [];\n\n function visit(node: ts.Node): void {\n const kind = kindOf(node);\n\n if (kind) {\n const nameNode = (node as { name?: ts.Identifier | undefined }).name;\n if (!nameNode || !ts.isIdentifier(nameNode)) return;\n const name = nameNode.text;\n const pos = nameNode.getStart(sourceFile);\n const { line, character } = sourceFile.getLineAndCharacterOfPosition(pos);\n const scope = buildScope(node);\n const signature = getSignature(node as ts.Declaration, sourceFile);\n const docComment = getJsDoc(node, sourceFile);\n const text = [name, signature, docComment].filter(Boolean).join(' | ');\n\n symbols.push({\n id: 0,\n lang,\n kind,\n name,\n file,\n line: line + 1,\n col: character,\n signature,\n docComment,\n scope,\n text,\n });\n }\n\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n\n // Second pass: collect cross-references (call/type/inherit refs)\n const refs = extractRefs(sourceFile);\n\n return { file, lang, symbols, refs, mtimeMs: Date.now() };\n}\n\n// ─── Reference extraction ──────────────────────────────────────────────────────\n\n/** Collect call/type/inherit references from a source file. */\nfunction extractRefs(sourceFile: ts.SourceFile): Ref[] {\n const refs: Ref[] = [];\n\n function visit(node: ts.Node): void {\n const pos = node.getStart(sourceFile);\n const { line } = sourceFile.getLineAndCharacterOfPosition(pos);\n const lineNum = line + 1;\n\n if (ts.isCallExpression(node)) {\n const expr = node.expression;\n if (ts.isIdentifier(expr)) {\n refs.push({ fromId: 0, toName: expr.text, callType: 'call', line: lineNum });\n }\n } else if (ts.isPropertyAccessExpression(node)) {\n if (ts.isIdentifier(node.expression)) {\n refs.push({ fromId: 0, toName: node.expression.text, callType: 'call', line: lineNum });\n }\n } else if (ts.isTypeReferenceNode(node)) {\n const name = getTypeName(node.typeName);\n if (name) refs.push({ fromId: 0, toName: name, callType: 'type_ref', line: lineNum });\n } else if (ts.isHeritageClause(node)) {\n for (const t of node.types) {\n const name = getTypeName(t.expression as ts.EntityName);\n if (name) refs.push({ fromId: 0, toName: name, callType: node.token === ts.SyntaxKind.ExtendsKeyword ? 'inherit' : 'implement', line: lineNum });\n }\n } else if (ts.isImportDeclaration(node)) {\n const moduleName = getModuleName(node);\n if (moduleName) refs.push({ fromId: 0, toName: moduleName, callType: 'import', line: lineNum });\n }\n\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return deduplicateRefs(refs);\n}\n\n/** Extract the name string from a type name node (simple or qualified). */\nfunction getTypeName(name: ts.EntityName): string {\n if (ts.isIdentifier(name)) return name.text;\n if (ts.isQualifiedName(name)) return `${getTypeName(name.left)}.${name.right.text}`;\n return '';\n}\n\n/** Get the module path string from an import declaration. */\nfunction getModuleName(node: ts.ImportDeclaration): string {\n const moduleSpecifier = node.moduleSpecifier;\n if (ts.isStringLiteral(moduleSpecifier)) return moduleSpecifier.text;\n return '';\n}\n\n/** Remove duplicate refs (same toName, callType, line). fromId is always 0 at this stage. */\nfunction deduplicateRefs(refs: Ref[]): Ref[] {\n const seen = new Set<string>();\n return refs.filter((r) => {\n const key = `${r.toName}:${r.callType}:${r.line}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\n/** Detect SymbolLang from a file path extension. */\nexport function detectLang(file: string): SymbolLang | null {\n const idx = file.lastIndexOf('.');\n if (idx < 0) return null;\n return extToLang(file.slice(idx));\n}","/**\n * Go source symbol extraction using `go/parser`.\n *\n * Spawns a `go run -` child process that parses the file with go/ast and\n * emits JSON. Falls back to empty results on any error.\n *\n * Extracts: package, func, type, const, var\n */\n\nimport { execFileSync } from 'node:child_process';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { mkdirSync, writeFileSync } from 'node:fs';\nimport type { FileSymbols, Symbol as IndexSymbol, SymbolLang } from './schema.js';\n\n// ─── Public API ─────────────────────────────────────────────────────────────\n\nexport function parseSymbols(opts: { file: string; content: string; lang: SymbolLang }): FileSymbols {\n const { file, content, lang } = opts;\n\n try {\n return syncGoParse(file, content, lang);\n } catch {\n return { file, lang, symbols: [], mtimeMs: Date.now() };\n }\n}\n\nexport { detectLang } from './ts-parser.js';\n\n// ─── Inline Go parser script ────────────────────────────────────────────────\n\nconst GO_PARSE_SCRIPT = `\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"go/ast\"\n\t\"go/parser\"\n\t\"go/token\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n)\n\ntype Sym struct {\n\tName string \\`json:\"name\"\\`\n\tKind string \\`json:\"kind\"\\`\n\tLine int \\`json:\"line\"\\`\n\tCol int \\`json:\"col\"\\`\n\tSignature string \\`json:\"signature\"\\`\n\tScope string \\`json:\"scope\"\\`\n}\n\nfunc main() {\n\tsrc, err := io.ReadAll(os.Stdin)\n\tif err != nil {\n\t\tfmt.Print(\"[]\")\n\t\treturn\n\t}\n\tfset := token.NewFileSet()\n\tnode, err := parser.ParseFile(fset, \"src.go\", src, 0)\n\tif err != nil {\n\t\tfmt.Print(\"[]\")\n\t\treturn\n\t}\n\n\tvar syms []Sym\n\n\t// Package-level scope\n\tpkgScope := node.Name.Name\n\n\t// Collect all top-level declarations\n\tfor _, decl := range node.Decls {\n\t\tswitch d := decl.(type) {\n\t\tcase *ast.FuncDecl:\n\t\t\tname := d.Name.Name\n\t\t\tkind := \"function\"\n\t\t\tscope := pkgScope\n\t\t\tif d.Recv != nil && len(d.Recv.List) > 0 {\n\t\t\t\tscope = pkgScope + \".\" + recvTypeName(d.Recv.List[0].Type) + \".\" + name\n\t\t\t\tkind = \"method\"\n\t\t\t} else {\n\t\t\t\tscope = pkgScope + \".\" + name\n\t\t\t}\n\t\t\tpos := fset.Position(d.Pos())\n\t\t\tsig := formatFuncSig(d)\n\t\t\tsyms = append(syms, Sym{Name: name, Kind: kind, Line: pos.Line, Col: pos.Column, Signature: sig, Scope: scope})\n\n\t\tcase *ast.GenDecl:\n\t\t\tfor _, spec := range d.Specs {\n\t\t\t\tswitch s := spec.(type) {\n\t\t\t\tcase *ast.TypeSpec:\n\t\t\t\t\tname := s.Name.Name\n\t\t\t\t\tpos := fset.Position(s.Pos())\n\t\t\t\t\tsig := \"type \" + name\n\t\t\t\t\tif s.TypeParams != nil {\n\t\t\t\t\t\tsig += formatTypeParams(s.TypeParams)\n\t\t\t\t\t}\n\t\t\t\t\tif st, ok := s.Type.(*ast.StructType); ok {\n\t\t\t\t\t\tsig += \" = struct { \" + formatFields(st.Fields.List) + \" }\"\n\t\t\t\t\t} else if it, ok := s.Type.(*ast.InterfaceType); ok {\n\t\t\t\t\t\tsig += \" = interface { \" + formatMethods(it.Methods.List) + \" }\"\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsig += \" = \" + formatType(s.Type)\n\t\t\t\t\t}\n\t\t\t\t\tsyms = append(syms, Sym{Name: name, Kind: \"type\", Line: pos.Line, Col: pos.Column, Signature: sig, Scope: pkgScope})\n\n\t\t\t\tcase *ast.ValueSpec:\n\t\t\t\t\tfor _, n := range s.Names {\n\t\t\t\t\t\tname := n.Name\n\t\t\t\t\t\tpos := fset.Position(n.Pos())\n\t\t\t\t\t\tkind := \"var\"\n\t\t\t\t\t\tif d.Tok == token.CONST {\n\t\t\t\t\t\t\tkind = \"const\"\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsig := kind + \" \" + name\n\t\t\t\t\t\tif s.Type != nil {\n\t\t\t\t\t\t\tsig += \" \" + formatType(s.Type)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsyms = append(syms, Sym{Name: name, Kind: kind, Line: pos.Line, Col: pos.Column, Signature: sig, Scope: pkgScope})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tdata, err := json.Marshal(syms)\n\tif err != nil {\n\t\tfmt.Print(\"[]\")\n\t\treturn\n\t}\n\tfmt.Print(string(data))\n}\n\nfunc recvTypeName(t ast.Expr) string {\n\tswitch v := t.(type) {\n\tcase *ast.Ident:\n\t\treturn v.Name\n\tcase *ast.StarExpr:\n\t\treturn recvTypeName(v.X)\n\tdefault:\n\t\treturn \"?\"\n\t}\n}\n\nfunc formatFuncSig(d *ast.FuncDecl) string {\n\tscope := \"\"\n\tif d.Recv != nil && len(d.Recv.List) > 0 {\n\t\tscope = \"(\" + formatFieldList(d.Recv.List) + \") \"\n\t}\n\tscope += formatFuncType(d.Type)\n\treturn \"func \" + scope\n}\n\nfunc formatFuncType(f *ast.FuncType) string {\n\tparams := formatFieldList(f.Params.List)\n\tresults := \"\"\n\tif f.Results != nil {\n\t\tresults = \" -> \" + formatFieldList(f.Results.List)\n\t}\n\treturn params + results\n}\n\nfunc formatFieldList(fields []*ast.Field) string {\n\tif len(fields) == 0 {\n\t\treturn \"()\"\n\t}\n\tnames := make([]string, 0, len(fields))\n\tfor _, f := range fields {\n\t\tname := \"\"\n\t\tif len(f.Names) > 0 {\n\t\t\tname = f.Names[0].Name\n\t\t}\n\t\tt := formatType(f.Type)\n\t\tif name != \"\" {\n\t\t\tnames = append(names, name+\" \"+t)\n\t\t} else {\n\t\t\tnames = append(names, t)\n\t\t}\n\t}\n\treturn \"(\" + strings.Join(names, \", \") + \")\"\n}\n\nfunc formatFields(fields []*ast.Field) string {\n\tlines := make([]string, 0)\n\tfor _, f := range fields {\n\t\tname := \"\"\n\t\tif len(f.Names) > 0 {\n\t\t\tname = f.Names[0].Name\n\t\t}\n\t\tt := formatType(f.Type)\n\t\tif name != \"\" {\n\t\t\tlines = append(lines, name+\" \"+t)\n\t\t} else {\n\t\t\tlines = append(lines, t)\n\t\t}\n\t}\n\treturn strings.Join(lines, \"; \")\n}\n\nfunc formatMethods(fields []*ast.Field) string {\n\treturn formatFields(fields)\n}\n\nfunc formatTypeParams(tp *ast.FieldList) string {\n\tif tp == nil || len(tp.List) == 0 {\n\t\treturn \"\"\n\t}\n\tparams := make([]string, len(tp.List))\n\tfor i, p := range tp.List {\n\t\tif len(p.Names) > 0 {\n\t\t\tparams[i] = p.Names[0].Name\n\t\t} else {\n\t\t\tparams[i] = \"T\"\n\t\t}\n\t}\n\treturn \"[\" + strings.Join(params, \", \") + \"]\"\n}\n\nfunc formatType(t ast.Expr) string {\n\tif t == nil {\n\t\treturn \"?\"\n\t}\n\tswitch v := t.(type) {\n\tcase *ast.Ident:\n\t\treturn v.Name\n\tcase *ast.SelectorExpr:\n\t\treturn formatType(v.X) + \".\" + v.Sel.Name\n\tcase *ast.StarExpr:\n\t\treturn \"*\" + formatType(v.X)\n\tcase *ast.ArrayType:\n\t\tif v.Len == nil {\n\t\t\treturn \"[]\" + formatType(v.Elt)\n\t\t}\n\t\treturn \"[...]\" + formatType(v.Elt)\n\tcase *ast.MapType:\n\t\treturn \"map[\" + formatType(v.Key) + \"]\" + formatType(v.Value)\n\tcase *ast.InterfaceType:\n\t\treturn \"interface{}\"\n\tcase *ast.StructType:\n\t\treturn \"struct{}\"\n\tcase *ast.FuncType:\n\t\treturn formatFuncType(v)\n\tcase *ast.ChanType:\n\t\treturn \"chan \" + formatType(v.Value)\n\tcase *ast.BasicLit:\n\t\treturn v.Value\n\tcase *ast.IndexExpr:\n\t\t// Generic instantiation with one type arg, e.g. Logger[int].\n\t\treturn formatType(v.X) + \"[\" + formatType(v.Index) + \"]\"\n\tcase *ast.IndexListExpr:\n\t\t// Generic instantiation with multiple type args, e.g. Map[K, V].\n\t\targs := make([]string, len(v.Indices))\n\t\tfor i, idx := range v.Indices {\n\t\t\targs[i] = formatType(idx)\n\t\t}\n\t\treturn formatType(v.X) + \"[\" + strings.Join(args, \", \") + \"]\"\n\tdefault:\n\t\treturn \"?\"\n\t}\n}\n`;\n\nfunction syncGoParse(filePath: string, content: string, lang: SymbolLang): FileSymbols {\n\t// Feed the source over stdin — never pass the target .go file as a CLI arg.\n\t// `go run script.go target.go` makes the toolchain treat target.go as a\n\t// second package file (\"named files must all be in one directory\") and\n\t// refuses *_test.go outright. Reading from stdin sidesteps both, and lets\n\t// us parse the in-memory content without touching disk.\n\tconst tmpDir = path.join(os.tmpdir(), 'ws-go-parse');\n\ttry {\n\t\tmkdirSync(tmpDir, { recursive: true });\n\t\tconst scriptPath = path.join(tmpDir, 'parse.go');\n\t\twriteFileSync(scriptPath, GO_PARSE_SCRIPT, 'utf8');\n\n\t\t// argv-array form (no shell): avoids any quoting/metachar issues in the\n\t\t// temp script path. The target source is fed via stdin, not as an arg.\n\t\tconst stdout = execFileSync('go', ['run', scriptPath], {\n\t\t\tinput: content,\n\t\t\ttimeout: 15_000,\n\t\t\tencoding: 'utf8',\n\t\t\twindowsHide: true,\n\t\t});\n\n\t\tif (!stdout.trim()) {\n\t\t\treturn { file: filePath, lang, symbols: [], mtimeMs: Date.now() };\n\t\t}\n\n\t\tconst raw = JSON.parse(stdout.trim()) as Array<{ name: string; kind: string; line: number; col: number; signature: string; scope: string }>;\n\t\tconst symbols: IndexSymbol[] = raw.map((s) => ({\n\t\t\tid: 0,\n\t\t\tlang,\n\t\t\tkind: s.kind as IndexSymbol['kind'],\n\t\t\tname: s.name,\n\t\t\tfile: filePath,\n\t\t\tline: s.line,\n\t\t\tcol: s.col,\n\t\t\tsignature: s.signature ?? '',\n\t\t\tdocComment: '',\n\t\t\tscope: s.scope ?? '',\n\t\t\ttext: `${s.name} ${s.signature ?? ''}`.trim(),\n\t\t}));\n\t\treturn { file: filePath, lang, symbols, mtimeMs: Date.now() };\n\t} catch {\n\t\treturn { file: filePath, lang, symbols: [], mtimeMs: Date.now() };\n\t}\n}","/**\n * Python source symbol extraction using the `ast` module.\n *\n * Spawns a `python -c` child process that parses the file with Python's `ast`\n * module and emits JSON. Falls back to empty results on any error.\n *\n * Extracts: class, function, async function, const, var, import, import_from\n */\n\nimport { execFileSync } from 'node:child_process';\nimport { mkdirSync, writeFileSync } from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { FileSymbols, Symbol as IndexSymbol, SymbolLang } from './schema.js';\n\n// ─── Public API ─────────────────────────────────────────────────────────────\n\nexport function parseSymbols(opts: { file: string; content: string; lang: SymbolLang }): FileSymbols {\n const { file, lang } = opts;\n\n try {\n return syncPyParse(file, lang);\n } catch {\n return { file, lang, symbols: [], mtimeMs: Date.now() };\n }\n}\n\nexport { detectLang } from './ts-parser.js';\n\n// ─── Inline Python parser script ────────────────────────────────────────────\n\nconst PY_PARSE_SCRIPT = `import ast, json, sys, os\n\ndef get_name(node):\n if isinstance(node, ast.Name):\n return node.id\n elif isinstance(node, ast.Attribute):\n return get_name(node.value) + \".\" + node.attr\n elif isinstance(node, ast.Subscript):\n return get_name(node.value)\n elif isinstance(node, ast.Call):\n return get_name(node.func)\n elif isinstance(node, ast.Constant):\n return str(node.value)\n return \"\"\n\ndef get_decorators(node):\n decs = []\n for dec in node.decorator_list:\n decs.append(get_name(dec))\n return decs\n\ndef get_bases(node):\n bases = []\n for base in node.bases:\n bases.append(get_name(base))\n return bases\n\ndef get_args(args):\n parts = []\n for arg in args.args:\n parts.append(arg.arg)\n return \", \".join(parts)\n\ndef get_returns(node):\n if node.returns is None:\n return \"\"\n return get_name(node.returns)\n\nclass Sym:\n def __init__(self, name, kind, line, col, signature, scope):\n self.name = name\n self.kind = kind\n self.line = line\n self.col = col\n self.signature = signature\n self.scope = scope\n def to_dict(self):\n return {\n \"name\": self.name,\n \"kind\": self.kind,\n \"line\": self.line,\n \"col\": self.col,\n \"signature\": self.signature,\n \"scope\": self.scope,\n }\n\ndef is_private(name):\n return name.startswith(\"__\") and not name.endswith(\"__\")\n\nsyms = []\nerrors = []\n\ntry:\n with open(sys.argv[1], \"r\", encoding=\"utf-8\") as f:\n source = f.read()\n tree = ast.parse(source, filename=sys.argv[1])\nexcept Exception as e:\n errors.append(str(e))\n print(\"[]\")\n sys.exit(0)\n\n# Module-level scope\nmodule_scope = os.path.basename(sys.argv[1])[:-3] # strip .py\n\nclass ModuleVisitor(ast.NodeVisitor):\n def __init__(self):\n self.scope_stack = [module_scope]\n\n def visit_ClassDef(self, node):\n bases = get_bases(node)\n decs = get_decorators(node)\n sig = \"class \" + node.name\n if bases:\n sig += \"(\" + \", \".join(bases) + \")\"\n sig += \": ...\"\n syms.append(Sym(\n name=node.name,\n kind=\"class\",\n line=node.lineno,\n col=node.col_offset,\n signature=sig,\n scope=\".\".join(self.scope_stack) + \".\" + node.name,\n ))\n self.scope_stack.append(node.name)\n self.generic_visit(node)\n self.scope_stack.pop()\n\n def visit_FunctionDef(self, node):\n decs = get_decorators(node)\n args = get_args(node.args)\n returns = get_returns(node)\n is_async = isinstance(node, ast.AsyncFunctionDef)\n\n kind = \"function\"\n prefix = \"def \"\n if decs:\n for d in decs:\n if d.endswith(\".staticmethod\"):\n kind = \"staticmethod\"\n elif d.endswith(\".classmethod\"):\n kind = \"classmethod\"\n elif d == \"property\":\n kind = \"property\"\n\n if is_async:\n kind = \"async_\" + kind\n\n sig = f\"{prefix}{node.name}({args})\"\n if returns:\n sig += f\" -> {returns}\"\n scope = \".\".join(self.scope_stack) + \".\" + node.name\n\n syms.append(Sym(\n name=node.name,\n kind=kind,\n line=node.lineno,\n col=node.col_offset,\n signature=sig,\n scope=scope,\n ))\n # Don't descend into function bodies to avoid local symbols\n # self.generic_visit(node)\n\n def visit_AsyncFunctionDef(self, node):\n # Treat as function\n self.visit_FunctionDef(node)\n\n def visit_Assign(self, node):\n for target in node.targets:\n if isinstance(target, ast.Name):\n name = target.id\n if is_private(name):\n continue\n # Infer constness from UPPER_CASE naming\n kind = \"const\" if name.isupper() else \"var\"\n col = target.col_offset if hasattr(target, 'col_offset') else 0\n syms.append(Sym(\n name=name,\n kind=kind,\n line=node.lineno,\n col=col,\n signature=f\"{name} = ...\",\n scope=\".\".join(self.scope_stack),\n ))\n\n def visit_AnnAssign(self, node):\n if isinstance(node.target, ast.Name):\n name = node.target.id\n if is_private(name):\n return\n kind = \"const\" if name.isupper() else \"var\"\n col = node.target.col_offset if hasattr(node.target, 'col_offset') else 0\n sig = f\"{name}: {get_name(node.annotation)}\"\n if node.value:\n sig += \" = ...\"\n syms.append(Sym(\n name=name,\n kind=kind,\n line=node.lineno,\n col=col,\n signature=sig,\n scope=\".\".join(self.scope_stack),\n ))\n\n def visit_Import(self, node):\n for alias in node.names:\n name = alias.asname or alias.name\n syms.append(Sym(\n name=name,\n kind=\"import\",\n line=node.lineno,\n col=node.col_offset,\n signature=f\"import {alias.name}\",\n scope=\".\".join(self.scope_stack),\n ))\n\n def visit_ImportFrom(self, node):\n module = node.module or \"\"\n for alias in node.names:\n name = alias.asname or alias.name\n syms.append(Sym(\n name=name,\n kind=\"import\",\n line=node.lineno,\n col=node.col_offset,\n signature=f\"from {module} import {alias.name}\",\n scope=\".\".join(self.scope_stack),\n ))\n\nvisitor = ModuleVisitor()\nvisitor.visit(tree)\n\nprint(json.dumps([s.to_dict() for s in syms]))\n`;\n\n// ─── Synchronous Python parse via child process ─────────────────────────────\n\nfunction syncPyParse(filePath: string, lang: SymbolLang): FileSymbols {\n\ttry {\n\t\t// Write the parser to a temp .py and run it as a script. Passing the\n\t\t// whole 200-line program via `python -c \"...\"` breaks under cmd.exe on\n\t\t// Windows (embedded newlines truncate the command), so the child saw a\n\t\t// mangled script and emitted nothing. A real file sidesteps all quoting.\n\t\tconst tmpDir = path.join(os.tmpdir(), 'ws-py-parse');\n\t\tmkdirSync(tmpDir, { recursive: true });\n\t\tconst scriptPath = path.join(tmpDir, 'parse.py');\n\t\twriteFileSync(scriptPath, PY_PARSE_SCRIPT, 'utf8');\n\n\t\t// argv-array form: no shell, so a hostile filename (e.g. one containing\n\t\t// shell metacharacters or command substitution) cannot inject commands.\n\t\tconst stdout = execFileSync('python', [scriptPath, filePath], {\n\t\t\ttimeout: 15_000,\n\t\t\tencoding: 'utf8',\n\t\t\twindowsHide: true,\n\t\t});\n\n\t\tif (!stdout.trim()) {\n\t\t\treturn { file: filePath, lang, symbols: [], mtimeMs: Date.now() };\n\t\t}\n\n\t\tconst raw = JSON.parse(stdout.trim()) as Array<{\n\t\t\tname: string;\n\t\t\tkind: string;\n\t\t\tline: number;\n\t\t\tcol: number;\n\t\t\tsignature: string;\n\t\t\tscope: string;\n\t\t}>;\n\t\tconst symbols: IndexSymbol[] = raw.map((s) => ({\n\t\t\tid: 0,\n\t\t\tlang,\n\t\t\tkind: s.kind as IndexSymbol['kind'],\n\t\t\tname: s.name,\n\t\t\tfile: filePath,\n\t\t\tline: s.line,\n\t\t\tcol: s.col,\n\t\t\tsignature: s.signature ?? '',\n\t\t\tdocComment: '',\n\t\t\tscope: s.scope ?? '',\n\t\t\ttext: `${s.name} ${s.signature ?? ''}`.trim(),\n\t\t}));\n\t\treturn { file: filePath, lang, symbols, mtimeMs: Date.now() };\n\t} catch {\n\t\treturn { file: filePath, lang, symbols: [], mtimeMs: Date.now() };\n\t}\n}","import { expectDefined } from '@wrongstack/core';\n/**\n * Rust source symbol extraction.\n *\n * Tries to use the native `syn` crate via a cargo subproject (tools/syn-parser/).\n * Falls back to a robust regex-based extractor when cargo/syn is not available.\n *\n * The regex fallback extracts: fn, struct, enum, trait, impl, type, const, static, mod\n */\n\nimport { execFileSync, spawnSync } from 'node:child_process';\nimport { writeFileSync } from 'node:fs';\nimport * as path from 'node:path';\nimport type { FileSymbols, Symbol as IndexSymbol, SymbolLang } from './schema.js';\n// ─── Public API ─────────────────────────────────────────────────────────────\n\nexport function parseSymbols(opts: {\n file: string;\n content: string;\n lang: SymbolLang;\n}): FileSymbols {\n const { file, content, lang } = opts;\n\n // Try native parser first, fall back to regex\n const nativeAvailable = checkNativeParser();\n if (nativeAvailable) {\n const result = tryNativeParse(file, content);\n if (result) return result;\n }\n\n return regexParse({ file, content, lang });\n}\n\nexport { detectLang } from './ts-parser.js';\n\n// ─── Native parser (syn) ─────────────────────────────────────────────────────\n\nfunction checkNativeParser(): boolean {\n try {\n execFileSync('rustc', ['--version'], { stdio: 'pipe' });\n // Check if our syn-parser crate is available. argv-array form (no shell)\n // so a cwd path containing spaces or shell metacharacters can't break out.\n const toolsDir = path.join(process.cwd(), 'tools');\n try {\n execFileSync(\n 'cargo',\n [\n 'metadata',\n '--no-deps',\n '--format-version',\n '1',\n '--manifest-path',\n path.join(toolsDir, 'Cargo.toml'),\n ],\n { stdio: 'pipe' },\n );\n return true;\n } catch {\n return false;\n }\n } catch {\n return false;\n }\n}\n\nfunction tryNativeParse(file: string, content: string): FileSymbols | null {\n try {\n const toolsDir = path.join(process.cwd(), 'tools');\n const crateDir = path.join(toolsDir, 'syn-parser');\n\n // Write source to temp file for cargo to read\n const tmpFile = path.join(crateDir, 'src', 'input.rs');\n writeFileSync(tmpFile, content, 'utf8');\n\n const result = spawnSync(\n 'cargo',\n ['run', '--manifest-path', path.join(toolsDir, 'Cargo.toml')],\n {\n cwd: process.cwd(),\n encoding: 'utf8',\n timeout: 15000,\n stdio: ['pipe', 'pipe', 'pipe'],\n },\n );\n\n if (result.status === 0 && result.stdout) {\n const symbols: IndexSymbol[] = JSON.parse(result.stdout);\n return {\n file,\n lang: 'rs',\n symbols: symbols.map((s) => ({ ...s, id: 0, lang: 'rs' as SymbolLang })),\n mtimeMs: Date.now(),\n };\n }\n } catch {\n // Fall through to regex\n }\n return null;\n}\n\n// ─── Regex fallback parser ───────────────────────────────────────────────────\n\ninterface RustPattern {\n regex: RegExp;\n kind: IndexSymbol['kind'];\n}\n\nconst RS_PATTERNS: RustPattern[] = [\n { regex: /fn\\s+(\\w+)\\s*\\([^)]*\\)/g, kind: 'function' },\n { regex: /struct\\s+(\\w+)/g, kind: 'struct' },\n { regex: /enum\\s+(\\w+)/g, kind: 'enum' },\n { regex: /trait\\s+(\\w+)/g, kind: 'trait' },\n { regex: /impl\\s+(?:<[^>]+>)?(\\w+)/g, kind: 'impl' },\n { regex: /type\\s+(\\w+)\\s*=/g, kind: 'type' },\n { regex: /const\\s+(\\w+)/g, kind: 'const' },\n { regex: /static\\s+(\\w+)/g, kind: 'static' },\n { regex: /mod\\s+(\\w+)/g, kind: 'mod' },\n];\n\nfunction regexParse(opts: { file: string; content: string; lang: SymbolLang }): FileSymbols {\n const { file, content, lang } = opts;\n const symbols: IndexSymbol[] = [];\n const lines = content.split('\\n');\n\n // Build line offset map\n const lineOffsets: number[] = [0];\n for (let i = 0; i < lines.length; i++) {\n lineOffsets.push((lineOffsets[i] ?? 0) + (lines[i]?.length ?? 0) + 1);\n }\n\n function lineFromOffset(offset: number): number {\n let lo = 0;\n let hi = lineOffsets.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >>> 1;\n if (expectDefined(lineOffsets[mid]) <= offset) lo = mid;\n else hi = mid - 1;\n }\n return lo + 1; // 1-based\n }\n\n function extractDeclaration(lineIdx: number, _match: RegExpExecArray): string {\n const line = lines[lineIdx] ?? '';\n return line.trim().slice(0, 500);\n }\n\n for (const pattern of RS_PATTERNS) {\n pattern.regex.lastIndex = 0;\n for (\n let match = pattern.regex.exec(content);\n match !== null;\n match = pattern.regex.exec(content)\n ) {\n const name = expectDefined(match[1]);\n const offset = (match.index ?? 0);\n const line = lineFromOffset(offset);\n const col = offset - (lineOffsets[line - 1] ?? 0);\n const lineIdx = line - 1;\n const signature = extractDeclaration(lineIdx, match);\n\n symbols.push({\n id: 0,\n lang,\n kind: pattern.kind,\n name,\n file,\n line,\n col,\n signature,\n docComment: '',\n scope: '',\n text: `${name} ${signature}`.trim(),\n });\n }\n }\n\n // Deduplicate by name+line\n const seen = new Set<string>();\n const deduped = symbols.filter((s) => {\n const key = `${s.name}:${s.line}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n\n return { file, lang, symbols: deduped, mtimeMs: Date.now() };\n}\n","import { expectDefined } from '@wrongstack/core';\n/**\n * JSON file symbol extraction.\n *\n * Extracts top-level keys as \"symbols\" with kind `property`.\n * Special handling for:\n * - package.json: scripts, dependencies, devDependencies → `const`\n * - tsconfig.json: compilerOptions keys → `property`\n * - JSON Schema / OpenAPI: $schema, $id, $ref → `schema`\n * - Root object itself → kind `object`\n *\n * Uses regex-based extraction for speed and zero dependencies.\n */\n\nimport * as path from 'node:path';\nimport type { FileSymbols, Symbol as IndexSymbol, SymbolLang } from './schema.js';\n// ─── Public API ─────────────────────────────────────────────────────────────\n\nexport function parseSymbols(opts: {\n file: string;\n content: string;\n lang: SymbolLang;\n}): FileSymbols {\n const { file, content, lang } = opts;\n\n try {\n return regexParse({ file, content, lang });\n } catch {\n return { file, lang, symbols: [], mtimeMs: Date.now() };\n }\n}\n\nexport { detectLang } from './ts-parser.js';\n\n// ─── Regex parser ───────────────────────────────────────────────────────────\n\n\n/**\n * Extract key-value pairs from JSON content using regex.\n * Handles: \"key\": value, arrays with keyed objects, nested objects (depth ≤ 3).\n */\nfunction regexParse(opts: { file: string; content: string; lang: SymbolLang }): FileSymbols {\n const { file, content, lang } = opts;\n const symbols: IndexSymbol[] = [];\n const basename = path.basename(file).toLowerCase();\n\n const isPackageJson = basename === 'package.json';\n const isTsconfig = basename === 'tsconfig.json' || basename === 'tsconfig.build.json';\n const isJsonSchema =\n content.includes('$schema') || content.includes('$id') || content.includes('$ref');\n const isOpenApi = content.includes('openapi') || content.includes('swagger');\n\n const lines = content.split('\\n');\n\n // Build line offset map\n const lineOffsets: number[] = [0];\n for (let i = 0; i < lines.length; i++) {\n lineOffsets.push((lineOffsets[i] ?? 0) + (lines[i]?.length ?? 0) + 1);\n }\n\n function lineFromOffset(offset: number): number {\n let lo = 0;\n let hi = lineOffsets.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >>> 1;\n if (expectDefined(lineOffsets[mid]) <= offset) lo = mid;\n else hi = mid - 1;\n }\n return lo + 1;\n }\n\n // Root object symbol\n const rootMatch = content.match(/^\\s*\\{/m);\n if (rootMatch) {\n const offset = expectDefined(rootMatch.index);\n const line = lineFromOffset(offset);\n symbols.push(\n makeSymbol({\n name: path.basename(file),\n kind: 'object',\n line,\n col: 0,\n signature: `\"${path.basename(file)}\" = { ... }`,\n file,\n lang,\n }),\n );\n }\n\n // Extract top-level keys\n const topLevelKeyRegex = /^\\s*\"([^\"]+)\"\\s*:/gm;\n for (\n let match = topLevelKeyRegex.exec(content);\n match !== null;\n match = topLevelKeyRegex.exec(content)\n ) {\n const key = expectDefined(match[1]);\n const offset = (match.index ?? 0);\n const line = lineFromOffset(offset);\n const col = offset - (lineOffsets[line - 1] ?? 0);\n\n let kind: IndexSymbol['kind'] = 'property';\n let signature = `\"${key}\": ...\"`;\n\n // Special casing for known file types\n if (isPackageJson) {\n if (\n key === 'scripts' ||\n key === 'dependencies' ||\n key === 'devDependencies' ||\n key === 'peerDependencies' ||\n key === 'optionalDependencies'\n ) {\n kind = 'const';\n signature = `\"${key}\": { ... }`;\n }\n } else if (isTsconfig) {\n if (key === 'compilerOptions') {\n kind = 'property';\n signature = `\"compilerOptions\": { ... }`;\n }\n }\n\n // JSON Schema / OpenAPI special keys\n if (isJsonSchema || isOpenApi) {\n if (key === '$schema' || key === '$id') {\n kind = 'schema';\n signature = `\"${key}\": \"...\"`;\n } else if (key === '$ref') {\n kind = 'schema';\n signature = `\"$ref\": \"...\"`;\n }\n }\n\n symbols.push(\n makeSymbol({\n name: key,\n kind,\n line,\n col,\n signature,\n file,\n lang,\n }),\n );\n\n // For package.json, also extract individual scripts as 'function'\n if (isPackageJson && key === 'scripts') {\n extractPackageScripts(content, symbols, file, lang, lineOffsets, lineFromOffset);\n }\n\n // For tsconfig.json compilerOptions, extract nested keys\n if (isTsconfig && key === 'compilerOptions') {\n extractCompilerOptions(content, symbols, file, lang, lineOffsets, line, lineFromOffset);\n }\n }\n\n // Extract JSON Schema $defs or definitions\n const defsRegex = /\"\\$defs\"\\s*:|\"\\$defs\"\\s*:/g;\n const defsMatch = defsRegex.exec(content);\n if (defsMatch !== null) {\n const offset = expectDefined(defsMatch.index);\n const line = lineFromOffset(offset);\n symbols.push(\n makeSymbol({\n name: '$defs',\n kind: 'property',\n line,\n col: offset - (lineOffsets[line - 1] ?? 0),\n signature: '\"$defs\": { ... }',\n file,\n lang,\n }),\n );\n }\n\n // Extract definitions (OpenAPI components, JSON Schema definitions)\n const defsPatterns = [\n /\"\\$defs\"\\s*:/g,\n /\"definitions\"\\s*:/g,\n /\"components\"\\s*:/g,\n /\"schemas\"\\s*:/g,\n ];\n for (const pat of defsPatterns) {\n pat.lastIndex = 0;\n for (let match = pat.exec(content); match !== null; match = pat.exec(content)) {\n const offset = (match.index ?? 0);\n const line = lineFromOffset(offset);\n const key = match[0]?.match(/\"([^\"]+)\"/)?.[1] ?? expectDefined(match[0]);\n symbols.push(\n makeSymbol({\n name: key,\n kind: 'property',\n line,\n col: offset - (lineOffsets[line - 1] ?? 0),\n signature: `\"${key}\": { ... }`,\n file,\n lang,\n }),\n );\n }\n }\n\n return { file, lang, symbols, mtimeMs: Date.now() };\n}\n\nfunction extractPackageScripts(\n content: string,\n symbols: IndexSymbol[],\n file: string,\n lang: SymbolLang,\n lineOffsets: number[],\n lineFromOffset: (offset: number) => number,\n): void {\n // Find the \"scripts\": { ... } block and extract each script key\n const scriptsBlockRegex = /\"scripts\"\\s*:\\s*\\{([^}]+)\\}/g;\n for (\n let match = scriptsBlockRegex.exec(content);\n match !== null;\n match = scriptsBlockRegex.exec(content)\n ) {\n const blockContent = expectDefined(match[0]);\n const blockOffset = (match.index ?? 0);\n\n // Extract each \"key\" inside the block (simple approach)\n const scriptKeyRegex = /\"(\\w[\\w-]*)\"\\s*:/g;\n for (\n let scriptMatch = scriptKeyRegex.exec(blockContent);\n scriptMatch !== null;\n scriptMatch = scriptKeyRegex.exec(blockContent)\n ) {\n const key = expectDefined(scriptMatch[1]);\n const keyOffset = blockOffset + expectDefined(scriptMatch.index);\n const line = lineFromOffset(keyOffset);\n symbols.push(\n makeSymbol({\n name: key,\n kind: 'function',\n line,\n col: keyOffset - (lineOffsets[line - 1] ?? 0),\n signature: `\"${key}\": \"...\"`,\n file,\n lang,\n }),\n );\n }\n }\n}\n\nfunction extractCompilerOptions(\n content: string,\n symbols: IndexSymbol[],\n file: string,\n lang: SymbolLang,\n lineOffsets: number[],\n parentLine: number,\n lineFromOffset: (offset: number) => number,\n): void {\n // Find the \"compilerOptions\": { ... } block\n const optsBlockRegex = /\"compilerOptions\"\\s*:\\s*\\{([^}]+)\\}/g;\n for (\n let match = optsBlockRegex.exec(content);\n match !== null;\n match = optsBlockRegex.exec(content)\n ) {\n const blockContent = expectDefined(match[0]);\n const blockOffset = (match.index ?? 0);\n\n // Extract nested key inside compilerOptions (up to depth 1)\n const optKeyRegex = /\"(\\w[\\w]*)\"\\s*:/g;\n for (\n let optMatch = optKeyRegex.exec(blockContent);\n optMatch !== null;\n optMatch = optKeyRegex.exec(blockContent)\n ) {\n const key = expectDefined(optMatch[1]);\n const keyOffset = blockOffset + expectDefined(optMatch.index);\n const line = lineFromOffset(keyOffset);\n if (line <= parentLine) continue; // Skip top-level (already captured)\n symbols.push(\n makeSymbol({\n name: key,\n kind: 'property',\n line,\n col: keyOffset - (lineOffsets[line - 1] ?? 0),\n signature: `\"${key}\": ...`,\n file,\n lang,\n }),\n );\n }\n }\n}\n\nfunction makeSymbol(opts: {\n name: string;\n kind: IndexSymbol['kind'];\n line: number;\n col: number;\n signature: string;\n file: string;\n lang: SymbolLang;\n}): IndexSymbol {\n return {\n id: 0,\n lang: opts.lang,\n kind: opts.kind,\n name: opts.name,\n file: opts.file,\n line: opts.line,\n col: opts.col,\n signature: opts.signature,\n docComment: '',\n scope: '',\n text: `${opts.name} ${opts.signature}`.trim(),\n };\n}\n","import { expectDefined } from '@wrongstack/core';\nimport type { FileSymbols, Symbol as IndexSymbol, SymbolLang } from './schema.js';\n// ─── Public API ─────────────────────────────────────────────────────────────\n\nexport function parseSymbols(opts: {\n file: string;\n content: string;\n lang: SymbolLang;\n}): FileSymbols {\n const { file, content, lang } = opts;\n\n try {\n return regexParse({ file, content, lang });\n } catch {\n return { file, lang, symbols: [], mtimeMs: Date.now() };\n }\n}\n\nexport { detectLang } from './ts-parser.js';\n\n// ─── Regex parser ───────────────────────────────────────────────────────────\n\nfunction regexParse(opts: { file: string; content: string; lang: SymbolLang }): FileSymbols {\n const { file, content, lang } = opts;\n const symbols: IndexSymbol[] = [];\n\n const lines = content.split('\\n');\n\n // Build line offset map for accurate line/col\n const lineOffsets: number[] = [0];\n for (let i = 0; i < lines.length; i++) {\n lineOffsets.push((lineOffsets[i] ?? 0) + (lines[i]?.length ?? 0) + 1);\n }\n\n function lineFromOffset(offset: number): number {\n let lo = 0;\n let hi = lineOffsets.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >>> 1;\n if (expectDefined(lineOffsets[mid]) <= offset) lo = mid;\n else hi = mid - 1;\n }\n return lo + 1;\n }\n\n // ── 1. Anchors and aliases ─────────────────────────────────────────────────\n // &anchor_name\n const anchorRegex = /&(\\w[\\w-]*)/g;\n for (let match = anchorRegex.exec(content); match !== null; match = anchorRegex.exec(content)) {\n const name = expectDefined(match[1]);\n const offset = (match.index ?? 0);\n const line = lineFromOffset(offset);\n const col = offset - (lineOffsets[line - 1] ?? 0);\n symbols.push(\n makeSymbol({\n name,\n kind: 'const',\n line,\n col,\n signature: `&${name}`,\n file,\n lang,\n }),\n );\n }\n\n // *alias_name\n const aliasRegex = /\\*(\\w[\\w-]*)/g;\n for (let match = aliasRegex.exec(content); match !== null; match = aliasRegex.exec(content)) {\n const name = expectDefined(match[1]);\n const offset = (match.index ?? 0);\n const line = lineFromOffset(offset);\n const col = offset - (lineOffsets[line - 1] ?? 0);\n symbols.push(\n makeSymbol({\n name,\n kind: 'const',\n line,\n col,\n signature: `*${name}`,\n file,\n lang,\n }),\n );\n }\n\n // ── 2. Top-level and nested key: value pairs ───────────────────────────────\n // Matches `key: value` (but not block scalars or document markers)\n // Uses negative lookbehind and context to avoid false positives\n const kvRegex = /^(\\s*)([^:#\\s][^:#\\s]*)\\s*:/gm;\n for (let match = kvRegex.exec(content); match !== null; match = kvRegex.exec(content)) {\n const indent = match[1]?.length ?? 0;\n const key = match[2];\n if (!key) continue;\n const offset = (match.index ?? 0);\n const line = lineFromOffset(offset);\n const col = offset - (lineOffsets[line - 1] ?? 0);\n\n // Skip block scalar indicators (| or > at column 0 with key name before :)\n const lineContent = lines[line - 1] ?? '';\n if (/^[|&>]/.test(lineContent.trim())) continue;\n // Skip YAML document markers\n if (key === '---' || key === '...') continue;\n // Skip keys that are clearly part of a string value (unusual indent)\n if (indent > 12) continue;\n\n const value = extractValue(content, (match.index ?? 0));\n const kind: IndexSymbol['kind'] = isScalar(value) ? 'literal' : 'property';\n const signature = `${key}: ${truncate(value, 60)}`;\n\n symbols.push(makeSymbol({ name: key, kind, line, col, signature, file, lang }));\n }\n\n // ── 3. List item keys ──────────────────────────────────────────────────────\n // `- key: value` (list item that is a keyed object)\n const listItemRegex = /^-(\\s+)([^:#\\s][^:#\\s]*)\\s*:/gm;\n for (let match = listItemRegex.exec(content); match !== null; match = listItemRegex.exec(content)) {\n const key = expectDefined(match[2]);\n const offset = (match.index ?? 0);\n const line = lineFromOffset(offset);\n const col = offset - (lineOffsets[line - 1] ?? 0);\n const value = extractValue(content, offset + match[0]?.length);\n const kind: IndexSymbol['kind'] = isScalar(value) ? 'literal' : 'property';\n symbols.push(\n makeSymbol({\n name: key,\n kind,\n line,\n col,\n signature: `- ${key}: ${truncate(value, 60)}`,\n file,\n lang,\n }),\n );\n }\n\n // ── 4. Block scalar keys (key: | or key: >) ────────────────────────────────\n const blockScalarRegex = /^(\\s*)([^:#\\s][^:#\\s]*)\\s*:\\s*[|>](\\s|$)/gm;\n for (let match = blockScalarRegex.exec(content); match !== null; match = blockScalarRegex.exec(content)) {\n const key = expectDefined(match[2]);\n const offset = (match.index ?? 0);\n const line = lineFromOffset(offset);\n const col = offset - (lineOffsets[line - 1] ?? 0);\n symbols.push(\n makeSymbol({\n name: key,\n kind: 'property',\n line,\n col,\n signature: `${key}: | ...`,\n file,\n lang,\n }),\n );\n }\n\n return { file, lang, symbols, mtimeMs: Date.now() };\n}\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\nfunction extractValue(content: string, afterColonOffset: number): string {\n // Get the rest of the line after the colon\n const lineEnd = content.indexOf('\\n', afterColonOffset);\n const rest = content.slice(afterColonOffset, lineEnd < 0 ? undefined : lineEnd);\n return rest.trim();\n}\n\nfunction isScalar(value: string): boolean {\n if (!value) return false;\n // Numbers, booleans, null, quoted strings\n if (/^-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?$/.test(value)) return true;\n if (/^(true|false|null|undefined)$/i.test(value)) return true;\n if (/^'[^']*'$/.test(value) || /^\"[^\"]*\"$/.test(value)) return true;\n return false;\n}\n\nfunction truncate(s: string, max: number): string {\n if (s.length <= max) return s;\n return s.slice(0, max) + '...';\n}\n\nfunction makeSymbol(opts: {\n name: string;\n kind: IndexSymbol['kind'];\n line: number;\n col: number;\n signature: string;\n file: string;\n lang: SymbolLang;\n}): IndexSymbol {\n return {\n id: 0,\n lang: opts.lang,\n kind: opts.kind,\n name: opts.name,\n file: opts.file,\n line: opts.line,\n col: opts.col,\n signature: opts.signature,\n docComment: '',\n scope: '',\n text: `${opts.name} ${opts.signature}`.trim(),\n };\n}\n","/**\n * Minimal but faithful `.gitignore` matcher for the indexer.\n *\n * Supports the parts of the gitignore spec that matter for skipping source\n * files: comments / blanks, `!` negation (last match wins), trailing-slash\n * directory-only rules, leading-slash / embedded-slash anchoring, and the\n * `*` / `**` / `?` / `[...]` globs (via core's {@link compileGlob}).\n *\n * Only the project-root `.gitignore` is read. Nested `.gitignore` files are not\n * walked — the common build/dependency dirs that would live deeper are already\n * covered by the indexer's always-on `DEFAULT_IGNORE`.\n *\n * Known limitation: a `!negated` file inside an ignored directory will not be\n * re-included, because the indexer prunes ignored directories before descending\n * (a large performance win). This matches most lightweight implementations.\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { compileGlob } from '@wrongstack/core';\n\nexport type IgnoreMatcher = (relPath: string, isDir: boolean) => boolean;\n\ninterface Rule {\n /** Matches the entry itself or anything under it (for dirs / plain names). */\n eqOrUnder: RegExp;\n /** Matches only entries strictly under it (for dir-only rules on files). */\n under: RegExp;\n negated: boolean;\n dirOnly: boolean;\n}\n\n/** Strip the `^`/`$` anchors compileGlob adds so we can re-anchor ourselves. */\nfunction globBody(glob: string): string {\n return compileGlob(glob).source.replace(/^\\^/, '').replace(/\\$$/, '');\n}\n\n/** Compile a list of raw `.gitignore` lines into a matcher. */\nexport function compileGitignore(lines: string[]): IgnoreMatcher {\n const rules: Rule[] = [];\n\n for (const raw of lines) {\n let line = raw.replace(/\\r$/, '');\n if (!line.trim() || line.trimStart().startsWith('#')) continue;\n line = line.trim();\n\n let negated = false;\n if (line.startsWith('!')) {\n negated = true;\n line = line.slice(1);\n }\n\n let dirOnly = false;\n if (line.endsWith('/')) {\n dirOnly = true;\n line = line.slice(0, -1);\n }\n if (!line) continue;\n\n // A slash anywhere (after the trailing slash is stripped) anchors the\n // pattern to the gitignore's directory (the project root here). A bare name\n // matches at any depth.\n const anchored = line.startsWith('/') || line.includes('/');\n if (line.startsWith('/')) line = line.slice(1);\n\n const body = globBody(line);\n const prefix = anchored ? '^' : '(?:^|.*/)';\n rules.push({\n eqOrUnder: new RegExp(`${prefix}${body}(?:/.*)?$`),\n under: new RegExp(`${prefix}${body}/.*$`),\n negated,\n dirOnly,\n });\n }\n\n return (relPath: string, isDir: boolean): boolean => {\n const p = relPath.replace(/\\\\/g, '/').replace(/^\\/+/, '');\n let ignored = false;\n for (const r of rules) {\n // A directory-only rule never matches a file by its own name; it only\n // matches files that live strictly beneath the named directory.\n const re = r.dirOnly && !isDir ? r.under : r.eqOrUnder;\n if (re.test(p)) ignored = !r.negated;\n }\n return ignored;\n };\n}\n\n/** Read `<projectRoot>/.gitignore` and compile it. Missing file → matches nothing. */\nexport async function loadGitignoreMatcher(projectRoot: string): Promise<IgnoreMatcher> {\n let lines: string[] = [];\n try {\n const raw = await fs.readFile(path.join(projectRoot, '.gitignore'), 'utf8');\n lines = raw.split('\\n');\n } catch {\n // No .gitignore — nothing extra to ignore beyond the indexer defaults.\n }\n return compileGitignore(lines);\n}\n","/**\n * Background indexing coordinator.\n *\n * Wraps {@link runIndexer} with two concerns the agent loop and the CLI wiring\n * both need but neither should own:\n *\n * 1. **Serialization** — every reindex (startup full scan, per-edit incremental,\n * external file-watch) goes through one process-wide promise-chain mutex.\n * `writer.ts` opens a synchronous `node:sqlite` `DatabaseSync` connection per\n * `IndexStore`; two concurrent `runIndexer` runs on the same `index.db` would\n * race the writer and risk `SQLITE_BUSY`. The mutex makes them queue instead.\n *\n * 2. **Debounce** — rapid successive edits to the same file (editor autosave,\n * multi-edit) coalesce into a single reindex, keyed per `(indexDir, file)`.\n *\n * 3. **State tracking** — exposes whether the initial index has completed (`ready`)\n * and whether a build is in progress (`indexing`), so downstream tools\n * (codebase-search, codebase-stats) can gate on it and UIs can show progress.\n *\n * `runIndexer` only reads `opts` (and ignores its `_ctx` parameter), so callers\n * outside the agent loop pass a minimal stub cast to the expected shape — no\n * live agent `Context` is required.\n */\n\nimport { runIndexer } from './indexer.js';\nimport type { IndexResult } from './schema.js';\nimport { detectLang } from './ts-parser.js';\n\n// ─── Indexing lifecycle state ─────────────────────────────────────────────────\n// Process-wide counters so codebase-search / codebase-stats can gate on\n// readiness and UIs can show an indexing indicator. Updated inside the\n// mutex so reads from the tools are consistent with the actual build.\nlet _ready = false;\nlet _indexing = false;\nlet _currentFile = 0;\nlet _totalFiles = 0;\nlet _lastError: string | null = null;\n\n/** True once the first full-project index has completed (success or failure). */\nexport function isIndexReady(): boolean {\n return _ready;\n}\n\n/**\n * Mark the index as ready so downstream tools (codebase-search, codebase-stats)\n * don't gate on a startup index that never ran (e.g. when runIndexer is called\n * directly via the codebase-index tool rather than through runStartupIndex).\n */\nexport function setIndexReady(): void {\n _ready = true;\n}\n\n/** True while an index build is actively running. */\nexport function isIndexing(): boolean {\n return _indexing;\n}\n\n/** Current indexing progress: { currentFile, totalFiles, ready, indexing }. */\nexport function getIndexState(): {\n ready: boolean;\n indexing: boolean;\n currentFile: number;\n totalFiles: number;\n lastError: string | null;\n} {\n return {\n ready: _ready,\n indexing: _indexing,\n currentFile: _currentFile,\n totalFiles: _totalFiles,\n lastError: _lastError,\n };\n}\n\n/**\n * Optional callback fired on every lifecycle transition (started, progress,\n * completed, failed). Plug into the event bus or a TUI dispatcher to surface\n * the indexing state in real time.\n */\ntype IndexStateListener = (state: ReturnType<typeof getIndexState>) => void;\nlet _listeners: IndexStateListener[] = [];\n\nexport function onIndexStateChange(listener: IndexStateListener): () => void {\n _listeners.push(listener);\n return () => {\n _listeners = _listeners.filter((l) => l !== listener);\n };\n}\n\nfunction emitState() {\n const state = getIndexState();\n for (const l of _listeners) l(state);\n}\n\n// Track progress during an index run. Called from runIndexer's inner loop.\nexport function _setIndexProgress(current: number, total: number) {\n _currentFile = current;\n _totalFiles = total;\n emitState();\n}\n\n/** A reindex run with no live agent Context — `runIndexer` only reads `opts`. */\ntype IndexerCtx = Parameters<typeof runIndexer>[0];\nfunction stubCtx(projectRoot: string): IndexerCtx {\n return {\n projectRoot,\n cwd: projectRoot,\n messages: [],\n todos: [],\n readFiles: new Set<string>(),\n fileMtimes: new Map<string, number>(),\n } as unknown as IndexerCtx;\n}\n\n// ─── Process-wide mutex ──────────────────────────────────────────────────────\n// A single promise chain. Each enqueued job awaits the previous one's settle\n// (success OR failure) before running, so a thrown job never wedges the chain.\nlet chain: Promise<unknown> = Promise.resolve();\n\nfunction withMutex<T>(job: () => Promise<T>): Promise<T> {\n const run = chain.then(job, job);\n // Keep the chain alive regardless of this job's outcome.\n chain = run.then(\n () => undefined,\n () => undefined,\n );\n return run;\n}\n\n// ─── Debounce ────────────────────────────────────────────────────────────────\nconst DEFAULT_DEBOUNCE_MS = 400;\nconst debounceTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\nfunction debounceKey(indexDir: string | undefined, file: string): string {\n return `${indexDir ?? ''}|${file}`;\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/** True when the file's extension maps to a language the indexer can parse. */\nexport function isIndexableFile(filePath: string): boolean {\n return detectLang(filePath) !== null;\n}\n\n/**\n * Run a full-project scan and await it. Used at session start and by the manual\n * `/codebase-reindex` command. Incremental by default (unchanged files skipped\n * via mtime, so repeat runs are cheap); pass `force` to clear and rebuild.\n *\n * Sets the global `_ready` flag on completion so downstream tools know the\n * index is usable.\n */\nexport async function runStartupIndex(opts: {\n projectRoot: string;\n indexDir?: string | undefined;\n force?: boolean | undefined;\n signal?: AbortSignal | undefined;\n}): Promise<IndexResult> {\n _indexing = true;\n emitState();\n\n try {\n const result = await withMutex(() => {\n // Reset counters inside the mutex — if runStartupIndex is called\n // twice concurrently, the second caller must not clobber a running\n // index's progress counters. The mutex serializes `runIndexer`, so\n // the second call waits for the first to finish before resetting.\n _currentFile = 0;\n _totalFiles = 0;\n _lastError = null;\n return runIndexer(stubCtx(opts.projectRoot), {\n projectRoot: opts.projectRoot,\n indexDir: opts.indexDir,\n force: opts.force,\n signal: opts.signal,\n });\n });\n _ready = true;\n return result;\n } catch (err) {\n _lastError = err instanceof Error ? err.message : String(err);\n _ready = true; // index is \"ready\" in the sense that we won't try again; downstream tools will see lastError\n throw err;\n } finally {\n _indexing = false;\n emitState();\n }\n}\n\n/**\n * Debounced, fire-and-forget incremental reindex of specific files. Used by the\n * per-edit toolCall middleware and the external file watcher. Non-indexable\n * paths are dropped. Errors are reported via the optional `onError` callback and\n * never thrown to the caller (background work must not crash a turn).\n */\nexport function enqueueReindex(opts: {\n projectRoot: string;\n files: string[];\n indexDir?: string | undefined;\n debounceMs?: number | undefined;\n onError?: ((err: unknown) => void) | undefined;\n}): void {\n const files = opts.files.filter(isIndexableFile);\n if (files.length === 0) return;\n const ms = opts.debounceMs ?? DEFAULT_DEBOUNCE_MS;\n\n for (const file of files) {\n const key = debounceKey(opts.indexDir, file);\n const existing = debounceTimers.get(key);\n if (existing) clearTimeout(existing);\n const timer = setTimeout(() => {\n debounceTimers.delete(key);\n void withMutex(() =>\n runIndexer(stubCtx(opts.projectRoot), {\n projectRoot: opts.projectRoot,\n files: [file],\n indexDir: opts.indexDir,\n }),\n ).catch((err) => opts.onError?.(err));\n }, ms);\n // Don't keep the event loop alive solely for a pending reindex.\n timer.unref?.();\n debounceTimers.set(key, timer);\n }\n}\n\n/** Cancel all pending debounced reindexes. For teardown / tests. */\nexport function cancelPendingReindexes(): void {\n for (const t of debounceTimers.values()) clearTimeout(t);\n debounceTimers.clear();\n}\n","import { expectDefined } from '@wrongstack/core';\n/**\n * Main indexing orchestrator.\n *\n * Given a project root and a list of files:\n * 1. Parse each file with the appropriate parser (TS, Go, Python, Rust, JSON, YAML)\n * 2. Delete old symbols for changed/deleted files\n * 3. Insert new symbols\n * 4. Update file metadata\n * 5. Return index statistics\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Dirent, Stats } from 'node:fs';\nimport type { Context } from '@wrongstack/core';\nimport { compileGlob } from '@wrongstack/core';\nimport type { FileMeta, IndexResult, Symbol as IndexSymbol } from './schema.js';\nimport { IndexStore } from './writer.js';\nimport { parseSymbols as parseTs, detectLang } from './ts-parser.js';\nimport { parseSymbols as parseGo } from './go-parser.js';\nimport { parseSymbols as parsePy } from './py-parser.js';\nimport { parseSymbols as parseRs } from './rs-parser.js';\nimport { parseSymbols as parseJson } from './json-parser.js';\nimport { parseSymbols as parseYaml } from './yaml-parser.js';\nimport { loadGitignoreMatcher, type IgnoreMatcher } from './gitignore.js';\nimport { _setIndexProgress } from './background-indexer.js';\n/** Yield the event loop every N files so the main thread stays responsive. */\nconst YIELD_EVERY_N = 50;\n\nfunction yieldEventLoop(): Promise<void> {\n return new Promise((resolve) => setImmediate(resolve));\n}\n\n/**\n * Cooperatively abort if the signal is set. Throws with the signal's reason\n * (or a descriptive Error) so callers know *why* the operation was cancelled.\n * Called at yield points — never after a Promise resolve (that would be a\n * microtask that the signal check could miss).\n */\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n if (!signal?.aborted) return;\n if (signal.reason instanceof Error) throw signal.reason;\n throw new Error(\n typeof signal.reason === 'string' ? signal.reason : 'Indexing cancelled',\n );\n}\n\n/**\n * Detect AbortError (DOMException with name 'AbortError') thrown by signal-aware\n * fs.promises calls (stat, readFile). We must re-throw these so the cancellation\n * propagates — catching them as ordinary errors would keep the loop running.\n */\nfunction isAbortError(err: unknown): boolean {\n return err instanceof DOMException && err.name === 'AbortError';\n}\n\nconst DEFAULT_IGNORE = [\n 'node_modules', '.git', 'dist', 'build', '.next', 'coverage',\n '.turbo', '__snapshots__', '.nyc_output',\n];\n\ninterface IndexerOptions {\n projectRoot: string;\n files?: string[] | undefined;\n force?: boolean | undefined;\n langs?: string[] | undefined;\n ignore?: string[] | undefined;\n /** Override the index directory (default: the global per-project dir). */\n indexDir?: string | undefined;\n /**\n * Signal that cancels indexing cooperatively. Polled at yield points\n * (file walk, per-file loop) so a hung filesystem won't lock up the\n * process. When the tool executor's timeout fires, this signal aborts\n * and `runIndexer` throws, releasing the mutex and resetting flags.\n */\n signal?: AbortSignal | undefined;\n}\n\nasync function findSourceFiles(\n projectRoot: string,\n ignore: string[],\n isGitIgnored: IgnoreMatcher,\n signal?: AbortSignal | undefined,\n): Promise<string[]> {\n const results: string[] = [];\n const ignoreSet = new Set([...DEFAULT_IGNORE, ...ignore]);\n // compileGlob does not support brace expansion — use one pattern per extension\n const globs = [\n { ext: '.ts', pat: compileGlob('**/*.ts') },\n { ext: '.tsx', pat: compileGlob('**/*.tsx') },\n { ext: '.js', pat: compileGlob('**/*.js') },\n { ext: '.jsx', pat: compileGlob('**/*.jsx') },\n { ext: '.go', pat: compileGlob('**/*.go') },\n { ext: '.py', pat: compileGlob('**/*.py') },\n { ext: '.rs', pat: compileGlob('**/*.rs') },\n { ext: '.json', pat: compileGlob('**/*.json') },\n { ext: '.yaml', pat: compileGlob('**/*.yaml') },\n { ext: '.yml', pat: compileGlob('**/*.yml') },\n ];\n\n let dirCount = 0;\n\n const walk = async (dir: string): Promise<void> => {\n // Yield + abort check before every readdir so a cancelled indexer\n // doesn't descend deeper into the tree.\n throwIfAborted(signal);\n // Periodically yield the event loop so the main thread stays responsive\n // during deep directory walks (Node 22's fs.promises.readdir doesn't\n // accept AbortSignal, so we rely on cooperative polling).\n if (dirCount > 0 && dirCount % YIELD_EVERY_N === 0) {\n await yieldEventLoop();\n throwIfAborted(signal);\n }\n let entries: Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n dirCount++;\n\n for (const e of entries) {\n if (ignoreSet.has(e.name)) continue;\n const full = path.join(dir, e.name);\n // Normalize to forward-slash relative path for pattern matching\n const rel = path.relative(projectRoot, full).replace(/\\\\/g, '/');\n if (e.isDirectory()) {\n // Prune .gitignore'd directories before descending (skips node_modules,\n // build output, and any project-specific ignored dirs).\n if (isGitIgnored(rel, true)) continue;\n await walk(full);\n } else if (e.isFile()) {\n if (isGitIgnored(rel, false)) continue;\n const ext = path.extname(e.name);\n for (const { ext: extName, pat } of globs) {\n if (ext === extName && (pat.test(rel) || pat.test(e.name))) {\n results.push(full);\n break;\n }\n }\n }\n }\n };\n\n await walk(projectRoot);\n return results;\n}\n\n/** Dispatch to the correct parser based on language. */\nasync function parseFile(\n file: string,\n content: string,\n lang: string,\n): Promise<ReturnType<typeof parseTs>> {\n switch (lang) {\n case 'ts':\n case 'tsx':\n case 'js':\n case 'jsx':\n return parseTs({ file, content, lang: lang as 'ts' | 'tsx' | 'js' | 'jsx' });\n case 'go':\n return parseGo({ file, content, lang: 'go' });\n case 'py':\n return parsePy({ file, content, lang: 'py' });\n case 'rs':\n return parseRs({ file, content, lang: 'rs' });\n case 'json':\n return parseJson({ file, content, lang: 'json' });\n case 'yaml':\n return parseYaml({ file, content, lang: 'yaml' });\n default:\n return { file, lang: lang as 'ts' | 'tsx' | 'js' | 'jsx', symbols: [], mtimeMs: Date.now() };\n }\n}\n\n/** Run a full or incremental index and return statistics. */\nexport async function runIndexer(\n _ctx: Context,\n opts: IndexerOptions,\n): Promise<IndexResult> {\n const store = new IndexStore(opts.projectRoot, { indexDir: opts.indexDir });\n try {\n return await runIndexerWithStore(store, opts);\n } finally {\n // Always release the synchronous SQLite connection — an abort mid-run\n // (executor timeout, session teardown) previously leaked it.\n try {\n store.close();\n } catch {\n /* already closed */\n }\n }\n}\n\nasync function runIndexerWithStore(store: IndexStore, opts: IndexerOptions): Promise<IndexResult> {\n const { projectRoot, force = false, langs, ignore = [], signal } = opts;\n const startMs = Date.now();\n const errors: string[] = [];\n const langStats: Record<string, number> = {};\n let filesIndexed = 0;\n let symbolsIndexed = 0;\n\n // Honor the project-root .gitignore (skips node_modules, build output, and\n // any project-specific ignored paths) on top of the always-on DEFAULT_IGNORE.\n const isGitIgnored = await loadGitignoreMatcher(projectRoot);\n\n let files: string[];\n if (opts.files && opts.files.length > 0) {\n // Explicit file list (per-edit / watcher path): drop any that are gitignored\n // so an ignored file edited in the editor never enters the index.\n files = opts.files\n .map((f) => path.resolve(projectRoot, f))\n .filter((f) => !isGitIgnored(path.relative(projectRoot, f).replace(/\\\\/g, '/'), false));\n } else {\n files = await findSourceFiles(projectRoot, ignore, isGitIgnored, signal);\n }\n\n if (langs && langs.length > 0) {\n const langSet = new Set(langs);\n files = files.filter((f) => {\n const lang = detectLang(f);\n return lang ? langSet.has(lang) : false;\n });\n }\n\n if (force) store.clearAll();\n\n // Collect existing file metadata for incremental check\n const existingMeta: Map<string, FileMeta> = new Map();\n if (!force) {\n for (const meta of store.getAllFileMetas()) existingMeta.set(meta.file, meta);\n }\n\n for (let fi = 0; fi < files.length; fi++) {\n const file = expectDefined(files[fi]);\n\n // Report progress to the state tracker so UIs can show indexing status.\n _setIndexProgress(fi + 1, files.length);\n\n // Yield the event loop periodically so the main thread stays responsive\n // (TUI rendering, input handling, etc.) during large index builds.\n // Also check for cancellation — the tool executor's timeout or a\n // session abort propagates through `signal`.\n if (fi > 0 && fi % YIELD_EVERY_N === 0) {\n await yieldEventLoop();\n throwIfAborted(signal);\n }\n\n let stat: Stats;\n try {\n // @types/node hasn't added `signal` to StatOptions yet (runtime\n // support added in Node 20.15+). Cast to the signature Node 22 uses.\n const statOpts = signal ? { signal } : {};\n stat = await (fs.stat as (path: string, opts: { signal?: AbortSignal }) => Promise<Stats>)(file, statOpts);\n } catch (e) {\n // If the signal fired, stop immediately — don't mutate the store.\n if (isAbortError(e)) throw e;\n store.deleteFile(file);\n continue;\n }\n if (!stat.isFile()) continue;\n\n const lang = detectLang(file);\n if (!lang) continue;\n\n const meta = existingMeta.get(file);\n if (!force && meta && meta.mtimeMs === Math.floor(stat.mtimeMs)) {\n langStats[lang] = (langStats[lang] ?? 0) + meta.symbolCount;\n symbolsIndexed += meta.symbolCount;\n filesIndexed++;\n continue;\n }\n\n // Refs first: deleteRefsForFile resolves the file's symbol ids via the\n // symbols table, so it must run before those symbols are deleted (otherwise\n // the lookup finds nothing and orphan refs are left behind).\n store.deleteRefsForFile(file);\n store.deleteSymbolsForFile(file);\n\n let content: string;\n try {\n content = await fs.readFile(file, { encoding: 'utf8', signal });\n } catch (e) {\n if (isAbortError(e)) throw e;\n errors.push(`read error: ${file}: ${e instanceof Error ? e.message : String(e)}`);\n continue;\n }\n\n let parsed: ReturnType<typeof parseTs>;\n try {\n parsed = await parseFile(file, content, lang);\n } catch (e) {\n errors.push(`parse error: ${file}: ${e instanceof Error ? e.message : String(e)}`);\n continue;\n }\n\n if (parsed.symbols.length === 0) {\n store.upsertFile({\n file,\n lang,\n mtimeMs: Math.floor(stat.mtimeMs),\n symbolCount: 0,\n lastIndexed: Date.now(),\n });\n filesIndexed++;\n continue;\n }\n\n // Allocate ids from MAX(id), not COUNT(*): incremental reindexes leave gaps,\n // so a count-based id would collide with a surviving row (symbols.id UNIQUE).\n const nextId = store.getMaxSymbolId() + 1;\n const symbolsWithIds: IndexSymbol[] = parsed.symbols.map((s, i) => ({ ...s, id: nextId + i }));\n store.insertSymbols(symbolsWithIds, nextId);\n const count = symbolsWithIds.length;\n symbolsIndexed += count;\n langStats[lang] = (langStats[lang] ?? 0) + count;\n\n // Insert cross-references for each symbol\n if (parsed.refs && parsed.refs.length > 0) {\n for (let i = 0; i < symbolsWithIds.length; i++) {\n const sym = expectDefined(symbolsWithIds[i]);\n const symRefs = parsed.refs.filter((r) => r.line === sym.line);\n if (symRefs.length > 0) {\n const refsWithFromId = symRefs.map((r) => ({ ...r, fromId: sym.id }));\n store.insertRefs(sym.id, refsWithFromId);\n }\n }\n }\n\n store.upsertFile({\n file,\n lang,\n mtimeMs: Math.floor(stat.mtimeMs),\n symbolCount: count,\n lastIndexed: Date.now(),\n });\n\n filesIndexed++;\n }\n\n // Remove stale entries for files deleted since last run\n for (const [file_] of existingMeta) {\n try {\n await fs.stat(file_);\n } catch {\n store.deleteFile(file_);\n }\n }\n\n const durationMs = Date.now() - startMs;\n store.setLastIndexed(Date.now());\n\n return {\n filesIndexed,\n symbolsIndexed,\n langStats,\n durationMs,\n errors,\n };\n}","\nimport type { Tool } from '@wrongstack/core';\nimport { runIndexer } from './indexer.js';\nimport { codebaseIndexDirOverride } from './writer.js';\nimport { isIndexing, setIndexReady } from './background-indexer.js';\n\nexport const codebaseIndexTool: Tool<CodebaseIndexInput, CodebaseIndexOutput> = {\n name: 'codebase-index',\n category: 'Project',\n description:\n 'Build or incrementally update the project-wide symbol index. This powers fast codebase search and understanding. ' +\n 'By default it only processes files that have changed since the last indexing run.',\n usageHint:\n 'IMPORTANT FOR LARGE CODEBASES:\\n\\n' +\n '- First run (or after major changes): consider `force: true` for a clean rebuild.\\n' +\n '- Normal usage: call without arguments for fast incremental updates.\\n' +\n '- Use `langs` to restrict to specific languages if you only care about certain parts of the project.\\n' +\n 'This tool is relatively expensive — do not call it on every turn. Use it when the index is stale or before heavy codebase-search sessions.',\n permission: 'confirm',\n mutating: true,\n capabilities: ['fs.write.outside-project'],\n timeoutMs: 120_000,\n inputSchema: {\n type: 'object',\n properties: {\n force: {\n type: 'boolean',\n description: 'Force a full reindex — clears the index first and reindexes all files.',\n },\n langs: {\n type: 'array',\n items: { type: 'string' },\n description: 'Limit reindex to specific languages: ts, tsx, js, jsx, go, py, rs',\n },\n },\n },\n async execute(input, ctx, execOpts) {\n // If the startup index is still running, tell the agent to wait instead of\n // firing a second reindex that would just queue behind the mutex.\n if (isIndexing()) {\n return {\n filesIndexed: 0,\n symbolsIndexed: 0,\n langStats: {},\n durationMs: 0,\n errors: [],\n note: 'A full index is already in progress. Retry codebase-index after it completes (check codebase-stats).',\n };\n }\n\n const result = await runIndexer(ctx, {\n projectRoot: ctx.projectRoot,\n force: input.force ?? false,\n langs: input.langs,\n indexDir: codebaseIndexDirOverride(ctx),\n signal: execOpts?.signal,\n });\n // Mark ready so downstream tools (search, stats) don't gate on a\n // missing startup index when runIndexer was called directly.\n setIndexReady();\n return result;\n },\n};\n\n// ─── Types for tool I/O ────────────────────────────────────────────────────────\n\ninterface CodebaseIndexInput {\n force?: boolean | undefined;\n langs?: string[] | undefined;\n}\n\ninterface CodebaseIndexOutput {\n filesIndexed: number;\n symbolsIndexed: number;\n langStats: Record<string, number>;\n durationMs: number;\n errors: string[];\n /** Advisory note when the indexer was skipped (e.g. another index in progress). */\n note?: string | undefined;\n}","/**\n * BM25 ranking implementation — no external dependencies.\n *\n * Algorithm: Okapi BM25 with standard parameters (k1=1.5, b=0.75).\n */\n\nconst K1 = 1.5;\nconst B = 0.75;\n\ninterface Bm25Doc {\n id: number;\n tokens: string[];\n raw: string;\n len: number;\n}\n\n/** Tokenise a string into lowercase word tokens. */\nexport function tokenise(text: string): string[] {\n // Preserve all Unicode letters + digits + $ + '. Split on everything else.\n const sanitised = text.replace(/[^\\p{L}\\p{N}$'_]/gu, ' ').replace(/_/g, ' ');\n return sanitised.toLowerCase().split(' ').filter(Boolean);\n}\n\nexport interface IndexableDoc {\n id: number;\n text: string;\n}\n\n/**\n * Split a camelCase/SnakeCase identifier into its constituent words.\n * e.g. \"complexOperation\" → \"complex Operation\"\n * \"foo_bar_baz\" → \"foo bar baz\"\n * This allows a query for \"complex\" to match \"complexOperation\"\n * via the shared \"complex\" token.\n */\nfunction splitName(name: string): string {\n return name\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .replace(/[_-]+/g, ' ')\n .trim();\n}\n\n/**\n * Build indexable text for BM25 from a symbol's fields.\n * The name is split into camelCase/SnakeCase words so that queries\n * like \"complex\" match \"complexOperation\". The verbatim name is\n * also included for exact-match queries.\n */\nexport function buildIndexableText(name: string, signature: string, docComment: string): string {\n return [splitName(name), name, signature, docComment].filter(Boolean).join(' ');\n}\n\nexport function buildBm25Index(docs: IndexableDoc[]): Bm25Index {\n const documents: Bm25Doc[] = docs.map((d) => {\n const tokens = tokenise(d.text);\n return { id: d.id, tokens, raw: d.text, len: tokens.length };\n });\n\n const df: Record<string, number> = {};\n for (const doc of documents) {\n const seen = new Set<string>();\n for (const t of doc.tokens) {\n if (!seen.has(t)) {\n df[t] = (df[t] ?? 0) + 1;\n seen.add(t);\n }\n }\n }\n\n const N = documents.length;\n const totalLen = documents.reduce((sum, d) => sum + d.len, 0);\n const avgLen = N === 0 ? 0 : totalLen / N;\n\n return new Bm25Index(documents, df, N, avgLen);\n}\n\nexport class Bm25Index {\n private readonly safeAvgLen: number;\n\n constructor(\n private documents: Bm25Doc[],\n private df: Record<string, number>,\n private N: number,\n avgLen: number,\n ) {\n this.safeAvgLen = avgLen === 0 ? 1 : avgLen;\n }\n\n score(query: string, filter?: (id: number) => boolean): Array<{ id: number; score: number }> {\n const qTokens = tokenise(query);\n if (qTokens.length === 0) return [];\n\n const results: Array<{ id: number; score: number }> = [];\n\n for (const doc of this.documents) {\n if (filter && !filter(doc.id)) continue;\n\n let docScore = 0;\n for (const qTerm of qTokens) {\n let tf = 0;\n for (const t of doc.tokens) {\n if (t === qTerm) tf++;\n }\n if (tf === 0) continue;\n\n const dfVal = this.df[qTerm] ?? 0;\n if (dfVal === 0) continue;\n\n const idf = Math.log((this.N - dfVal + 0.5) / (dfVal + 0.5) + 1);\n const lenRatio = B * (doc.len / this.safeAvgLen);\n const tfComponent = (tf * (K1 + 1)) / (tf + K1 * (1 - B + lenRatio));\n\n docScore += idf * tfComponent;\n }\n\n if (docScore > 0) results.push({ id: doc.id, score: docScore });\n }\n\n return results;\n }\n\n getDoc(id: number): Bm25Doc | undefined {\n return this.documents.find((d) => d.id === id);\n }\n\n extractSnippet(docId: number, queryTokens: string[], radius = 40): string {\n const doc = this.getDoc(docId);\n if (!doc) return '';\n\n for (const tok of queryTokens) {\n const idx = doc.raw.toLowerCase().indexOf(tok);\n if (idx !== -1) {\n const start = Math.max(0, idx - radius);\n const end = Math.min(doc.raw.length, idx + tok.length + radius);\n const excerpt = doc.raw.slice(start, end);\n const ellipsis = '\\u2026';\n return (start > 0 ? ellipsis : '') + excerpt + (end < doc.raw.length ? ellipsis : '');\n }\n }\n return doc.raw.slice(0, radius * 2) + (doc.raw.length > radius * 2 ? '\\u2026' : '');\n }\n}\n","import { expectDefined } from '@wrongstack/core';\n/**\n * `codebase-search` tool — search the symbol index with BM25 ranking.\n *\n * Usage: codebase-search({\n * query: string, // search terms\n * kind?: string, // class|function|interface|method|const|...\n * lang?: string, // ts|tsx|js|jsx|go|py|rs\n * file?: string, // filter to a specific file path (substring match)\n * limit?: number, // max results (default 20, max 100)\n * })\n *\n * Returns: [{ name, kind, lang, file, line, signature, snippet, score }, ...]\n */\n\nimport type { Tool } from '@wrongstack/core';\nimport { IndexStore, codebaseIndexDirOverride } from './writer.js';\nimport { buildBm25Index, buildIndexableText, tokenise } from './bm25.js';\nimport type { SearchResult, SymbolKind, SymbolLang } from './schema.js';\nimport { getIndexState } from './background-indexer.js';\nexport const codebaseSearchTool: Tool<CodebaseSearchInput, CodebaseSearchOutput> = {\n name: 'codebase-search',\n category: 'Project',\n description:\n 'Semantic/keyword search over the indexed codebase symbols (functions, classes, interfaces, etc.). Uses BM25 ranking. ' +\n 'Much more powerful and structured than raw `grep` for finding code by name or concept.',\n usageHint:\n 'PREFERRED FOR CODE UNDERSTANDING:\\n\\n' +\n '- Use when you need to find where something is defined or used by name.\\n' +\n '- `kind` filter is very useful (e.g. only functions or only interfaces).\\n' +\n '- Combine with `file` filter to scope to a specific directory or module.\\n' +\n 'This is generally better than `grep` when you are looking for symbols rather than arbitrary text patterns.',\n permission: 'auto',\n mutating: false,\n capabilities: ['fs.read'],\n timeoutMs: 10_000,\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Search query — searches symbol names, signatures, and doc comments',\n },\n kind: {\n type: 'string',\n description: 'Filter by symbol kind: class, function, interface, method, const, let, var, property, type, enum',\n },\n lang: {\n type: 'string',\n description: 'Filter by language: ts, tsx, js, jsx',\n },\n lspKind: {\n type: 'integer',\n description: 'Filter by LSP SymbolKind number (e.g. 5=Class, 12=Function, 11=Interface, 10=Enum)',\n },\n file: {\n type: 'string',\n description: 'Filter to files matching this path substring',\n },\n limit: {\n type: 'integer',\n description: 'Maximum results to return (default 20, max 100)',\n minimum: 1,\n maximum: 100,\n },\n },\n required: ['query'],\n },\n async execute(input, ctx) {\n // Gate: if the index is still building or hasn't been built yet, return a\n // clear status instead of querying partial/inconsistent data.\n const state = getIndexState();\n if (!state.ready) {\n return {\n results: [],\n total: 0,\n query: input.query,\n indexStatus: state.indexing\n ? `Indexing in progress (${state.currentFile}/${state.totalFiles} files) — retry in a moment.`\n : 'Index not yet built. The codebase is being indexed at startup — search will be available shortly.',\n };\n }\n if (state.indexing) {\n return {\n results: [],\n total: 0,\n query: input.query,\n indexStatus: `Index refresh in progress (${state.currentFile}/${state.totalFiles} files). Results may be incomplete.`,\n };\n }\n if (state.lastError) {\n return {\n results: [],\n total: 0,\n query: input.query,\n indexStatus: `Index build failed: ${state.lastError}. Try /codebase-reindex.`,\n };\n }\n\n const store = new IndexStore(ctx.projectRoot, { indexDir: codebaseIndexDirOverride(ctx) });\n try {\n const limit = Math.min(input.limit ?? 20, 100);\n\n // 1. Get initial candidates from SQLite (broad filter)\n const candidates = store.search(input.query, {\n kind: input.kind as SymbolKind | undefined,\n lang: input.lang as SymbolLang | undefined,\n file: input.file,\n lspKind: input.lspKind,\n });\n\n if (candidates.length === 0) {\n return { results: [], total: 0, query: input.query };\n }\n\n // 2. Build BM25 index over candidates\n // Use buildIndexableText to split camelCase names so queries like\n // \"complex\" match \"complexOperation\" (split → \"complex Operation\")\n const indexable = candidates.map((c) => ({\n id: c.id,\n text: buildIndexableText(c.name, c.signature, c.docComment),\n }));\n const bm25 = buildBm25Index(indexable);\n\n // 3. Score and rank\n const scored = bm25.score(input.query, (id) => candidates.some((c) => c.id === id));\n\n // 4. Sort descending by score and take top N\n scored.sort((a, b) => b.score - a.score);\n const top = scored.slice(0, limit);\n\n const qTokens = tokenise(input.query);\n\n const results: SearchResult[] = top.map(({ id, score }) => {\n const c = expectDefined(candidates.find((c) => c.id === id));\n const snippet = bm25.extractSnippet(id, qTokens);\n return {\n ...c,\n score,\n snippet,\n };\n });\n\n return {\n results,\n total: candidates.length,\n query: input.query,\n };\n } finally {\n store.close();\n }\n },\n};\n\n// ─── Types ─────────────────────────────────────────────────────────────────────\n\ninterface CodebaseSearchInput {\n query: string;\n kind?: string | undefined;\n lang?: string | undefined;\n file?: string | undefined;\n limit?: number | undefined;\n lspKind?: number | undefined;\n}\n\ninterface CodebaseSearchOutput {\n results: SearchResult[];\n total: number; // total candidates before limit\n query: string;\n /** Non-empty when the index blocked the search (not ready, indexing, failed). */\n indexStatus?: string | undefined;\n}\n","/**\n * `codebase-stats` tool — report index health and statistics.\n *\n * Usage: codebase-stats({})\n *\n * Returns: { totalSymbols, totalFiles, byLang, byKind, lastIndexed, sizeBytes, version }\n */\n\nimport type { Tool } from '@wrongstack/core';\nimport { IndexStore, codebaseIndexDirOverride } from './writer.js';\nimport { getIndexState } from './background-indexer.js';\nimport { SCHEMA_VERSION } from './schema.js';\n\nexport const codebaseStatsTool: Tool<Record<string, never>, CodebaseStatsOutput> = {\n name: 'codebase-stats',\n category: 'Project',\n description: 'Return health and statistics about the current symbol index (total symbols, files, language/kind breakdown, size, last update). Useful to decide whether to re-index.',\n usageHint:\n 'CALL BEFORE HEAVY CODEBASE-SEARCH WORK:\\n\\n' +\n '- Use to see if the index is up-to-date or needs a refresh.\\n' +\n '- No arguments required.\\n' +\n '- Helps avoid wasting tokens on searches against a stale index.\\n' +\n 'Lightweight and safe to call frequently.',\n permission: 'auto',\n mutating: false,\n capabilities: ['fs.read'],\n timeoutMs: 5_000,\n inputSchema: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n async execute(_input, ctx) {\n const idxState = getIndexState();\n if (!idxState.ready) {\n return {\n totalSymbols: 0,\n totalFiles: 0,\n byLang: {},\n byKind: {},\n lastIndexed: null,\n sizeBytes: 0,\n indexPath: '',\n version: SCHEMA_VERSION,\n indexStatus: idxState.indexing\n ? `Indexing in progress (${idxState.currentFile}/${idxState.totalFiles} files).`\n : 'Index not yet built.',\n };\n }\n if (idxState.indexing) {\n // Still serve real stats but note they may be incomplete.\n const store = new IndexStore(ctx.projectRoot, { indexDir: codebaseIndexDirOverride(ctx) });\n try {\n const stats = store.getStats();\n return {\n ...stats,\n indexStatus: `Index refresh in progress (${idxState.currentFile}/${idxState.totalFiles} files). Stats may be incomplete.`,\n };\n } finally {\n store.close();\n }\n }\n\n const store = new IndexStore(ctx.projectRoot, { indexDir: codebaseIndexDirOverride(ctx) });\n try {\n const stats = store.getStats();\n return {\n totalSymbols: stats.totalSymbols,\n totalFiles: stats.totalFiles,\n byLang: stats.byLang,\n byKind: stats.byKind,\n lastIndexed: stats.lastIndexed,\n sizeBytes: stats.sizeBytes,\n indexPath: stats.indexPath,\n version: stats.version,\n };\n } finally {\n store.close();\n }\n },\n};\n\ninterface CodebaseStatsOutput {\n totalSymbols: number;\n totalFiles: number;\n byLang: Record<string, number>;\n byKind: Record<string, number>;\n lastIndexed: number | null;\n sizeBytes: number;\n indexPath: string;\n version: number;\n /** Non-empty when the index is not ready or is still building. */\n indexStatus?: string | undefined;\n}"]}
1
+ {"version":3,"sources":["../../src/codebase-index/circuit-breaker.ts","../../src/codebase-index/schema.ts","../../src/codebase-index/lsp-kind.ts","../../src/codebase-index/bm25.ts","../../src/codebase-index/writer.ts","../../src/codebase-index/ts-parser.ts","../../src/codebase-index/go-parser.ts","../../src/codebase-index/py-parser.ts","../../src/codebase-index/rs-parser.ts","../../src/codebase-index/json-parser.ts","../../src/codebase-index/yaml-parser.ts","../../src/codebase-index/gitignore.ts","../../src/codebase-index/indexer.ts","../../src/codebase-index/index-service.ts","../../src/codebase-index/background-indexer.ts","../../src/codebase-index/codebase-index-tool.ts","../../src/codebase-index/codebase-search-tool.ts","../../src/codebase-index/codebase-stats-tool.ts"],"names":["path","ts","parseSymbols","path2","mkdirSync","path3","os2","writeFileSync","execFileSync","expectDefined","regexParse","basename","path5","makeSymbol","fs2","path6","resolve","compileGlob","path7","stat","fs4"],"mappings":";;;;;;;;;;;;;;;AAuCO,IAAM,gBAAA,GAAN,cAA+B,KAAA,CAAM;AAAA,EACxB,IAAA,GAAO,kBAAA;AAC3B;AAGO,IAAM,iBAAA,GAAN,cAAgC,KAAA,CAAM;AAAA,EACzB,IAAA,GAAO,mBAAA;AAC3B;AAUO,IAAM,SAAA,GAAN,cAAwB,KAAA,CAAM;AAAA,EACjB,IAAA,GAAO,WAAA;AAC3B,CAAA;AAWO,IAAM,sBAAN,MAA0B;AAAA,EACd,gBAAA;AAAA,EACA,UAAA;AAAA,EACA,GAAA;AAAA,EAET,KAAA,GAAsB,QAAA;AAAA,EACtB,mBAAA,GAAsB,CAAA;AAAA,EACtB,QAAA,GAAW,CAAA;AAAA,EACX,WAAA,GAA6B,IAAA;AAAA,EAC7B,aAAA,GAAgB,KAAA;AAAA,EAExB,WAAA,CAAY,IAAA,GAA8B,EAAC,EAAG;AAC5C,IAAA,IAAA,CAAK,gBAAA,GAAmB,KAAK,gBAAA,IAAoB,CAAA;AACjD,IAAA,IAAA,CAAK,UAAA,GAAa,KAAK,UAAA,IAAc,GAAA;AACrC,IAAA,IAAA,CAAK,GAAA,GAAM,IAAA,CAAK,GAAA,IAAO,IAAA,CAAK,GAAA;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAA,GAAwB;AACtB,IAAA,IAAI,IAAA,CAAK,KAAA,KAAU,QAAA,EAAU,OAAO,IAAA;AACpC,IAAA,IAAI,IAAA,CAAK,UAAU,MAAA,EAAQ;AACzB,MAAA,IAAI,KAAK,GAAA,EAAI,GAAI,KAAK,QAAA,GAAW,IAAA,CAAK,YAAY,OAAO,KAAA;AACzD,MAAA,IAAA,CAAK,KAAA,GAAQ,WAAA;AACb,MAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AACrB,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,IAAI,IAAA,CAAK,eAAe,OAAO,KAAA;AAC/B,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AACrB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,aAAA,GAAsB;AACpB,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAA;AACb,IAAA,IAAA,CAAK,mBAAA,GAAsB,CAAA;AAC3B,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,IAAA,IAAA,CAAK,aAAA,GAAgB,KAAA;AAAA,EACvB;AAAA,EAEA,cAAc,GAAA,EAAoB;AAGhC,IAAA,IAAI,eAAe,SAAA,EAAW;AAC5B,MAAA,IAAA,CAAK,WAAA,GAAc,CAAA,iBAAA,EAAoB,GAAA,CAAI,OAAO,CAAA,CAAA;AAClD,MAAA,IAAA,CAAK,aAAA,GAAgB,KAAA;AACrB,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,cAAc,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAClE,IAAA,IAAA,CAAK,aAAA,GAAgB,KAAA;AACrB,IAAA,IAAA,CAAK,mBAAA,EAAA;AACL,IAAA,IAAI,KAAK,KAAA,KAAU,WAAA,IAAe,IAAA,CAAK,mBAAA,IAAuB,KAAK,gBAAA,EAAkB;AACnF,MAAA,IAAA,CAAK,KAAA,GAAQ,MAAA;AACb,MAAA,IAAA,CAAK,QAAA,GAAW,KAAK,GAAA,EAAI;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAA;AACb,IAAA,IAAA,CAAK,mBAAA,GAAsB,CAAA;AAC3B,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,IAAA,IAAA,CAAK,aAAA,GAAgB,KAAA;AACrB,IAAA,IAAA,CAAK,QAAA,GAAW,CAAA;AAAA,EAClB;AAAA,EAEA,QAAA,GAA4B;AAC1B,IAAA,OAAO;AAAA,MACL,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,qBAAqB,IAAA,CAAK,mBAAA;AAAA,MAC1B,aAAa,IAAA,CAAK,WAAA;AAAA,MAClB,mBAAA,EACE,IAAA,CAAK,KAAA,KAAU,MAAA,GAAS,KAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,UAAA,IAAc,IAAA,CAAK,GAAA,EAAI,GAAI,IAAA,CAAK,SAAS,CAAA,GAAI;AAAA,KAC1F;AAAA,EACF;AACF;AAQO,IAAM,mBAAA,GAAsB,IAAI,mBAAA;AAGhC,SAAS,wBAAA,GAAiC;AAC/C,EAAA,mBAAA,CAAoB,KAAA,EAAM;AAC5B;;;ACzCO,IAAM,cAAA,GAAiB;;;AC1EvB,SAAS,sBAAsB,CAAA,EAA8B;AAClE,EAAA,QAAQ,CAAA;AAAG,IACT,KAAK,CAAA;AAA4B,MAAA,OAAO,OAAA;AAAA,IACxC,KAAK,CAAA;AAA4B,MAAA,OAAO,QAAA;AAAA,IACxC,KAAK,CAAA;AAAA,IACL,KAAK,CAAA;AAA4B,MAAA,OAAO,UAAA;AAAA,IACxC,KAAK,CAAA;AAA4B,MAAA,OAAO,OAAA;AAAA,IACxC,KAAK,EAAA;AAA4B,MAAA,OAAO,MAAA;AAAA,IACxC,KAAK,EAAA;AAA4B,MAAA,OAAO,WAAA;AAAA,IACxC,KAAK,EAAA;AAA4B,MAAA,OAAO,UAAA;AAAA,IACxC,KAAK,EAAA;AAA4B,MAAA,OAAO,KAAA;AAAA,IACxC,KAAK,EAAA;AAA4B,MAAA,OAAO,OAAA;AAAA,IACxC,KAAK,EAAA;AAA4B,MAAA,OAAO,MAAA;AAAA,IACxC,KAAK,EAAA;AAA4B,MAAA,OAAO,MAAA;AAAA,IACxC,KAAK,CAAA;AAA4B,MAAA,OAAO,WAAA;AAAA,IACxC;AAAiC,MAAA,OAAO,IAAA;AAAA;AAE5C;AAMO,SAAS,sBAAsB,CAAA,EAA8B;AAClE,EAAA,QAAQ,CAAA;AAAG,IACT,KAAK,OAAA;AAAa,MAAA,OAAO,CAAA;AAAA,IACzB,KAAK,QAAA;AAAa,MAAA,OAAO,CAAA;AAAA,IACzB,KAAK,UAAA;AAAa,MAAA,OAAO,CAAA;AAAA,IACzB,KAAK,UAAA;AAAa,MAAA,OAAO,EAAA;AAAA,IACzB,KAAK,KAAA;AAAa,MAAA,OAAO,EAAA;AAAA,IACzB,KAAK,OAAA;AAAa,MAAA,OAAO,EAAA;AAAA,IACzB,KAAK,KAAA;AAAa,MAAA,OAAO,EAAA;AAAA,IACzB,KAAK,MAAA;AAAa,MAAA,OAAO,EAAA;AAAA,IACzB,KAAK,WAAA;AAAa,MAAA,OAAO,EAAA;AAAA,IACzB,KAAK,WAAA;AAAa,MAAA,OAAO,CAAA;AAAA,IACzB,KAAK,MAAA;AAAa,MAAA,OAAO,EAAA;AAAA;AAAA,IAEzB;AAAkB,MAAA,OAAO,IAAA;AAAA;AAE7B;;;AC9EA,IAAM,EAAA,GAAK,GAAA;AACX,IAAM,CAAA,GAAI,IAAA;AAUH,SAAS,SAAS,IAAA,EAAwB;AAE/C,EAAA,MAAM,SAAA,GAAY,KAAK,OAAA,CAAQ,oBAAA,EAAsB,GAAG,CAAA,CAAE,OAAA,CAAQ,MAAM,GAAG,CAAA;AAC3E,EAAA,OAAO,UAAU,WAAA,EAAY,CAAE,MAAM,GAAG,CAAA,CAAE,OAAO,OAAO,CAAA;AAC1D;AAcA,SAAS,UAAU,IAAA,EAAsB;AACvC,EAAA,OAAO,IAAA,CACJ,QAAQ,iBAAA,EAAmB,OAAO,EAClC,OAAA,CAAQ,QAAA,EAAU,GAAG,CAAA,CACrB,IAAA,EAAK;AACV;AAQO,SAAS,kBAAA,CAAmB,IAAA,EAAc,SAAA,EAAmB,UAAA,EAA4B;AAC9F,EAAA,OAAO,CAAC,SAAA,CAAU,IAAI,CAAA,EAAG,IAAA,EAAM,SAAA,EAAW,UAAU,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAChF;AAEO,SAAS,eAAe,IAAA,EAAiC;AAC9D,EAAA,MAAM,SAAA,GAAuB,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM;AAC3C,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,CAAA,CAAE,IAAI,CAAA;AAC9B,IAAA,OAAO,EAAE,EAAA,EAAI,CAAA,CAAE,EAAA,EAAI,MAAA,EAAQ,KAAK,CAAA,CAAE,IAAA,EAAM,GAAA,EAAK,MAAA,CAAO,MAAA,EAAO;AAAA,EAC7D,CAAC,CAAA;AAED,EAAA,MAAM,KAA6B,EAAC;AACpC,EAAA,KAAA,MAAW,OAAO,SAAA,EAAW;AAC3B,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,MAAA,EAAQ;AAC1B,MAAA,IAAI,CAAC,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG;AAChB,QAAA,EAAA,CAAG,CAAC,CAAA,GAAA,CAAK,EAAA,CAAG,CAAC,KAAK,CAAA,IAAK,CAAA;AACvB,QAAA,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAEA,EAAA,MAAM,IAAI,SAAA,CAAU,MAAA;AACpB,EAAA,MAAM,QAAA,GAAW,UAAU,MAAA,CAAO,CAAC,KAAK,CAAA,KAAM,GAAA,GAAM,CAAA,CAAE,GAAA,EAAK,CAAC,CAAA;AAC5D,EAAA,MAAM,MAAA,GAAS,CAAA,KAAM,CAAA,GAAI,CAAA,GAAI,QAAA,GAAW,CAAA;AAExC,EAAA,OAAO,IAAI,SAAA,CAAU,SAAA,EAAW,EAAA,EAAI,GAAG,MAAM,CAAA;AAC/C;AAEO,IAAM,YAAN,MAAgB;AAAA,EAGrB,WAAA,CACU,SAAA,EACA,EAAA,EACA,CAAA,EACR,MAAA,EACA;AAJQ,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AACA,IAAA,IAAA,CAAA,EAAA,GAAA,EAAA;AACA,IAAA,IAAA,CAAA,CAAA,GAAA,CAAA;AAGR,IAAA,IAAA,CAAK,UAAA,GAAa,MAAA,KAAW,CAAA,GAAI,CAAA,GAAI,MAAA;AAAA,EACvC;AAAA,EANU,SAAA;AAAA,EACA,EAAA;AAAA,EACA,CAAA;AAAA,EALO,UAAA;AAAA,EAWjB,KAAA,CAAM,OAAe,MAAA,EAAwE;AAC3F,IAAA,MAAM,OAAA,GAAU,SAAS,KAAK,CAAA;AAC9B,IAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,EAAC;AAElC,IAAA,MAAM,UAAgD,EAAC;AAEvD,IAAA,KAAA,MAAW,GAAA,IAAO,KAAK,SAAA,EAAW;AAChC,MAAA,IAAI,MAAA,IAAU,CAAC,MAAA,CAAO,GAAA,CAAI,EAAE,CAAA,EAAG;AAE/B,MAAA,IAAI,QAAA,GAAW,CAAA;AACf,MAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,QAAA,IAAI,EAAA,GAAK,CAAA;AACT,QAAA,KAAA,MAAW,CAAA,IAAK,IAAI,MAAA,EAAQ;AAC1B,UAAA,IAAI,MAAM,KAAA,EAAO,EAAA,EAAA;AAAA,QACnB;AACA,QAAA,IAAI,OAAO,CAAA,EAAG;AAEd,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,EAAA,CAAG,KAAK,CAAA,IAAK,CAAA;AAChC,QAAA,IAAI,UAAU,CAAA,EAAG;AAEjB,QAAA,MAAM,GAAA,GAAM,KAAK,GAAA,CAAA,CAAK,IAAA,CAAK,IAAI,KAAA,GAAQ,GAAA,KAAQ,KAAA,GAAQ,GAAA,CAAA,GAAO,CAAC,CAAA;AAC/D,QAAA,MAAM,QAAA,GAAW,CAAA,IAAK,GAAA,CAAI,GAAA,GAAM,IAAA,CAAK,UAAA,CAAA;AACrC,QAAA,MAAM,cAAe,EAAA,IAAM,EAAA,GAAK,MAAO,EAAA,GAAK,EAAA,IAAM,IAAI,CAAA,GAAI,QAAA,CAAA,CAAA;AAE1D,QAAA,QAAA,IAAY,GAAA,GAAM,WAAA;AAAA,MACpB;AAEA,MAAA,IAAI,QAAA,GAAW,CAAA,EAAG,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAI,GAAA,CAAI,EAAA,EAAI,KAAA,EAAO,QAAA,EAAU,CAAA;AAAA,IAChE;AAEA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,OAAO,EAAA,EAAiC;AACtC,IAAA,OAAO,KAAK,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AAAA,EAC/C;AAAA,EAEA,cAAA,CAAe,KAAA,EAAe,WAAA,EAAuB,MAAA,GAAS,EAAA,EAAY;AACxE,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA;AAC7B,IAAA,IAAI,CAAC,KAAK,OAAO,EAAA;AAEjB,IAAA,KAAA,MAAW,OAAO,WAAA,EAAa;AAC7B,MAAA,MAAM,MAAM,GAAA,CAAI,GAAA,CAAI,WAAA,EAAY,CAAE,QAAQ,GAAG,CAAA;AAC7C,MAAA,IAAI,QAAQ,EAAA,EAAI;AACd,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAM,MAAM,CAAA;AACtC,QAAA,MAAM,GAAA,GAAM,KAAK,GAAA,CAAI,GAAA,CAAI,IAAI,MAAA,EAAQ,GAAA,GAAM,GAAA,CAAI,MAAA,GAAS,MAAM,CAAA;AAC9D,QAAA,MAAM,OAAA,GAAU,GAAA,CAAI,GAAA,CAAI,KAAA,CAAM,OAAO,GAAG,CAAA;AACxC,QAAA,MAAM,QAAA,GAAW,QAAA;AACjB,QAAA,OAAA,CAAQ,KAAA,GAAQ,IAAI,QAAA,GAAW,EAAA,IAAM,WAAW,GAAA,GAAM,GAAA,CAAI,GAAA,CAAI,MAAA,GAAS,QAAA,GAAW,EAAA,CAAA;AAAA,MACpF;AAAA,IACF;AACA,IAAA,OAAO,GAAA,CAAI,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,MAAA,GAAS,CAAC,CAAA,IAAK,GAAA,CAAI,GAAA,CAAI,MAAA,GAAS,MAAA,GAAS,CAAA,GAAI,QAAA,GAAW,EAAA,CAAA;AAAA,EAClF;AACF,CAAA;;;AChHA,IAAM,OAAA,GAAU,UAAA;AAST,SAAS,eAAA,CAAgB,aAAqB,QAAA,EAA2B;AAC9E,EAAA,OAAO,QAAA,IAAY,kBAAA,CAAmB,EAAE,WAAA,EAAa,CAAA,CAAE,oBAAA;AACzD;AAOO,SAAS,yBAAyB,GAAA,EAA6D;AACpG,EAAA,MAAM,CAAA,GAAI,GAAA,CAAI,IAAA,GAAO,kBAAkB,CAAA;AACvC,EAAA,OAAO,OAAO,CAAA,KAAM,QAAA,GAAW,CAAA,GAAI,MAAA;AACrC;AAEA,IAAI,eAAA,GAAkB,KAAA;AAMtB,SAAS,gCAAA,GAAyC;AAChD,EAAA,IAAI,eAAA,EAAiB;AACrB,EAAA,eAAA,GAAkB,IAAA;AAClB,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA;AACjD,EAAA,OAAA,CAAQ,WAAA,IAAe,CAAC,OAAA,EAAA,GAAqB,IAAA,KAA0B;AACrE,IAAA,MAAM,MAAM,OAAO,OAAA,KAAY,QAAA,GAAW,OAAA,GAAY,SAAmB,OAAA,IAAW,EAAA;AACpF,IAAA,MAAM,IAAA,GAAO,OAAO,OAAA,KAAY,QAAA,GAAW,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,IAAK,EAAE,CAAA,GAAM,OAAA,EAAmB,IAAA,IAAQ,EAAA;AAChG,IAAA,IAAI,SAAA,CAAU,IAAA,CAAK,GAAG,CAAA,IAAK,eAAA,CAAgB,IAAA,CAAK,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,CAAA,EAAG;AACnE,IAAC,QAAA,CAAmD,OAAA,EAAS,GAAG,IAAI,CAAA;AAAA,EACtE,CAAA,CAAA;AACF;AAEA,IAAI,gBAAA;AAQJ,SAAS,gBAAA,GAAwC;AAC/C,EAAA,IAAI,kBAAkB,OAAO,gBAAA;AAC7B,EAAA,gCAAA,EAAiC;AACjC,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AACzC,IAAA,gBAAA,GAAoB,GAAA,CAAI,aAAa,CAAA,CAAmC,YAAA;AAAA,EAC1E,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,8HACsC,GAAA,YAAe,KAAA,GAAQ,IAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,KACxF;AAAA,EACF;AACA,EAAA,OAAO,gBAAA;AACT;AAKA,IAAM,gBAAA,GAAmB,CAAA;AAOzB,IAAM,wBAAA,GAA2B,EAAA;AAEjC,IAAM,uBAAA,GAA0B,GAAA;AAYhC,SAAS,YAAY,GAAA,EAAuB;AAC1C,EAAA,IAAI,EAAE,GAAA,YAAe,KAAA,CAAA,EAAQ,OAAO,KAAA;AACpC,EAAA,MAAM,CAAA,GAAI,GAAA;AACV,EAAA,MAAM,IAAA,GAAO,CAAA,CAAE,IAAA,IAAQ,CAAA,CAAE,UAAA;AACzB,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,uBAAuB,IAAA,CAAK,IAAI,GAAG,OAAO,IAAA;AAC1E,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,KAAa,SAAS,CAAA,IAAK,IAAA,KAAS,IAAI,OAAO,IAAA;AAEnE,EAAA,IAAI,sBAAA,CAAuB,IAAA,CAAK,GAAA,CAAI,OAAO,GAAG,OAAO,IAAA;AACrD,EAAA,OAAO,KAAA;AACT;AAWA,SAAS,UAAU,EAAA,EAAkB;AACnC,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,IAAI,iBAAA,CAAkB,CAAC,CAAA;AACnC,IAAA,MAAM,IAAA,GAAO,IAAI,UAAA,CAAW,GAAG,CAAA;AAC/B,IAAA,OAAA,CAAQ,IAAA,CAAK,IAAA,EAAM,CAAA,EAAG,CAAA,EAAG,EAAE,CAAA;AAAA,EAC7B,CAAA,CAAA,MAAQ;AAAA,EAIR;AACF;AAEO,IAAM,aAAN,MAAiB;AAAA,EACd,EAAA;AAAA;AAAA,EAES,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKT,YAAA,GAAe,KAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAevB,aAAgB,EAAA,EAAgB;AAC9B,IAAA,IAAI,SAAA;AACJ,IAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,gBAAA,EAAkB,OAAA,EAAA,EAAW;AAC5D,MAAA,IAAI;AACF,QAAA,OAAO,EAAA,EAAG;AAAA,MACZ,SAAS,GAAA,EAAK;AACZ,QAAA,SAAA,GAAY,GAAA;AACZ,QAAA,IAAI,CAAC,WAAA,CAAY,GAAG,CAAA,EAAG,MAAM,GAAA;AAC7B,QAAA,IAAI,YAAY,gBAAA,EAAkB;AAGhC,UAAA,MAAM,MAAM,SAAA,YAAqB,KAAA,GAAQ,SAAA,CAAU,OAAA,GAAU,OAAO,SAAS,CAAA;AAC7E,UAAA,MAAM,IAAI,SAAA,CAAU,CAAA,2BAAA,EAA8B,gBAAgB,CAAA,UAAA,EAAa,GAAG,CAAA,CAAE,CAAA;AAAA,QACtF;AAEA,QAAA,MAAM,QAAQ,IAAA,CAAK,GAAA;AAAA,UACjB,wBAAA,GAA2B,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAO,CAAA;AAAA,UAC9C;AAAA,SACF;AACA,QAAA,SAAA,CAAU,KAAK,CAAA;AAAA,MACjB;AAAA,IACF;AACA,IAAA,MAAM,SAAA;AAAA,EACR;AAAA,EAEA,WAAA,CAAY,WAAA,EAAqB,IAAA,GAA0C,EAAC,EAAG;AAC7E,IAAA,IAAA,CAAK,QAAA,GAAW,eAAA,CAAgB,WAAA,EAAa,IAAA,CAAK,QAAQ,CAAA;AAC1D,IAAG,aAAU,IAAA,CAAK,QAAA,EAAU,EAAE,SAAA,EAAW,MAAM,CAAA;AAC/C,IAAA,MAAM,WAAW,gBAAA,EAAiB;AAClC,IAAA,IAAA,CAAK,KAAK,IAAI,QAAA,CAAcA,WAAK,IAAA,CAAK,QAAA,EAAU,OAAO,CAAC,CAAA;AAOxD,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,EAAA,CAAG,KAAK,2BAA2B,CAAA;AACxC,MAAA,IAAA,CAAK,EAAA,CAAG,KAAK,4BAA4B,CAAA;AAAA,IAC3C,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,IAAA,CAAK,UAAA,EAAW;AAAA,EAClB;AAAA,EAEQ,UAAA,GAAmB;AACzB,IAAA,IAAA,CAAK,GAAG,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAKZ,CAAA;AAKD,IAAA,MAAM,aAAa,IAAA,CAAK,EAAA,CAAG,QAAQ,0CAA0C,CAAA,CAAE,IAAI,SAAS,CAAA;AAC5F,IAAA,MAAM,aAAA,GAAgB,WAAW,MAAA,GAAS,MAAA,CAAO,WAAW,CAAC,CAAA,EAAG,KAAK,CAAA,GAAI,IAAA;AACzE,IAAA,IAAI,aAAA,KAAkB,IAAA,IAAQ,aAAA,KAAkB,cAAA,EAAgB;AAC9D,MAAA,IAAA,CAAK,GAAG,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA,MAAA,CAIZ,CAAA;AACD,MAAA,IAAA,CAAK,EAAA,CAAG,KAAK,kCAAkC,CAAA;AAC/C,MAAA,IAAA,CAAK,EAAA,CAAG,QAAQ,6CAA6C,CAAA,CAAE,IAAI,MAAA,CAAO,cAAc,GAAG,SAAS,CAAA;AAAA,IACtG,CAAA,MAAA,IAAW,kBAAkB,IAAA,EAAM;AACjC,MAAA,IAAA,CAAK,EAAA,CAAG,QAAQ,gDAAgD,CAAA,CAAE,IAAI,SAAA,EAAW,MAAA,CAAO,cAAc,CAAC,CAAA;AAAA,IACzG;AAEA,IAAA,IAAA,CAAK,GAAG,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAsBZ,CAAA;AAED,IAAA,IAAA,CAAK,EAAA,CAAG,KAAK,wDAAwD,CAAA;AACrE,IAAA,IAAA,CAAK,EAAA,CAAG,KAAK,wDAAwD,CAAA;AACrE,IAAA,IAAA,CAAK,EAAA,CAAG,KAAK,wDAAwD,CAAA;AACrE,IAAA,IAAA,CAAK,EAAA,CAAG,KAAK,wDAAwD,CAAA;AAErE,IAAA,IAAA,CAAK,GAAG,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CASZ,CAAA;AAED,IAAA,IAAA,CAAK,EAAA,CAAG,KAAK,wDAAwD,CAAA;AACrE,IAAA,IAAA,CAAK,EAAA,CAAG,KAAK,uDAAuD,CAAA;AACpE,IAAA,IAAA,CAAK,EAAA,CAAG,KAAK,2DAA2D,CAAA;AACxE,IAAA,IAAA,CAAK,EAAA,CAAG,KAAK,+DAA+D,CAAA;AAM5E,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,EAAA,CAAG,KAAK,yFAAyF,CAAA;AACtG,MAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AAAA,IACtB,CAAA,CAAA,MAAQ;AAEN,MAAA,IAAA,CAAK,YAAA,GAAe,KAAA;AAAA,IACtB;AAAA,EACF;AAAA;AAAA,EAIA,aAAA,CAAc,SAAwB,MAAA,EAAwB;AAC5D,IAAA,OAAO,IAAA,CAAK,aAAa,MAAM;AAC7B,MAAA,MAAM,IAAA,GAAO,KAAK,EAAA,CAAG,OAAA;AAAA,QACnB,CAAA;AAAA,oDAAA;AAAA,OAEF;AACA,MAAA,MAAM,UAAU,IAAA,CAAK,YAAA,GACjB,KAAK,EAAA,CAAG,OAAA,CAAQ,oDAAoD,CAAA,GACpE,IAAA;AAEJ,MAAA,IAAI,EAAA,GAAK,MAAA;AACT,MAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,QAAA,IAAA,CAAK,GAAA;AAAA,UACH,EAAA;AAAA,UACA,CAAA,CAAE,IAAA;AAAA,UACF,CAAA,CAAE,IAAA;AAAA,UACF,CAAA,CAAE,IAAA;AAAA,UACF,CAAA,CAAE,IAAA;AAAA,UACF,CAAA,CAAE,IAAA;AAAA,UACF,CAAA,CAAE,GAAA;AAAA,UACF,CAAA,CAAE,SAAA;AAAA,UACF,CAAA,CAAE,UAAA;AAAA,UACF,CAAA,CAAE,KAAA;AAAA,UACF,CAAA,CAAE,IAAA;AAAA,UACF,CAAA,CAAE;AAAA,SACJ;AAGA,QAAA,OAAA,EAAS,GAAA,CAAI,IAAI,kBAAA,CAAmB,CAAA,CAAE,MAAM,CAAA,CAAE,SAAA,EAAW,CAAA,CAAE,UAAU,CAAC,CAAA;AACtE,QAAA,EAAA,EAAA;AAAA,MACF;AACA,MAAA,OAAO,EAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,qBAAqB,IAAA,EAAoB;AACvC,IAAA,IAAA,CAAK,aAAa,MAAM;AACtB,MAAA,IAAI,KAAK,YAAA,EAAc;AACrB,QAAA,IAAA,CAAK,EAAA,CACF,OAAA,CAAQ,mFAAmF,CAAA,CAC3F,IAAI,IAAI,CAAA;AAAA,MACb;AACA,MAAA,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ,uCAAuC,CAAA,CAAE,IAAI,IAAI,CAAA;AAAA,IACnE,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAW,IAAA,EAAoB;AAC7B,IAAA,IAAA,CAAK,aAAa,MAAM;AACtB,MAAA,IAAA,CAAK,kBAAkB,IAAI,CAAA;AAC3B,MAAA,IAAA,CAAK,qBAAqB,IAAI,CAAA;AAC9B,MAAA,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ,kCAAkC,CAAA,CAAE,IAAI,IAAI,CAAA;AAAA,IAC9D,CAAC,CAAA;AAAA,EACH;AAAA;AAAA,EAIA,WAAW,IAAA,EAAsB;AAC/B,IAAA,IAAA,CAAK,aAAa,MAAM;AACtB,MAAA,IAAA,CAAK,EAAA,CAAG,OAAA;AAAA,QACN,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+CAAA;AAAA,OAOF,CAAE,GAAA,CAAI,IAAA,CAAK,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,WAAA,EAAa,IAAA,CAAK,WAAW,CAAA;AAAA,IAC9E,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,YAAY,IAAA,EAA+B;AACzC,IAAA,MAAM,IAAA,GAAO,KAAK,EAAA,CAAG,OAAA;AAAA,MACnB;AAAA,KACF,CAAE,IAAI,IAAI,CAAA;AACV,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,OAAO,IAAA;AACzB,IAAA,MAAM,CAAA,GAAI,aAAA,CAAc,IAAA,CAAK,CAAC,CAAC,CAAA;AAC/B,IAAA,OAAO,EAAE,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,MAAM,CAAA,CAAE,IAAA,EAAoB,OAAA,EAAS,CAAA,CAAE,UAAU,WAAA,EAAa,CAAA,CAAE,YAAA,EAAc,WAAA,EAAa,EAAE,YAAA,EAAa;AAAA,EACnI;AAAA,EAEA,eAAA,GAA8B;AAC5B,IAAA,OAAQ,KAAK,EAAA,CAAG,OAAA;AAAA,MACd;AAAA,KACF,CAAE,KAAI,CAAqG,GAAA;AAAA,MACzG,CAAC,CAAA,MAAO,EAAE,IAAA,EAAM,CAAA,CAAE,MAAM,IAAA,EAAM,CAAA,CAAE,IAAA,EAAoB,OAAA,EAAS,EAAE,QAAA,EAAU,WAAA,EAAa,EAAE,YAAA,EAAc,WAAA,EAAa,EAAE,YAAA,EAAa;AAAA,KACpI;AAAA,EACF;AAAA;AAAA,EAIA,MAAA,CACE,OACA,MAAA,EACgB;AAChB,IAAA,MAAM,aAAuB,EAAC;AAC9B,IAAA,MAAM,SAAoB,EAAC;AAE3B,IAAA,IAAI,gBAAwC,MAAA,EAAQ,IAAA;AACpD,IAAA,IAAI,MAAA,EAAQ,YAAY,MAAA,EAAW;AACjC,MAAA,MAAM,MAAA,GAAS,qBAAA,CAAsB,MAAA,CAAO,OAAO,CAAA;AACnD,MAAA,IAAI,WAAW,IAAA,EAAM;AACnB,QAAA,aAAA,GAAgB,MAAA;AAAA,MAClB,CAAA,MAAO;AAEL,QAAA,OAAO,EAAC;AAAA,MACV;AAAA,IACF;AAEA,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,UAAA,CAAW,KAAK,UAAU,CAAA;AAC1B,MAAA,MAAA,CAAO,KAAK,aAAa,CAAA;AAAA,IAC3B;AACA,IAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,UAAA,CAAW,KAAK,UAAU,CAAA;AAC1B,MAAA,MAAA,CAAO,IAAA,CAAK,OAAO,IAAI,CAAA;AAAA,IACzB;AACA,IAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,UAAA,CAAW,KAAK,aAAa,CAAA;AAC7B,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,CAAA,EAAI,MAAA,CAAO,IAAI,CAAA,CAAA,CAAG,CAAA;AAAA,IAChC;AACA,IAAA,IAAI,KAAA,CAAM,MAAK,EAAG;AAChB,MAAA,MAAM,MAAA,GAAS,MAAM,WAAA,EAAY,CAAE,MAAM,KAAK,CAAA,CAAE,OAAO,OAAO,CAAA;AAC9D,MAAA,MAAM,UAAA,GAAa,MAAA,CAAO,GAAA,CAAI,MAAM,aAAa,CAAA;AACjD,MAAA,UAAA,CAAW,KAAK,CAAA,CAAA,EAAI,UAAA,CAAW,IAAA,CAAK,MAAM,CAAC,CAAA,CAAA,CAAG,CAAA;AAC9C,MAAA,KAAA,MAAW,KAAK,MAAA,EAAQ,MAAA,CAAO,IAAA,CAAK,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,IAC9C;AAEA,IAAA,MAAM,KAAA,GAAQ,WAAW,MAAA,GAAS,CAAA,MAAA,EAAS,WAAW,IAAA,CAAK,OAAO,CAAC,CAAA,CAAA,GAAK,EAAA;AACxE,IAAA,MAAM,GAAA,GAAM,2FAA2F,KAAK,CAAA,CAAA;AAE5G,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ,GAAG,CAAA;AAChC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,GAAG,MAA6B,CAAA;AAKtD,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MACtB,IAAI,CAAA,CAAE,EAAA;AAAA,MACN,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,KAAK,CAAA,CAAE,GAAA;AAAA,MACP,WAAW,CAAA,CAAE,SAAA;AAAA,MACb,YAAY,CAAA,CAAE,WAAA;AAAA,MACd,KAAA,EAAO,CAAA;AAAA,MACP,OAAA,EAAS,EAAA;AAAA,MACT,SAAS,MAAA,EAAQ;AAAA,KACnB,CAAE,CAAA;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,YAAA,CACE,KAAA,EACA,MAAA,EAGA,KAAA,EAC4C;AAC5C,IAAA,MAAM,MAAA,GAAS,SAAS,KAAK,CAAA;AAE7B,IAAA,IAAI,MAAA,CAAO,MAAA,KAAW,CAAA,IAAK,CAAC,KAAK,YAAA,EAAc;AAC7C,MAAA,OAAO,IAAA,CAAK,oBAAA,CAAqB,KAAA,EAAO,MAAA,EAAQ,KAAK,CAAA;AAAA,IACvD;AAEA,IAAA,IAAI,gBAAwC,MAAA,EAAQ,IAAA;AACpD,IAAA,IAAI,MAAA,EAAQ,YAAY,MAAA,EAAW;AACjC,MAAA,MAAM,MAAA,GAAS,qBAAA,CAAsB,MAAA,CAAO,OAAO,CAAA;AACnD,MAAA,IAAI,MAAA,KAAW,MAAM,OAAO,EAAE,SAAS,EAAC,EAAG,OAAO,CAAA,EAAE;AACpD,MAAA,aAAA,GAAgB,MAAA;AAAA,IAClB;AAGA,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,GAAA,CAAI,CAAC,MAAM,CAAA,CAAA,EAAI,CAAA,CAAE,UAAA,CAAW,GAAA,EAAK,EAAE,CAAC,CAAA,EAAA,CAAI,CAAA,CAAE,KAAK,MAAM,CAAA;AAE1E,IAAA,MAAM,UAAA,GAAuB,CAAC,qBAAqB,CAAA;AACnD,IAAA,MAAM,MAAA,GAA8B,CAAC,KAAK,CAAA;AAC1C,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,UAAA,CAAW,KAAK,YAAY,CAAA;AAC5B,MAAA,MAAA,CAAO,KAAK,aAAa,CAAA;AAAA,IAC3B;AACA,IAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,UAAA,CAAW,KAAK,YAAY,CAAA;AAC5B,MAAA,MAAA,CAAO,IAAA,CAAK,OAAO,IAAI,CAAA;AAAA,IACzB;AACA,IAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,UAAA,CAAW,KAAK,eAAe,CAAA;AAC/B,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,CAAA,EAAI,MAAA,CAAO,IAAI,CAAA,CAAA,CAAG,CAAA;AAAA,IAChC;AACA,IAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,IAAA,CAAK,OAAO,CAAA;AAErC,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,EAAA,CACpB,OAAA,CAAQ,CAAA,uFAAA,EAA0F,KAAK,CAAA,CAAE,CAAA,CACzG,GAAA,CAAI,GAAG,MAAM,CAAA;AAChB,IAAA,MAAM,KAAA,GAAQ,UAAU,CAAC,CAAA,GAAI,OAAO,SAAA,CAAU,CAAC,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA;AACtD,IAAA,IAAI,KAAA,KAAU,GAAG,OAAO,EAAE,SAAS,EAAC,EAAG,OAAO,CAAA,EAAE;AAEhD,IAAA,MAAM,IAAA,GAAO,KAAK,EAAA,CACf,OAAA;AAAA,MACC,CAAA;AAAA;AAAA;AAAA;AAAA,eAAA,EAIS,KAAK;AAAA;AAAA,gBAAA;AAAA,KAGhB,CACC,GAAA,CAAI,GAAG,MAAA,EAAQ,KAAK,CAAA;AAMvB,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,QACxB,IAAI,CAAA,CAAE,EAAA;AAAA,QACN,MAAM,CAAA,CAAE,IAAA;AAAA,QACR,MAAM,CAAA,CAAE,IAAA;AAAA,QACR,MAAM,CAAA,CAAE,IAAA;AAAA,QACR,MAAM,CAAA,CAAE,IAAA;AAAA,QACR,MAAM,CAAA,CAAE,IAAA;AAAA,QACR,KAAK,CAAA,CAAE,GAAA;AAAA,QACP,WAAW,CAAA,CAAE,SAAA;AAAA,QACb,YAAY,CAAA,CAAE,WAAA;AAAA;AAAA;AAAA,QAGd,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,IAAA,EAAQ,EAAE,KAAK,CAAA;AAAA,QAC/B,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,MAAA,EAAQ;AAAA,OACnB,CAAE,CAAA;AAAA,MACF;AAAA,KACF;AAAA,EACF;AAAA;AAAA,EAGQ,oBAAA,CACN,KAAA,EACA,MAAA,EAGA,KAAA,EAC4C;AAC5C,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,MAAA,CAAO,KAAA,EAAO,MAAM,CAAA;AAC5C,IAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG,OAAO,EAAE,OAAA,EAAS,EAAC,EAAG,KAAA,EAAO,CAAA,EAAE;AAE5D,IAAA,IAAI,CAAC,KAAA,CAAM,IAAA,EAAK,EAAG;AACjB,MAAA,OAAO,EAAE,SAAS,UAAA,CAAW,KAAA,CAAM,GAAG,KAAK,CAAA,EAAG,KAAA,EAAO,UAAA,CAAW,MAAA,EAAO;AAAA,IACzE;AAEA,IAAA,MAAM,IAAA,GAAO,cAAA;AAAA,MACX,WAAW,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,IAAI,CAAA,CAAE,EAAA,EAAI,IAAA,EAAM,kBAAA,CAAmB,EAAE,IAAA,EAAM,CAAA,CAAE,WAAW,CAAA,CAAE,UAAU,GAAE,CAAE;AAAA,KACnG;AACA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,KAAA,EAAO,CAAC,EAAA,KAAO,UAAA,CAAW,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,EAAE,CAAC,CAAA;AAC5E,IAAA,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AACvC,IAAA,MAAM,OAAA,GAAU,SAAS,KAAK,CAAA;AAE9B,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA,CAAE,GAAA,CAAI,CAAC,EAAE,EAAA,EAAI,KAAA,EAAM,KAAM;AAC5D,MAAA,MAAM,CAAA,GAAI,cAAc,UAAA,CAAW,IAAA,CAAK,CAAC,IAAA,KAAS,IAAA,CAAK,EAAA,KAAO,EAAE,CAAC,CAAA;AACjE,MAAA,OAAO,EAAE,GAAG,CAAA,EAAG,KAAA,EAAO,SAAS,IAAA,CAAK,cAAA,CAAe,EAAA,EAAI,OAAO,CAAA,EAAE;AAAA,IAClE,CAAC,CAAA;AACD,IAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,UAAA,CAAW,MAAA,EAAO;AAAA,EAC7C;AAAA,EAEA,eAAA,GAAuD;AACrD,IAAA,OAAQ,KAAK,EAAA,CAAG,OAAA,CAAQ,8BAA8B,CAAA,CAAE,KAAI,CAAqC,GAAA;AAAA,MAC/F,CAAC,EAAE,EAAA,EAAI,MAAK,MAAO,EAAE,IAAI,IAAA,EAAK;AAAA,KAChC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,cAAA,GAAyB;AACvB,IAAA,MAAM,OAAO,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ,kCAAkC,EAAE,GAAA,EAAI;AACrE,IAAA,OAAO,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,IAAK,CAAA;AAAA,EACvB;AAAA;AAAA,EAIA,QAAA,GAAuB;AACrB,IAAA,MAAM,SAAA,GAAY,KAAK,SAAA,EAAU;AAEjC,IAAA,MAAM,QAAA,GAAW,KAAK,EAAA,CAAG,OAAA;AAAA,MACvB;AAAA,MACA,GAAA,EAAI;AACN,IAAA,MAAM,WAAA,GAAc,SAAS,MAAA,GAAS,MAAA,CAAO,SAAS,CAAC,CAAA,EAAG,KAAK,CAAA,GAAI,IAAA;AAEnE,IAAA,MAAM,YAAY,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ,8BAA8B,EAAE,GAAA,EAAI;AACtE,IAAA,MAAM,YAAA,GAAe,SAAA,CAAU,CAAC,CAAA,GAAI,MAAA,CAAO,UAAU,CAAC,CAAA,CAAE,UAAU,CAAC,CAAA,GAAI,CAAA;AAEvE,IAAA,MAAM,WAAW,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ,4BAA4B,EAAE,GAAA,EAAI;AACnE,IAAA,MAAM,UAAA,GAAa,QAAA,CAAS,CAAC,CAAA,GAAI,MAAA,CAAO,SAAS,CAAC,CAAA,CAAE,UAAU,CAAC,CAAA,GAAI,CAAA;AAEnE,IAAA,MAAM,QAAA,GAAW,KAAK,EAAA,CAAG,OAAA;AAAA,MACvB;AAAA,MACA,GAAA,EAAI;AACN,IAAA,MAAM,SAAS,EAAC;AAChB,IAAA,KAAA,MAAW,GAAA,IAAO,UAAU,MAAA,CAAO,GAAA,CAAI,IAAkB,CAAA,GAAI,MAAA,CAAO,GAAA,CAAI,UAAU,CAAC,CAAA;AAEnF,IAAA,MAAM,QAAA,GAAW,KAAK,EAAA,CAAG,OAAA;AAAA,MACvB;AAAA,MACA,GAAA,EAAI;AACN,IAAA,MAAM,SAAS,EAAC;AAChB,IAAA,KAAA,MAAW,GAAA,IAAO,UAAU,MAAA,CAAO,GAAA,CAAI,IAAkB,CAAA,GAAI,MAAA,CAAO,GAAA,CAAI,UAAU,CAAC,CAAA;AAEnF,IAAA,OAAO;AAAA,MACL,YAAA;AAAA,MACA,UAAA;AAAA,MACA,MAAA;AAAA,MACA,MAAA;AAAA,MACA,WAAW,IAAA,CAAK,QAAA;AAAA,MAChB,WAAA;AAAA,MACA,SAAA;AAAA,MACA,OAAA,EAAS;AAAA,KACX;AAAA,EACF;AAAA,EAEA,eAAeC,GAAAA,EAAkB;AAC/B,IAAA,IAAA,CAAK,aAAa,MAAM;AACtB,MAAA,IAAA,CAAK,EAAA,CAAG,OAAA;AAAA,QACN;AAAA,OACF,CAAE,GAAA,CAAI,MAAA,CAAOA,GAAE,CAAC,CAAA;AAAA,IAClB,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,QAAA,GAAiB;AACf,IAAA,IAAA,CAAK,aAAa,MAAM;AACtB,MAAA,IAAA,CAAK,EAAA,CAAG,KAAK,qBAAqB,CAAA;AAClC,MAAA,IAAA,CAAK,EAAA,CAAG,KAAK,mBAAmB,CAAA;AAChC,MAAA,IAAA,CAAK,EAAA,CAAG,KAAK,kBAAkB,CAAA;AAC/B,MAAA,IAAI,IAAA,CAAK,YAAA,EAAc,IAAA,CAAK,EAAA,CAAG,KAAK,yBAAyB,CAAA;AAAA,IAC/D,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,UAAA,CAAW,QAAgB,IAAA,EAAmB;AAC5C,IAAA,IAAA,CAAK,aAAa,MAAM;AAEtB,MAAA,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ,oCAAoC,CAAA,CAAE,IAAI,MAAM,CAAA;AAChE,MAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AAEvB,MAAA,MAAM,IAAA,GAAO,KAAK,EAAA,CAAG,OAAA;AAAA,QACnB,CAAA;AAAA,+BAAA;AAAA,OAEF;AACA,MAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,QAAA,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,GAAA,CAAI,MAAA,EAAQ,GAAA,CAAI,QAAQ,IAAA,EAAM,GAAA,CAAI,QAAA,EAAU,GAAA,CAAI,IAAI,CAAA;AAAA,MACvE;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAkB,IAAA,EAAoB;AACpC,IAAA,IAAA,CAAK,aAAa,MAAM;AACtB,MAAA,MAAM,GAAA,GAAM,KAAK,EAAA,CAAG,OAAA;AAAA,QAClB;AAAA,OACF,CAAE,IAAI,IAAI,CAAA;AACV,MAAA,IAAI,CAAC,IAAI,MAAA,EAAQ;AACjB,MAAA,MAAM,eAAe,GAAA,CAAI,GAAA,CAAI,MAAM,GAAG,CAAA,CAAE,KAAK,GAAG,CAAA;AAChD,MAAA,IAAA,CAAK,EAAA,CAAG,OAAA,CAAQ,CAAA,mCAAA,EAAsC,YAAY,GAAG,CAAA,CAAE,GAAA,CAAI,GAAG,GAAA,CAAI,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AAAA,IACpG,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAA,GAAsB;AACpB,IAAA,OAAO,IAAA,CAAK,aAAa,MAAM;AAC7B,MAAA,MAAM,UAAA,GAAa,KAAK,EAAA,CAAG,OAAA;AAAA,QACzB;AAAA,QACA,GAAA,EAAI;AAEN,MAAA,IAAI,QAAA,GAAW,CAAA;AACf,MAAA,KAAA,MAAW,OAAO,UAAA,EAAY;AAC5B,QAAA,MAAM,MAAA,GAAS,KAAK,EAAA,CAAG,OAAA,CAAQ,+CAA+C,CAAA,CAAE,GAAA,CAAI,IAAI,OAAO,CAAA;AAC/F,QAAA,MAAM,KAAA,GAAQ,OAAO,CAAC,CAAA;AACtB,QAAA,IAAI,KAAA,EAAO;AACT,UAAA,IAAA,CAAK,EAAA,CAAG,QAAQ,wCAAwC,CAAA,CAAE,IAAI,KAAA,CAAM,EAAA,EAAI,IAAI,EAAE,CAAA;AAC9E,UAAA,QAAA,EAAA;AAAA,QACF;AAAA,MACF;AACA,MAAA,OAAO,QAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,QAAA,EAAyB;AAClC,IAAA,OAAQ,KAAK,EAAA,CAAG,OAAA;AAAA,MACd;AAAA,MACA,GAAA,CAAI,QAAA,EAAU,QAAQ,CAAA,CAAgH,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MAClJ,IAAI,CAAA,CAAE,EAAA;AAAA,MAAI,QAAQ,CAAA,CAAE,OAAA;AAAA,MAAS,QAAQ,CAAA,CAAE,OAAA;AAAA,MAAS,IAAA,EAAM,EAAE,KAAA,IAAS,MAAA;AAAA,MAAW,UAAU,CAAA,CAAE,SAAA;AAAA,MAA8B,MAAM,CAAA,CAAE;AAAA,KAChI,CAAE,CAAA;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,QAAA,EAAyB;AACpC,IAAA,OAAQ,KAAK,EAAA,CAAG,OAAA;AAAA,MACd;AAAA,MACA,GAAA,CAAI,QAAQ,CAAA,CAAgH,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MACxI,IAAI,CAAA,CAAE,EAAA;AAAA,MAAI,QAAQ,CAAA,CAAE,OAAA;AAAA,MAAS,QAAQ,CAAA,CAAE,OAAA;AAAA,MAAS,IAAA,EAAM,EAAE,KAAA,IAAS,MAAA;AAAA,MAAW,UAAU,CAAA,CAAE,SAAA;AAAA,MAA8B,MAAM,CAAA,CAAE;AAAA,KAChI,CAAE,CAAA;AAAA,EACJ;AAAA,EAEQ,SAAA,GAAoB;AAC1B,IAAA,MAAM,MAAA,GAAcD,KAAA,CAAA,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,OAAO,CAAA;AAC/C,IAAA,IAAI;AACF,MAAA,OAAU,EAAA,CAAA,QAAA,CAAS,MAAM,CAAA,CAAE,IAAA;AAAA,IAC7B,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,CAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAI;AAAE,MAAA,IAAA,CAAK,GAAG,KAAA,EAAM;AAAA,IAAG,CAAA,CAAA,MAAQ;AAAA,IAAuB;AAAA,EACxD;AACF;AC3tBA,IAAM,QAAA,GAAuD;AAAA,EAC3D,CAAI,EAAA,CAAA,UAAA,CAAW,gBAAgB,GAAQ,OAAA;AAAA,EACvC,CAAI,EAAA,CAAA,UAAA,CAAW,oBAAoB,GAAG,WAAA;AAAA,EACtC,CAAI,EAAA,CAAA,UAAA,CAAW,eAAe,GAAS,MAAA;AAAA,EACvC,CAAI,EAAA,CAAA,UAAA,CAAW,oBAAoB,GAAI,MAAA;AAAA,EACvC,CAAI,EAAA,CAAA,UAAA,CAAW,mBAAmB,GAAM,UAAA;AAAA,EACxC,CAAI,EAAA,CAAA,UAAA,CAAW,iBAAiB,GAAO,QAAA;AAAA,EACvC,CAAI,EAAA,CAAA,UAAA,CAAW,WAAW,GAAa,UAAA;AAAA,EACvC,CAAI,EAAA,CAAA,UAAA,CAAW,WAAW,GAAa,UAAA;AAAA,EACvC,CAAI,EAAA,CAAA,UAAA,CAAW,mBAAmB,GAAK,UAAA;AAAA,EACvC,CAAI,EAAA,CAAA,UAAA,CAAW,SAAS,GAAc,WAAA;AAAA,EACtC,CAAI,EAAA,CAAA,UAAA,CAAW,0BAA0B,GAAG;AAC9C,CAAA;AAEA,SAAS,OAAO,IAAA,EAAkC;AAGhD,EAAA,IAAO,EAAA,CAAA,qBAAA,CAAsB,IAAI,CAAA,EAAG;AAClC,IAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AACpB,IAAA,IAAO,EAAA,CAAA,yBAAA,CAA0B,MAAM,CAAA,EAAG;AACxC,MAAA,MAAM,QAAQ,MAAA,CAAO,KAAA;AACrB,MAAA,IAAI,KAAA,GAAW,EAAA,CAAA,SAAA,CAAU,GAAA,EAAK,OAAO,KAAA;AACrC,MAAA,IAAI,KAAA,GAAW,EAAA,CAAA,SAAA,CAAU,KAAA,EAAO,OAAO,OAAA;AACvC,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAGA,EAAA,IAAO,EAAA,CAAA,mBAAA,CAAoB,IAAI,CAAA,EAAG,OAAO,WAAA;AAEzC,EAAA,OAAO,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA,IAAK,IAAA;AAChC;AAEA,SAAS,UAAU,GAAA,EAAgC;AACjD,EAAA,QAAQ,GAAA;AAAK,IACX,KAAK,KAAA;AAAS,MAAA,OAAO,IAAA;AAAA,IACrB,KAAK,MAAA;AAAS,MAAA,OAAO,KAAA;AAAA,IACrB,KAAK,KAAA;AAAS,MAAA,OAAO,IAAA;AAAA,IACrB,KAAK,MAAA;AAAS,MAAA,OAAO,KAAA;AAAA,IACrB,KAAK,KAAA;AAAS,MAAA,OAAO,IAAA;AAAA,IACrB,KAAK,KAAA;AAAS,MAAA,OAAO,IAAA;AAAA,IACrB,KAAK,KAAA;AAAS,MAAA,OAAO,IAAA;AAAA,IACrB,KAAK,OAAA;AAAS,MAAA,OAAO,MAAA;AAAA,IACrB,KAAK,OAAA;AAAS,MAAA,OAAO,MAAA;AAAA,IACrB,KAAK,MAAA;AAAS,MAAA,OAAO,MAAA;AAAA,IACrB;AAAc,MAAA,OAAO,IAAA;AAAA;AAEzB;AAEA,SAAS,YAAA,CAAa,MAAsB,UAAA,EAAmC;AAC7E,EAAA,MAAM,OAAA,GAAa,EAAA,CAAA,aAAA,CAAc,EAAE,CAAA;AACnC,EAAA,MAAM,MAAM,OAAA,CAAQ,SAAA,CAAa,EAAA,CAAA,QAAA,CAAS,WAAA,EAAa,MAAM,UAAU,CAAA;AACvE,EAAA,OAAO,IAAI,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CAAE,KAAA,CAAM,GAAG,GAAG,CAAA;AAC9C;AAOA,SAAS,QAAA,CAAS,MAAe,UAAA,EAAmC;AAClE,EAAA,MAAM,QAAA,GAAW,WAAW,WAAA,EAAY;AACxC,EAAA,MAAM,OAAA,GAAU,KAAK,YAAA,EAAa;AAClC,EAAA,MAAM,QAAA,GAAc,EAAA,CAAA,uBAAA,CAAwB,QAAA,EAAU,OAAO,CAAA;AAC7D,EAAA,IAAI,CAAC,UAAU,OAAO,EAAA;AAEtB,EAAA,KAAA,MAAW,SAAS,QAAA,EAAU;AAC5B,IAAA,MAAM,cAAc,QAAA,CAAS,KAAA,CAAM,KAAA,CAAM,GAAA,EAAK,MAAM,GAAG,CAAA;AAEvD,IAAA,MAAM,OAAA,GAAU,YAAY,IAAA,EAAK;AACjC,IAAA,IAAI,QAAQ,UAAA,CAAW,KAAK,KAAK,OAAA,CAAQ,QAAA,CAAS,IAAI,CAAA,EAAG;AAEvD,MAAA,MAAM,KAAA,GAAQ,OAAA,CACX,KAAA,CAAM,CAAA,EAAG,EAAE,EACX,OAAA,CAAQ,iBAAA,EAAmB,EAAE,CAAA,CAC7B,IAAA,EAAK;AACR,MAAA,OAAO,KAAA,CAAM,KAAA,CAAM,IAAI,CAAA,CAAE,CAAC,CAAA,EAAG,IAAA,EAAK,CAAE,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA,IAAK,EAAA;AAAA,IACvD;AAAA,EACF;AACA,EAAA,OAAO,EAAA;AACT;AAGA,SAAS,WAAW,IAAA,EAAuB;AACzC,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,IAAI,UAA+B,IAAA,CAAK,MAAA;AACxC,EAAA,OAAO,OAAA,EAAS;AACd,IAAA,IACK,EAAA,CAAA,kBAAA,CAAmB,OAAO,CAAA,IAC1B,EAAA,CAAA,sBAAA,CAAuB,OAAO,CAAA,IAC9B,EAAA,CAAA,iBAAA,CAAkB,OAAO,CAAA,IACzB,EAAA,CAAA,sBAAA,CAAuB,OAAO,CAAA,EACjC;AACA,MAAA,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,IAAA,EAAM,IAAA,IAAQ,MAAM,CAAA;AAAA,IAC5C,CAAA,MAAA,IACK,EAAA,CAAA,mBAAA,CAAoB,OAAO,CAAA,IAC3B,iBAAc,OAAO,CAAA,IACrB,EAAA,CAAA,aAAA,CAAc,OAAO,KACrB,EAAA,CAAA,qBAAA,CAAsB,OAAO,CAAA,IAC7B,EAAA,CAAA,qBAAA,CAAsB,OAAO,CAAA,EAChC;AACA,MAAA,IAAI,OAAA,CAAQ,IAAA,IAAW,EAAA,CAAA,YAAA,CAAa,OAAA,CAAQ,IAAI,CAAA,EAAG;AACjD,QAAA,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA;AAAA,MACjC;AAAA,IACF;AACA,IAAA,OAAA,GAAU,OAAA,CAAQ,MAAA;AAAA,EACpB;AACA,EAAA,OAAO,KAAA,CAAM,KAAK,GAAG,CAAA;AACvB;AAgBO,SAAS,aAAa,IAAA,EAAiC;AAC5D,EAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAK,GAAI,IAAA;AAEhC,EAAA,IAAI,UAAA;AACJ,EAAA,IAAI;AACF,IAAA,UAAA,GAAgB,EAAA,CAAA,gBAAA,CAAiB,IAAA,EAAM,OAAA,EAAY,EAAA,CAAA,YAAA,CAAa,QAAQ,IAAI,CAAA;AAAA,EAC9E,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,MAAM,IAAA,EAAM,OAAA,EAAS,EAAC,EAAG,OAAA,EAAS,IAAA,CAAK,GAAA,EAAI,EAAE;AAAA,EACxD;AAEA,EAAA,MAAM,UAAyB,EAAC;AAEhC,EAAA,SAAS,MAAM,IAAA,EAAqB;AAClC,IAAA,MAAM,IAAA,GAAO,OAAO,IAAI,CAAA;AAExB,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,MAAM,WAAY,IAAA,CAA8C,IAAA;AAChE,MAAA,IAAI,CAAC,QAAA,IAAY,CAAI,EAAA,CAAA,YAAA,CAAa,QAAQ,CAAA,EAAG;AAC7C,MAAA,MAAM,OAAO,QAAA,CAAS,IAAA;AACtB,MAAA,MAAM,GAAA,GAAM,QAAA,CAAS,QAAA,CAAS,UAAU,CAAA;AACxC,MAAA,MAAM,EAAE,IAAA,EAAM,SAAA,EAAU,GAAI,UAAA,CAAW,8BAA8B,GAAG,CAAA;AACxE,MAAA,MAAM,KAAA,GAAQ,WAAW,IAAI,CAAA;AAC7B,MAAA,MAAM,SAAA,GAAY,YAAA,CAAa,IAAA,EAAwB,UAAU,CAAA;AACjE,MAAA,MAAM,UAAA,GAAa,QAAA,CAAS,IAAA,EAAM,UAAU,CAAA;AAC5C,MAAA,MAAM,IAAA,GAAO,CAAC,IAAA,EAAM,SAAA,EAAW,UAAU,EAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,KAAK,CAAA;AAErE,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACX,EAAA,EAAI,CAAA;AAAA,QACJ,IAAA;AAAA,QACA,IAAA;AAAA,QACA,IAAA;AAAA,QACA,IAAA;AAAA,QACA,MAAM,IAAA,GAAO,CAAA;AAAA,QACb,GAAA,EAAK,SAAA;AAAA,QACL,SAAA;AAAA,QACA,UAAA;AAAA,QACA,KAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH;AAEA,IAAG,EAAA,CAAA,YAAA,CAAa,MAAM,KAAK,CAAA;AAAA,EAC7B;AAEA,EAAA,KAAA,CAAM,UAAU,CAAA;AAGhB,EAAA,MAAM,IAAA,GAAO,YAAY,UAAU,CAAA;AAEnC,EAAA,OAAO,EAAE,MAAM,IAAA,EAAM,OAAA,EAAS,MAAM,OAAA,EAAS,IAAA,CAAK,KAAI,EAAE;AAC1D;AAKA,SAAS,YAAY,UAAA,EAAkC;AACrD,EAAA,MAAM,OAAc,EAAC;AAErB,EAAA,SAAS,MAAM,IAAA,EAAqB;AAClC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,UAAU,CAAA;AACpC,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,UAAA,CAAW,8BAA8B,GAAG,CAAA;AAC7D,IAAA,MAAM,UAAU,IAAA,GAAO,CAAA;AAEvB,IAAA,IAAO,EAAA,CAAA,gBAAA,CAAiB,IAAI,CAAA,EAAG;AAC7B,MAAA,MAAM,OAAO,IAAA,CAAK,UAAA;AAClB,MAAA,IAAO,EAAA,CAAA,YAAA,CAAa,IAAI,CAAA,EAAG;AACzB,QAAA,IAAA,CAAK,IAAA,CAAK,EAAE,MAAA,EAAQ,CAAA,EAAG,MAAA,EAAQ,IAAA,CAAK,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,IAAA,EAAM,OAAA,EAAS,CAAA;AAAA,MAC7E;AAAA,IACF,CAAA,MAAA,IAAc,EAAA,CAAA,0BAAA,CAA2B,IAAI,CAAA,EAAG;AAC9C,MAAA,IAAO,EAAA,CAAA,YAAA,CAAa,IAAA,CAAK,UAAU,CAAA,EAAG;AACpC,QAAA,IAAA,CAAK,IAAA,CAAK,EAAE,MAAA,EAAQ,CAAA,EAAG,MAAA,EAAQ,IAAA,CAAK,UAAA,CAAW,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,IAAA,EAAM,OAAA,EAAS,CAAA;AAAA,MACxF;AAAA,IACF,CAAA,MAAA,IAAc,EAAA,CAAA,mBAAA,CAAoB,IAAI,CAAA,EAAG;AACvC,MAAA,MAAM,IAAA,GAAO,WAAA,CAAY,IAAA,CAAK,QAAQ,CAAA;AACtC,MAAA,IAAI,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,EAAE,MAAA,EAAQ,CAAA,EAAG,MAAA,EAAQ,IAAA,EAAM,QAAA,EAAU,UAAA,EAAY,IAAA,EAAM,OAAA,EAAS,CAAA;AAAA,IACtF,CAAA,MAAA,IAAc,EAAA,CAAA,gBAAA,CAAiB,IAAI,CAAA,EAAG;AACpC,MAAA,KAAA,MAAW,CAAA,IAAK,KAAK,KAAA,EAAO;AAC1B,QAAA,MAAM,IAAA,GAAO,WAAA,CAAY,CAAA,CAAE,UAA2B,CAAA;AACtD,QAAA,IAAI,MAAM,IAAA,CAAK,IAAA,CAAK,EAAE,MAAA,EAAQ,GAAG,MAAA,EAAQ,IAAA,EAAM,QAAA,EAAU,IAAA,CAAK,UAAa,EAAA,CAAA,UAAA,CAAW,cAAA,GAAiB,YAAY,WAAA,EAAa,IAAA,EAAM,SAAS,CAAA;AAAA,MACjJ;AAAA,IACF,CAAA,MAAA,IAAc,EAAA,CAAA,mBAAA,CAAoB,IAAI,CAAA,EAAG;AACvC,MAAA,MAAM,UAAA,GAAa,cAAc,IAAI,CAAA;AACrC,MAAA,IAAI,UAAA,EAAY,IAAA,CAAK,IAAA,CAAK,EAAE,MAAA,EAAQ,CAAA,EAAG,MAAA,EAAQ,UAAA,EAAY,QAAA,EAAU,QAAA,EAAU,IAAA,EAAM,OAAA,EAAS,CAAA;AAAA,IAChG;AAEA,IAAG,EAAA,CAAA,YAAA,CAAa,MAAM,KAAK,CAAA;AAAA,EAC7B;AAEA,EAAA,KAAA,CAAM,UAAU,CAAA;AAChB,EAAA,OAAO,gBAAgB,IAAI,CAAA;AAC7B;AAGA,SAAS,YAAY,IAAA,EAA6B;AAChD,EAAA,IAAO,EAAA,CAAA,YAAA,CAAa,IAAI,CAAA,EAAG,OAAO,IAAA,CAAK,IAAA;AACvC,EAAA,IAAO,EAAA,CAAA,eAAA,CAAgB,IAAI,CAAA,EAAG,OAAO,CAAA,EAAG,WAAA,CAAY,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,CAAA;AACjF,EAAA,OAAO,EAAA;AACT;AAGA,SAAS,cAAc,IAAA,EAAoC;AACzD,EAAA,MAAM,kBAAkB,IAAA,CAAK,eAAA;AAC7B,EAAA,IAAO,EAAA,CAAA,eAAA,CAAgB,eAAe,CAAA,EAAG,OAAO,eAAA,CAAgB,IAAA;AAChE,EAAA,OAAO,EAAA;AACT;AAGA,SAAS,gBAAgB,IAAA,EAAoB;AAC3C,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,OAAO,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,KAAM;AACxB,IAAA,MAAM,GAAA,GAAM,GAAG,CAAA,CAAE,MAAM,IAAI,CAAA,CAAE,QAAQ,CAAA,CAAA,EAAI,CAAA,CAAE,IAAI,CAAA,CAAA;AAC/C,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG,OAAO,KAAA;AAC1B,IAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACZ,IAAA,OAAO,IAAA;AAAA,EACT,CAAC,CAAA;AACH;AAGO,SAAS,WAAW,IAAA,EAAiC;AAC1D,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,WAAA,CAAY,GAAG,CAAA;AAChC,EAAA,IAAI,GAAA,GAAM,GAAG,OAAO,IAAA;AACpB,EAAA,OAAO,SAAA,CAAU,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA;AAClC;ACtPO,SAASE,cAAa,IAAA,EAAwE;AACnG,EAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAK,GAAI,IAAA;AAEhC,EAAA,IAAI;AACF,IAAA,OAAO,WAAA,CAAY,IAAA,EAAM,OAAA,EAAS,IAAI,CAAA;AAAA,EACxC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,MAAM,IAAA,EAAM,OAAA,EAAS,EAAC,EAAG,OAAA,EAAS,IAAA,CAAK,GAAA,EAAI,EAAE;AAAA,EACxD;AACF;AAMA,IAAM,eAAA,GAAkB;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAyOxB,SAAS,WAAA,CAAY,QAAA,EAAkB,OAAA,EAAiB,IAAA,EAA+B;AAMtF,EAAA,MAAM,MAAA,GAAcC,KAAA,CAAA,IAAA,CAAQ,EAAA,CAAA,MAAA,EAAO,EAAG,aAAa,CAAA;AACnD,EAAA,IAAI;AACH,IAAAC,SAAAA,CAAU,MAAA,EAAQ,EAAE,SAAA,EAAW,MAAM,CAAA;AACrC,IAAA,MAAM,UAAA,GAAkBD,KAAA,CAAA,IAAA,CAAK,MAAA,EAAQ,UAAU,CAAA;AAC/C,IAAA,aAAA,CAAc,UAAA,EAAY,iBAAiB,MAAM,CAAA;AAIjD,IAAA,MAAM,SAAS,YAAA,CAAa,IAAA,EAAM,CAAC,KAAA,EAAO,UAAU,CAAA,EAAG;AAAA,MACtD,KAAA,EAAO,OAAA;AAAA,MACP,OAAA,EAAS,IAAA;AAAA,MACT,QAAA,EAAU,MAAA;AAAA,MACV,WAAA,EAAa;AAAA,KACb,CAAA;AAED,IAAA,IAAI,CAAC,MAAA,CAAO,IAAA,EAAK,EAAG;AACnB,MAAA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,OAAA,EAAS,EAAC,EAAG,OAAA,EAAS,IAAA,CAAK,GAAA,EAAI,EAAE;AAAA,IACjE;AAEA,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,MAAM,CAAA;AACpC,IAAA,MAAM,OAAA,GAAyB,GAAA,CAAI,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MAC9C,EAAA,EAAI,CAAA;AAAA,MACJ,IAAA;AAAA,MACA,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,IAAA,EAAM,QAAA;AAAA,MACN,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,KAAK,CAAA,CAAE,GAAA;AAAA,MACP,SAAA,EAAW,EAAE,SAAA,IAAa,EAAA;AAAA,MAC1B,UAAA,EAAY,EAAA;AAAA,MACZ,KAAA,EAAO,EAAE,KAAA,IAAS,EAAA;AAAA,MAClB,IAAA,EAAM,GAAG,CAAA,CAAE,IAAI,IAAI,CAAA,CAAE,SAAA,IAAa,EAAE,CAAA,CAAA,CAAG,IAAA;AAAK,KAC7C,CAAE,CAAA;AACF,IAAA,OAAO,EAAE,MAAM,QAAA,EAAU,IAAA,EAAM,SAAS,OAAA,EAAS,IAAA,CAAK,KAAI,EAAE;AAAA,EAC7D,CAAA,CAAA,MAAQ;AACP,IAAA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,OAAA,EAAS,EAAC,EAAG,OAAA,EAAS,IAAA,CAAK,GAAA,EAAI,EAAE;AAAA,EACjE;AACD;AClSO,SAASD,cAAa,IAAA,EAAwE;AACnG,EAAA,MAAM,EAAE,IAAA,EAAM,IAAA,EAAK,GAAI,IAAA;AAEvB,EAAA,IAAI;AACF,IAAA,OAAO,WAAA,CAAY,MAAM,IAAI,CAAA;AAAA,EAC/B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,MAAM,IAAA,EAAM,OAAA,EAAS,EAAC,EAAG,OAAA,EAAS,IAAA,CAAK,GAAA,EAAI,EAAE;AAAA,EACxD;AACF;AAMA,IAAM,eAAA,GAAkB,CAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA,CAAA;AA+MxB,SAAS,WAAA,CAAY,UAAkB,IAAA,EAA+B;AACrE,EAAA,IAAI;AAKH,IAAA,MAAM,MAAA,GAAcG,KAAA,CAAA,IAAA,CAAQC,EAAA,CAAA,MAAA,EAAO,EAAG,aAAa,CAAA;AACnD,IAAAF,SAAAA,CAAU,MAAA,EAAQ,EAAE,SAAA,EAAW,MAAM,CAAA;AACrC,IAAA,MAAM,UAAA,GAAkBC,KAAA,CAAA,IAAA,CAAK,MAAA,EAAQ,UAAU,CAAA;AAC/C,IAAAE,aAAAA,CAAc,UAAA,EAAY,eAAA,EAAiB,MAAM,CAAA;AAIjD,IAAA,MAAM,SAASC,YAAAA,CAAa,QAAA,EAAU,CAAC,UAAA,EAAY,QAAQ,CAAA,EAAG;AAAA,MAC7D,OAAA,EAAS,IAAA;AAAA,MACT,QAAA,EAAU,MAAA;AAAA,MACV,WAAA,EAAa;AAAA,KACb,CAAA;AAED,IAAA,IAAI,CAAC,MAAA,CAAO,IAAA,EAAK,EAAG;AACnB,MAAA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,OAAA,EAAS,EAAC,EAAG,OAAA,EAAS,IAAA,CAAK,GAAA,EAAI,EAAE;AAAA,IACjE;AAEA,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,MAAM,CAAA;AAQpC,IAAA,MAAM,OAAA,GAAyB,GAAA,CAAI,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MAC9C,EAAA,EAAI,CAAA;AAAA,MACJ,IAAA;AAAA,MACA,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,IAAA,EAAM,QAAA;AAAA,MACN,MAAM,CAAA,CAAE,IAAA;AAAA,MACR,KAAK,CAAA,CAAE,GAAA;AAAA,MACP,SAAA,EAAW,EAAE,SAAA,IAAa,EAAA;AAAA,MAC1B,UAAA,EAAY,EAAA;AAAA,MACZ,KAAA,EAAO,EAAE,KAAA,IAAS,EAAA;AAAA,MAClB,IAAA,EAAM,GAAG,CAAA,CAAE,IAAI,IAAI,CAAA,CAAE,SAAA,IAAa,EAAE,CAAA,CAAA,CAAG,IAAA;AAAK,KAC7C,CAAE,CAAA;AACF,IAAA,OAAO,EAAE,MAAM,QAAA,EAAU,IAAA,EAAM,SAAS,OAAA,EAAS,IAAA,CAAK,KAAI,EAAE;AAAA,EAC7D,CAAA,CAAA,MAAQ;AACP,IAAA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,OAAA,EAAS,EAAC,EAAG,OAAA,EAAS,IAAA,CAAK,GAAA,EAAI,EAAE;AAAA,EACjE;AACD;AC9QO,SAASN,cAAa,IAAA,EAIb;AACd,EAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAK,GAAI,IAAA;AAGhC,EAAA,MAAM,kBAAkB,iBAAA,EAAkB;AAC1C,EAAA,IAAI,eAAA,EAAiB;AACnB,IAAA,MAAM,MAAA,GAAS,cAAA,CAAe,IAAA,EAAM,OAAO,CAAA;AAC3C,IAAA,IAAI,QAAQ,OAAO,MAAA;AAAA,EACrB;AAEA,EAAA,OAAO,UAAA,CAAW,EAAE,IAAA,EAAM,OAAA,EAAS,MAAM,CAAA;AAC3C;AAMA,SAAS,iBAAA,GAA6B;AACpC,EAAA,IAAI;AACF,IAAAM,YAAAA,CAAa,OAAA,EAAS,CAAC,WAAW,CAAA,EAAG,EAAE,KAAA,EAAO,MAAA,EAAQ,WAAA,EAAa,IAAA,EAAM,CAAA;AAGzE,IAAA,MAAM,QAAA,GAAgB,KAAA,CAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,IAAO,OAAO,CAAA;AACjD,IAAA,IAAI;AACF,MAAAA,YAAAA;AAAA,QACE,OAAA;AAAA,QACA;AAAA,UACE,UAAA;AAAA,UACA,WAAA;AAAA,UACA,kBAAA;AAAA,UACA,GAAA;AAAA,UACA,iBAAA;AAAA,UACK,KAAA,CAAA,IAAA,CAAK,UAAU,YAAY;AAAA,SAClC;AAAA,QACA,EAAE,KAAA,EAAO,MAAA,EAAQ,WAAA,EAAa,IAAA;AAAK,OACrC;AACA,MAAA,OAAO,IAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAEA,SAAS,cAAA,CAAe,MAAc,OAAA,EAAqC;AACzE,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAgB,KAAA,CAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,IAAO,OAAO,CAAA;AACjD,IAAA,MAAM,QAAA,GAAgB,KAAA,CAAA,IAAA,CAAK,QAAA,EAAU,YAAY,CAAA;AAGjD,IAAA,MAAM,OAAA,GAAe,KAAA,CAAA,IAAA,CAAK,QAAA,EAAU,KAAA,EAAO,UAAU,CAAA;AACrD,IAAAD,aAAAA,CAAc,OAAA,EAAS,OAAA,EAAS,MAAM,CAAA;AAEtC,IAAA,MAAM,MAAA,GAAS,SAAA;AAAA,MACb,OAAA;AAAA,MACA,CAAC,KAAA,EAAO,iBAAA,EAAwB,KAAA,CAAA,IAAA,CAAK,QAAA,EAAU,YAAY,CAAC,CAAA;AAAA,MAC5D;AAAA,QACE,GAAA,EAAK,QAAQ,GAAA,EAAI;AAAA,QACjB,QAAA,EAAU,MAAA;AAAA,QACV,OAAA,EAAS,IAAA;AAAA,QACT,KAAA,EAAO,CAAC,MAAA,EAAQ,MAAA,EAAQ,MAAM,CAAA;AAAA,QAC9B,WAAA,EAAa;AAAA;AACf,KACF;AAEA,IAAA,IAAI,MAAA,CAAO,MAAA,KAAW,CAAA,IAAK,MAAA,CAAO,MAAA,EAAQ;AACxC,MAAA,MAAM,OAAA,GAAyB,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,MAAM,CAAA;AACvD,MAAA,OAAO;AAAA,QACL,IAAA;AAAA,QACA,IAAA,EAAM,IAAA;AAAA,QACN,OAAA,EAAS,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,IAAA,EAAM,IAAA,EAAmB,CAAE,CAAA;AAAA,QACvE,OAAA,EAAS,KAAK,GAAA;AAAI,OACpB;AAAA,IACF;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,IAAA;AACT;AASA,IAAM,WAAA,GAA6B;AAAA,EACjC,EAAE,KAAA,EAAO,yBAAA,EAA2B,IAAA,EAAM,UAAA,EAAW;AAAA,EACrD,EAAE,KAAA,EAAO,iBAAA,EAAmB,IAAA,EAAM,QAAA,EAAS;AAAA,EAC3C,EAAE,KAAA,EAAO,eAAA,EAAiB,IAAA,EAAM,MAAA,EAAO;AAAA,EACvC,EAAE,KAAA,EAAO,gBAAA,EAAkB,IAAA,EAAM,OAAA,EAAQ;AAAA,EACzC,EAAE,KAAA,EAAO,2BAAA,EAA6B,IAAA,EAAM,MAAA,EAAO;AAAA,EACnD,EAAE,KAAA,EAAO,mBAAA,EAAqB,IAAA,EAAM,MAAA,EAAO;AAAA,EAC3C,EAAE,KAAA,EAAO,gBAAA,EAAkB,IAAA,EAAM,OAAA,EAAQ;AAAA,EACzC,EAAE,KAAA,EAAO,iBAAA,EAAmB,IAAA,EAAM,QAAA,EAAS;AAAA,EAC3C,EAAE,KAAA,EAAO,cAAA,EAAgB,IAAA,EAAM,KAAA;AACjC,CAAA;AAEA,SAAS,WAAW,IAAA,EAAwE;AAC1F,EAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAK,GAAI,IAAA;AAChC,EAAA,MAAM,UAAyB,EAAC;AAChC,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA;AAGhC,EAAA,MAAM,WAAA,GAAwB,CAAC,CAAC,CAAA;AAChC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,WAAA,CAAY,IAAA,CAAA,CAAM,WAAA,CAAY,CAAC,CAAA,IAAK,CAAA,KAAM,MAAM,CAAC,CAAA,EAAG,MAAA,IAAU,CAAA,CAAA,GAAK,CAAC,CAAA;AAAA,EACtE;AAEA,EAAA,SAAS,eAAe,MAAA,EAAwB;AAC9C,IAAA,IAAI,EAAA,GAAK,CAAA;AACT,IAAA,IAAI,EAAA,GAAK,YAAY,MAAA,GAAS,CAAA;AAC9B,IAAA,OAAO,KAAK,EAAA,EAAI;AACd,MAAA,MAAM,GAAA,GAAO,EAAA,GAAK,EAAA,GAAK,CAAA,KAAO,CAAA;AAC9B,MAAA,IAAIE,cAAc,WAAA,CAAY,GAAG,CAAC,CAAA,IAAK,QAAQ,EAAA,GAAK,GAAA;AAAA,gBAC1C,GAAA,GAAM,CAAA;AAAA,IAClB;AACA,IAAA,OAAO,EAAA,GAAK,CAAA;AAAA,EACd;AAEA,EAAA,SAAS,kBAAA,CAAmB,SAAiB,MAAA,EAAiC;AAC5E,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,OAAO,CAAA,IAAK,EAAA;AAC/B,IAAA,OAAO,IAAA,CAAK,IAAA,EAAK,CAAE,KAAA,CAAM,GAAG,GAAG,CAAA;AAAA,EACjC;AAEA,EAAA,KAAA,MAAW,WAAW,WAAA,EAAa;AACjC,IAAA,OAAA,CAAQ,MAAM,SAAA,GAAY,CAAA;AAC1B,IAAA,KAAA,IACM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,IAAA,CAAK,OAAO,CAAA,EACtC,KAAA,KAAU,IAAA,EACV,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,IAAA,CAAK,OAAO,CAAA,EAClC;AACA,MAAA,MAAM,IAAA,GAAOA,aAAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA;AACnC,MAAA,MAAM,MAAA,GAAU,MAAM,KAAA,IAAS,CAAA;AAC/B,MAAA,MAAM,IAAA,GAAO,eAAe,MAAM,CAAA;AAClC,MAAA,MAAM,GAAA,GAAM,MAAA,IAAU,WAAA,CAAY,IAAA,GAAO,CAAC,CAAA,IAAK,CAAA,CAAA;AAC/C,MAAA,MAAM,UAAU,IAAA,GAAO,CAAA;AACvB,MAAA,MAAM,SAAA,GAAY,kBAAA,CAAmB,OAAc,CAAA;AAEnD,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACX,EAAA,EAAI,CAAA;AAAA,QACJ,IAAA;AAAA,QACA,MAAM,OAAA,CAAQ,IAAA;AAAA,QACd,IAAA;AAAA,QACA,IAAA;AAAA,QACA,IAAA;AAAA,QACA,GAAA;AAAA,QACA,SAAA;AAAA,QACA,UAAA,EAAY,EAAA;AAAA,QACZ,KAAA,EAAO,EAAA;AAAA,QACP,MAAM,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,SAAS,GAAG,IAAA;AAAK,OACnC,CAAA;AAAA,IACH;AAAA,EACF;AAGA,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM;AACpC,IAAA,MAAM,MAAM,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,EAAE,IAAI,CAAA,CAAA;AAC/B,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG,OAAO,KAAA;AAC1B,IAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACZ,IAAA,OAAO,IAAA;AAAA,EACT,CAAC,CAAA;AAED,EAAA,OAAO,EAAE,MAAM,IAAA,EAAM,OAAA,EAAS,SAAS,OAAA,EAAS,IAAA,CAAK,KAAI,EAAE;AAC7D;ACzKO,SAASP,cAAa,IAAA,EAIb;AACd,EAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAK,GAAI,IAAA;AAEhC,EAAA,IAAI;AACF,IAAA,OAAOQ,WAAAA,CAAW,EAAE,IAAA,EAAM,OAAA,EAAS,MAAM,CAAA;AAAA,EAC3C,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,MAAM,IAAA,EAAM,OAAA,EAAS,EAAC,EAAG,OAAA,EAAS,IAAA,CAAK,GAAA,EAAI,EAAE;AAAA,EACxD;AACF;AAWA,SAASA,YAAW,IAAA,EAAwE;AAC1F,EAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAK,GAAI,IAAA;AAChC,EAAA,MAAM,UAAyB,EAAC;AAChC,EAAA,MAAMC,SAAAA,GAAgBC,KAAA,CAAA,QAAA,CAAS,IAAI,CAAA,CAAE,WAAA,EAAY;AAEjD,EAAA,MAAM,gBAAgBD,SAAAA,KAAa,cAAA;AACnC,EAAA,MAAM,UAAA,GAAaA,SAAAA,KAAa,eAAA,IAAmBA,SAAAA,KAAa,qBAAA;AAChE,EAAA,MAAM,YAAA,GACJ,OAAA,CAAQ,QAAA,CAAS,SAAS,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,MAAM,CAAA;AACnF,EAAA,MAAM,YAAY,OAAA,CAAQ,QAAA,CAAS,SAAS,CAAA,IAAK,OAAA,CAAQ,SAAS,SAAS,CAAA;AAE3E,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA;AAGhC,EAAA,MAAM,WAAA,GAAwB,CAAC,CAAC,CAAA;AAChC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,WAAA,CAAY,IAAA,CAAA,CAAM,WAAA,CAAY,CAAC,CAAA,IAAK,CAAA,KAAM,MAAM,CAAC,CAAA,EAAG,MAAA,IAAU,CAAA,CAAA,GAAK,CAAC,CAAA;AAAA,EACtE;AAEA,EAAA,SAAS,eAAe,MAAA,EAAwB;AAC9C,IAAA,IAAI,EAAA,GAAK,CAAA;AACT,IAAA,IAAI,EAAA,GAAK,YAAY,MAAA,GAAS,CAAA;AAC9B,IAAA,OAAO,KAAK,EAAA,EAAI;AACd,MAAA,MAAM,GAAA,GAAO,EAAA,GAAK,EAAA,GAAK,CAAA,KAAO,CAAA;AAC9B,MAAA,IAAIF,cAAc,WAAA,CAAY,GAAG,CAAC,CAAA,IAAK,QAAQ,EAAA,GAAK,GAAA;AAAA,gBAC1C,GAAA,GAAM,CAAA;AAAA,IAClB;AACA,IAAA,OAAO,EAAA,GAAK,CAAA;AAAA,EACd;AAGA,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,KAAA,CAAM,SAAS,CAAA;AACzC,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,MAAM,MAAA,GAASA,aAAAA,CAAc,SAAA,CAAU,KAAK,CAAA;AAC5C,IAAA,MAAM,IAAA,GAAO,eAAe,MAAM,CAAA;AAClC,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN,UAAA,CAAW;AAAA,QACT,IAAA,EAAWG,eAAS,IAAI,CAAA;AAAA,QACxB,IAAA,EAAM,QAAA;AAAA,QACN,IAAA;AAAA,QACA,GAAA,EAAK,CAAA;AAAA,QACL,SAAA,EAAW,CAAA,CAAA,EAASA,KAAA,CAAA,QAAA,CAAS,IAAI,CAAC,CAAA,WAAA,CAAA;AAAA,QAClC,IAAA;AAAA,QACA;AAAA,OACD;AAAA,KACH;AAAA,EACF;AAGA,EAAA,MAAM,gBAAA,GAAmB,qBAAA;AACzB,EAAA,KAAA,IACM,KAAA,GAAQ,gBAAA,CAAiB,IAAA,CAAK,OAAO,CAAA,EACzC,KAAA,KAAU,IAAA,EACV,KAAA,GAAQ,gBAAA,CAAiB,IAAA,CAAK,OAAO,CAAA,EACrC;AACA,IAAA,MAAM,GAAA,GAAMH,aAAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA;AAClC,IAAA,MAAM,MAAA,GAAU,MAAM,KAAA,IAAS,CAAA;AAC/B,IAAA,MAAM,IAAA,GAAO,eAAe,MAAM,CAAA;AAClC,IAAA,MAAM,GAAA,GAAM,MAAA,IAAU,WAAA,CAAY,IAAA,GAAO,CAAC,CAAA,IAAK,CAAA,CAAA;AAE/C,IAAA,IAAI,IAAA,GAA4B,UAAA;AAChC,IAAA,IAAI,SAAA,GAAY,IAAI,GAAG,CAAA,OAAA,CAAA;AAGvB,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,IACE,GAAA,KAAQ,aACR,GAAA,KAAQ,cAAA,IACR,QAAQ,iBAAA,IACR,GAAA,KAAQ,kBAAA,IACR,GAAA,KAAQ,sBAAA,EACR;AACA,QAAA,IAAA,GAAO,OAAA;AACP,QAAA,SAAA,GAAY,IAAI,GAAG,CAAA,UAAA,CAAA;AAAA,MACrB;AAAA,IACF,WAAW,UAAA,EAAY;AACrB,MAAA,IAAI,QAAQ,iBAAA,EAAmB;AAC7B,QAAA,IAAA,GAAO,UAAA;AACP,QAAA,SAAA,GAAY,CAAA,0BAAA,CAAA;AAAA,MACd;AAAA,IACF;AAGA,IAAA,IAAI,gBAAgB,SAAA,EAAW;AAC7B,MAAA,IAAI,GAAA,KAAQ,SAAA,IAAa,GAAA,KAAQ,KAAA,EAAO;AACtC,QAAA,IAAA,GAAO,QAAA;AACP,QAAA,SAAA,GAAY,IAAI,GAAG,CAAA,QAAA,CAAA;AAAA,MACrB,CAAA,MAAA,IAAW,QAAQ,MAAA,EAAQ;AACzB,QAAA,IAAA,GAAO,QAAA;AACP,QAAA,SAAA,GAAY,CAAA,aAAA,CAAA;AAAA,MACd;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN,UAAA,CAAW;AAAA,QACT,IAAA,EAAM,GAAA;AAAA,QACN,IAAA;AAAA,QACA,IAAA;AAAA,QACA,GAAA;AAAA,QACA,SAAA;AAAA,QACA,IAAA;AAAA,QACA;AAAA,OACD;AAAA,KACH;AAGA,IAAA,IAAI,aAAA,IAAiB,QAAQ,SAAA,EAAW;AACtC,MAAA,qBAAA,CAAsB,OAAA,EAAS,OAAA,EAAS,IAAA,EAAM,IAAA,EAAM,aAAa,cAAc,CAAA;AAAA,IACjF;AAGA,IAAA,IAAI,UAAA,IAAc,QAAQ,iBAAA,EAAmB;AAC3C,MAAA,sBAAA,CAAuB,SAAS,OAAA,EAAS,IAAA,EAAM,IAAA,EAAM,WAAA,EAAa,MAAM,cAAc,CAAA;AAAA,IACxF;AAAA,EACF;AAGA,EAAA,MAAM,SAAA,GAAY,4BAAA;AAClB,EAAA,MAAM,SAAA,GAAY,SAAA,CAAU,IAAA,CAAK,OAAO,CAAA;AACxC,EAAA,IAAI,cAAc,IAAA,EAAM;AACtB,IAAA,MAAM,MAAA,GAASA,aAAAA,CAAc,SAAA,CAAU,KAAK,CAAA;AAC5C,IAAA,MAAM,IAAA,GAAO,eAAe,MAAM,CAAA;AAClC,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN,UAAA,CAAW;AAAA,QACT,IAAA,EAAM,OAAA;AAAA,QACN,IAAA,EAAM,UAAA;AAAA,QACN,IAAA;AAAA,QACA,GAAA,EAAK,MAAA,IAAU,WAAA,CAAY,IAAA,GAAO,CAAC,CAAA,IAAK,CAAA,CAAA;AAAA,QACxC,SAAA,EAAW,kBAAA;AAAA,QACX,IAAA;AAAA,QACA;AAAA,OACD;AAAA,KACH;AAAA,EACF;AAGA,EAAA,MAAM,YAAA,GAAe;AAAA,IACnB,eAAA;AAAA,IACA,oBAAA;AAAA,IACA,mBAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,KAAA,MAAW,OAAO,YAAA,EAAc;AAC9B,IAAA,GAAA,CAAI,SAAA,GAAY,CAAA;AAChB,IAAA,KAAA,IAAS,KAAA,GAAQ,GAAA,CAAI,IAAA,CAAK,OAAO,CAAA,EAAG,KAAA,KAAU,IAAA,EAAM,KAAA,GAAQ,GAAA,CAAI,IAAA,CAAK,OAAO,CAAA,EAAG;AAC7E,MAAA,MAAM,MAAA,GAAU,MAAM,KAAA,IAAS,CAAA;AAC/B,MAAA,MAAM,IAAA,GAAO,eAAe,MAAM,CAAA;AAClC,MAAA,MAAM,GAAA,GAAM,KAAA,CAAM,CAAC,CAAA,EAAG,KAAA,CAAM,WAAW,CAAA,GAAI,CAAC,CAAA,IAAKA,aAAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA;AACvE,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,UAAA,CAAW;AAAA,UACT,IAAA,EAAM,GAAA;AAAA,UACN,IAAA,EAAM,UAAA;AAAA,UACN,IAAA;AAAA,UACA,GAAA,EAAK,MAAA,IAAU,WAAA,CAAY,IAAA,GAAO,CAAC,CAAA,IAAK,CAAA,CAAA;AAAA,UACxC,SAAA,EAAW,IAAI,GAAG,CAAA,UAAA,CAAA;AAAA,UAClB,IAAA;AAAA,UACA;AAAA,SACD;AAAA,OACH;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,SAAS,OAAA,EAAS,IAAA,CAAK,KAAI,EAAE;AACpD;AAEA,SAAS,sBACP,OAAA,EACA,OAAA,EACA,IAAA,EACA,IAAA,EACA,aACA,cAAA,EACM;AAEN,EAAA,MAAM,iBAAA,GAAoB,8BAAA;AAC1B,EAAA,KAAA,IACM,KAAA,GAAQ,iBAAA,CAAkB,IAAA,CAAK,OAAO,CAAA,EAC1C,KAAA,KAAU,IAAA,EACV,KAAA,GAAQ,iBAAA,CAAkB,IAAA,CAAK,OAAO,CAAA,EACtC;AACA,IAAA,MAAM,YAAA,GAAeA,aAAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA;AAC3C,IAAA,MAAM,WAAA,GAAe,MAAM,KAAA,IAAS,CAAA;AAGpC,IAAA,MAAM,cAAA,GAAiB,mBAAA;AACvB,IAAA,KAAA,IACM,WAAA,GAAc,cAAA,CAAe,IAAA,CAAK,YAAY,CAAA,EAClD,WAAA,KAAgB,IAAA,EAChB,WAAA,GAAc,cAAA,CAAe,IAAA,CAAK,YAAY,CAAA,EAC9C;AACA,MAAA,MAAM,GAAA,GAAMA,aAAAA,CAAc,WAAA,CAAY,CAAC,CAAC,CAAA;AACxC,MAAA,MAAM,SAAA,GAAY,WAAA,GAAcA,aAAAA,CAAc,WAAA,CAAY,KAAK,CAAA;AAC/D,MAAA,MAAM,IAAA,GAAO,eAAe,SAAS,CAAA;AACrC,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,UAAA,CAAW;AAAA,UACT,IAAA,EAAM,GAAA;AAAA,UACN,IAAA,EAAM,UAAA;AAAA,UACN,IAAA;AAAA,UACA,GAAA,EAAK,SAAA,IAAa,WAAA,CAAY,IAAA,GAAO,CAAC,CAAA,IAAK,CAAA,CAAA;AAAA,UAC3C,SAAA,EAAW,IAAI,GAAG,CAAA,QAAA,CAAA;AAAA,UAClB,IAAA;AAAA,UACA;AAAA,SACD;AAAA,OACH;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,uBACP,OAAA,EACA,OAAA,EACA,MACA,IAAA,EACA,WAAA,EACA,YACA,cAAA,EACM;AAEN,EAAA,MAAM,cAAA,GAAiB,sCAAA;AACvB,EAAA,KAAA,IACM,KAAA,GAAQ,cAAA,CAAe,IAAA,CAAK,OAAO,CAAA,EACvC,KAAA,KAAU,IAAA,EACV,KAAA,GAAQ,cAAA,CAAe,IAAA,CAAK,OAAO,CAAA,EACnC;AACA,IAAA,MAAM,YAAA,GAAeA,aAAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA;AAC3C,IAAA,MAAM,WAAA,GAAe,MAAM,KAAA,IAAS,CAAA;AAGpC,IAAA,MAAM,WAAA,GAAc,kBAAA;AACpB,IAAA,KAAA,IACM,QAAA,GAAW,WAAA,CAAY,IAAA,CAAK,YAAY,CAAA,EAC5C,QAAA,KAAa,IAAA,EACb,QAAA,GAAW,WAAA,CAAY,IAAA,CAAK,YAAY,CAAA,EACxC;AACA,MAAA,MAAM,GAAA,GAAMA,aAAAA,CAAc,QAAA,CAAS,CAAC,CAAC,CAAA;AACrC,MAAA,MAAM,SAAA,GAAY,WAAA,GAAcA,aAAAA,CAAc,QAAA,CAAS,KAAK,CAAA;AAC5D,MAAA,MAAM,IAAA,GAAO,eAAe,SAAS,CAAA;AACrC,MAAA,IAAI,QAAQ,UAAA,EAAY;AACxB,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,UAAA,CAAW;AAAA,UACT,IAAA,EAAM,GAAA;AAAA,UACN,IAAA,EAAM,UAAA;AAAA,UACN,IAAA;AAAA,UACA,GAAA,EAAK,SAAA,IAAa,WAAA,CAAY,IAAA,GAAO,CAAC,CAAA,IAAK,CAAA,CAAA;AAAA,UAC3C,SAAA,EAAW,IAAI,GAAG,CAAA,MAAA,CAAA;AAAA,UAClB,IAAA;AAAA,UACA;AAAA,SACD;AAAA,OACH;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,WAAW,IAAA,EAQJ;AACd,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,CAAA;AAAA,IACJ,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,KAAK,IAAA,CAAK,GAAA;AAAA,IACV,WAAW,IAAA,CAAK,SAAA;AAAA,IAChB,UAAA,EAAY,EAAA;AAAA,IACZ,KAAA,EAAO,EAAA;AAAA,IACP,IAAA,EAAM,GAAG,IAAA,CAAK,IAAI,IAAI,IAAA,CAAK,SAAS,GAAG,IAAA;AAAK,GAC9C;AACF;ACxTO,SAASP,cAAa,IAAA,EAIb;AACd,EAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAK,GAAI,IAAA;AAEhC,EAAA,IAAI;AACF,IAAA,OAAOQ,WAAAA,CAAW,EAAE,IAAA,EAAM,OAAA,EAAS,MAAM,CAAA;AAAA,EAC3C,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,MAAM,IAAA,EAAM,OAAA,EAAS,EAAC,EAAG,OAAA,EAAS,IAAA,CAAK,GAAA,EAAI,EAAE;AAAA,EACxD;AACF;AAMA,SAASA,YAAW,IAAA,EAAwE;AAC1F,EAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAK,GAAI,IAAA;AAChC,EAAA,MAAM,UAAyB,EAAC;AAEhC,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA;AAGhC,EAAA,MAAM,WAAA,GAAwB,CAAC,CAAC,CAAA;AAChC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,WAAA,CAAY,IAAA,CAAA,CAAM,WAAA,CAAY,CAAC,CAAA,IAAK,CAAA,KAAM,MAAM,CAAC,CAAA,EAAG,MAAA,IAAU,CAAA,CAAA,GAAK,CAAC,CAAA;AAAA,EACtE;AAEA,EAAA,SAAS,eAAe,MAAA,EAAwB;AAC9C,IAAA,IAAI,EAAA,GAAK,CAAA;AACT,IAAA,IAAI,EAAA,GAAK,YAAY,MAAA,GAAS,CAAA;AAC9B,IAAA,OAAO,KAAK,EAAA,EAAI;AACd,MAAA,MAAM,GAAA,GAAO,EAAA,GAAK,EAAA,GAAK,CAAA,KAAO,CAAA;AAC9B,MAAA,IAAID,cAAc,WAAA,CAAY,GAAG,CAAC,CAAA,IAAK,QAAQ,EAAA,GAAK,GAAA;AAAA,gBAC1C,GAAA,GAAM,CAAA;AAAA,IAClB;AACA,IAAA,OAAO,EAAA,GAAK,CAAA;AAAA,EACd;AAIA,EAAA,MAAM,WAAA,GAAc,cAAA;AACpB,EAAA,KAAA,IAAS,KAAA,GAAQ,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA,EAAG,KAAA,KAAU,IAAA,EAAM,KAAA,GAAQ,WAAA,CAAY,IAAA,CAAK,OAAO,CAAA,EAAG;AAC7F,IAAA,MAAM,IAAA,GAAOA,aAAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA;AACnC,IAAA,MAAM,MAAA,GAAU,MAAM,KAAA,IAAS,CAAA;AAC/B,IAAA,MAAM,IAAA,GAAO,eAAe,MAAM,CAAA;AAClC,IAAA,MAAM,GAAA,GAAM,MAAA,IAAU,WAAA,CAAY,IAAA,GAAO,CAAC,CAAA,IAAK,CAAA,CAAA;AAC/C,IAAA,OAAA,CAAQ,IAAA;AAAA,MACNI,WAAAA,CAAW;AAAA,QACT,IAAA;AAAA,QACA,IAAA,EAAM,OAAA;AAAA,QACN,IAAA;AAAA,QACA,GAAA;AAAA,QACA,SAAA,EAAW,IAAI,IAAI,CAAA,CAAA;AAAA,QACnB,IAAA;AAAA,QACA;AAAA,OACD;AAAA,KACH;AAAA,EACF;AAGA,EAAA,MAAM,UAAA,GAAa,eAAA;AACnB,EAAA,KAAA,IAAS,KAAA,GAAQ,UAAA,CAAW,IAAA,CAAK,OAAO,CAAA,EAAG,KAAA,KAAU,IAAA,EAAM,KAAA,GAAQ,UAAA,CAAW,IAAA,CAAK,OAAO,CAAA,EAAG;AAC3F,IAAA,MAAM,IAAA,GAAOJ,aAAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA;AACnC,IAAA,MAAM,MAAA,GAAU,MAAM,KAAA,IAAS,CAAA;AAC/B,IAAA,MAAM,IAAA,GAAO,eAAe,MAAM,CAAA;AAClC,IAAA,MAAM,GAAA,GAAM,MAAA,IAAU,WAAA,CAAY,IAAA,GAAO,CAAC,CAAA,IAAK,CAAA,CAAA;AAC/C,IAAA,OAAA,CAAQ,IAAA;AAAA,MACNI,WAAAA,CAAW;AAAA,QACT,IAAA;AAAA,QACA,IAAA,EAAM,OAAA;AAAA,QACN,IAAA;AAAA,QACA,GAAA;AAAA,QACA,SAAA,EAAW,IAAI,IAAI,CAAA,CAAA;AAAA,QACnB,IAAA;AAAA,QACA;AAAA,OACD;AAAA,KACH;AAAA,EACF;AAKA,EAAA,MAAM,OAAA,GAAU,+BAAA;AAChB,EAAA,KAAA,IAAS,KAAA,GAAQ,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA,EAAG,KAAA,KAAU,IAAA,EAAM,KAAA,GAAQ,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA,EAAG;AACrF,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,CAAC,CAAA,EAAG,MAAA,IAAU,CAAA;AACnC,IAAA,MAAM,GAAA,GAAM,MAAM,CAAC,CAAA;AACnB,IAAA,IAAI,CAAC,GAAA,EAAK;AACV,IAAA,MAAM,MAAA,GAAU,MAAM,KAAA,IAAS,CAAA;AAC/B,IAAA,MAAM,IAAA,GAAO,eAAe,MAAM,CAAA;AAClC,IAAA,MAAM,GAAA,GAAM,MAAA,IAAU,WAAA,CAAY,IAAA,GAAO,CAAC,CAAA,IAAK,CAAA,CAAA;AAG/C,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,IAAA,GAAO,CAAC,CAAA,IAAK,EAAA;AACvC,IAAA,IAAI,QAAA,CAAS,IAAA,CAAK,WAAA,CAAY,IAAA,EAAM,CAAA,EAAG;AAEvC,IAAA,IAAI,GAAA,KAAQ,KAAA,IAAS,GAAA,KAAQ,KAAA,EAAO;AAEpC,IAAA,IAAI,SAAS,EAAA,EAAI;AAEjB,IAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,OAAA,EAAU,KAAA,CAAM,SAAS,CAAE,CAAA;AACtD,IAAA,MAAM,IAAA,GAA4B,QAAA,CAAS,KAAK,CAAA,GAAI,SAAA,GAAY,UAAA;AAChE,IAAA,MAAM,YAAY,CAAA,EAAG,GAAG,KAAK,QAAA,CAAS,KAAA,EAAO,EAAE,CAAC,CAAA,CAAA;AAEhD,IAAA,OAAA,CAAQ,IAAA,CAAKA,WAAAA,CAAW,EAAE,IAAA,EAAM,GAAA,EAAK,IAAA,EAAM,IAAA,EAAM,GAAA,EAAK,SAAA,EAAW,IAAA,EAAM,IAAA,EAAM,CAAC,CAAA;AAAA,EAChF;AAIA,EAAA,MAAM,aAAA,GAAgB,gCAAA;AACtB,EAAA,KAAA,IAAS,KAAA,GAAQ,aAAA,CAAc,IAAA,CAAK,OAAO,CAAA,EAAG,KAAA,KAAU,IAAA,EAAM,KAAA,GAAQ,aAAA,CAAc,IAAA,CAAK,OAAO,CAAA,EAAG;AACjG,IAAA,MAAM,GAAA,GAAMJ,aAAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA;AAClC,IAAA,MAAM,MAAA,GAAU,MAAM,KAAA,IAAS,CAAA;AAC/B,IAAA,MAAM,IAAA,GAAO,eAAe,MAAM,CAAA;AAClC,IAAA,MAAM,GAAA,GAAM,MAAA,IAAU,WAAA,CAAY,IAAA,GAAO,CAAC,CAAA,IAAK,CAAA,CAAA;AAC/C,IAAA,MAAM,QAAQ,YAAA,CAAa,OAAA,EAAS,SAAS,KAAA,CAAM,CAAC,GAAG,MAAM,CAAA;AAC7D,IAAA,MAAM,IAAA,GAA4B,QAAA,CAAS,KAAK,CAAA,GAAI,SAAA,GAAY,UAAA;AAChE,IAAA,OAAA,CAAQ,IAAA;AAAA,MACNI,WAAAA,CAAW;AAAA,QACT,IAAA,EAAM,GAAA;AAAA,QACN,IAAA;AAAA,QACA,IAAA;AAAA,QACA,GAAA;AAAA,QACA,WAAW,CAAA,EAAA,EAAK,GAAG,KAAK,QAAA,CAAS,KAAA,EAAO,EAAE,CAAC,CAAA,CAAA;AAAA,QAC3C,IAAA;AAAA,QACA;AAAA,OACD;AAAA,KACH;AAAA,EACF;AAGA,EAAA,MAAM,gBAAA,GAAmB,4CAAA;AACzB,EAAA,KAAA,IAAS,KAAA,GAAQ,gBAAA,CAAiB,IAAA,CAAK,OAAO,CAAA,EAAG,KAAA,KAAU,IAAA,EAAM,KAAA,GAAQ,gBAAA,CAAiB,IAAA,CAAK,OAAO,CAAA,EAAG;AACvG,IAAA,MAAM,GAAA,GAAMJ,aAAAA,CAAc,KAAA,CAAM,CAAC,CAAC,CAAA;AAClC,IAAA,MAAM,MAAA,GAAU,MAAM,KAAA,IAAS,CAAA;AAC/B,IAAA,MAAM,IAAA,GAAO,eAAe,MAAM,CAAA;AAClC,IAAA,MAAM,GAAA,GAAM,MAAA,IAAU,WAAA,CAAY,IAAA,GAAO,CAAC,CAAA,IAAK,CAAA,CAAA;AAC/C,IAAA,OAAA,CAAQ,IAAA;AAAA,MACNI,WAAAA,CAAW;AAAA,QACT,IAAA,EAAM,GAAA;AAAA,QACN,IAAA,EAAM,UAAA;AAAA,QACN,IAAA;AAAA,QACA,GAAA;AAAA,QACA,SAAA,EAAW,GAAG,GAAG,CAAA,OAAA,CAAA;AAAA,QACjB,IAAA;AAAA,QACA;AAAA,OACD;AAAA,KACH;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,SAAS,OAAA,EAAS,IAAA,CAAK,KAAI,EAAE;AACpD;AAIA,SAAS,YAAA,CAAa,SAAiB,gBAAA,EAAkC;AAEvE,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,IAAA,EAAM,gBAAgB,CAAA;AACtD,EAAA,MAAM,OAAO,OAAA,CAAQ,KAAA,CAAM,kBAAkB,OAAA,GAAU,CAAA,GAAI,SAAY,OAAO,CAAA;AAC9E,EAAA,OAAO,KAAK,IAAA,EAAK;AACnB;AAEA,SAAS,SAAS,KAAA,EAAwB;AACxC,EAAA,IAAI,CAAC,OAAO,OAAO,KAAA;AAEnB,EAAA,IAAI,gCAAA,CAAiC,IAAA,CAAK,KAAK,CAAA,EAAG,OAAO,IAAA;AACzD,EAAA,IAAI,gCAAA,CAAiC,IAAA,CAAK,KAAK,CAAA,EAAG,OAAO,IAAA;AACzD,EAAA,IAAI,WAAA,CAAY,KAAK,KAAK,CAAA,IAAK,YAAY,IAAA,CAAK,KAAK,GAAG,OAAO,IAAA;AAC/D,EAAA,OAAO,KAAA;AACT;AAEA,SAASA,YAAW,IAAA,EAQJ;AACd,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,CAAA;AAAA,IACJ,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,KAAK,IAAA,CAAK,GAAA;AAAA,IACV,WAAW,IAAA,CAAK,SAAA;AAAA,IAChB,UAAA,EAAY,EAAA;AAAA,IACZ,KAAA,EAAO,EAAA;AAAA,IACP,IAAA,EAAM,GAAG,IAAA,CAAK,IAAI,IAAI,IAAA,CAAK,SAAS,GAAG,IAAA;AAAK,GAC9C;AACF;ACtKA,SAAS,SAAS,IAAA,EAAsB;AACtC,EAAA,OAAO,WAAA,CAAY,IAAI,CAAA,CAAE,MAAA,CAAO,OAAA,CAAQ,OAAO,EAAE,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AACtE;AAGO,SAAS,iBAAiB,KAAA,EAAgC;AAC/D,EAAA,MAAM,QAAgB,EAAC;AAEvB,EAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,IAAA,IAAI,IAAA,GAAO,GAAA,CAAI,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAChC,IAAA,IAAI,CAAC,KAAK,IAAA,EAAK,IAAK,KAAK,SAAA,EAAU,CAAE,UAAA,CAAW,GAAG,CAAA,EAAG;AACtD,IAAA,IAAA,GAAO,KAAK,IAAA,EAAK;AAEjB,IAAA,IAAI,OAAA,GAAU,KAAA;AACd,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,EAAG;AACxB,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,IAAA,GAAO,IAAA,CAAK,MAAM,CAAC,CAAA;AAAA,IACrB;AAEA,IAAA,IAAI,OAAA,GAAU,KAAA;AACd,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAG;AACtB,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAAA,IACzB;AACA,IAAA,IAAI,CAAC,IAAA,EAAM;AAKX,IAAA,MAAM,WAAW,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,IAAK,IAAA,CAAK,SAAS,GAAG,CAAA;AAC1D,IAAA,IAAI,KAAK,UAAA,CAAW,GAAG,GAAG,IAAA,GAAO,IAAA,CAAK,MAAM,CAAC,CAAA;AAE7C,IAAA,MAAM,IAAA,GAAO,SAAS,IAAI,CAAA;AAC1B,IAAA,MAAM,MAAA,GAAS,WAAW,GAAA,GAAM,WAAA;AAChC,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,WAAW,IAAI,MAAA,CAAO,GAAG,MAAM,CAAA,EAAG,IAAI,CAAA,SAAA,CAAW,CAAA;AAAA,MACjD,OAAO,IAAI,MAAA,CAAO,GAAG,MAAM,CAAA,EAAG,IAAI,CAAA,IAAA,CAAM,CAAA;AAAA,MACxC,OAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,CAAC,SAAiB,KAAA,KAA4B;AACnD,IAAA,MAAM,CAAA,GAAI,QAAQ,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAAE,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACxD,IAAA,IAAI,OAAA,GAAU,KAAA;AACd,IAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AAGrB,MAAA,MAAM,KAAK,CAAA,CAAE,OAAA,IAAW,CAAC,KAAA,GAAQ,CAAA,CAAE,QAAQ,CAAA,CAAE,SAAA;AAC7C,MAAA,IAAI,GAAG,IAAA,CAAK,CAAC,CAAA,EAAG,OAAA,GAAU,CAAC,CAAA,CAAE,OAAA;AAAA,IAC/B;AACA,IAAA,OAAO,OAAA;AAAA,EACT,CAAA;AACF;AAGA,eAAsB,qBAAqB,WAAA,EAA6C;AACtF,EAAA,IAAI,QAAkB,EAAC;AACvB,EAAA,IAAI;AACF,IAAA,MAAM,MAAM,MAASC,GAAA,CAAA,QAAA,CAAcC,WAAK,WAAA,EAAa,YAAY,GAAG,MAAM,CAAA;AAC1E,IAAA,KAAA,GAAQ,GAAA,CAAI,MAAM,IAAI,CAAA;AAAA,EACxB,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,iBAAiB,KAAK,CAAA;AAC/B;;;ACvEA,IAAM,aAAA,GAAgB,EAAA;AAEtB,SAAS,cAAA,GAAgC;AACvC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAACC,QAAAA,KAAY,YAAA,CAAaA,QAAO,CAAC,CAAA;AACvD;AAQA,SAAS,eAAe,MAAA,EAAuC;AAC7D,EAAA,IAAI,CAAC,QAAQ,OAAA,EAAS;AACtB,EAAA,IAAI,MAAA,CAAO,MAAA,YAAkB,KAAA,EAAO,MAAM,MAAA,CAAO,MAAA;AACjD,EAAA,MAAM,IAAI,KAAA;AAAA,IACR,OAAO,MAAA,CAAO,MAAA,KAAW,QAAA,GAAW,OAAO,MAAA,GAAS;AAAA,GACtD;AACF;AAOA,SAAS,aAAa,GAAA,EAAuB;AAC3C,EAAA,OAAO,GAAA,YAAe,YAAA,IAAgB,GAAA,CAAI,IAAA,KAAS,YAAA;AACrD;AAEA,IAAM,cAAA,GAAiB;AAAA,EACrB,cAAA;AAAA,EAAgB,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,OAAA;AAAA,EAAS,OAAA;AAAA,EAAS,UAAA;AAAA,EAClD,QAAA;AAAA,EAAU,eAAA;AAAA,EAAiB;AAC7B,CAAA;AAyBA,eAAe,eAAA,CACb,WAAA,EACA,MAAA,EACA,YAAA,EACA,MAAA,EACmB;AACnB,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,MAAM,SAAA,uBAAgB,GAAA,CAAI,CAAC,GAAG,cAAA,EAAgB,GAAG,MAAM,CAAC,CAAA;AAExD,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,EAAE,GAAA,EAAK,KAAA,EAAS,GAAA,EAAKC,WAAAA,CAAY,SAAS,CAAA,EAAE;AAAA,IAC5C,EAAE,GAAA,EAAK,MAAA,EAAS,GAAA,EAAKA,WAAAA,CAAY,UAAU,CAAA,EAAE;AAAA,IAC7C,EAAE,GAAA,EAAK,KAAA,EAAS,GAAA,EAAKA,WAAAA,CAAY,SAAS,CAAA,EAAE;AAAA,IAC5C,EAAE,GAAA,EAAK,MAAA,EAAS,GAAA,EAAKA,WAAAA,CAAY,UAAU,CAAA,EAAE;AAAA,IAC7C,EAAE,GAAA,EAAK,KAAA,EAAS,GAAA,EAAKA,WAAAA,CAAY,SAAS,CAAA,EAAE;AAAA,IAC5C,EAAE,GAAA,EAAK,KAAA,EAAS,GAAA,EAAKA,WAAAA,CAAY,SAAS,CAAA,EAAE;AAAA,IAC5C,EAAE,GAAA,EAAK,KAAA,EAAS,GAAA,EAAKA,WAAAA,CAAY,SAAS,CAAA,EAAE;AAAA,IAC5C,EAAE,GAAA,EAAK,OAAA,EAAS,GAAA,EAAKA,WAAAA,CAAY,WAAW,CAAA,EAAE;AAAA,IAC9C,EAAE,GAAA,EAAK,OAAA,EAAS,GAAA,EAAKA,WAAAA,CAAY,WAAW,CAAA,EAAE;AAAA,IAC9C,EAAE,GAAA,EAAK,MAAA,EAAS,GAAA,EAAKA,WAAAA,CAAY,UAAU,CAAA;AAAE,GAC/C;AAEA,EAAA,IAAI,QAAA,GAAW,CAAA;AAEf,EAAA,MAAM,IAAA,GAAO,OAAO,GAAA,KAA+B;AAGjD,IAAA,cAAA,CAAe,MAAM,CAAA;AAIrB,IAAA,IAAI,QAAA,GAAW,CAAA,IAAK,QAAA,GAAW,aAAA,KAAkB,CAAA,EAAG;AAClD,MAAA,MAAM,cAAA,EAAe;AACrB,MAAA,cAAA,CAAe,MAAM,CAAA;AAAA,IACvB;AACA,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAA,GAAU,MAAS,GAAA,CAAA,OAAA,CAAQ,GAAA,EAAK,EAAE,aAAA,EAAe,MAAM,CAAA;AAAA,IACzD,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AACA,IAAA,QAAA,EAAA;AAEA,IAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,MAAA,IAAI,SAAA,CAAU,GAAA,CAAI,CAAA,CAAE,IAAI,CAAA,EAAG;AAC3B,MAAA,MAAM,IAAA,GAAYC,KAAA,CAAA,IAAA,CAAK,GAAA,EAAK,CAAA,CAAE,IAAI,CAAA;AAElC,MAAA,MAAM,MAAWA,KAAA,CAAA,QAAA,CAAS,WAAA,EAAa,IAAI,CAAA,CAAE,OAAA,CAAQ,OAAO,GAAG,CAAA;AAC/D,MAAA,IAAI,CAAA,CAAE,aAAY,EAAG;AAGnB,QAAA,IAAI,YAAA,CAAa,GAAA,EAAK,IAAI,CAAA,EAAG;AAC7B,QAAA,MAAM,KAAK,IAAI,CAAA;AAAA,MACjB,CAAA,MAAA,IAAW,CAAA,CAAE,MAAA,EAAO,EAAG;AACrB,QAAA,IAAI,YAAA,CAAa,GAAA,EAAK,KAAK,CAAA,EAAG;AAC9B,QAAA,MAAM,GAAA,GAAWA,KAAA,CAAA,OAAA,CAAQ,CAAA,CAAE,IAAI,CAAA;AAC/B,QAAA,KAAA,MAAW,EAAE,GAAA,EAAK,OAAA,EAAS,GAAA,MAAS,KAAA,EAAO;AACzC,UAAA,IAAI,GAAA,KAAQ,OAAA,KAAY,GAAA,CAAI,IAAA,CAAK,GAAG,KAAK,GAAA,CAAI,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI;AAC1D,YAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AACjB,YAAA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,KAAK,WAAW,CAAA;AACtB,EAAA,OAAO,OAAA;AACT;AAGA,eAAe,SAAA,CACb,IAAA,EACA,OAAA,EACA,IAAA,EACqC;AACrC,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,IAAA;AAAA,IACL,KAAK,KAAA;AAAA,IACL,KAAK,IAAA;AAAA,IACL,KAAK,KAAA;AACH,MAAA,OAAO,YAAA,CAAQ,EAAE,IAAA,EAAM,OAAA,EAAS,MAA2C,CAAA;AAAA,IAC7E,KAAK,IAAA;AACH,MAAA,OAAOhB,cAAQ,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,MAAM,CAAA;AAAA,IAC9C,KAAK,IAAA;AACH,MAAA,OAAOA,cAAQ,EAAE,IAAA,EAAe,IAAA,EAAM,MAAM,CAAA;AAAA,IAC9C,KAAK,IAAA;AACH,MAAA,OAAOA,cAAQ,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,MAAM,CAAA;AAAA,IAC9C,KAAK,MAAA;AACH,MAAA,OAAOA,cAAU,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,QAAQ,CAAA;AAAA,IAClD,KAAK,MAAA;AACH,MAAA,OAAOA,cAAU,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,QAAQ,CAAA;AAAA,IAClD;AACE,MAAA,OAAO,EAAE,MAAM,IAAA,EAA2C,OAAA,EAAS,EAAC,EAAG,OAAA,EAAS,IAAA,CAAK,GAAA,EAAI,EAAE;AAAA;AAEjG;AAGA,eAAsB,UAAA,CACpB,MACA,IAAA,EACsB;AACtB,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,IAAA,CAAK,aAAa,EAAE,QAAA,EAAU,IAAA,CAAK,QAAA,EAAU,CAAA;AAC1E,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,mBAAA,CAAoB,KAAA,EAAO,IAAI,CAAA;AAAA,EAC9C,CAAA,SAAE;AAGA,IAAA,IAAI;AACF,MAAA,KAAA,CAAM,KAAA,EAAM;AAAA,IACd,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACF;AAEA,eAAe,mBAAA,CAAoB,OAAmB,IAAA,EAA4C;AAChG,EAAA,MAAM,EAAE,aAAa,KAAA,GAAQ,KAAA,EAAO,OAAO,MAAA,GAAS,EAAC,EAAG,MAAA,EAAO,GAAI,IAAA;AACnE,EAAA,MAAM,OAAA,GAAU,KAAK,GAAA,EAAI;AACzB,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,MAAM,YAAoC,EAAC;AAC3C,EAAA,IAAI,YAAA,GAAe,CAAA;AACnB,EAAA,IAAI,cAAA,GAAiB,CAAA;AAIrB,EAAA,MAAM,YAAA,GAAe,MAAM,oBAAA,CAAqB,WAAW,CAAA;AAE3D,EAAA,IAAI,KAAA;AACJ,EAAA,IAAI,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA,EAAG;AAGvC,IAAA,KAAA,GAAQ,IAAA,CAAK,KAAA,CACV,GAAA,CAAI,CAAC,CAAA,KAAWgB,cAAQ,WAAA,EAAa,CAAC,CAAC,CAAA,CACvC,MAAA,CAAO,CAAC,MAAM,CAAC,YAAA,CAAkBA,KAAA,CAAA,QAAA,CAAS,WAAA,EAAa,CAAC,CAAA,CAAE,QAAQ,KAAA,EAAO,GAAG,CAAA,EAAG,KAAK,CAAC,CAAA;AAAA,EAC1F,CAAA,MAAO;AACL,IAAA,KAAA,GAAQ,MAAM,eAAA,CAAgB,WAAA,EAAa,MAAA,EAAQ,cAAc,MAAM,CAAA;AAAA,EACzE;AAEA,EAAA,IAAI,KAAA,IAAS,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG;AAC7B,IAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAI,KAAK,CAAA;AAC7B,IAAA,KAAA,GAAQ,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM;AAC1B,MAAA,MAAM,IAAA,GAAO,WAAW,CAAC,CAAA;AACzB,MAAA,OAAO,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA,GAAI,KAAA;AAAA,IACpC,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,KAAA,QAAa,QAAA,EAAS;AAG1B,EAAA,MAAM,YAAA,uBAA0C,GAAA,EAAI;AACpD,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,KAAA,MAAW,IAAA,IAAQ,MAAM,eAAA,EAAgB,eAAgB,GAAA,CAAI,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,EAC9E;AAEA,EAAA,KAAA,IAAS,EAAA,GAAK,CAAA,EAAG,EAAA,GAAK,KAAA,CAAM,QAAQ,EAAA,EAAA,EAAM;AACxC,IAAA,MAAM,IAAA,GAAOT,aAAAA,CAAc,KAAA,CAAM,EAAE,CAAC,CAAA;AAGpC,IAAA,IAAA,CAAK,UAAA,GAAa,EAAA,GAAK,CAAA,EAAG,KAAA,CAAM,MAAM,CAAA;AAMtC,IAAA,IAAI,EAAA,GAAK,CAAA,IAAK,EAAA,GAAK,aAAA,KAAkB,CAAA,EAAG;AACtC,MAAA,MAAM,cAAA,EAAe;AACrB,MAAA,cAAA,CAAe,MAAM,CAAA;AAAA,IACvB;AAEA,IAAA,IAAIU,KAAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,QAAA,GAAW,MAAA,GAAS,EAAE,MAAA,KAAW,EAAC;AACxC,MAAAA,KAAAA,GAAO,MAAU,GAAA,CAAA,IAAA,CAA0E,IAAA,EAAM,QAAQ,CAAA;AAAA,IAC3G,SAAS,CAAA,EAAG;AAEV,MAAA,IAAI,YAAA,CAAa,CAAC,CAAA,EAAG,MAAM,CAAA;AAC3B,MAAA,KAAA,CAAM,WAAW,IAAI,CAAA;AACrB,MAAA;AAAA,IACF;AACA,IAAA,IAAI,CAACA,KAAAA,CAAK,MAAA,EAAO,EAAG;AAEpB,IAAA,MAAM,IAAA,GAAO,WAAW,IAAI,CAAA;AAC5B,IAAA,IAAI,CAAC,IAAA,EAAM;AAEX,IAAA,MAAM,IAAA,GAAO,YAAA,CAAa,GAAA,CAAI,IAAI,CAAA;AAClC,IAAA,IAAI,CAAC,SAAS,IAAA,IAAQ,IAAA,CAAK,YAAY,IAAA,CAAK,KAAA,CAAMA,KAAAA,CAAK,OAAO,CAAA,EAAG;AAC/D,MAAA,SAAA,CAAU,IAAI,CAAA,GAAA,CAAK,SAAA,CAAU,IAAI,CAAA,IAAK,KAAK,IAAA,CAAK,WAAA;AAChD,MAAA,cAAA,IAAkB,IAAA,CAAK,WAAA;AACvB,MAAA,YAAA,EAAA;AACA,MAAA;AAAA,IACF;AAKA,IAAA,KAAA,CAAM,kBAAkB,IAAI,CAAA;AAC5B,IAAA,KAAA,CAAM,qBAAqB,IAAI,CAAA;AAE/B,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAA,GAAU,MAAS,GAAA,CAAA,QAAA,CAAS,IAAA,EAAM,EAAE,QAAA,EAAU,MAAA,EAAQ,QAAQ,CAAA;AAAA,IAChE,SAAS,CAAA,EAAG;AACV,MAAA,IAAI,YAAA,CAAa,CAAC,CAAA,EAAG,MAAM,CAAA;AAC3B,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,YAAA,EAAe,IAAI,CAAA,EAAA,EAAK,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,CAAA;AAChF,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,MAAM,SAAA,CAAU,IAAA,EAAM,OAAA,EAAS,IAAI,CAAA;AAAA,IAC9C,SAAS,CAAA,EAAG;AACV,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,aAAA,EAAgB,IAAI,CAAA,EAAA,EAAK,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,CAAA;AACjF,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG;AAC/B,MAAA,KAAA,CAAM,UAAA,CAAW;AAAA,QACf,IAAA;AAAA,QACA,IAAA;AAAA,QACA,OAAA,EAAS,IAAA,CAAK,KAAA,CAAMA,KAAAA,CAAK,OAAO,CAAA;AAAA,QAChC,WAAA,EAAa,CAAA;AAAA,QACb,WAAA,EAAa,KAAK,GAAA;AAAI,OACvB,CAAA;AACD,MAAA,YAAA,EAAA;AACA,MAAA;AAAA,IACF;AAIA,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,cAAA,EAAe,GAAI,CAAA;AACxC,IAAA,MAAM,cAAA,GAAgC,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,EAAA,EAAI,MAAA,GAAS,GAAE,CAAE,CAAA;AAC7F,IAAA,KAAA,CAAM,aAAA,CAAc,gBAAgB,MAAM,CAAA;AAC1C,IAAA,MAAM,QAAQ,cAAA,CAAe,MAAA;AAC7B,IAAA,cAAA,IAAkB,KAAA;AAClB,IAAA,SAAA,CAAU,IAAI,CAAA,GAAA,CAAK,SAAA,CAAU,IAAI,KAAK,CAAA,IAAK,KAAA;AAG3C,IAAA,IAAI,MAAA,CAAO,IAAA,IAAQ,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,EAAG;AACzC,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,cAAA,CAAe,QAAQ,CAAA,EAAA,EAAK;AAC9C,QAAA,MAAM,GAAA,GAAMV,aAAAA,CAAc,cAAA,CAAe,CAAC,CAAC,CAAA;AAC3C,QAAA,MAAM,OAAA,GAAU,OAAO,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,GAAA,CAAI,IAAI,CAAA;AAC7D,QAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,UAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,MAAA,EAAQ,GAAA,CAAI,EAAA,EAAG,CAAE,CAAA;AACpE,UAAA,KAAA,CAAM,UAAA,CAAW,GAAA,CAAI,EAAA,EAAI,cAAc,CAAA;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAEA,IAAA,KAAA,CAAM,UAAA,CAAW;AAAA,MACf,IAAA;AAAA,MACA,IAAA;AAAA,MACA,OAAA,EAAS,IAAA,CAAK,KAAA,CAAMU,KAAAA,CAAK,OAAO,CAAA;AAAA,MAChC,WAAA,EAAa,KAAA;AAAA,MACb,WAAA,EAAa,KAAK,GAAA;AAAI,KACvB,CAAA;AAED,IAAA,YAAA,EAAA;AAAA,EACF;AAGA,EAAA,KAAA,MAAW,CAAC,KAAK,CAAA,IAAK,YAAA,EAAc;AAClC,IAAA,IAAI;AACF,MAAA,MAAS,SAAK,KAAK,CAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AACN,MAAA,KAAA,CAAM,WAAW,KAAK,CAAA;AAAA,IACxB;AAAA,EACF;AAEA,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,OAAA;AAChC,EAAA,KAAA,CAAM,cAAA,CAAe,IAAA,CAAK,GAAA,EAAK,CAAA;AAE/B,EAAA,OAAO;AAAA,IACL,YAAA;AAAA,IACA,cAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AACF;;;ACzVA,SAAS,QAAQ,WAAA,EAA8B;AAC7C,EAAA,OAAO;AAAA,IACL,WAAA;AAAA,IACA,GAAA,EAAK,WAAA;AAAA,IACL,UAAU,EAAC;AAAA,IACX,OAAO,EAAC;AAAA,IACR,SAAA,sBAAe,GAAA,EAAY;AAAA,IAC3B,UAAA,sBAAgB,GAAA;AAAoB,GACtC;AACF;AAQA,eAAsB,YAAA,CACpB,IAAA,EACA,KAAA,GAAsB,EAAC,EACD;AACtB,EAAA,OAAO,UAAA,CAAW,OAAA,CAAQ,IAAA,CAAK,WAAW,CAAA,EAAG;AAAA,IAC3C,aAAa,IAAA,CAAK,WAAA;AAAA,IAClB,UAAU,IAAA,CAAK,QAAA;AAAA,IACf,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,QAAQ,KAAA,CAAM,MAAA;AAAA,IACd,YAAY,KAAA,CAAM;AAAA,GACnB,CAAA;AACH;AAGO,SAAS,cAAc,IAAA,EAAoC;AAChE,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,IAAA,CAAK,aAAa,EAAE,QAAA,EAAU,IAAA,CAAK,QAAA,EAAU,CAAA;AAC1E,EAAA,IAAI;AACF,IAAA,OAAO,KAAA,CAAM,YAAA;AAAA,MACX,IAAA,CAAK,KAAA;AAAA,MACL;AAAA,QACE,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,SAAS,IAAA,CAAK;AAAA,OAChB;AAAA,MACA,IAAA,CAAK;AAAA,KACP;AAAA,EACF,CAAA,SAAE;AACA,IAAA,KAAA,CAAM,KAAA,EAAM;AAAA,EACd;AACF;AAGO,SAAS,aAAa,IAAA,EAA+B;AAC1D,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,IAAA,CAAK,aAAa,EAAE,QAAA,EAAU,IAAA,CAAK,QAAA,EAAU,CAAA;AAC1E,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,QAAA,EAAS;AAAA,EACxB,CAAA,SAAE;AACA,IAAA,KAAA,CAAM,KAAA,EAAM;AAAA,EACd;AACF;;;AC1BA,IAAM,6BAAA,GAAgC,IAAA;AAEtC,IAAM,8BAAA,GAAiC,GAAA;AAEvC,IAAM,wBAAA,GAA2B,GAAA;AAKjC,IAAI,MAAA,GAAS,KAAA;AACb,IAAI,SAAA,GAAY,KAAA;AAChB,IAAI,YAAA,GAAe,CAAA;AACnB,IAAI,WAAA,GAAc,CAAA;AAClB,IAAI,UAAA,GAA4B,IAAA;AAGzB,SAAS,YAAA,GAAwB;AACtC,EAAA,OAAO,MAAA;AACT;AAWO,SAAS,UAAA,GAAsB;AACpC,EAAA,OAAO,SAAA;AACT;AAGO,SAAS,aAAA,GAQd;AACA,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,MAAA;AAAA,IACP,QAAA,EAAU,SAAA;AAAA,IACV,WAAA,EAAa,YAAA;AAAA,IACb,UAAA,EAAY,WAAA;AAAA,IACZ,SAAA,EAAW,UAAA;AAAA,IACX,OAAA,EAAS,oBAAoB,QAAA;AAAS,GACxC;AACF;AAQA,IAAI,aAAmC,EAAC;AAEjC,SAAS,mBAAmB,QAAA,EAA0C;AAC3E,EAAA,UAAA,CAAW,KAAK,QAAQ,CAAA;AACxB,EAAA,OAAO,MAAM;AACX,IAAA,UAAA,GAAa,UAAA,CAAW,MAAA,CAAO,CAAC,CAAA,KAAM,MAAM,QAAQ,CAAA;AAAA,EACtD,CAAA;AACF;AAEA,SAAS,SAAA,GAAY;AACnB,EAAA,MAAM,QAAQ,aAAA,EAAc;AAC5B,EAAA,KAAA,MAAW,CAAA,IAAK,UAAA,EAAY,CAAA,CAAE,KAAK,CAAA;AACrC;AAEA,SAAS,gBAAA,CAAiB,SAAiB,KAAA,EAAe;AACxD,EAAA,YAAA,GAAe,OAAA;AACf,EAAA,WAAA,GAAc,KAAA;AACd,EAAA,SAAA,EAAU;AACZ;AAUA,IAAI,MAAA,GAAwB,IAAA;AAC5B,IAAI,iBAAA,GAAoB,KAAA;AACxB,IAAI,SAAA,GAAY,CAAA;AAChB,IAAM,OAAA,uBAAc,GAAA,EAAwB;AAQ5C,SAAS,gBAAA,GAA+B;AACtC,EAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,yBAAyB,CAAA,EAAG,OAAO,IAAA;AACnD,EAAA,KAAA,MAAW,GAAA,IAAO,CAAC,aAAA,EAAe,4BAA4B,CAAA,EAAG;AAC/D,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,GAAA,EAAK,YAAY,GAAG,CAAA;AACxC,MAAA,IAAI,GAAA,CAAI,aAAa,OAAA,IAAcC,EAAA,CAAA,UAAA,CAAW,cAAc,GAAG,CAAC,GAAG,OAAO,GAAA;AAAA,IAC5E,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,eAAe,GAAA,EAAoB;AAC1C,EAAA,MAAM,OAAA,GAAU,CAAC,GAAG,OAAA,CAAQ,QAAQ,CAAA;AACpC,EAAA,OAAA,CAAQ,KAAA,EAAM;AACd,EAAA,KAAA,MAAW,CAAA,IAAK,OAAA,EAAS,CAAA,CAAE,MAAA,CAAO,GAAG,CAAA;AACvC;AAEA,SAAS,YAAA,GAA8B;AACrC,EAAA,IAAI,QAAQ,OAAO,MAAA;AACnB,EAAA,IAAI,mBAAmB,OAAO,IAAA;AAC9B,EAAA,MAAM,MAAM,gBAAA,EAAiB;AAC7B,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,iBAAA,GAAoB,IAAA;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI;AACF,IAAA,MAAM,IAAI,IAAI,MAAA,CAAO,KAAK,EAAE,IAAA,EAAM,yBAAyB,CAAA;AAE3D,IAAA,CAAA,CAAE,KAAA,EAAM;AACR,IAAA,CAAA,CAAE,EAAA,CAAG,SAAA,EAAW,CAAC,GAAA,KAAsB;AACrC,MAAA,IAAI,GAAA,CAAI,SAAS,UAAA,EAAY;AAC3B,QAAA,OAAA,CAAQ,GAAA,CAAI,IAAI,EAAE,CAAA,EAAG,aAAa,GAAA,CAAI,OAAA,EAAS,IAAI,KAAK,CAAA;AACxD,QAAA;AAAA,MACF;AACA,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AAChC,MAAA,IAAI,CAAC,KAAA,EAAO;AACZ,MAAA,OAAA,CAAQ,MAAA,CAAO,IAAI,EAAE,CAAA;AACrB,MAAA,IAAI,GAAA,CAAI,EAAA,EAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,MAAM,CAAA;AAAA,iBACzB,MAAA,CAAO,IAAI,KAAA,CAAM,GAAA,CAAI,KAAK,CAAC,CAAA;AAAA,IACxC,CAAC,CAAA;AACD,IAAA,CAAA,CAAE,EAAA,CAAG,OAAA,EAAS,CAAC,GAAA,KAAQ;AACrB,MAAA,MAAA,GAAS,IAAA;AACT,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB,CAAC,CAAA;AACD,IAAA,CAAA,CAAE,EAAA,CAAG,QAAQ,MAAM;AACjB,MAAA,IAAI,MAAA,KAAW,GAAG,MAAA,GAAS,IAAA;AAC3B,MAAA,cAAA,CAAe,IAAI,KAAA,CAAM,8BAA8B,CAAC,CAAA;AAAA,IAC1D,CAAC,CAAA;AACD,IAAA,MAAA,GAAS,CAAA;AACT,IAAA,OAAO,CAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AAGN,IAAA,iBAAA,GAAoB,IAAA;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAGA,SAAS,gBAAgB,MAAA,EAAuB;AAC9C,EAAA,MAAM,CAAA,GAAI,MAAA;AACV,EAAA,MAAA,GAAS,IAAA;AACT,EAAA,cAAA,CAAe,MAAM,CAAA;AACrB,EAAA,IAAI,GAAG,KAAK,CAAA,CAAE,SAAA,EAAU,CAAE,MAAM,MAAM;AAAA,EAAC,CAAC,CAAA;AAC1C;AAMO,SAAS,yBAAA,GAAkC;AAChD,EAAA,sBAAA,EAAuB;AACvB,EAAA,eAAA,CAAgB,IAAI,KAAA,CAAM,+BAA+B,CAAC,CAAA;AAC1D,EAAA,iBAAA,GAAoB,KAAA;AACtB;AAcA,SAAS,WAAA,CACP,EAAA,EACA,IAAA,EACA,IAAA,EACgC;AAChC,EAAA,MAAM,IAAI,YAAA,EAAa;AACvB,EAAA,IAAI,CAAC,CAAA,EAAG,OAAO,UAAA,CAAW,EAAA,EAAI,MAAM,IAAI,CAAA;AAExC,EAAA,OAAO,IAAI,OAAA,CAA+B,CAACJ,QAAAA,EAAS,MAAA,KAAW;AAC7D,IAAA,MAAM,EAAA,GAAK,SAAA,EAAA;AAEX,IAAA,MAAM,KAAA,GAAQ,WAAW,MAAM;AAC7B,MAAA,OAAA,CAAQ,OAAO,EAAE,CAAA;AACjB,MAAA,MAAM,MAAM,IAAI,iBAAA;AAAA,QACd,CAAA,MAAA,EAAS,EAAE,CAAA,cAAA,EAAiB,IAAA,CAAK,SAAS,CAAA,mBAAA;AAAA,OAC5C;AAGA,MAAA,eAAA,CAAgB,GAAG,CAAA;AACnB,MAAA,MAAA,CAAO,GAAG,CAAA;AAAA,IACZ,CAAA,EAAG,KAAK,SAAS,CAAA;AACjB,IAAA,KAAA,CAAM,KAAA,IAAQ;AAEd,IAAA,MAAM,UAAU,MAAM;AAGpB,MAAA,CAAA,CAAE,WAAA,CAAY,EAAE,IAAA,EAAM,QAAA,EAAU,IAA2B,CAAA;AAAA,IAC7D,CAAA;AACA,IAAA,IAAI,IAAA,CAAK,MAAA,EAAQ,OAAA,EAAS,OAAA,EAAQ;AAAA,SAC7B,IAAA,CAAK,QAAQ,gBAAA,CAAiB,OAAA,EAAS,SAAS,EAAE,IAAA,EAAM,MAAM,CAAA;AAEnE,IAAA,MAAM,UAAU,MAAM;AACpB,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA,IAAA,CAAK,MAAA,EAAQ,mBAAA,CAAoB,OAAA,EAAS,OAAO,CAAA;AAAA,IACnD,CAAA;AACA,IAAA,OAAA,CAAQ,IAAI,EAAA,EAAI;AAAA,MACd,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,QAAA,OAAA,EAAQ;AACR,QAAAA,SAAQ,CAA0B,CAAA;AAAA,MACpC,CAAA;AAAA,MACA,MAAA,EAAQ,CAAC,CAAA,KAAM;AACb,QAAA,OAAA,EAAQ;AACR,QAAA,MAAA,CAAO,CAAC,CAAA;AAAA,MACV,CAAA;AAAA,MACA,YAAY,IAAA,CAAK;AAAA,KAClB,CAAA;AAED,IAAA,CAAA,CAAE,YAAY,EAAE,IAAA,EAAM,WAAW,EAAA,EAAI,EAAA,EAAI,MAA6B,CAAA;AAAA,EACxE,CAAC,CAAA;AACH;AAGA,eAAe,UAAA,CACb,EAAA,EACA,IAAA,EACA,IAAA,EACgC;AAChC,EAAA,MAAM,EAAA,GAAK,IAAI,eAAA,EAAgB;AAC/B,EAAA,MAAM,YAAA,GAAe,MAAM,EAAA,CAAG,KAAA,CAAM,IAAA,CAAK,QAAQ,MAAA,IAAU,IAAI,KAAA,CAAM,oBAAoB,CAAC,CAAA;AAC1F,EAAA,IAAI,IAAA,CAAK,MAAA,EAAQ,OAAA,EAAS,YAAA,EAAa;AAAA,OAClC,IAAA,CAAK,QAAQ,gBAAA,CAAiB,OAAA,EAAS,cAAc,EAAE,IAAA,EAAM,MAAM,CAAA;AAExE,EAAA,IAAI,KAAA;AACJ,EAAA,MAAM,QAAA,GAAW,IAAI,OAAA,CAAe,CAAC,GAAG,MAAA,KAAW;AACjD,IAAA,KAAA,GAAQ,WAAW,MAAM;AACvB,MAAA,MAAM,MAAM,IAAI,iBAAA;AAAA,QACd,CAAA,MAAA,EAAS,EAAE,CAAA,cAAA,EAAiB,IAAA,CAAK,SAAS,CAAA,mBAAA;AAAA,OAC5C;AACA,MAAA,EAAA,CAAG,MAAM,GAAG,CAAA;AACZ,MAAA,MAAA,CAAO,GAAG,CAAA;AAAA,IACZ,CAAA,EAAG,KAAK,SAAS,CAAA;AACjB,IAAA,KAAA,CAAM,KAAA,IAAQ;AAAA,EAChB,CAAC,CAAA;AAED,EAAA,MAAM,MAAM,YAA4C;AACtD,IAAA,QAAQ,EAAA;AAAI,MACV,KAAK,OAAA;AACH,QAAA,OAAQ,MAAM,aAAa,IAAA,EAAqB;AAAA,UAC9C,QAAQ,EAAA,CAAG,MAAA;AAAA,UACX,YAAY,IAAA,CAAK;AAAA,SAClB,CAAA;AAAA,MACH,KAAK,QAAA;AACH,QAAA,OAAO,cAAc,IAAoB,CAAA;AAAA,MAC3C,KAAK,OAAA;AACH,QAAA,OAAO,aAAa,IAAmB,CAAA;AAAA,MACzC;AACE,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kBAAA,EAAqB,MAAA,CAAO,EAAE,CAAC,CAAA,CAAE,CAAA;AAAA;AACrD,EACF,CAAA;AAEA,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,OAAA,CAAQ,IAAA,CAAK,CAAC,GAAA,EAAI,EAAG,QAAQ,CAAC,CAAA;AAAA,EAC7C,CAAA,SAAE;AACA,IAAA,IAAI,KAAA,eAAoB,KAAK,CAAA;AAC7B,IAAA,IAAA,CAAK,MAAA,EAAQ,mBAAA,CAAoB,OAAA,EAAS,YAAY,CAAA;AAAA,EACxD;AACF;AAMA,IAAI,KAAA,GAA0B,QAAQ,OAAA,EAAQ;AAE9C,SAAS,UAAa,GAAA,EAAmC;AACvD,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,IAAA,CAAK,GAAA,EAAK,GAAG,CAAA;AAE/B,EAAA,KAAA,GAAQ,GAAA,CAAI,IAAA;AAAA,IACV,MAAM,MAAA;AAAA,IACN,MAAM;AAAA,GACR;AACA,EAAA,OAAO,GAAA;AACT;AAGA,SAAS,gBAAA,GAAqC;AAC5C,EAAA,MAAM,CAAA,GAAI,oBAAoB,QAAA,EAAS;AACvC,EAAA,OAAO,IAAI,gBAAA;AAAA,IACT,qEACG,CAAA,CAAE,WAAA,GAAc,WAAW,CAAA,CAAE,WAAW,MAAM,EAAA,CAAA,IAC9C,CAAA,CAAE,sBAAsB,CAAA,GACrB,CAAA,gBAAA,EAAmB,KAAK,IAAA,CAAK,CAAA,CAAE,sBAAsB,GAAI,CAAC,MAC1D,EAAA,CAAA,GACJ;AAAA,GACJ;AACF;AAGA,IAAM,mBAAA,GAAsB,GAAA;AAC5B,IAAM,cAAA,uBAAqB,GAAA,EAA2C;AAEtE,SAAS,WAAA,CAAY,UAA8B,IAAA,EAAsB;AACvE,EAAA,OAAO,CAAA,EAAG,QAAA,IAAY,EAAE,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AAClC;AAKO,SAAS,gBAAgB,QAAA,EAA2B;AACzD,EAAA,OAAO,UAAA,CAAW,QAAQ,CAAA,KAAM,IAAA;AAClC;AAWA,SAAS,wBAAwB,GAAA,EAAuB;AACtD,EAAA,IAAI,eAAe,KAAA,EAAO;AACxB,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,WAAA,EAAY;AACpC,IAAA,OAAO,IAAI,QAAA,CAAS,mBAAmB,CAAA,IAAK,GAAA,CAAI,SAAS,mBAAmB,CAAA;AAAA,EAC9E;AACA,EAAA,OAAO,KAAA;AACT;AAEA,eAAsB,gBAAgB,IAAA,EAQb;AAGvB,EAAA,IAAI,CAAC,mBAAA,CAAoB,YAAA,EAAa,QAAS,gBAAA,EAAiB;AAEhE,EAAA,SAAA,GAAY,IAAA;AACZ,EAAA,SAAA,EAAU;AAEV,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAM,SAAA,CAAU,MAAM;AAInC,MAAA,YAAA,GAAe,CAAA;AACf,MAAA,WAAA,GAAc,CAAA;AACd,MAAA,UAAA,GAAa,IAAA;AACb,MAAA,OAAO,WAAA;AAAA,QACL,OAAA;AAAA,QACA;AAAA,UACE,aAAa,IAAA,CAAK,WAAA;AAAA,UAClB,UAAU,IAAA,CAAK,QAAA;AAAA,UACf,OAAO,IAAA,CAAK,KAAA;AAAA,UACZ,OAAO,IAAA,CAAK;AAAA,SACd;AAAA,QACA;AAAA,UACE,SAAA,EAAW,KAAK,SAAA,IAAa,6BAAA;AAAA,UAC7B,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb,UAAA,EAAY;AAAA;AACd,OACF;AAAA,IACF,CAAC,CAAA;AACD,IAAA,MAAA,GAAS,IAAA;AACT,IAAA,mBAAA,CAAoB,aAAA,EAAc;AAClC,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,GAAA,EAAK;AACZ,IAAA,UAAA,GAAa,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAK5D,IAAA,IAAI,uBAAA,CAAwB,GAAG,CAAA,IAAK,CAAC,KAAK,KAAA,EAAO;AAC/C,MAAA,UAAA,GAAa,IAAA;AACb,MAAA,MAAM,aAAA,GAAgB,MAAM,eAAA,CAAgB;AAAA,QAC1C,GAAG,IAAA;AAAA,QACH,KAAA,EAAO;AAAA,OACR,CAAA;AACD,MAAA,MAAA,GAAS,IAAA;AACT,MAAA,OAAO,aAAA;AAAA,IACT;AAEA,IAAA,MAAA,GAAS,IAAA;AAGT,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,OAAA,EAAS,mBAAA,CAAoB,cAAc,GAAG,CAAA;AAChE,IAAA,MAAM,GAAA;AAAA,EACR,CAAA,SAAE;AACA,IAAA,SAAA,GAAY,KAAA;AACZ,IAAA,SAAA,EAAU;AAAA,EACZ;AACF;AAQO,SAAS,eAAe,IAAA,EAQtB;AACP,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,eAAe,CAAA;AAC/C,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACxB,EAAA,MAAM,EAAA,GAAK,KAAK,UAAA,IAAc,mBAAA;AAE9B,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAM,GAAA,GAAM,WAAA,CAAY,IAAA,CAAK,QAAA,EAAU,IAAI,CAAA;AAC3C,IAAA,MAAM,QAAA,GAAW,cAAA,CAAe,GAAA,CAAI,GAAG,CAAA;AACvC,IAAA,IAAI,QAAA,eAAuB,QAAQ,CAAA;AACnC,IAAA,MAAM,KAAA,GAAQ,WAAW,MAAM;AAC7B,MAAA,cAAA,CAAe,OAAO,GAAG,CAAA;AAGzB,MAAA,IAAI,CAAC,mBAAA,CAAoB,YAAA,EAAa,EAAG;AACvC,QAAA,IAAA,CAAK,OAAA,GAAU,kBAAkB,CAAA;AACjC,QAAA;AAAA,MACF;AACA,MAAA,KAAK,SAAA;AAAA,QAAU,MACb,WAAA;AAAA,UACE,OAAA;AAAA,UACA,EAAE,WAAA,EAAa,IAAA,CAAK,WAAA,EAAa,KAAA,EAAO,CAAC,IAAI,CAAA,EAAG,QAAA,EAAU,IAAA,CAAK,QAAA,EAAS;AAAA,UACxE,EAAE,SAAA,EAAW,IAAA,CAAK,SAAA,IAAa,8BAAA;AAA+B;AAChE,OACF,CAAE,IAAA;AAAA,QACA,MAAM,oBAAoB,aAAA,EAAc;AAAA,QACxC,CAAC,GAAA,KAAQ;AACP,UAAA,mBAAA,CAAoB,cAAc,GAAG,CAAA;AACrC,UAAA,IAAA,CAAK,UAAU,GAAG,CAAA;AAAA,QACpB;AAAA,OACF;AAAA,IACF,GAAG,EAAE,CAAA;AAEL,IAAA,KAAA,CAAM,KAAA,IAAQ;AACd,IAAA,cAAA,CAAe,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,EAC/B;AACF;AAGO,SAAS,sBAAA,GAA+B;AAC7C,EAAA,KAAA,MAAW,CAAA,IAAK,cAAA,CAAe,MAAA,EAAO,eAAgB,CAAC,CAAA;AACvD,EAAA,cAAA,CAAe,KAAA,EAAM;AACvB;AASA,eAAsB,mBAAA,CACpB,IAAA,EACA,IAAA,GAA6E,EAAC,EACrD;AACzB,EAAA,OAAO,WAAA,CAAY,UAAU,IAAA,EAAM;AAAA,IACjC,SAAA,EAAW,KAAK,SAAA,IAAa,wBAAA;AAAA,IAC7B,QAAQ,IAAA,CAAK;AAAA,GACd,CAAA;AACH;AAGA,eAAsB,kBAAA,CACpB,IAAA,EACA,IAAA,GAA6E,EAAC,EACzD;AACrB,EAAA,OAAO,WAAA,CAAY,SAAS,IAAA,EAAM;AAAA,IAChC,SAAA,EAAW,KAAK,SAAA,IAAa,wBAAA;AAAA,IAC7B,QAAQ,IAAA,CAAK;AAAA,GACd,CAAA;AACH;;;ACniBO,IAAM,iBAAA,GAAmE;AAAA,EAC9E,IAAA,EAAM,gBAAA;AAAA,EACN,QAAA,EAAU,SAAA;AAAA,EACV,WAAA,EACE,oMAAA;AAAA,EAEF,SAAA,EACE,kbAAA;AAAA,EAKF,UAAA,EAAY,SAAA;AAAA,EACZ,QAAA,EAAU,IAAA;AAAA,EACV,YAAA,EAAc,CAAC,0BAA0B,CAAA;AAAA,EACzC,SAAA,EAAW,IAAA;AAAA,EACX,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,QAAA;AAAA,IACN,UAAA,EAAY;AAAA,MACV,KAAA,EAAO;AAAA,QACL,IAAA,EAAM,SAAA;AAAA,QACN,WAAA,EAAa;AAAA,OACf;AAAA,MACA,KAAA,EAAO;AAAA,QACL,IAAA,EAAM,OAAA;AAAA,QACN,KAAA,EAAO,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QACxB,WAAA,EAAa;AAAA;AACf;AACF,GACF;AAAA,EACA,MAAM,OAAA,CAAQ,KAAA,EAAO,GAAA,EAAK,QAAA,EAAU;AAGlC,IAAA,IAAI,YAAW,EAAG;AAChB,MAAA,OAAO;AAAA,QACL,YAAA,EAAc,CAAA;AAAA,QACd,cAAA,EAAgB,CAAA;AAAA,QAChB,WAAW,EAAC;AAAA,QACZ,UAAA,EAAY,CAAA;AAAA,QACZ,QAAQ,EAAC;AAAA,QACT,IAAA,EAAM;AAAA,OACR;AAAA,IACF;AAIA,IAAA,MAAM,OAAA,GAAU,oBAAoB,QAAA,EAAS;AAC7C,IAAA,IAAI,OAAA,CAAQ,KAAA,KAAU,MAAA,IAAU,OAAA,CAAQ,sBAAsB,CAAA,EAAG;AAC/D,MAAA,OAAO;AAAA,QACL,YAAA,EAAc,CAAA;AAAA,QACd,cAAA,EAAgB,CAAA;AAAA,QAChB,WAAW,EAAC;AAAA,QACZ,UAAA,EAAY,CAAA;AAAA,QACZ,QAAQ,EAAC;AAAA,QACT,IAAA,EACE,CAAA,2DAAA,EAA8D,OAAA,CAAQ,WAAA,IAAe,SAAS,CAAA,0BAAA,EACpE,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,mBAAA,GAAsB,GAAI,CAAC,CAAA,2DAAA;AAAA,OAC3E;AAAA,IACF;AAMA,IAAA,OAAO,MAAM,eAAA,CAAgB;AAAA,MAC3B,aAAa,GAAA,CAAI,WAAA;AAAA,MACjB,KAAA,EAAO,MAAM,KAAA,IAAS,KAAA;AAAA,MACtB,OAAO,KAAA,CAAM,KAAA;AAAA,MACb,QAAA,EAAU,yBAAyB,GAAG,CAAA;AAAA,MACtC,QAAQ,QAAA,EAAU;AAAA,KACnB,CAAA;AAAA,EACH;AACF;;;ACxDO,IAAM,kBAAA,GAAsE;AAAA,EACjF,IAAA,EAAM,iBAAA;AAAA,EACN,QAAA,EAAU,SAAA;AAAA,EACV,WAAA,EACE,6MAAA;AAAA,EAEF,SAAA,EACE,8WAAA;AAAA,EAKF,UAAA,EAAY,MAAA;AAAA,EACZ,QAAA,EAAU,KAAA;AAAA,EACV,YAAA,EAAc,CAAC,SAAS,CAAA;AAAA,EACxB,SAAA,EAAW,GAAA;AAAA,EACX,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,QAAA;AAAA,IACN,UAAA,EAAY;AAAA,MACV,KAAA,EAAO;AAAA,QACL,IAAA,EAAM,QAAA;AAAA,QACN,WAAA,EAAa;AAAA,OACf;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,IAAA,EAAM,QAAA;AAAA,QACN,WAAA,EACE;AAAA,OACJ;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,IAAA,EAAM,QAAA;AAAA,QACN,WAAA,EAAa;AAAA,OACf;AAAA,MACA,OAAA,EAAS;AAAA,QACP,IAAA,EAAM,SAAA;AAAA,QACN,WAAA,EACE;AAAA,OACJ;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,IAAA,EAAM,QAAA;AAAA,QACN,WAAA,EAAa;AAAA,OACf;AAAA,MACA,KAAA,EAAO;AAAA,QACL,IAAA,EAAM,SAAA;AAAA,QACN,WAAA,EAAa,iDAAA;AAAA,QACb,OAAA,EAAS,CAAA;AAAA,QACT,OAAA,EAAS;AAAA;AACX,KACF;AAAA,IACA,QAAA,EAAU,CAAC,OAAO;AAAA,GACpB;AAAA,EACA,MAAM,OAAA,CAAQ,KAAA,EAAO,GAAA,EAAK,QAAA,EAAU;AAGlC,IAAA,MAAM,QAAQ,aAAA,EAAc;AAC5B,IAAA,IAAI,CAAC,MAAM,KAAA,EAAO;AAChB,MAAA,OAAO;AAAA,QACL,SAAS,EAAC;AAAA,QACV,KAAA,EAAO,CAAA;AAAA,QACP,OAAO,KAAA,CAAM,KAAA;AAAA,QACb,WAAA,EAAa,MAAM,QAAA,GACf,CAAA,sBAAA,EAAyB,MAAM,WAAW,CAAA,CAAA,EAAI,KAAA,CAAM,UAAU,CAAA,iCAAA,CAAA,GAC9D;AAAA,OACN;AAAA,IACF;AACA,IAAA,IAAI,MAAM,QAAA,EAAU;AAClB,MAAA,OAAO;AAAA,QACL,SAAS,EAAC;AAAA,QACV,KAAA,EAAO,CAAA;AAAA,QACP,OAAO,KAAA,CAAM,KAAA;AAAA,QACb,aAAa,CAAA,2BAAA,EAA8B,KAAA,CAAM,WAAW,CAAA,CAAA,EAAI,MAAM,UAAU,CAAA,mCAAA;AAAA,OAClF;AAAA,IACF;AACA,IAAA,IAAI,MAAM,SAAA,EAAW;AACnB,MAAA,MAAM,UAAU,KAAA,CAAM,OAAA;AACtB,MAAA,MAAM,SAAA,GACJ,OAAA,CAAQ,KAAA,KAAU,MAAA,GACd,CAAA,2CAAA,EAA8C,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,mBAAA,GAAsB,GAAI,CAAC,CAAA,oDAAA,CAAA,GAC3F,wBAAA;AACN,MAAA,OAAO;AAAA,QACL,SAAS,EAAC;AAAA,QACV,KAAA,EAAO,CAAA;AAAA,QACP,OAAO,KAAA,CAAM,KAAA;AAAA,QACb,WAAA,EAAa,CAAA,oBAAA,EAAuB,KAAA,CAAM,SAAS,KAAK,SAAS,CAAA;AAAA,OACnE;AAAA,IACF;AAEA,IAAA,MAAM,QAAQ,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,KAAA,IAAS,IAAI,GAAG,CAAA;AAC7C,IAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,MAAM,mBAAA;AAAA,MAC/B;AAAA,QACE,aAAa,GAAA,CAAI,WAAA;AAAA,QACjB,QAAA,EAAU,yBAAyB,GAAG,CAAA;AAAA,QACtC,OAAO,KAAA,CAAM,KAAA;AAAA,QACb,MAAM,KAAA,CAAM,IAAA;AAAA,QACZ,MAAM,KAAA,CAAM,IAAA;AAAA,QACZ,MAAM,KAAA,CAAM,IAAA;AAAA,QACZ,SAAS,KAAA,CAAM,OAAA;AAAA,QACf;AAAA,OACF;AAAA,MACA,EAAE,MAAA,EAAQ,QAAA,EAAU,MAAA;AAAO,KAC7B;AACA,IAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,MAAM,KAAA,EAAM;AAAA,EAC9C;AACF;;;AC/GO,IAAM,iBAAA,GAAsE;AAAA,EACjF,IAAA,EAAM,gBAAA;AAAA,EACN,QAAA,EAAU,SAAA;AAAA,EACV,WAAA,EACE,uKAAA;AAAA,EACF,SAAA,EACE,6OAAA;AAAA,EAKF,UAAA,EAAY,MAAA;AAAA,EACZ,QAAA,EAAU,KAAA;AAAA,EACV,YAAA,EAAc,CAAC,SAAS,CAAA;AAAA,EACxB,SAAA,EAAW,GAAA;AAAA,EACX,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,QAAA;AAAA,IACN,YAAY,EAAC;AAAA,IACb,oBAAA,EAAsB;AAAA,GACxB;AAAA,EACA,MAAM,OAAA,CAAQ,MAAA,EAAQ,GAAA,EAAK,QAAA,EAAU;AACnC,IAAA,MAAM,WAAW,aAAA,EAAc;AAC/B,IAAA,IAAI,CAAC,SAAS,KAAA,EAAO;AACnB,MAAA,OAAO;AAAA,QACL,YAAA,EAAc,CAAA;AAAA,QACd,UAAA,EAAY,CAAA;AAAA,QACZ,QAAQ,EAAC;AAAA,QACT,QAAQ,EAAC;AAAA,QACT,WAAA,EAAa,IAAA;AAAA,QACb,SAAA,EAAW,CAAA;AAAA,QACX,SAAA,EAAW,EAAA;AAAA,QACX,OAAA,EAAS,cAAA;AAAA,QACT,WAAA,EAAa,SAAS,QAAA,GAClB,CAAA,sBAAA,EAAyB,SAAS,WAAW,CAAA,CAAA,EAAI,QAAA,CAAS,UAAU,CAAA,QAAA,CAAA,GACpE;AAAA,OACN;AAAA,IACF;AAIA,IAAA,MAAM,QAAQ,MAAM,kBAAA;AAAA,MAClB,EAAE,WAAA,EAAa,GAAA,CAAI,aAAa,QAAA,EAAU,wBAAA,CAAyB,GAAG,CAAA,EAAE;AAAA,MACxE,EAAE,MAAA,EAAQ,QAAA,EAAU,MAAA;AAAO,KAC7B;AAEA,IAAA,IAAI,SAAS,QAAA,EAAU;AACrB,MAAA,OAAO;AAAA,QACL,GAAG,KAAA;AAAA,QACH,aAAa,CAAA,2BAAA,EAA8B,QAAA,CAAS,WAAW,CAAA,CAAA,EAAI,SAAS,UAAU,CAAA,iCAAA;AAAA,OACxF;AAAA,IACF;AAEA,IAAA,MAAM,UAAU,QAAA,CAAS,OAAA;AACzB,IAAA,OAAO;AAAA,MACL,cAAc,KAAA,CAAM,YAAA;AAAA,MACpB,YAAY,KAAA,CAAM,UAAA;AAAA,MAClB,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,aAAa,KAAA,CAAM,WAAA;AAAA,MACnB,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,GAAI,OAAA,CAAQ,KAAA,KAAU,MAAA,GAClB;AAAA,QACE,WAAA,EACE,CAAA,kDAAA,EAAqD,OAAA,CAAQ,WAAA,IAAe,SAAS,CAAA,iBAAA,EACpE,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,mBAAA,GAAsB,GAAI,CAAC,CAAA,qEAAA;AAAA,UAElE;AAAC,KACP;AAAA,EACF;AACF","file":"index.js","sourcesContent":["/**\n * Circuit breaker for the codebase indexer.\n *\n * The indexer can wedge: a hung filesystem, a parser pathology, or another\n * wstack process holding the SQLite write lock (several surfaces — TUI, WebUI,\n * parallel terminals — share one per-project `index.db`). Without protection,\n * every queued reindex piles up behind the process-wide mutex, `isIndexing()`\n * stays true forever, and anything that awaits an index run (the startup scan,\n * `/codebase-reindex`) locks its terminal.\n *\n * Standard three-state breaker:\n *\n * closed — normal operation; consecutive failures are counted.\n * open — after `failureThreshold` consecutive failures, every request\n * is rejected fast ({@link CircuitOpenError}) for `cooldownMs`.\n * half-open — after the cooldown exactly one probe run is admitted;\n * success closes the circuit, failure re-opens it.\n *\n * Watchdog timeouts ({@link IndexTimeoutError}) count as failures;\n * caller-initiated aborts (session teardown) do not — the background indexer\n * makes that distinction before recording.\n *\n * Lock conflicts ({@link LockError}) do NOT count as failures — they are expected\n * transient conditions when multiple wstack surfaces share the same `index.db`.\n * The index store retries automatically; a LockError only reaches the circuit\n * breaker when all retries are exhausted.\n */\n\nexport type CircuitState = 'closed' | 'open' | 'half-open';\n\nexport interface CircuitSnapshot {\n state: CircuitState;\n consecutiveFailures: number;\n lastFailure: string | null;\n /** ms until an open circuit admits a half-open probe (0 unless open). */\n cooldownRemainingMs: number;\n}\n\n/** Thrown when a run is rejected because the circuit is open. */\nexport class CircuitOpenError extends Error {\n override readonly name = 'CircuitOpenError';\n}\n\n/** Thrown by the background indexer's watchdog when a run exceeds its timeout. */\nexport class IndexTimeoutError extends Error {\n override readonly name = 'IndexTimeoutError';\n}\n\n/**\n * Thrown when an SQLite operation fails with a lock conflict (SQLITE_BUSY or\n * SQLITE_LOCKED) even after all retry attempts are exhausted.\n *\n * The circuit breaker does **not** count `LockError` as a failure — a lock\n * conflict means another writer is active, not that this indexer is broken.\n * The caller should treat it as a transient failure and retry later.\n */\nexport class LockError extends Error {\n override readonly name = 'LockError';\n}\n\nexport interface CircuitBreakerOptions {\n /** Consecutive failures before the circuit opens. Default: 3. */\n failureThreshold?: number | undefined;\n /** How long an open circuit rejects requests before allowing a probe. Default: 60s. */\n cooldownMs?: number | undefined;\n /** Injectable clock for tests. Default: Date.now. */\n now?: (() => number) | undefined;\n}\n\nexport class IndexCircuitBreaker {\n private readonly failureThreshold: number;\n private readonly cooldownMs: number;\n private readonly now: () => number;\n\n private state: CircuitState = 'closed';\n private consecutiveFailures = 0;\n private openedAt = 0;\n private lastFailure: string | null = null;\n private probeInFlight = false;\n\n constructor(opts: CircuitBreakerOptions = {}) {\n this.failureThreshold = opts.failureThreshold ?? 3;\n this.cooldownMs = opts.cooldownMs ?? 60_000;\n this.now = opts.now ?? Date.now;\n }\n\n /**\n * True when a run may proceed. An open circuit transitions to half-open once\n * the cooldown has elapsed, admitting exactly one probe; further requests\n * are rejected until that probe settles via recordSuccess/recordFailure.\n */\n allowRequest(): boolean {\n if (this.state === 'closed') return true;\n if (this.state === 'open') {\n if (this.now() - this.openedAt < this.cooldownMs) return false;\n this.state = 'half-open';\n this.probeInFlight = true;\n return true;\n }\n // half-open: admit only one probe at a time.\n if (this.probeInFlight) return false;\n this.probeInFlight = true;\n return true;\n }\n\n recordSuccess(): void {\n this.state = 'closed';\n this.consecutiveFailures = 0;\n this.lastFailure = null;\n this.probeInFlight = false;\n }\n\n recordFailure(err: unknown): void {\n // LockError means \"another process is writing — try again later\", not a\n // broken indexer. Do not count it against the failure threshold.\n if (err instanceof LockError) {\n this.lastFailure = `[transient/lock] ${err.message}`;\n this.probeInFlight = false;\n return;\n }\n this.lastFailure = err instanceof Error ? err.message : String(err);\n this.probeInFlight = false;\n this.consecutiveFailures++;\n if (this.state === 'half-open' || this.consecutiveFailures >= this.failureThreshold) {\n this.state = 'open';\n this.openedAt = this.now();\n }\n }\n\n /** Force-close the circuit (manual recovery: `/codebase-reindex`). */\n reset(): void {\n this.state = 'closed';\n this.consecutiveFailures = 0;\n this.lastFailure = null;\n this.probeInFlight = false;\n this.openedAt = 0;\n }\n\n snapshot(): CircuitSnapshot {\n return {\n state: this.state,\n consecutiveFailures: this.consecutiveFailures,\n lastFailure: this.lastFailure,\n cooldownRemainingMs:\n this.state === 'open' ? Math.max(0, this.cooldownMs - (this.now() - this.openedAt)) : 0,\n };\n }\n}\n\n/**\n * Process-wide breaker shared by every index path (startup scan, per-edit\n * incremental, external watcher, the `codebase-index` tool). Module-level for\n * the same reason the mutex is: there is one `index.db` per project and one\n * indexing pipeline per process.\n */\nexport const indexCircuitBreaker = new IndexCircuitBreaker();\n\n/** Reset the shared breaker — used by `/codebase-reindex` and tests. */\nexport function resetIndexCircuitBreaker(): void {\n indexCircuitBreaker.reset();\n}\n","// ─── Symbol kind taxonomy ───────────────────────────────────────────────────────\n\n/** Language a symbol belongs to. */\nexport type SymbolLang = 'ts' | 'js' | 'tsx' | 'jsx' | 'go' | 'py' | 'rs' | 'json' | 'yaml';\n\n/** What kind of symbol this is. */\nexport type SymbolKind =\n | 'class'\n | 'interface'\n | 'enum'\n | 'type'\n | 'function'\n | 'method'\n | 'var'\n | 'const'\n | 'let'\n | 'property'\n | 'parameter'\n | 'namespace'\n | 'object' // JSON root object\n | 'literal' // scalar value in JSON/YAML\n | 'schema' // JSON Schema $ref/$schema entry\n // Rust-specific\n | 'struct'\n | 'trait'\n | 'impl'\n | 'static'\n | 'mod';\n\n/** A single indexed code symbol. */\nexport interface Symbol {\n id: number;\n lang: SymbolLang;\n kind: SymbolKind;\n name: string;\n file: string; // absolute path\n line: number; // 1-based\n col: number; // 0-based\n signature: string; // e.g. \"function foo(a: string): Promise<void>\"\n docComment: string; // JSDoc / docstring first line\n scope: string; // e.g. \"MyClass.method\" or module-level \"\"\n text: string; // concatenated searchable text: name + signature + docComment\n}\n\n/** Extracted symbols and cross-references for one file. */\nexport interface FileSymbols {\n file: string;\n lang: SymbolLang;\n symbols: Symbol[];\n refs?: Ref[] | undefined; // cross-references extracted from this file (optional for back-compat)\n mtimeMs: number;\n}\n\n/** Source file metadata tracked for incremental indexing. */\nexport interface FileMeta {\n file: string;\n lang: SymbolLang;\n mtimeMs: number;\n symbolCount: number;\n lastIndexed: number; // unix ms\n}\n\n/** Statistics about the index. */\nexport interface IndexStats {\n totalSymbols: number;\n totalFiles: number;\n byLang: Record<SymbolLang, number>;\n byKind: Record<SymbolKind, number>;\n indexPath: string;\n lastIndexed: number | null;\n sizeBytes: number;\n version: number;\n}\n\n/** Result of a search query. */\nexport interface SearchResult {\n id: number;\n name: string;\n kind: SymbolKind;\n lang: SymbolLang;\n file: string;\n line: number;\n col: number;\n signature: string;\n docComment: string;\n score: number;\n snippet: string;\n /** Original LSP SymbolKind number if the result was filtered by an LSP kind. */\n lspKind?: number | undefined;\n}\n\n/** Result of a full reindex. */\nexport interface IndexResult {\n filesIndexed: number;\n symbolsIndexed: number;\n langStats: Record<SymbolLang, number>;\n durationMs: number;\n errors: string[];\n}\n\n// ─── Cross-reference types ───────────────────────────────────────────────────\n\n/** What kind of reference this is. */\nexport type CallType = 'call' | 'type_ref' | 'inherit' | 'implement' | 'import';\n\n/** A cross-reference between two symbols (who references whom). */\nexport interface Ref {\n id?: number | undefined;\n fromId: number; // symbol that makes the reference\n toName: string; // resolved name of the referenced symbol\n toId?: number | undefined; // resolved target symbol id (filled after index resolution)\n callType: CallType; // kind of reference\n line: number; // source line where the reference occurs\n}\n\n// ─── Schema version ───────────────────────────────────────────────────────────\n\n// v2: added the symbols_fts FTS5 table (ranked search moved into SQLite).\n// A version mismatch on open drops & rebuilds the index (it is derived data).\nexport const SCHEMA_VERSION = 2;\n","/**\n * LSP SymbolKind mapping utilities.\n *\n * LSP SymbolKind numbers are defined by vscode-languageserver-protocol.\n * This module maps between LSP kind numbers and the internal SymbolKind taxonomy.\n */\n\nimport type { SymbolKind } from './schema.js';\n\n/**\n * LSP SymbolKind values (1–26) as defined by vscode-languageserver-protocol.\n */\nexport enum LSPSymbolKind {\n File = 1,\n Module = 2,\n Namespace = 3,\n Package = 4,\n Class = 5,\n Method = 6,\n Property = 7,\n Field = 8,\n Constructor = 9,\n Enum = 10,\n Interface = 11,\n Function = 12,\n Variable = 13,\n Constant = 14,\n String = 15,\n Number = 16,\n Boolean = 17,\n Array = 18,\n Object = 19,\n Key = 20,\n Null = 21,\n EnumMember = 22,\n Struct = 23,\n Event = 24,\n Operator = 25,\n TypeParameter = 26,\n}\n\n/**\n * Maps an LSP kind number to the corresponding internal SymbolKind.\n * Returns null if the LSP kind has no equivalent in the internal taxonomy.\n */\nexport function lspKindToInternalKind(k: number): SymbolKind | null {\n switch (k) {\n case LSPSymbolKind.Class: return 'class';\n case LSPSymbolKind.Method: return 'method';\n case LSPSymbolKind.Property:\n case LSPSymbolKind.Field: return 'property';\n case LSPSymbolKind.Constructor: return 'class';\n case LSPSymbolKind.Enum: return 'enum';\n case LSPSymbolKind.Interface: return 'interface';\n case LSPSymbolKind.Function: return 'function';\n case LSPSymbolKind.Variable: return 'var';\n case LSPSymbolKind.Constant: return 'const';\n case LSPSymbolKind.EnumMember: return 'enum';\n case LSPSymbolKind.TypeParameter:return 'type';\n case LSPSymbolKind.Namespace: return 'namespace';\n default: return null;\n }\n}\n\n/**\n * Maps an internal SymbolKind to the corresponding LSP kind number.\n * Returns null if the internal kind has no equivalent LSP kind.\n */\nexport function internalKindToLspKind(k: SymbolKind): number | null {\n switch (k) {\n case 'class': return LSPSymbolKind.Class;\n case 'method': return LSPSymbolKind.Method;\n case 'property': return LSPSymbolKind.Property;\n case 'function': return LSPSymbolKind.Function;\n case 'var': return LSPSymbolKind.Variable;\n case 'const': return LSPSymbolKind.Constant;\n case 'let': return LSPSymbolKind.Variable;\n case 'enum': return LSPSymbolKind.Enum;\n case 'interface': return LSPSymbolKind.Interface;\n case 'namespace': return LSPSymbolKind.Namespace;\n case 'type': return LSPSymbolKind.TypeParameter;\n // parameter and other internal-only kinds have no LSP equivalent\n default: return null;\n }\n}\n\n/**\n * Returns true if `k` is a valid LSP SymbolKind number (1–26).\n */\nexport function isLspKind(k: number): boolean {\n return Number.isInteger(k) && k >= 1 && k <= 26;\n}\n","/**\n * BM25 ranking implementation — no external dependencies.\n *\n * Algorithm: Okapi BM25 with standard parameters (k1=1.5, b=0.75).\n */\n\nconst K1 = 1.5;\nconst B = 0.75;\n\ninterface Bm25Doc {\n id: number;\n tokens: string[];\n raw: string;\n len: number;\n}\n\n/** Tokenise a string into lowercase word tokens. */\nexport function tokenise(text: string): string[] {\n // Preserve all Unicode letters + digits + $ + '. Split on everything else.\n const sanitised = text.replace(/[^\\p{L}\\p{N}$'_]/gu, ' ').replace(/_/g, ' ');\n return sanitised.toLowerCase().split(' ').filter(Boolean);\n}\n\nexport interface IndexableDoc {\n id: number;\n text: string;\n}\n\n/**\n * Split a camelCase/SnakeCase identifier into its constituent words.\n * e.g. \"complexOperation\" → \"complex Operation\"\n * \"foo_bar_baz\" → \"foo bar baz\"\n * This allows a query for \"complex\" to match \"complexOperation\"\n * via the shared \"complex\" token.\n */\nfunction splitName(name: string): string {\n return name\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .replace(/[_-]+/g, ' ')\n .trim();\n}\n\n/**\n * Build indexable text for BM25 from a symbol's fields.\n * The name is split into camelCase/SnakeCase words so that queries\n * like \"complex\" match \"complexOperation\". The verbatim name is\n * also included for exact-match queries.\n */\nexport function buildIndexableText(name: string, signature: string, docComment: string): string {\n return [splitName(name), name, signature, docComment].filter(Boolean).join(' ');\n}\n\nexport function buildBm25Index(docs: IndexableDoc[]): Bm25Index {\n const documents: Bm25Doc[] = docs.map((d) => {\n const tokens = tokenise(d.text);\n return { id: d.id, tokens, raw: d.text, len: tokens.length };\n });\n\n const df: Record<string, number> = {};\n for (const doc of documents) {\n const seen = new Set<string>();\n for (const t of doc.tokens) {\n if (!seen.has(t)) {\n df[t] = (df[t] ?? 0) + 1;\n seen.add(t);\n }\n }\n }\n\n const N = documents.length;\n const totalLen = documents.reduce((sum, d) => sum + d.len, 0);\n const avgLen = N === 0 ? 0 : totalLen / N;\n\n return new Bm25Index(documents, df, N, avgLen);\n}\n\nexport class Bm25Index {\n private readonly safeAvgLen: number;\n\n constructor(\n private documents: Bm25Doc[],\n private df: Record<string, number>,\n private N: number,\n avgLen: number,\n ) {\n this.safeAvgLen = avgLen === 0 ? 1 : avgLen;\n }\n\n score(query: string, filter?: (id: number) => boolean): Array<{ id: number; score: number }> {\n const qTokens = tokenise(query);\n if (qTokens.length === 0) return [];\n\n const results: Array<{ id: number; score: number }> = [];\n\n for (const doc of this.documents) {\n if (filter && !filter(doc.id)) continue;\n\n let docScore = 0;\n for (const qTerm of qTokens) {\n let tf = 0;\n for (const t of doc.tokens) {\n if (t === qTerm) tf++;\n }\n if (tf === 0) continue;\n\n const dfVal = this.df[qTerm] ?? 0;\n if (dfVal === 0) continue;\n\n const idf = Math.log((this.N - dfVal + 0.5) / (dfVal + 0.5) + 1);\n const lenRatio = B * (doc.len / this.safeAvgLen);\n const tfComponent = (tf * (K1 + 1)) / (tf + K1 * (1 - B + lenRatio));\n\n docScore += idf * tfComponent;\n }\n\n if (docScore > 0) results.push({ id: doc.id, score: docScore });\n }\n\n return results;\n }\n\n getDoc(id: number): Bm25Doc | undefined {\n return this.documents.find((d) => d.id === id);\n }\n\n extractSnippet(docId: number, queryTokens: string[], radius = 40): string {\n const doc = this.getDoc(docId);\n if (!doc) return '';\n\n for (const tok of queryTokens) {\n const idx = doc.raw.toLowerCase().indexOf(tok);\n if (idx !== -1) {\n const start = Math.max(0, idx - radius);\n const end = Math.min(doc.raw.length, idx + tok.length + radius);\n const excerpt = doc.raw.slice(start, end);\n const ellipsis = '\\u2026';\n return (start > 0 ? ellipsis : '') + excerpt + (end < doc.raw.length ? ellipsis : '');\n }\n }\n return doc.raw.slice(0, radius * 2) + (doc.raw.length > radius * 2 ? '\\u2026' : '');\n }\n}\n","import { expectDefined } from '@wrongstack/core';\nimport { LockError } from './circuit-breaker.js';\n/**\n * SQLite storage layer for the codebase index.\n *\n * Uses `node:sqlite` (synchronous API — DatabaseSync class).\n * Database file: ~/.wrongstack/projects/<hash>/codebase-index/index.db — kept\n * out of the repo so it never clutters the working tree or needs gitignoring.\n *\n * ### Multi-process safety\n *\n * Several wstack surfaces (TUI, WebUI, parallel terminals) share this per-project\n * database. WAL mode allows concurrent reads alongside a writer, and\n * `busy_timeout` bounds how long a write operation waits for the lock. When\n * the timeout expires and SQLite returns SQLITE_BUSY, the store retries with\n * exponential backoff (up to 3 attempts) before letting the error propagate.\n * If all retries are exhausted, a {@link LockError} is thrown — the circuit\n * breaker treats this as a transient condition and does NOT count it as a failure.\n */\n\nimport { createRequire } from 'node:module';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { DatabaseSync } from 'node:sqlite';\nimport { resolveWstackPaths } from '@wrongstack/core';\nimport type { FileMeta, IndexStats, Ref, SearchResult, Symbol as IndexSymbol, SymbolKind, SymbolLang } from './schema.js';\nimport { SCHEMA_VERSION } from './schema.js';\nimport { lspKindToInternalKind } from './lsp-kind.js';\nimport { buildBm25Index, buildIndexableText, tokenise } from './bm25.js';\nconst DB_FILE = 'index.db';\n\n/**\n * Resolve the per-project index directory. By default it lives under the\n * global project dir (`~/.wrongstack/projects/<hash>/codebase-index`),\n * matching every other piece of per-project state. Callers may pass an\n * explicit `override` (used by tests and any wiring that already resolved the\n * path) to avoid touching the real home directory.\n */\nexport function resolveIndexDir(projectRoot: string, override?: string): string {\n return override ?? resolveWstackPaths({ projectRoot }).projectCodebaseIndex;\n}\n\n/**\n * Optional index-directory override carried on the run context's `meta` bag.\n * Production leaves it unset (the index resolves to the global per-project\n * dir); tests and bespoke wiring set `meta.codebaseIndexDir` to redirect it.\n */\nexport function codebaseIndexDirOverride(ctx: { meta?: Record<string, unknown> }): string | undefined {\n const v = ctx.meta?.['codebaseIndexDir'];\n return typeof v === 'string' ? v : undefined;\n}\n\nlet warningSilenced = false;\n/**\n * Swallow the one-time `ExperimentalWarning: SQLite ...` Node prints the first\n * time `node:sqlite` loads. Patched only once, and only filters that specific\n * warning — every other warning passes through untouched.\n */\nfunction silenceSqliteExperimentalWarning(): void {\n if (warningSilenced) return;\n warningSilenced = true;\n const original = process.emitWarning.bind(process);\n process.emitWarning = ((warning: unknown, ...rest: unknown[]): void => {\n const msg = typeof warning === 'string' ? warning : ((warning as Error)?.message ?? '');\n const name = typeof warning === 'string' ? String(rest[0] ?? '') : ((warning as Error)?.name ?? '');\n if (/sqlite/i.test(msg) && /experimental/i.test(`${name} ${msg}`)) return;\n (original as (w: unknown, ...r: unknown[]) => void)(warning, ...rest);\n }) as typeof process.emitWarning;\n}\n\nlet DatabaseSyncCtor: typeof DatabaseSync | undefined;\n/**\n * Load `node:sqlite`'s `DatabaseSync` lazily. Keeping this off the module's\n * top-level import means the codebase-index tools can be registered at CLI boot\n * without eagerly loading SQLite — so a runtime that lacks `node:sqlite` (it is\n * experimental, available since Node 22.5) only fails if the index is actually\n * used, with a clear message instead of a crash on import.\n */\nfunction loadDatabaseSync(): typeof DatabaseSync {\n if (DatabaseSyncCtor) return DatabaseSyncCtor;\n silenceSqliteExperimentalWarning();\n try {\n const req = createRequire(import.meta.url);\n DatabaseSyncCtor = (req('node:sqlite') as typeof import('node:sqlite')).DatabaseSync;\n } catch (err) {\n throw new Error(\n \"The codebase index needs Node's built-in SQLite (node:sqlite), available since Node 22.5. \" +\n `This runtime doesn't provide it: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n return DatabaseSyncCtor;\n}\n\n// ─── SQLite lock-error retry ───────────────────────────────────────────────────\n\n/** Maximum retry attempts for a lock-conflict error. */\nconst MAX_LOCK_RETRIES = 3;\n/**\n * Base delay (ms) before the first retry after a lock error. Each subsequent\n * retry doubles this (exponential backoff). Combined with the 5-second\n * busy_timeout pragma, this means: 5s (pragma) + 50ms + 100ms + 200ms per\n * attempt — enough to wait out most cross-process writer conflicts.\n */\nconst LOCK_RETRY_BASE_DELAY_MS = 50;\n/** Cap on the per-retry delay so we never sleep for more than this. */\nconst LOCK_RETRY_MAX_DELAY_MS = 500;\n\n/**\n * Returns true when `err` represents a SQLite lock conflict (SQLITE_BUSY or\n * SQLITE_LOCKED). These are transient — another process holds the write lock\n * and will release it shortly. Retry instead of failing.\n *\n * node:sqlite surfaces these as plain Error instances with `code` set to\n * 'SQLITE_BUSY' or 'SQLITE_LOCKED', or with a message that contains the\n * error name. Defensive: anything we can't classify as safe is NOT treated\n * as a lock error so real failures are not retried indefinitely.\n */\nfunction isLockError(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n const e = err as { code?: unknown; sqliteCode?: unknown };\n const code = e.code ?? e.sqliteCode;\n if (typeof code === 'string' && /SQLITE_(BUSY|LOCKED)/.test(code)) return true;\n if (typeof code === 'number' && (code === 5 || code === 6)) return true; // SQLITE_BUSY=5, SQLITE_LOCKED=6\n // node:sqlite sometimes surfaces the numeric code as a string in the message\n if (/SQLITE_(BUSY|LOCKED)/.test(err.message)) return true;\n return false;\n}\n\n/**\n * Synchronous sleep via Atomics.wait on a zero-length SharedArrayBuffer.\n * This is the only way to synchronously block in a Worker thread without\n * busy-waiting. The main thread (where DatabaseSync is never used) is\n * unaffected.\n *\n * The call is wrapped in try/catch because Atomics.wait throws in browsers\n * and other environments where SharedArrayBuffer is not available.\n */\nfunction sleepSync(ms: number): void {\n try {\n const sab = new SharedArrayBuffer(4);\n const view = new Int32Array(sab);\n Atomics.wait(view, 0, 0, ms);\n } catch {\n // Atomics.wait not available (browser, unknown runtime) — fall through.\n // The retry still happens but without sleeping, which is acceptable because\n // busy_timeout already handled the bulk of the wait.\n }\n}\n\nexport class IndexStore {\n private db: DatabaseSync;\n /** Absolute path to this project's index directory. */\n private readonly indexDir: string;\n /**\n * True when the SQLite build provides FTS5 (Node's bundled SQLite does).\n * When false, ranked search falls back to the LIKE + in-process BM25 path.\n */\n private ftsAvailable = false;\n\n /**\n * Execute a SQLite write operation with automatic retry on lock conflicts.\n *\n * When another wstack process is holding the write lock the statement first\n * waits up to `busy_timeout` ms, then throws SQLITE_BUSY. This wrapper catches\n * that error and retries (up to MAX_LOCK_RETRIES) with exponential backoff,\n * giving the competing writer time to finish and release the lock.\n *\n * @param fn The write operation to execute. Can return a value which is\n * returned to the caller on success.\n * @throws {@link LockError} when all retries are exhausted on a lock conflict\n * (non-lock errors always propagate on the first attempt).\n */\n runWithRetry<T>(fn: () => T): T {\n let lastError: unknown;\n for (let attempt = 0; attempt <= MAX_LOCK_RETRIES; attempt++) {\n try {\n return fn();\n } catch (err) {\n lastError = err;\n if (!isLockError(err)) throw err;\n if (attempt === MAX_LOCK_RETRIES) {\n // All retries exhausted — wrap in LockError so the circuit breaker\n // knows this is a transient lock conflict, not a real failure.\n const msg = lastError instanceof Error ? lastError.message : String(lastError);\n throw new LockError(`SQLite lock conflict after ${MAX_LOCK_RETRIES} retries: ${msg}`);\n }\n // Exponential backoff: 50ms → 100ms → 200ms, capped at 500ms.\n const delay = Math.min(\n LOCK_RETRY_BASE_DELAY_MS * Math.pow(2, attempt),\n LOCK_RETRY_MAX_DELAY_MS,\n );\n sleepSync(delay);\n }\n }\n throw lastError; // unreachable — satisfies TypeScript\n }\n\n constructor(projectRoot: string, opts: { indexDir?: string | undefined } = {}) {\n this.indexDir = resolveIndexDir(projectRoot, opts.indexDir);\n fs.mkdirSync(this.indexDir, { recursive: true });\n const Database = loadDatabaseSync();\n this.db = new Database(path.join(this.indexDir, DB_FILE));\n // Multi-process safety: several wstack surfaces (TUI, WebUI, parallel\n // terminals) share this per-project db. WAL lets readers coexist with the\n // writer, and busy_timeout gives SQLite a head start waiting for the lock.\n // When the timeout expires the statement throws SQLITE_BUSY; the\n // runWithRetry() wrapper then retries with exponential backoff so most\n // lock-conflict errors are resolved without a circuit-breaker failure.\n try {\n this.db.exec('PRAGMA journal_mode = WAL');\n this.db.exec('PRAGMA busy_timeout = 5000');\n } catch {\n /* pragmas are best-effort — an old SQLite build without WAL still works */\n }\n this.initSchema();\n }\n\n private initSchema(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS metadata (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n `);\n\n // Schema migration: the index is derived, rebuildable data — on any\n // version mismatch we drop everything and let the next index run repopulate\n // from source, instead of maintaining per-version migration scripts.\n const storedRows = this.db.prepare('SELECT value FROM metadata WHERE key = ?').all('version') as { value: string }[];\n const storedVersion = storedRows.length ? Number(storedRows[0]?.value) : null;\n if (storedVersion !== null && storedVersion !== SCHEMA_VERSION) {\n this.db.exec(`\n DROP TABLE IF EXISTS symbols;\n DROP TABLE IF EXISTS files;\n DROP TABLE IF EXISTS refs;\n `);\n this.db.exec('DROP TABLE IF EXISTS symbols_fts');\n this.db.prepare('UPDATE metadata SET value = ? WHERE key = ?').run(String(SCHEMA_VERSION), 'version');\n } else if (storedVersion === null) {\n this.db.prepare('INSERT INTO metadata(key, value) VALUES (?, ?)').run('version', String(SCHEMA_VERSION));\n }\n\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS files (\n file TEXT PRIMARY KEY,\n lang TEXT NOT NULL,\n mtime_ms INTEGER NOT NULL,\n symbol_count INTEGER NOT NULL DEFAULT 0,\n last_indexed INTEGER NOT NULL\n );\n CREATE TABLE IF NOT EXISTS symbols (\n id INTEGER PRIMARY KEY,\n lang TEXT NOT NULL,\n kind TEXT NOT NULL,\n name TEXT NOT NULL,\n file TEXT NOT NULL,\n line INTEGER NOT NULL,\n col INTEGER NOT NULL,\n signature TEXT NOT NULL DEFAULT '',\n doc_comment TEXT NOT NULL DEFAULT '',\n scope TEXT NOT NULL DEFAULT '',\n text TEXT NOT NULL DEFAULT '',\n file_fk TEXT NOT NULL\n );\n `);\n\n this.db.exec('CREATE INDEX IF NOT EXISTS idx_s_name ON symbols(name)');\n this.db.exec('CREATE INDEX IF NOT EXISTS idx_s_kind ON symbols(kind)');\n this.db.exec('CREATE INDEX IF NOT EXISTS idx_s_lang ON symbols(lang)');\n this.db.exec('CREATE INDEX IF NOT EXISTS idx_s_file ON symbols(file)');\n\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS refs (\n id INTEGER PRIMARY KEY,\n from_id INTEGER NOT NULL,\n to_name TEXT NOT NULL,\n to_id INTEGER,\n call_type TEXT NOT NULL,\n line INTEGER NOT NULL\n );\n `);\n\n this.db.exec('CREATE INDEX IF NOT EXISTS idx_r_from ON refs(from_id)');\n this.db.exec('CREATE INDEX IF NOT EXISTS idx_r_to_id ON refs(to_id)');\n this.db.exec('CREATE INDEX IF NOT EXISTS idx_r_to_name ON refs(to_name)');\n this.db.exec('CREATE INDEX IF NOT EXISTS idx_r_call_type ON refs(call_type)');\n\n // FTS5 full-text index over the camelCase-split symbol text; rowid is the\n // symbol id. Replaces the old `LIKE '%token%'` full-table scan + per-query\n // in-process BM25 build: MATCH uses the inverted index and bm25() ranks\n // natively. Kept in sync explicitly in insertSymbols/delete*/clearAll.\n try {\n this.db.exec(\"CREATE VIRTUAL TABLE IF NOT EXISTS symbols_fts USING fts5(text, tokenize = 'unicode61')\");\n this.ftsAvailable = true;\n } catch {\n // SQLite built without FTS5 — searchRanked falls back to LIKE + BM25.\n this.ftsAvailable = false;\n }\n }\n\n // ─── Symbol CRUD ─────────────────────────────────────────────────────────────\n\n insertSymbols(symbols: IndexSymbol[], nextId: number): number {\n return this.runWithRetry(() => {\n const stmt = this.db.prepare(\n `INSERT INTO symbols(id, lang, kind, name, file, line, col, signature, doc_comment, scope, text, file_fk)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n );\n const ftsStmt = this.ftsAvailable\n ? this.db.prepare('INSERT INTO symbols_fts(rowid, text) VALUES (?, ?)')\n : null;\n\n let id = nextId;\n for (const s of symbols) {\n stmt.run(\n id,\n s.lang,\n s.kind,\n s.name,\n s.file,\n s.line,\n s.col,\n s.signature,\n s.docComment,\n s.scope,\n s.text,\n s.file,\n );\n // The FTS row indexes the camelCase-split text so a query for \"complex\"\n // matches \"complexOperation\" — same recall the JS BM25 path provided.\n ftsStmt?.run(id, buildIndexableText(s.name, s.signature, s.docComment));\n id++;\n }\n return id;\n });\n }\n\n deleteSymbolsForFile(file: string): void {\n this.runWithRetry(() => {\n if (this.ftsAvailable) {\n this.db\n .prepare('DELETE FROM symbols_fts WHERE rowid IN (SELECT id FROM symbols WHERE file_fk = ?)')\n .run(file);\n }\n this.db.prepare('DELETE FROM symbols WHERE file_fk = ?').run(file);\n });\n }\n\n /**\n * Remove every trace of a file (refs, symbols, FTS rows, file meta). Used\n * when a source file disappears between index runs — previously this only\n * dropped the `files` row, leaving its symbols orphaned but still searchable.\n */\n deleteFile(file: string): void {\n this.runWithRetry(() => {\n this.deleteRefsForFile(file);\n this.deleteSymbolsForFile(file);\n this.db.prepare('DELETE FROM files WHERE file = ?').run(file);\n });\n }\n\n // ─── File metadata ──────────────────────────────────────────────────────────\n\n upsertFile(meta: FileMeta): void {\n this.runWithRetry(() => {\n this.db.prepare(\n `INSERT INTO files(file, lang, mtime_ms, symbol_count, last_indexed)\n VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(file) DO UPDATE SET\n lang = excluded.lang,\n mtime_ms = excluded.mtime_ms,\n symbol_count = excluded.symbol_count,\n last_indexed = excluded.last_indexed`,\n ).run(meta.file, meta.lang, meta.mtimeMs, meta.symbolCount, meta.lastIndexed);\n });\n }\n\n getFileMeta(file: string): FileMeta | null {\n const rows = this.db.prepare(\n 'SELECT file, lang, mtime_ms, symbol_count, last_indexed FROM files WHERE file = ?',\n ).all(file) as { file: string; lang: string; mtime_ms: number; symbol_count: number; last_indexed: number }[];\n if (!rows.length) return null;\n const r = expectDefined(rows[0]);\n return { file: r.file, lang: r.lang as SymbolLang, mtimeMs: r.mtime_ms, symbolCount: r.symbol_count, lastIndexed: r.last_indexed };\n }\n\n getAllFileMetas(): FileMeta[] {\n return (this.db.prepare(\n 'SELECT file, lang, mtime_ms, symbol_count, last_indexed FROM files',\n ).all() as { file: string; lang: string; mtime_ms: number; symbol_count: number; last_indexed: number }[]).map(\n (r) => ({ file: r.file, lang: r.lang as SymbolLang, mtimeMs: r.mtime_ms, symbolCount: r.symbol_count, lastIndexed: r.last_indexed }),\n );\n }\n\n // ─── Search ──────────────────────────────────────────────────────────────────\n\n search(\n query: string,\n filter?: { kind?: SymbolKind | undefined; lang?: SymbolLang | undefined; file?: string | undefined; lspKind?: number | undefined },\n ): SearchResult[] {\n const conditions: string[] = [];\n const values: unknown[] = [];\n\n let effectiveKind: SymbolKind | undefined = filter?.kind;\n if (filter?.lspKind !== undefined) {\n const mapped = lspKindToInternalKind(filter.lspKind);\n if (mapped !== null) {\n effectiveKind = mapped;\n } else {\n // LSP kind was explicitly provided but has no internal mapping → no results\n return [];\n }\n }\n\n if (effectiveKind) {\n conditions.push('kind = ?');\n values.push(effectiveKind);\n }\n if (filter?.lang) {\n conditions.push('lang = ?');\n values.push(filter.lang);\n }\n if (filter?.file) {\n conditions.push('file LIKE ?');\n values.push(`%${filter.file}%`);\n }\n if (query.trim()) {\n const tokens = query.toLowerCase().split(/\\s+/).filter(Boolean);\n const tokenConds = tokens.map(() => 'text LIKE ?');\n conditions.push(`(${tokenConds.join(' OR ')})`);\n for (const t of tokens) values.push(`%${t}%`);\n }\n\n const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';\n const sql = `SELECT id, lang, kind, name, file, line, col, signature, doc_comment, text FROM symbols ${where}`;\n\n const stmt = this.db.prepare(sql);\n const rows = stmt.all(...values as (string | number)[]) as {\n id: number; lang: string; kind: string; name: string; file: string;\n line: number; col: number; signature: string; doc_comment: string; text: string;\n }[];\n\n return rows.map((r) => ({\n id: r.id,\n lang: r.lang as SymbolLang,\n kind: r.kind as SymbolKind,\n name: r.name,\n file: r.file,\n line: r.line,\n col: r.col,\n signature: r.signature,\n docComment: r.doc_comment,\n score: 0,\n snippet: '',\n lspKind: filter?.lspKind,\n }));\n }\n\n /**\n * Ranked search — the one-stop query the codebase-search tool and plug-lsp\n * use. With FTS5 this is a single indexed `MATCH` ranked by SQLite's native\n * `bm25()` with a built-in `snippet()`; without FTS5 it falls back to the\n * legacy LIKE scan + in-process BM25 (identical semantics, slower).\n *\n * Tokens are matched as prefixes (`\"tok\"*`), mirroring the old\n * `LIKE '%tok%'` recall for the common symbol-search shapes (\"user\" finds\n * \"users\", camelCase-split text makes \"complex\" find \"complexOperation\").\n */\n searchRanked(\n query: string,\n filter:\n | { kind?: SymbolKind | undefined; lang?: SymbolLang | undefined; file?: string | undefined; lspKind?: number | undefined }\n | undefined,\n limit: number,\n ): { results: SearchResult[]; total: number } {\n const tokens = tokenise(query);\n // No usable tokens → plain filtered listing (matches old `search('')`).\n if (tokens.length === 0 || !this.ftsAvailable) {\n return this.searchRankedFallback(query, filter, limit);\n }\n\n let effectiveKind: SymbolKind | undefined = filter?.kind;\n if (filter?.lspKind !== undefined) {\n const mapped = lspKindToInternalKind(filter.lspKind);\n if (mapped === null) return { results: [], total: 0 };\n effectiveKind = mapped;\n }\n\n // Each token is quoted (neutralises FTS5 query syntax) and prefix-starred.\n const match = tokens.map((t) => `\"${t.replaceAll('\"', '')}\"*`).join(' OR ');\n\n const conditions: string[] = ['symbols_fts MATCH ?'];\n const values: (string | number)[] = [match];\n if (effectiveKind) {\n conditions.push('s.kind = ?');\n values.push(effectiveKind);\n }\n if (filter?.lang) {\n conditions.push('s.lang = ?');\n values.push(filter.lang);\n }\n if (filter?.file) {\n conditions.push('s.file LIKE ?');\n values.push(`%${filter.file}%`);\n }\n const where = conditions.join(' AND ');\n\n const countRows = this.db\n .prepare(`SELECT COUNT(*) AS n FROM symbols_fts JOIN symbols s ON s.id = symbols_fts.rowid WHERE ${where}`)\n .all(...values) as { n: number }[];\n const total = countRows[0] ? Number(countRows[0].n) : 0;\n if (total === 0) return { results: [], total: 0 };\n\n const rows = this.db\n .prepare(\n `SELECT s.id, s.lang, s.kind, s.name, s.file, s.line, s.col, s.signature, s.doc_comment,\n -bm25(symbols_fts) AS score,\n snippet(symbols_fts, 0, '', '', '…', 12) AS snippet\n FROM symbols_fts JOIN symbols s ON s.id = symbols_fts.rowid\n WHERE ${where}\n ORDER BY bm25(symbols_fts)\n LIMIT ?`,\n )\n .all(...values, limit) as {\n id: number; lang: string; kind: string; name: string; file: string;\n line: number; col: number; signature: string; doc_comment: string;\n score: number; snippet: string;\n }[];\n\n return {\n results: rows.map((r) => ({\n id: r.id,\n lang: r.lang as SymbolLang,\n kind: r.kind as SymbolKind,\n name: r.name,\n file: r.file,\n line: r.line,\n col: r.col,\n signature: r.signature,\n docComment: r.doc_comment,\n // bm25() is negative-is-better; negate so callers keep \"higher is\n // better\" and clamp so a match never reports a zero score.\n score: Math.max(0.0001, r.score),\n snippet: r.snippet,\n lspKind: filter?.lspKind,\n })),\n total,\n };\n }\n\n /** Legacy ranked path: LIKE candidates + in-process BM25 + JS snippets. */\n private searchRankedFallback(\n query: string,\n filter:\n | { kind?: SymbolKind | undefined; lang?: SymbolLang | undefined; file?: string | undefined; lspKind?: number | undefined }\n | undefined,\n limit: number,\n ): { results: SearchResult[]; total: number } {\n const candidates = this.search(query, filter);\n if (candidates.length === 0) return { results: [], total: 0 };\n\n if (!query.trim()) {\n return { results: candidates.slice(0, limit), total: candidates.length };\n }\n\n const bm25 = buildBm25Index(\n candidates.map((c) => ({ id: c.id, text: buildIndexableText(c.name, c.signature, c.docComment) })),\n );\n const scored = bm25.score(query, (id) => candidates.some((c) => c.id === id));\n scored.sort((a, b) => b.score - a.score);\n const qTokens = tokenise(query);\n\n const results = scored.slice(0, limit).map(({ id, score }) => {\n const c = expectDefined(candidates.find((cand) => cand.id === id));\n return { ...c, score, snippet: bm25.extractSnippet(id, qTokens) };\n });\n return { results, total: candidates.length };\n }\n\n getAllIndexable(): Array<{ id: number; text: string }> {\n return (this.db.prepare('SELECT id, text FROM symbols').all() as { id: number; text: string }[]).map(\n ({ id, text }) => ({ id, text }),\n );\n }\n\n /**\n * Largest symbol id currently in the table (0 when empty). New ids must be\n * allocated from this, NOT from `COUNT(*)`: incremental reindexes delete a\n * changed file's rows, so the row count drops below the max id and a\n * count-based id would collide with a surviving row (UNIQUE constraint on\n * `symbols.id`). Ids may have gaps — that is fine.\n */\n getMaxSymbolId(): number {\n const rows = this.db.prepare('SELECT MAX(id) AS m FROM symbols').all() as { m: number | null }[];\n return rows[0]?.m ?? 0;\n }\n\n // ─── Stats ───────────────────────────────────────────────────────────────────\n\n getStats(): IndexStats {\n const sizeBytes = this.sizeBytes();\n\n const lastRows = this.db.prepare(\n \"SELECT value FROM metadata WHERE key = 'last_indexed'\",\n ).all() as { value: string }[];\n const lastIndexed = lastRows.length ? Number(lastRows[0]?.value) : null;\n\n const totalRows = this.db.prepare('SELECT COUNT(*) FROM symbols').all() as { 'COUNT(*)': number }[];\n const totalSymbols = totalRows[0] ? Number(totalRows[0]['COUNT(*)']) : 0;\n\n const fileRows = this.db.prepare('SELECT COUNT(*) FROM files').all() as { 'COUNT(*)': number }[];\n const totalFiles = fileRows[0] ? Number(fileRows[0]['COUNT(*)']) : 0;\n\n const langRows = this.db.prepare(\n 'SELECT lang, COUNT(*) FROM symbols GROUP BY lang',\n ).all() as { lang: string; 'COUNT(*)': number }[];\n const byLang = {} as Record<SymbolLang, number>;\n for (const row of langRows) byLang[row.lang as SymbolLang] = Number(row['COUNT(*)']);\n\n const kindRows = this.db.prepare(\n 'SELECT kind, COUNT(*) FROM symbols GROUP BY kind',\n ).all() as { kind: string; 'COUNT(*)': number }[];\n const byKind = {} as Record<SymbolKind, number>;\n for (const row of kindRows) byKind[row.kind as SymbolKind] = Number(row['COUNT(*)']);\n\n return {\n totalSymbols,\n totalFiles,\n byLang,\n byKind,\n indexPath: this.indexDir,\n lastIndexed,\n sizeBytes,\n version: SCHEMA_VERSION,\n };\n }\n\n setLastIndexed(ts: number): void {\n this.runWithRetry(() => {\n this.db.prepare(\n \"INSERT OR REPLACE INTO metadata(key, value) VALUES('last_indexed', ?)\",\n ).run(String(ts));\n });\n }\n\n clearAll(): void {\n this.runWithRetry(() => {\n this.db.exec('DELETE FROM symbols');\n this.db.exec('DELETE FROM files');\n this.db.exec('DELETE FROM refs');\n if (this.ftsAvailable) this.db.exec('DELETE FROM symbols_fts');\n });\n }\n\n // ─── Ref CRUD ────────────────────────────────────────────────────────────────\n\n /**\n * Insert cross-references for a given source symbol id.\n * Replaces any existing refs from the same source (idempotent on re-index).\n */\n insertRefs(fromId: number, refs: Ref[]): void {\n this.runWithRetry(() => {\n // Delete old refs from this symbol (handles re-index)\n this.db.prepare('DELETE FROM refs WHERE from_id = ?').run(fromId);\n if (refs.length === 0) return;\n\n const stmt = this.db.prepare(\n `INSERT INTO refs(from_id, to_name, to_id, call_type, line)\n VALUES (?, ?, ?, ?, ?)`,\n );\n for (const ref of refs) {\n stmt.run(fromId, ref.toName, ref.toId ?? null, ref.callType, ref.line);\n }\n });\n }\n\n /**\n * Delete all refs whose source symbols are in a given file.\n * Used when re-indexing a file to clear stale refs.\n */\n deleteRefsForFile(file: string): void {\n this.runWithRetry(() => {\n const ids = this.db.prepare(\n 'SELECT id FROM symbols WHERE file = ?',\n ).all(file) as { id: number }[];\n if (!ids.length) return;\n const placeholders = ids.map(() => '?').join(',');\n this.db.prepare(`DELETE FROM refs WHERE from_id IN (${placeholders})`).run(...ids.map((r) => r.id));\n });\n }\n\n /**\n * Resolve `to_name` → `to_id` for all refs that have a name but no id.\n * Call this after all symbols have been inserted to fill in cross-references.\n */\n resolveRefs(): number {\n return this.runWithRetry(() => {\n const unresolved = this.db.prepare(\n 'SELECT id, to_name FROM refs WHERE to_id IS NULL AND to_name IS NOT NULL',\n ).all() as { id: number; to_name: string }[];\n\n let resolved = 0;\n for (const row of unresolved) {\n const target = this.db.prepare('SELECT id FROM symbols WHERE name = ? LIMIT 1').all(row.to_name) as { id: number }[];\n const first = target[0];\n if (first) {\n this.db.prepare('UPDATE refs SET to_id = ? WHERE id = ?').run(first.id, row.id);\n resolved++;\n }\n }\n return resolved;\n });\n }\n\n /**\n * Find all references TO a given symbol (who calls / uses this symbol?).\n */\n findRefsTo(symbolId: number): Ref[] {\n return (this.db.prepare(\n 'SELECT id, from_id, to_name, to_id, call_type, line FROM refs WHERE to_id = ? OR to_name = (SELECT name FROM symbols WHERE id = ?)',\n ).all(symbolId, symbolId) as { id: number; from_id: number; to_name: string; to_id: number | null; call_type: string; line: number }[]).map((r) => ({\n id: r.id, fromId: r.from_id, toName: r.to_name, toId: r.to_id ?? undefined, callType: r.call_type as Ref['callType'], line: r.line,\n }));\n }\n\n /**\n * Find all references FROM a given symbol (what does this symbol call/use?).\n */\n findRefsFrom(symbolId: number): Ref[] {\n return (this.db.prepare(\n 'SELECT id, from_id, to_name, to_id, call_type, line FROM refs WHERE from_id = ?',\n ).all(symbolId) as { id: number; from_id: number; to_name: string; to_id: number | null; call_type: string; line: number }[]).map((r) => ({\n id: r.id, fromId: r.from_id, toName: r.to_name, toId: r.to_id ?? undefined, callType: r.call_type as Ref['callType'], line: r.line,\n }));\n }\n\n private sizeBytes(): number {\n const dbPath = path.join(this.indexDir, DB_FILE);\n try {\n return fs.statSync(dbPath).size;\n } catch {\n return 0;\n }\n }\n\n close(): void {\n try { this.db.close(); } catch { /* already closed */ }\n }\n}\n","/**\n * TypeScript/JavaScript symbol extraction using the TypeScript Compiler API.\n *\n * We traverse the AST and collect:\n * - classes, interfaces, enums, type aliases → class|interface|enum|type\n * - functions and methods → function|method\n * - const/let/var declarations → const|let|var\n * - property/accessor declarations → property\n *\n * The `id` field on each Symbol is always 0 — the caller is responsible for\n * assigning unique ids during insertion.\n */\n\nimport * as ts from 'typescript';\nimport type { FileSymbols, Ref, Symbol as IndexSymbol, SymbolKind, SymbolLang } from './schema.js';\n\n// Map TypeScript SyntaxKind → our SymbolKind taxonomy\nconst KIND_MAP: Partial<Record<ts.SyntaxKind, SymbolKind>> = {\n [ts.SyntaxKind.ClassDeclaration]: 'class',\n [ts.SyntaxKind.InterfaceDeclaration]: 'interface',\n [ts.SyntaxKind.EnumDeclaration]: 'enum',\n [ts.SyntaxKind.TypeAliasDeclaration]: 'type',\n [ts.SyntaxKind.FunctionDeclaration]: 'function',\n [ts.SyntaxKind.MethodDeclaration]: 'method',\n [ts.SyntaxKind.GetAccessor]: 'property',\n [ts.SyntaxKind.SetAccessor]: 'property',\n [ts.SyntaxKind.PropertyDeclaration]: 'property',\n [ts.SyntaxKind.Parameter]: 'parameter',\n [ts.SyntaxKind.NamespaceExportDeclaration]: 'namespace',\n};\n\nfunction kindOf(node: ts.Node): SymbolKind | null {\n // VariableDeclaration needs special handling — its parent tells us whether\n // it's `const`, `let`, or `var`.\n if (ts.isVariableDeclaration(node)) {\n const parent = node.parent;\n if (ts.isVariableDeclarationList(parent)) {\n const flags = parent.flags;\n if (flags & ts.NodeFlags.Let) return 'let';\n if (flags & ts.NodeFlags.Const) return 'const';\n return 'var';\n }\n }\n\n // Namespace (module) declaration\n if (ts.isModuleDeclaration(node)) return 'namespace';\n\n return KIND_MAP[node.kind] ?? null;\n}\n\nfunction extToLang(ext: string): SymbolLang | null {\n switch (ext) {\n case '.ts': return 'ts';\n case '.tsx': return 'tsx';\n case '.js': return 'js';\n case '.jsx': return 'jsx';\n case '.go': return 'go';\n case '.py': return 'py';\n case '.rs': return 'rs';\n case '.json': return 'json';\n case '.yaml': return 'yaml';\n case '.yml': return 'yaml';\n default: return null;\n }\n}\n\nfunction getSignature(node: ts.Declaration, sourceFile: ts.SourceFile): string {\n const printer = ts.createPrinter({});\n const raw = printer.printNode(ts.EmitHint.Unspecified, node, sourceFile);\n return raw.replace(/\\s+/g, ' ').slice(0, 500);\n}\n\n/**\n * Extract the first line of a JSDoc comment preceding a node.\n * Uses `ts.getLeadingCommentRanges` which is the modern replacement for\n * the removed `ts.getJSDocComments`.\n */\nfunction getJsDoc(node: ts.Node, sourceFile: ts.SourceFile): string {\n const fullText = sourceFile.getFullText();\n const nodePos = node.getFullWidth();\n const comments = ts.getLeadingCommentRanges(fullText, nodePos);\n if (!comments) return '';\n\n for (const range of comments) {\n const commentText = fullText.slice(range.pos, range.end);\n // Only process JSDoc comments (/** ... */)\n const trimmed = commentText.trim();\n if (trimmed.startsWith('/**') && trimmed.endsWith('*/')) {\n // Strip the /** and */ delimiters and leading * on each line\n const inner = trimmed\n .slice(3, -2) // remove /** and */\n .replace(/^[ \\t]*\\*[ ]?/gm, '') // remove leading \" * \" or \" *\" on each line\n .trim();\n return inner.split('\\n')[0]?.trim().slice(0, 200) ?? '';\n }\n }\n return '';\n}\n\n/** Build the scope path from a node up to the root (for class-method scope). */\nfunction buildScope(node: ts.Node): string {\n const parts: string[] = [];\n let current: ts.Node | undefined = node.parent;\n while (current) {\n if (\n ts.isClassDeclaration(current) ||\n ts.isInterfaceDeclaration(current) ||\n ts.isEnumDeclaration(current) ||\n ts.isTypeAliasDeclaration(current)\n ) {\n parts.unshift(current.name?.text ?? 'Anon');\n } else if (\n ts.isMethodDeclaration(current) ||\n ts.isGetAccessor(current) ||\n ts.isSetAccessor(current) ||\n ts.isPropertyDeclaration(current) ||\n ts.isFunctionDeclaration(current)\n ) {\n if (current.name && ts.isIdentifier(current.name)) {\n parts.unshift(current.name.text);\n }\n }\n current = current.parent;\n }\n return parts.join('.');\n}\n\nexport interface ParseOptions {\n file: string;\n content: string;\n lang: SymbolLang;\n}\n\n/**\n * Parse a TypeScript/JavaScript source file and extract all code symbols.\n *\n * The returned `Symbol.id` field is always `0` — the caller is responsible\n * for assigning unique numeric ids during bulk insertion.\n *\n * Returns an empty array for files that can't be parsed or contain no symbols.\n */\nexport function parseSymbols(opts: ParseOptions): FileSymbols {\n const { file, content, lang } = opts;\n\n let sourceFile: ts.SourceFile;\n try {\n sourceFile = ts.createSourceFile(file, content, ts.ScriptTarget.Latest, true);\n } catch {\n return { file, lang, symbols: [], mtimeMs: Date.now() };\n }\n\n const symbols: IndexSymbol[] = [];\n\n function visit(node: ts.Node): void {\n const kind = kindOf(node);\n\n if (kind) {\n const nameNode = (node as { name?: ts.Identifier | undefined }).name;\n if (!nameNode || !ts.isIdentifier(nameNode)) return;\n const name = nameNode.text;\n const pos = nameNode.getStart(sourceFile);\n const { line, character } = sourceFile.getLineAndCharacterOfPosition(pos);\n const scope = buildScope(node);\n const signature = getSignature(node as ts.Declaration, sourceFile);\n const docComment = getJsDoc(node, sourceFile);\n const text = [name, signature, docComment].filter(Boolean).join(' | ');\n\n symbols.push({\n id: 0,\n lang,\n kind,\n name,\n file,\n line: line + 1,\n col: character,\n signature,\n docComment,\n scope,\n text,\n });\n }\n\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n\n // Second pass: collect cross-references (call/type/inherit refs)\n const refs = extractRefs(sourceFile);\n\n return { file, lang, symbols, refs, mtimeMs: Date.now() };\n}\n\n// ─── Reference extraction ──────────────────────────────────────────────────────\n\n/** Collect call/type/inherit references from a source file. */\nfunction extractRefs(sourceFile: ts.SourceFile): Ref[] {\n const refs: Ref[] = [];\n\n function visit(node: ts.Node): void {\n const pos = node.getStart(sourceFile);\n const { line } = sourceFile.getLineAndCharacterOfPosition(pos);\n const lineNum = line + 1;\n\n if (ts.isCallExpression(node)) {\n const expr = node.expression;\n if (ts.isIdentifier(expr)) {\n refs.push({ fromId: 0, toName: expr.text, callType: 'call', line: lineNum });\n }\n } else if (ts.isPropertyAccessExpression(node)) {\n if (ts.isIdentifier(node.expression)) {\n refs.push({ fromId: 0, toName: node.expression.text, callType: 'call', line: lineNum });\n }\n } else if (ts.isTypeReferenceNode(node)) {\n const name = getTypeName(node.typeName);\n if (name) refs.push({ fromId: 0, toName: name, callType: 'type_ref', line: lineNum });\n } else if (ts.isHeritageClause(node)) {\n for (const t of node.types) {\n const name = getTypeName(t.expression as ts.EntityName);\n if (name) refs.push({ fromId: 0, toName: name, callType: node.token === ts.SyntaxKind.ExtendsKeyword ? 'inherit' : 'implement', line: lineNum });\n }\n } else if (ts.isImportDeclaration(node)) {\n const moduleName = getModuleName(node);\n if (moduleName) refs.push({ fromId: 0, toName: moduleName, callType: 'import', line: lineNum });\n }\n\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return deduplicateRefs(refs);\n}\n\n/** Extract the name string from a type name node (simple or qualified). */\nfunction getTypeName(name: ts.EntityName): string {\n if (ts.isIdentifier(name)) return name.text;\n if (ts.isQualifiedName(name)) return `${getTypeName(name.left)}.${name.right.text}`;\n return '';\n}\n\n/** Get the module path string from an import declaration. */\nfunction getModuleName(node: ts.ImportDeclaration): string {\n const moduleSpecifier = node.moduleSpecifier;\n if (ts.isStringLiteral(moduleSpecifier)) return moduleSpecifier.text;\n return '';\n}\n\n/** Remove duplicate refs (same toName, callType, line). fromId is always 0 at this stage. */\nfunction deduplicateRefs(refs: Ref[]): Ref[] {\n const seen = new Set<string>();\n return refs.filter((r) => {\n const key = `${r.toName}:${r.callType}:${r.line}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\n/** Detect SymbolLang from a file path extension. */\nexport function detectLang(file: string): SymbolLang | null {\n const idx = file.lastIndexOf('.');\n if (idx < 0) return null;\n return extToLang(file.slice(idx));\n}","/**\n * Go source symbol extraction using `go/parser`.\n *\n * Spawns a `go run -` child process that parses the file with go/ast and\n * emits JSON. Falls back to empty results on any error.\n *\n * Extracts: package, func, type, const, var\n */\n\nimport { execFileSync } from 'node:child_process';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { mkdirSync, writeFileSync } from 'node:fs';\nimport type { FileSymbols, Symbol as IndexSymbol, SymbolLang } from './schema.js';\n\n// ─── Public API ─────────────────────────────────────────────────────────────\n\nexport function parseSymbols(opts: { file: string; content: string; lang: SymbolLang }): FileSymbols {\n const { file, content, lang } = opts;\n\n try {\n return syncGoParse(file, content, lang);\n } catch {\n return { file, lang, symbols: [], mtimeMs: Date.now() };\n }\n}\n\nexport { detectLang } from './ts-parser.js';\n\n// ─── Inline Go parser script ────────────────────────────────────────────────\n\nconst GO_PARSE_SCRIPT = `\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"go/ast\"\n\t\"go/parser\"\n\t\"go/token\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n)\n\ntype Sym struct {\n\tName string \\`json:\"name\"\\`\n\tKind string \\`json:\"kind\"\\`\n\tLine int \\`json:\"line\"\\`\n\tCol int \\`json:\"col\"\\`\n\tSignature string \\`json:\"signature\"\\`\n\tScope string \\`json:\"scope\"\\`\n}\n\nfunc main() {\n\tsrc, err := io.ReadAll(os.Stdin)\n\tif err != nil {\n\t\tfmt.Print(\"[]\")\n\t\treturn\n\t}\n\tfset := token.NewFileSet()\n\tnode, err := parser.ParseFile(fset, \"src.go\", src, 0)\n\tif err != nil {\n\t\tfmt.Print(\"[]\")\n\t\treturn\n\t}\n\n\tvar syms []Sym\n\n\t// Package-level scope\n\tpkgScope := node.Name.Name\n\n\t// Collect all top-level declarations\n\tfor _, decl := range node.Decls {\n\t\tswitch d := decl.(type) {\n\t\tcase *ast.FuncDecl:\n\t\t\tname := d.Name.Name\n\t\t\tkind := \"function\"\n\t\t\tscope := pkgScope\n\t\t\tif d.Recv != nil && len(d.Recv.List) > 0 {\n\t\t\t\tscope = pkgScope + \".\" + recvTypeName(d.Recv.List[0].Type) + \".\" + name\n\t\t\t\tkind = \"method\"\n\t\t\t} else {\n\t\t\t\tscope = pkgScope + \".\" + name\n\t\t\t}\n\t\t\tpos := fset.Position(d.Pos())\n\t\t\tsig := formatFuncSig(d)\n\t\t\tsyms = append(syms, Sym{Name: name, Kind: kind, Line: pos.Line, Col: pos.Column, Signature: sig, Scope: scope})\n\n\t\tcase *ast.GenDecl:\n\t\t\tfor _, spec := range d.Specs {\n\t\t\t\tswitch s := spec.(type) {\n\t\t\t\tcase *ast.TypeSpec:\n\t\t\t\t\tname := s.Name.Name\n\t\t\t\t\tpos := fset.Position(s.Pos())\n\t\t\t\t\tsig := \"type \" + name\n\t\t\t\t\tif s.TypeParams != nil {\n\t\t\t\t\t\tsig += formatTypeParams(s.TypeParams)\n\t\t\t\t\t}\n\t\t\t\t\tif st, ok := s.Type.(*ast.StructType); ok {\n\t\t\t\t\t\tsig += \" = struct { \" + formatFields(st.Fields.List) + \" }\"\n\t\t\t\t\t} else if it, ok := s.Type.(*ast.InterfaceType); ok {\n\t\t\t\t\t\tsig += \" = interface { \" + formatMethods(it.Methods.List) + \" }\"\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsig += \" = \" + formatType(s.Type)\n\t\t\t\t\t}\n\t\t\t\t\tsyms = append(syms, Sym{Name: name, Kind: \"type\", Line: pos.Line, Col: pos.Column, Signature: sig, Scope: pkgScope})\n\n\t\t\t\tcase *ast.ValueSpec:\n\t\t\t\t\tfor _, n := range s.Names {\n\t\t\t\t\t\tname := n.Name\n\t\t\t\t\t\tpos := fset.Position(n.Pos())\n\t\t\t\t\t\tkind := \"var\"\n\t\t\t\t\t\tif d.Tok == token.CONST {\n\t\t\t\t\t\t\tkind = \"const\"\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsig := kind + \" \" + name\n\t\t\t\t\t\tif s.Type != nil {\n\t\t\t\t\t\t\tsig += \" \" + formatType(s.Type)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsyms = append(syms, Sym{Name: name, Kind: kind, Line: pos.Line, Col: pos.Column, Signature: sig, Scope: pkgScope})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tdata, err := json.Marshal(syms)\n\tif err != nil {\n\t\tfmt.Print(\"[]\")\n\t\treturn\n\t}\n\tfmt.Print(string(data))\n}\n\nfunc recvTypeName(t ast.Expr) string {\n\tswitch v := t.(type) {\n\tcase *ast.Ident:\n\t\treturn v.Name\n\tcase *ast.StarExpr:\n\t\treturn recvTypeName(v.X)\n\tdefault:\n\t\treturn \"?\"\n\t}\n}\n\nfunc formatFuncSig(d *ast.FuncDecl) string {\n\tscope := \"\"\n\tif d.Recv != nil && len(d.Recv.List) > 0 {\n\t\tscope = \"(\" + formatFieldList(d.Recv.List) + \") \"\n\t}\n\tscope += formatFuncType(d.Type)\n\treturn \"func \" + scope\n}\n\nfunc formatFuncType(f *ast.FuncType) string {\n\tparams := formatFieldList(f.Params.List)\n\tresults := \"\"\n\tif f.Results != nil {\n\t\tresults = \" -> \" + formatFieldList(f.Results.List)\n\t}\n\treturn params + results\n}\n\nfunc formatFieldList(fields []*ast.Field) string {\n\tif len(fields) == 0 {\n\t\treturn \"()\"\n\t}\n\tnames := make([]string, 0, len(fields))\n\tfor _, f := range fields {\n\t\tname := \"\"\n\t\tif len(f.Names) > 0 {\n\t\t\tname = f.Names[0].Name\n\t\t}\n\t\tt := formatType(f.Type)\n\t\tif name != \"\" {\n\t\t\tnames = append(names, name+\" \"+t)\n\t\t} else {\n\t\t\tnames = append(names, t)\n\t\t}\n\t}\n\treturn \"(\" + strings.Join(names, \", \") + \")\"\n}\n\nfunc formatFields(fields []*ast.Field) string {\n\tlines := make([]string, 0)\n\tfor _, f := range fields {\n\t\tname := \"\"\n\t\tif len(f.Names) > 0 {\n\t\t\tname = f.Names[0].Name\n\t\t}\n\t\tt := formatType(f.Type)\n\t\tif name != \"\" {\n\t\t\tlines = append(lines, name+\" \"+t)\n\t\t} else {\n\t\t\tlines = append(lines, t)\n\t\t}\n\t}\n\treturn strings.Join(lines, \"; \")\n}\n\nfunc formatMethods(fields []*ast.Field) string {\n\treturn formatFields(fields)\n}\n\nfunc formatTypeParams(tp *ast.FieldList) string {\n\tif tp == nil || len(tp.List) == 0 {\n\t\treturn \"\"\n\t}\n\tparams := make([]string, len(tp.List))\n\tfor i, p := range tp.List {\n\t\tif len(p.Names) > 0 {\n\t\t\tparams[i] = p.Names[0].Name\n\t\t} else {\n\t\t\tparams[i] = \"T\"\n\t\t}\n\t}\n\treturn \"[\" + strings.Join(params, \", \") + \"]\"\n}\n\nfunc formatType(t ast.Expr) string {\n\tif t == nil {\n\t\treturn \"?\"\n\t}\n\tswitch v := t.(type) {\n\tcase *ast.Ident:\n\t\treturn v.Name\n\tcase *ast.SelectorExpr:\n\t\treturn formatType(v.X) + \".\" + v.Sel.Name\n\tcase *ast.StarExpr:\n\t\treturn \"*\" + formatType(v.X)\n\tcase *ast.ArrayType:\n\t\tif v.Len == nil {\n\t\t\treturn \"[]\" + formatType(v.Elt)\n\t\t}\n\t\treturn \"[...]\" + formatType(v.Elt)\n\tcase *ast.MapType:\n\t\treturn \"map[\" + formatType(v.Key) + \"]\" + formatType(v.Value)\n\tcase *ast.InterfaceType:\n\t\treturn \"interface{}\"\n\tcase *ast.StructType:\n\t\treturn \"struct{}\"\n\tcase *ast.FuncType:\n\t\treturn formatFuncType(v)\n\tcase *ast.ChanType:\n\t\treturn \"chan \" + formatType(v.Value)\n\tcase *ast.BasicLit:\n\t\treturn v.Value\n\tcase *ast.IndexExpr:\n\t\t// Generic instantiation with one type arg, e.g. Logger[int].\n\t\treturn formatType(v.X) + \"[\" + formatType(v.Index) + \"]\"\n\tcase *ast.IndexListExpr:\n\t\t// Generic instantiation with multiple type args, e.g. Map[K, V].\n\t\targs := make([]string, len(v.Indices))\n\t\tfor i, idx := range v.Indices {\n\t\t\targs[i] = formatType(idx)\n\t\t}\n\t\treturn formatType(v.X) + \"[\" + strings.Join(args, \", \") + \"]\"\n\tdefault:\n\t\treturn \"?\"\n\t}\n}\n`;\n\nfunction syncGoParse(filePath: string, content: string, lang: SymbolLang): FileSymbols {\n\t// Feed the source over stdin — never pass the target .go file as a CLI arg.\n\t// `go run script.go target.go` makes the toolchain treat target.go as a\n\t// second package file (\"named files must all be in one directory\") and\n\t// refuses *_test.go outright. Reading from stdin sidesteps both, and lets\n\t// us parse the in-memory content without touching disk.\n\tconst tmpDir = path.join(os.tmpdir(), 'ws-go-parse');\n\ttry {\n\t\tmkdirSync(tmpDir, { recursive: true });\n\t\tconst scriptPath = path.join(tmpDir, 'parse.go');\n\t\twriteFileSync(scriptPath, GO_PARSE_SCRIPT, 'utf8');\n\n\t\t// argv-array form (no shell): avoids any quoting/metachar issues in the\n\t\t// temp script path. The target source is fed via stdin, not as an arg.\n\t\tconst stdout = execFileSync('go', ['run', scriptPath], {\n\t\t\tinput: content,\n\t\t\ttimeout: 15_000,\n\t\t\tencoding: 'utf8',\n\t\t\twindowsHide: true,\n\t\t});\n\n\t\tif (!stdout.trim()) {\n\t\t\treturn { file: filePath, lang, symbols: [], mtimeMs: Date.now() };\n\t\t}\n\n\t\tconst raw = JSON.parse(stdout.trim()) as Array<{ name: string; kind: string; line: number; col: number; signature: string; scope: string }>;\n\t\tconst symbols: IndexSymbol[] = raw.map((s) => ({\n\t\t\tid: 0,\n\t\t\tlang,\n\t\t\tkind: s.kind as IndexSymbol['kind'],\n\t\t\tname: s.name,\n\t\t\tfile: filePath,\n\t\t\tline: s.line,\n\t\t\tcol: s.col,\n\t\t\tsignature: s.signature ?? '',\n\t\t\tdocComment: '',\n\t\t\tscope: s.scope ?? '',\n\t\t\ttext: `${s.name} ${s.signature ?? ''}`.trim(),\n\t\t}));\n\t\treturn { file: filePath, lang, symbols, mtimeMs: Date.now() };\n\t} catch {\n\t\treturn { file: filePath, lang, symbols: [], mtimeMs: Date.now() };\n\t}\n}","/**\n * Python source symbol extraction using the `ast` module.\n *\n * Spawns a `python -c` child process that parses the file with Python's `ast`\n * module and emits JSON. Falls back to empty results on any error.\n *\n * Extracts: class, function, async function, const, var, import, import_from\n */\n\nimport { execFileSync } from 'node:child_process';\nimport { mkdirSync, writeFileSync } from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { FileSymbols, Symbol as IndexSymbol, SymbolLang } from './schema.js';\n\n// ─── Public API ─────────────────────────────────────────────────────────────\n\nexport function parseSymbols(opts: { file: string; content: string; lang: SymbolLang }): FileSymbols {\n const { file, lang } = opts;\n\n try {\n return syncPyParse(file, lang);\n } catch {\n return { file, lang, symbols: [], mtimeMs: Date.now() };\n }\n}\n\nexport { detectLang } from './ts-parser.js';\n\n// ─── Inline Python parser script ────────────────────────────────────────────\n\nconst PY_PARSE_SCRIPT = `import ast, json, sys, os\n\ndef get_name(node):\n if isinstance(node, ast.Name):\n return node.id\n elif isinstance(node, ast.Attribute):\n return get_name(node.value) + \".\" + node.attr\n elif isinstance(node, ast.Subscript):\n return get_name(node.value)\n elif isinstance(node, ast.Call):\n return get_name(node.func)\n elif isinstance(node, ast.Constant):\n return str(node.value)\n return \"\"\n\ndef get_decorators(node):\n decs = []\n for dec in node.decorator_list:\n decs.append(get_name(dec))\n return decs\n\ndef get_bases(node):\n bases = []\n for base in node.bases:\n bases.append(get_name(base))\n return bases\n\ndef get_args(args):\n parts = []\n for arg in args.args:\n parts.append(arg.arg)\n return \", \".join(parts)\n\ndef get_returns(node):\n if node.returns is None:\n return \"\"\n return get_name(node.returns)\n\nclass Sym:\n def __init__(self, name, kind, line, col, signature, scope):\n self.name = name\n self.kind = kind\n self.line = line\n self.col = col\n self.signature = signature\n self.scope = scope\n def to_dict(self):\n return {\n \"name\": self.name,\n \"kind\": self.kind,\n \"line\": self.line,\n \"col\": self.col,\n \"signature\": self.signature,\n \"scope\": self.scope,\n }\n\ndef is_private(name):\n return name.startswith(\"__\") and not name.endswith(\"__\")\n\nsyms = []\nerrors = []\n\ntry:\n with open(sys.argv[1], \"r\", encoding=\"utf-8\") as f:\n source = f.read()\n tree = ast.parse(source, filename=sys.argv[1])\nexcept Exception as e:\n errors.append(str(e))\n print(\"[]\")\n sys.exit(0)\n\n# Module-level scope\nmodule_scope = os.path.basename(sys.argv[1])[:-3] # strip .py\n\nclass ModuleVisitor(ast.NodeVisitor):\n def __init__(self):\n self.scope_stack = [module_scope]\n\n def visit_ClassDef(self, node):\n bases = get_bases(node)\n decs = get_decorators(node)\n sig = \"class \" + node.name\n if bases:\n sig += \"(\" + \", \".join(bases) + \")\"\n sig += \": ...\"\n syms.append(Sym(\n name=node.name,\n kind=\"class\",\n line=node.lineno,\n col=node.col_offset,\n signature=sig,\n scope=\".\".join(self.scope_stack) + \".\" + node.name,\n ))\n self.scope_stack.append(node.name)\n self.generic_visit(node)\n self.scope_stack.pop()\n\n def visit_FunctionDef(self, node):\n decs = get_decorators(node)\n args = get_args(node.args)\n returns = get_returns(node)\n is_async = isinstance(node, ast.AsyncFunctionDef)\n\n kind = \"function\"\n prefix = \"def \"\n if decs:\n for d in decs:\n if d.endswith(\".staticmethod\"):\n kind = \"staticmethod\"\n elif d.endswith(\".classmethod\"):\n kind = \"classmethod\"\n elif d == \"property\":\n kind = \"property\"\n\n if is_async:\n kind = \"async_\" + kind\n\n sig = f\"{prefix}{node.name}({args})\"\n if returns:\n sig += f\" -> {returns}\"\n scope = \".\".join(self.scope_stack) + \".\" + node.name\n\n syms.append(Sym(\n name=node.name,\n kind=kind,\n line=node.lineno,\n col=node.col_offset,\n signature=sig,\n scope=scope,\n ))\n # Don't descend into function bodies to avoid local symbols\n # self.generic_visit(node)\n\n def visit_AsyncFunctionDef(self, node):\n # Treat as function\n self.visit_FunctionDef(node)\n\n def visit_Assign(self, node):\n for target in node.targets:\n if isinstance(target, ast.Name):\n name = target.id\n if is_private(name):\n continue\n # Infer constness from UPPER_CASE naming\n kind = \"const\" if name.isupper() else \"var\"\n col = target.col_offset if hasattr(target, 'col_offset') else 0\n syms.append(Sym(\n name=name,\n kind=kind,\n line=node.lineno,\n col=col,\n signature=f\"{name} = ...\",\n scope=\".\".join(self.scope_stack),\n ))\n\n def visit_AnnAssign(self, node):\n if isinstance(node.target, ast.Name):\n name = node.target.id\n if is_private(name):\n return\n kind = \"const\" if name.isupper() else \"var\"\n col = node.target.col_offset if hasattr(node.target, 'col_offset') else 0\n sig = f\"{name}: {get_name(node.annotation)}\"\n if node.value:\n sig += \" = ...\"\n syms.append(Sym(\n name=name,\n kind=kind,\n line=node.lineno,\n col=col,\n signature=sig,\n scope=\".\".join(self.scope_stack),\n ))\n\n def visit_Import(self, node):\n for alias in node.names:\n name = alias.asname or alias.name\n syms.append(Sym(\n name=name,\n kind=\"import\",\n line=node.lineno,\n col=node.col_offset,\n signature=f\"import {alias.name}\",\n scope=\".\".join(self.scope_stack),\n ))\n\n def visit_ImportFrom(self, node):\n module = node.module or \"\"\n for alias in node.names:\n name = alias.asname or alias.name\n syms.append(Sym(\n name=name,\n kind=\"import\",\n line=node.lineno,\n col=node.col_offset,\n signature=f\"from {module} import {alias.name}\",\n scope=\".\".join(self.scope_stack),\n ))\n\nvisitor = ModuleVisitor()\nvisitor.visit(tree)\n\nprint(json.dumps([s.to_dict() for s in syms]))\n`;\n\n// ─── Synchronous Python parse via child process ─────────────────────────────\n\nfunction syncPyParse(filePath: string, lang: SymbolLang): FileSymbols {\n\ttry {\n\t\t// Write the parser to a temp .py and run it as a script. Passing the\n\t\t// whole 200-line program via `python -c \"...\"` breaks under cmd.exe on\n\t\t// Windows (embedded newlines truncate the command), so the child saw a\n\t\t// mangled script and emitted nothing. A real file sidesteps all quoting.\n\t\tconst tmpDir = path.join(os.tmpdir(), 'ws-py-parse');\n\t\tmkdirSync(tmpDir, { recursive: true });\n\t\tconst scriptPath = path.join(tmpDir, 'parse.py');\n\t\twriteFileSync(scriptPath, PY_PARSE_SCRIPT, 'utf8');\n\n\t\t// argv-array form: no shell, so a hostile filename (e.g. one containing\n\t\t// shell metacharacters or command substitution) cannot inject commands.\n\t\tconst stdout = execFileSync('python', [scriptPath, filePath], {\n\t\t\ttimeout: 15_000,\n\t\t\tencoding: 'utf8',\n\t\t\twindowsHide: true,\n\t\t});\n\n\t\tif (!stdout.trim()) {\n\t\t\treturn { file: filePath, lang, symbols: [], mtimeMs: Date.now() };\n\t\t}\n\n\t\tconst raw = JSON.parse(stdout.trim()) as Array<{\n\t\t\tname: string;\n\t\t\tkind: string;\n\t\t\tline: number;\n\t\t\tcol: number;\n\t\t\tsignature: string;\n\t\t\tscope: string;\n\t\t}>;\n\t\tconst symbols: IndexSymbol[] = raw.map((s) => ({\n\t\t\tid: 0,\n\t\t\tlang,\n\t\t\tkind: s.kind as IndexSymbol['kind'],\n\t\t\tname: s.name,\n\t\t\tfile: filePath,\n\t\t\tline: s.line,\n\t\t\tcol: s.col,\n\t\t\tsignature: s.signature ?? '',\n\t\t\tdocComment: '',\n\t\t\tscope: s.scope ?? '',\n\t\t\ttext: `${s.name} ${s.signature ?? ''}`.trim(),\n\t\t}));\n\t\treturn { file: filePath, lang, symbols, mtimeMs: Date.now() };\n\t} catch {\n\t\treturn { file: filePath, lang, symbols: [], mtimeMs: Date.now() };\n\t}\n}","import { expectDefined } from '@wrongstack/core';\n/**\n * Rust source symbol extraction.\n *\n * Tries to use the native `syn` crate via a cargo subproject (tools/syn-parser/).\n * Falls back to a robust regex-based extractor when cargo/syn is not available.\n *\n * The regex fallback extracts: fn, struct, enum, trait, impl, type, const, static, mod\n */\n\nimport { execFileSync, spawnSync } from 'node:child_process';\nimport { writeFileSync } from 'node:fs';\nimport * as path from 'node:path';\nimport type { FileSymbols, Symbol as IndexSymbol, SymbolLang } from './schema.js';\n// ─── Public API ─────────────────────────────────────────────────────────────\n\nexport function parseSymbols(opts: {\n file: string;\n content: string;\n lang: SymbolLang;\n}): FileSymbols {\n const { file, content, lang } = opts;\n\n // Try native parser first, fall back to regex\n const nativeAvailable = checkNativeParser();\n if (nativeAvailable) {\n const result = tryNativeParse(file, content);\n if (result) return result;\n }\n\n return regexParse({ file, content, lang });\n}\n\nexport { detectLang } from './ts-parser.js';\n\n// ─── Native parser (syn) ─────────────────────────────────────────────────────\n\nfunction checkNativeParser(): boolean {\n try {\n execFileSync('rustc', ['--version'], { stdio: 'pipe', windowsHide: true });\n // Check if our syn-parser crate is available. argv-array form (no shell)\n // so a cwd path containing spaces or shell metacharacters can't break out.\n const toolsDir = path.join(process.cwd(), 'tools');\n try {\n execFileSync(\n 'cargo',\n [\n 'metadata',\n '--no-deps',\n '--format-version',\n '1',\n '--manifest-path',\n path.join(toolsDir, 'Cargo.toml'),\n ],\n { stdio: 'pipe', windowsHide: true },\n );\n return true;\n } catch {\n return false;\n }\n } catch {\n return false;\n }\n}\n\nfunction tryNativeParse(file: string, content: string): FileSymbols | null {\n try {\n const toolsDir = path.join(process.cwd(), 'tools');\n const crateDir = path.join(toolsDir, 'syn-parser');\n\n // Write source to temp file for cargo to read\n const tmpFile = path.join(crateDir, 'src', 'input.rs');\n writeFileSync(tmpFile, content, 'utf8');\n\n const result = spawnSync(\n 'cargo',\n ['run', '--manifest-path', path.join(toolsDir, 'Cargo.toml')],\n {\n cwd: process.cwd(),\n encoding: 'utf8',\n timeout: 15000,\n stdio: ['pipe', 'pipe', 'pipe'],\n windowsHide: true,\n },\n );\n\n if (result.status === 0 && result.stdout) {\n const symbols: IndexSymbol[] = JSON.parse(result.stdout);\n return {\n file,\n lang: 'rs',\n symbols: symbols.map((s) => ({ ...s, id: 0, lang: 'rs' as SymbolLang })),\n mtimeMs: Date.now(),\n };\n }\n } catch {\n // Fall through to regex\n }\n return null;\n}\n\n// ─── Regex fallback parser ───────────────────────────────────────────────────\n\ninterface RustPattern {\n regex: RegExp;\n kind: IndexSymbol['kind'];\n}\n\nconst RS_PATTERNS: RustPattern[] = [\n { regex: /fn\\s+(\\w+)\\s*\\([^)]*\\)/g, kind: 'function' },\n { regex: /struct\\s+(\\w+)/g, kind: 'struct' },\n { regex: /enum\\s+(\\w+)/g, kind: 'enum' },\n { regex: /trait\\s+(\\w+)/g, kind: 'trait' },\n { regex: /impl\\s+(?:<[^>]+>)?(\\w+)/g, kind: 'impl' },\n { regex: /type\\s+(\\w+)\\s*=/g, kind: 'type' },\n { regex: /const\\s+(\\w+)/g, kind: 'const' },\n { regex: /static\\s+(\\w+)/g, kind: 'static' },\n { regex: /mod\\s+(\\w+)/g, kind: 'mod' },\n];\n\nfunction regexParse(opts: { file: string; content: string; lang: SymbolLang }): FileSymbols {\n const { file, content, lang } = opts;\n const symbols: IndexSymbol[] = [];\n const lines = content.split('\\n');\n\n // Build line offset map\n const lineOffsets: number[] = [0];\n for (let i = 0; i < lines.length; i++) {\n lineOffsets.push((lineOffsets[i] ?? 0) + (lines[i]?.length ?? 0) + 1);\n }\n\n function lineFromOffset(offset: number): number {\n let lo = 0;\n let hi = lineOffsets.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >>> 1;\n if (expectDefined(lineOffsets[mid]) <= offset) lo = mid;\n else hi = mid - 1;\n }\n return lo + 1; // 1-based\n }\n\n function extractDeclaration(lineIdx: number, _match: RegExpExecArray): string {\n const line = lines[lineIdx] ?? '';\n return line.trim().slice(0, 500);\n }\n\n for (const pattern of RS_PATTERNS) {\n pattern.regex.lastIndex = 0;\n for (\n let match = pattern.regex.exec(content);\n match !== null;\n match = pattern.regex.exec(content)\n ) {\n const name = expectDefined(match[1]);\n const offset = (match.index ?? 0);\n const line = lineFromOffset(offset);\n const col = offset - (lineOffsets[line - 1] ?? 0);\n const lineIdx = line - 1;\n const signature = extractDeclaration(lineIdx, match);\n\n symbols.push({\n id: 0,\n lang,\n kind: pattern.kind,\n name,\n file,\n line,\n col,\n signature,\n docComment: '',\n scope: '',\n text: `${name} ${signature}`.trim(),\n });\n }\n }\n\n // Deduplicate by name+line\n const seen = new Set<string>();\n const deduped = symbols.filter((s) => {\n const key = `${s.name}:${s.line}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n\n return { file, lang, symbols: deduped, mtimeMs: Date.now() };\n}\n","import { expectDefined } from '@wrongstack/core';\n/**\n * JSON file symbol extraction.\n *\n * Extracts top-level keys as \"symbols\" with kind `property`.\n * Special handling for:\n * - package.json: scripts, dependencies, devDependencies → `const`\n * - tsconfig.json: compilerOptions keys → `property`\n * - JSON Schema / OpenAPI: $schema, $id, $ref → `schema`\n * - Root object itself → kind `object`\n *\n * Uses regex-based extraction for speed and zero dependencies.\n */\n\nimport * as path from 'node:path';\nimport type { FileSymbols, Symbol as IndexSymbol, SymbolLang } from './schema.js';\n// ─── Public API ─────────────────────────────────────────────────────────────\n\nexport function parseSymbols(opts: {\n file: string;\n content: string;\n lang: SymbolLang;\n}): FileSymbols {\n const { file, content, lang } = opts;\n\n try {\n return regexParse({ file, content, lang });\n } catch {\n return { file, lang, symbols: [], mtimeMs: Date.now() };\n }\n}\n\nexport { detectLang } from './ts-parser.js';\n\n// ─── Regex parser ───────────────────────────────────────────────────────────\n\n\n/**\n * Extract key-value pairs from JSON content using regex.\n * Handles: \"key\": value, arrays with keyed objects, nested objects (depth ≤ 3).\n */\nfunction regexParse(opts: { file: string; content: string; lang: SymbolLang }): FileSymbols {\n const { file, content, lang } = opts;\n const symbols: IndexSymbol[] = [];\n const basename = path.basename(file).toLowerCase();\n\n const isPackageJson = basename === 'package.json';\n const isTsconfig = basename === 'tsconfig.json' || basename === 'tsconfig.build.json';\n const isJsonSchema =\n content.includes('$schema') || content.includes('$id') || content.includes('$ref');\n const isOpenApi = content.includes('openapi') || content.includes('swagger');\n\n const lines = content.split('\\n');\n\n // Build line offset map\n const lineOffsets: number[] = [0];\n for (let i = 0; i < lines.length; i++) {\n lineOffsets.push((lineOffsets[i] ?? 0) + (lines[i]?.length ?? 0) + 1);\n }\n\n function lineFromOffset(offset: number): number {\n let lo = 0;\n let hi = lineOffsets.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >>> 1;\n if (expectDefined(lineOffsets[mid]) <= offset) lo = mid;\n else hi = mid - 1;\n }\n return lo + 1;\n }\n\n // Root object symbol\n const rootMatch = content.match(/^\\s*\\{/m);\n if (rootMatch) {\n const offset = expectDefined(rootMatch.index);\n const line = lineFromOffset(offset);\n symbols.push(\n makeSymbol({\n name: path.basename(file),\n kind: 'object',\n line,\n col: 0,\n signature: `\"${path.basename(file)}\" = { ... }`,\n file,\n lang,\n }),\n );\n }\n\n // Extract top-level keys\n const topLevelKeyRegex = /^\\s*\"([^\"]+)\"\\s*:/gm;\n for (\n let match = topLevelKeyRegex.exec(content);\n match !== null;\n match = topLevelKeyRegex.exec(content)\n ) {\n const key = expectDefined(match[1]);\n const offset = (match.index ?? 0);\n const line = lineFromOffset(offset);\n const col = offset - (lineOffsets[line - 1] ?? 0);\n\n let kind: IndexSymbol['kind'] = 'property';\n let signature = `\"${key}\": ...\"`;\n\n // Special casing for known file types\n if (isPackageJson) {\n if (\n key === 'scripts' ||\n key === 'dependencies' ||\n key === 'devDependencies' ||\n key === 'peerDependencies' ||\n key === 'optionalDependencies'\n ) {\n kind = 'const';\n signature = `\"${key}\": { ... }`;\n }\n } else if (isTsconfig) {\n if (key === 'compilerOptions') {\n kind = 'property';\n signature = `\"compilerOptions\": { ... }`;\n }\n }\n\n // JSON Schema / OpenAPI special keys\n if (isJsonSchema || isOpenApi) {\n if (key === '$schema' || key === '$id') {\n kind = 'schema';\n signature = `\"${key}\": \"...\"`;\n } else if (key === '$ref') {\n kind = 'schema';\n signature = `\"$ref\": \"...\"`;\n }\n }\n\n symbols.push(\n makeSymbol({\n name: key,\n kind,\n line,\n col,\n signature,\n file,\n lang,\n }),\n );\n\n // For package.json, also extract individual scripts as 'function'\n if (isPackageJson && key === 'scripts') {\n extractPackageScripts(content, symbols, file, lang, lineOffsets, lineFromOffset);\n }\n\n // For tsconfig.json compilerOptions, extract nested keys\n if (isTsconfig && key === 'compilerOptions') {\n extractCompilerOptions(content, symbols, file, lang, lineOffsets, line, lineFromOffset);\n }\n }\n\n // Extract JSON Schema $defs or definitions\n const defsRegex = /\"\\$defs\"\\s*:|\"\\$defs\"\\s*:/g;\n const defsMatch = defsRegex.exec(content);\n if (defsMatch !== null) {\n const offset = expectDefined(defsMatch.index);\n const line = lineFromOffset(offset);\n symbols.push(\n makeSymbol({\n name: '$defs',\n kind: 'property',\n line,\n col: offset - (lineOffsets[line - 1] ?? 0),\n signature: '\"$defs\": { ... }',\n file,\n lang,\n }),\n );\n }\n\n // Extract definitions (OpenAPI components, JSON Schema definitions)\n const defsPatterns = [\n /\"\\$defs\"\\s*:/g,\n /\"definitions\"\\s*:/g,\n /\"components\"\\s*:/g,\n /\"schemas\"\\s*:/g,\n ];\n for (const pat of defsPatterns) {\n pat.lastIndex = 0;\n for (let match = pat.exec(content); match !== null; match = pat.exec(content)) {\n const offset = (match.index ?? 0);\n const line = lineFromOffset(offset);\n const key = match[0]?.match(/\"([^\"]+)\"/)?.[1] ?? expectDefined(match[0]);\n symbols.push(\n makeSymbol({\n name: key,\n kind: 'property',\n line,\n col: offset - (lineOffsets[line - 1] ?? 0),\n signature: `\"${key}\": { ... }`,\n file,\n lang,\n }),\n );\n }\n }\n\n return { file, lang, symbols, mtimeMs: Date.now() };\n}\n\nfunction extractPackageScripts(\n content: string,\n symbols: IndexSymbol[],\n file: string,\n lang: SymbolLang,\n lineOffsets: number[],\n lineFromOffset: (offset: number) => number,\n): void {\n // Find the \"scripts\": { ... } block and extract each script key\n const scriptsBlockRegex = /\"scripts\"\\s*:\\s*\\{([^}]+)\\}/g;\n for (\n let match = scriptsBlockRegex.exec(content);\n match !== null;\n match = scriptsBlockRegex.exec(content)\n ) {\n const blockContent = expectDefined(match[0]);\n const blockOffset = (match.index ?? 0);\n\n // Extract each \"key\" inside the block (simple approach)\n const scriptKeyRegex = /\"(\\w[\\w-]*)\"\\s*:/g;\n for (\n let scriptMatch = scriptKeyRegex.exec(blockContent);\n scriptMatch !== null;\n scriptMatch = scriptKeyRegex.exec(blockContent)\n ) {\n const key = expectDefined(scriptMatch[1]);\n const keyOffset = blockOffset + expectDefined(scriptMatch.index);\n const line = lineFromOffset(keyOffset);\n symbols.push(\n makeSymbol({\n name: key,\n kind: 'function',\n line,\n col: keyOffset - (lineOffsets[line - 1] ?? 0),\n signature: `\"${key}\": \"...\"`,\n file,\n lang,\n }),\n );\n }\n }\n}\n\nfunction extractCompilerOptions(\n content: string,\n symbols: IndexSymbol[],\n file: string,\n lang: SymbolLang,\n lineOffsets: number[],\n parentLine: number,\n lineFromOffset: (offset: number) => number,\n): void {\n // Find the \"compilerOptions\": { ... } block\n const optsBlockRegex = /\"compilerOptions\"\\s*:\\s*\\{([^}]+)\\}/g;\n for (\n let match = optsBlockRegex.exec(content);\n match !== null;\n match = optsBlockRegex.exec(content)\n ) {\n const blockContent = expectDefined(match[0]);\n const blockOffset = (match.index ?? 0);\n\n // Extract nested key inside compilerOptions (up to depth 1)\n const optKeyRegex = /\"(\\w[\\w]*)\"\\s*:/g;\n for (\n let optMatch = optKeyRegex.exec(blockContent);\n optMatch !== null;\n optMatch = optKeyRegex.exec(blockContent)\n ) {\n const key = expectDefined(optMatch[1]);\n const keyOffset = blockOffset + expectDefined(optMatch.index);\n const line = lineFromOffset(keyOffset);\n if (line <= parentLine) continue; // Skip top-level (already captured)\n symbols.push(\n makeSymbol({\n name: key,\n kind: 'property',\n line,\n col: keyOffset - (lineOffsets[line - 1] ?? 0),\n signature: `\"${key}\": ...`,\n file,\n lang,\n }),\n );\n }\n }\n}\n\nfunction makeSymbol(opts: {\n name: string;\n kind: IndexSymbol['kind'];\n line: number;\n col: number;\n signature: string;\n file: string;\n lang: SymbolLang;\n}): IndexSymbol {\n return {\n id: 0,\n lang: opts.lang,\n kind: opts.kind,\n name: opts.name,\n file: opts.file,\n line: opts.line,\n col: opts.col,\n signature: opts.signature,\n docComment: '',\n scope: '',\n text: `${opts.name} ${opts.signature}`.trim(),\n };\n}\n","import { expectDefined, truncate } from '@wrongstack/core';\nimport type { FileSymbols, Symbol as IndexSymbol, SymbolLang } from './schema.js';\n// ─── Public API ─────────────────────────────────────────────────────────────\n\nexport function parseSymbols(opts: {\n file: string;\n content: string;\n lang: SymbolLang;\n}): FileSymbols {\n const { file, content, lang } = opts;\n\n try {\n return regexParse({ file, content, lang });\n } catch {\n return { file, lang, symbols: [], mtimeMs: Date.now() };\n }\n}\n\nexport { detectLang } from './ts-parser.js';\n\n// ─── Regex parser ───────────────────────────────────────────────────────────\n\nfunction regexParse(opts: { file: string; content: string; lang: SymbolLang }): FileSymbols {\n const { file, content, lang } = opts;\n const symbols: IndexSymbol[] = [];\n\n const lines = content.split('\\n');\n\n // Build line offset map for accurate line/col\n const lineOffsets: number[] = [0];\n for (let i = 0; i < lines.length; i++) {\n lineOffsets.push((lineOffsets[i] ?? 0) + (lines[i]?.length ?? 0) + 1);\n }\n\n function lineFromOffset(offset: number): number {\n let lo = 0;\n let hi = lineOffsets.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >>> 1;\n if (expectDefined(lineOffsets[mid]) <= offset) lo = mid;\n else hi = mid - 1;\n }\n return lo + 1;\n }\n\n // ── 1. Anchors and aliases ─────────────────────────────────────────────────\n // &anchor_name\n const anchorRegex = /&(\\w[\\w-]*)/g;\n for (let match = anchorRegex.exec(content); match !== null; match = anchorRegex.exec(content)) {\n const name = expectDefined(match[1]);\n const offset = (match.index ?? 0);\n const line = lineFromOffset(offset);\n const col = offset - (lineOffsets[line - 1] ?? 0);\n symbols.push(\n makeSymbol({\n name,\n kind: 'const',\n line,\n col,\n signature: `&${name}`,\n file,\n lang,\n }),\n );\n }\n\n // *alias_name\n const aliasRegex = /\\*(\\w[\\w-]*)/g;\n for (let match = aliasRegex.exec(content); match !== null; match = aliasRegex.exec(content)) {\n const name = expectDefined(match[1]);\n const offset = (match.index ?? 0);\n const line = lineFromOffset(offset);\n const col = offset - (lineOffsets[line - 1] ?? 0);\n symbols.push(\n makeSymbol({\n name,\n kind: 'const',\n line,\n col,\n signature: `*${name}`,\n file,\n lang,\n }),\n );\n }\n\n // ── 2. Top-level and nested key: value pairs ───────────────────────────────\n // Matches `key: value` (but not block scalars or document markers)\n // Uses negative lookbehind and context to avoid false positives\n const kvRegex = /^(\\s*)([^:#\\s][^:#\\s]*)\\s*:/gm;\n for (let match = kvRegex.exec(content); match !== null; match = kvRegex.exec(content)) {\n const indent = match[1]?.length ?? 0;\n const key = match[2];\n if (!key) continue;\n const offset = (match.index ?? 0);\n const line = lineFromOffset(offset);\n const col = offset - (lineOffsets[line - 1] ?? 0);\n\n // Skip block scalar indicators (| or > at column 0 with key name before :)\n const lineContent = lines[line - 1] ?? '';\n if (/^[|&>]/.test(lineContent.trim())) continue;\n // Skip YAML document markers\n if (key === '---' || key === '...') continue;\n // Skip keys that are clearly part of a string value (unusual indent)\n if (indent > 12) continue;\n\n const value = extractValue(content, (match.index ?? 0));\n const kind: IndexSymbol['kind'] = isScalar(value) ? 'literal' : 'property';\n const signature = `${key}: ${truncate(value, 60)}`;\n\n symbols.push(makeSymbol({ name: key, kind, line, col, signature, file, lang }));\n }\n\n // ── 3. List item keys ──────────────────────────────────────────────────────\n // `- key: value` (list item that is a keyed object)\n const listItemRegex = /^-(\\s+)([^:#\\s][^:#\\s]*)\\s*:/gm;\n for (let match = listItemRegex.exec(content); match !== null; match = listItemRegex.exec(content)) {\n const key = expectDefined(match[2]);\n const offset = (match.index ?? 0);\n const line = lineFromOffset(offset);\n const col = offset - (lineOffsets[line - 1] ?? 0);\n const value = extractValue(content, offset + match[0]?.length);\n const kind: IndexSymbol['kind'] = isScalar(value) ? 'literal' : 'property';\n symbols.push(\n makeSymbol({\n name: key,\n kind,\n line,\n col,\n signature: `- ${key}: ${truncate(value, 60)}`,\n file,\n lang,\n }),\n );\n }\n\n // ── 4. Block scalar keys (key: | or key: >) ────────────────────────────────\n const blockScalarRegex = /^(\\s*)([^:#\\s][^:#\\s]*)\\s*:\\s*[|>](\\s|$)/gm;\n for (let match = blockScalarRegex.exec(content); match !== null; match = blockScalarRegex.exec(content)) {\n const key = expectDefined(match[2]);\n const offset = (match.index ?? 0);\n const line = lineFromOffset(offset);\n const col = offset - (lineOffsets[line - 1] ?? 0);\n symbols.push(\n makeSymbol({\n name: key,\n kind: 'property',\n line,\n col,\n signature: `${key}: | ...`,\n file,\n lang,\n }),\n );\n }\n\n return { file, lang, symbols, mtimeMs: Date.now() };\n}\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\nfunction extractValue(content: string, afterColonOffset: number): string {\n // Get the rest of the line after the colon\n const lineEnd = content.indexOf('\\n', afterColonOffset);\n const rest = content.slice(afterColonOffset, lineEnd < 0 ? undefined : lineEnd);\n return rest.trim();\n}\n\nfunction isScalar(value: string): boolean {\n if (!value) return false;\n // Numbers, booleans, null, quoted strings\n if (/^-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?$/.test(value)) return true;\n if (/^(true|false|null|undefined)$/i.test(value)) return true;\n if (/^'[^']*'$/.test(value) || /^\"[^\"]*\"$/.test(value)) return true;\n return false;\n}\n\nfunction makeSymbol(opts: {\n name: string;\n kind: IndexSymbol['kind'];\n line: number;\n col: number;\n signature: string;\n file: string;\n lang: SymbolLang;\n}): IndexSymbol {\n return {\n id: 0,\n lang: opts.lang,\n kind: opts.kind,\n name: opts.name,\n file: opts.file,\n line: opts.line,\n col: opts.col,\n signature: opts.signature,\n docComment: '',\n scope: '',\n text: `${opts.name} ${opts.signature}`.trim(),\n };\n}\n","/**\n * Minimal but faithful `.gitignore` matcher for the indexer.\n *\n * Supports the parts of the gitignore spec that matter for skipping source\n * files: comments / blanks, `!` negation (last match wins), trailing-slash\n * directory-only rules, leading-slash / embedded-slash anchoring, and the\n * `*` / `**` / `?` / `[...]` globs (via core's {@link compileGlob}).\n *\n * Only the project-root `.gitignore` is read. Nested `.gitignore` files are not\n * walked — the common build/dependency dirs that would live deeper are already\n * covered by the indexer's always-on `DEFAULT_IGNORE`.\n *\n * Known limitation: a `!negated` file inside an ignored directory will not be\n * re-included, because the indexer prunes ignored directories before descending\n * (a large performance win). This matches most lightweight implementations.\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { compileGlob } from '@wrongstack/core';\n\nexport type IgnoreMatcher = (relPath: string, isDir: boolean) => boolean;\n\ninterface Rule {\n /** Matches the entry itself or anything under it (for dirs / plain names). */\n eqOrUnder: RegExp;\n /** Matches only entries strictly under it (for dir-only rules on files). */\n under: RegExp;\n negated: boolean;\n dirOnly: boolean;\n}\n\n/** Strip the `^`/`$` anchors compileGlob adds so we can re-anchor ourselves. */\nfunction globBody(glob: string): string {\n return compileGlob(glob).source.replace(/^\\^/, '').replace(/\\$$/, '');\n}\n\n/** Compile a list of raw `.gitignore` lines into a matcher. */\nexport function compileGitignore(lines: string[]): IgnoreMatcher {\n const rules: Rule[] = [];\n\n for (const raw of lines) {\n let line = raw.replace(/\\r$/, '');\n if (!line.trim() || line.trimStart().startsWith('#')) continue;\n line = line.trim();\n\n let negated = false;\n if (line.startsWith('!')) {\n negated = true;\n line = line.slice(1);\n }\n\n let dirOnly = false;\n if (line.endsWith('/')) {\n dirOnly = true;\n line = line.slice(0, -1);\n }\n if (!line) continue;\n\n // A slash anywhere (after the trailing slash is stripped) anchors the\n // pattern to the gitignore's directory (the project root here). A bare name\n // matches at any depth.\n const anchored = line.startsWith('/') || line.includes('/');\n if (line.startsWith('/')) line = line.slice(1);\n\n const body = globBody(line);\n const prefix = anchored ? '^' : '(?:^|.*/)';\n rules.push({\n eqOrUnder: new RegExp(`${prefix}${body}(?:/.*)?$`),\n under: new RegExp(`${prefix}${body}/.*$`),\n negated,\n dirOnly,\n });\n }\n\n return (relPath: string, isDir: boolean): boolean => {\n const p = relPath.replace(/\\\\/g, '/').replace(/^\\/+/, '');\n let ignored = false;\n for (const r of rules) {\n // A directory-only rule never matches a file by its own name; it only\n // matches files that live strictly beneath the named directory.\n const re = r.dirOnly && !isDir ? r.under : r.eqOrUnder;\n if (re.test(p)) ignored = !r.negated;\n }\n return ignored;\n };\n}\n\n/** Read `<projectRoot>/.gitignore` and compile it. Missing file → matches nothing. */\nexport async function loadGitignoreMatcher(projectRoot: string): Promise<IgnoreMatcher> {\n let lines: string[] = [];\n try {\n const raw = await fs.readFile(path.join(projectRoot, '.gitignore'), 'utf8');\n lines = raw.split('\\n');\n } catch {\n // No .gitignore — nothing extra to ignore beyond the indexer defaults.\n }\n return compileGitignore(lines);\n}\n","import { expectDefined } from '@wrongstack/core';\n/**\n * Main indexing orchestrator.\n *\n * Given a project root and a list of files:\n * 1. Parse each file with the appropriate parser (TS, Go, Python, Rust, JSON, YAML)\n * 2. Delete old symbols for changed/deleted files\n * 3. Insert new symbols\n * 4. Update file metadata\n * 5. Return index statistics\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Dirent, Stats } from 'node:fs';\nimport type { Context } from '@wrongstack/core';\nimport { compileGlob } from '@wrongstack/core';\nimport type { FileMeta, IndexResult, Symbol as IndexSymbol } from './schema.js';\nimport { IndexStore } from './writer.js';\nimport { parseSymbols as parseTs, detectLang } from './ts-parser.js';\nimport { parseSymbols as parseGo } from './go-parser.js';\nimport { parseSymbols as parsePy } from './py-parser.js';\nimport { parseSymbols as parseRs } from './rs-parser.js';\nimport { parseSymbols as parseJson } from './json-parser.js';\nimport { parseSymbols as parseYaml } from './yaml-parser.js';\nimport { loadGitignoreMatcher, type IgnoreMatcher } from './gitignore.js';\n/** Yield the event loop every N files so the main thread stays responsive. */\nconst YIELD_EVERY_N = 50;\n\nfunction yieldEventLoop(): Promise<void> {\n return new Promise((resolve) => setImmediate(resolve));\n}\n\n/**\n * Cooperatively abort if the signal is set. Throws with the signal's reason\n * (or a descriptive Error) so callers know *why* the operation was cancelled.\n * Called at yield points — never after a Promise resolve (that would be a\n * microtask that the signal check could miss).\n */\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n if (!signal?.aborted) return;\n if (signal.reason instanceof Error) throw signal.reason;\n throw new Error(\n typeof signal.reason === 'string' ? signal.reason : 'Indexing cancelled',\n );\n}\n\n/**\n * Detect AbortError (DOMException with name 'AbortError') thrown by signal-aware\n * fs.promises calls (stat, readFile). We must re-throw these so the cancellation\n * propagates — catching them as ordinary errors would keep the loop running.\n */\nfunction isAbortError(err: unknown): boolean {\n return err instanceof DOMException && err.name === 'AbortError';\n}\n\nconst DEFAULT_IGNORE = [\n 'node_modules', '.git', 'dist', 'build', '.next', 'coverage',\n '.turbo', '__snapshots__', '.nyc_output',\n];\n\ninterface IndexerOptions {\n projectRoot: string;\n files?: string[] | undefined;\n force?: boolean | undefined;\n langs?: string[] | undefined;\n ignore?: string[] | undefined;\n /** Override the index directory (default: the global per-project dir). */\n indexDir?: string | undefined;\n /**\n * Signal that cancels indexing cooperatively. Polled at yield points\n * (file walk, per-file loop) so a hung filesystem won't lock up the\n * process. When the tool executor's timeout fires, this signal aborts\n * and `runIndexer` throws, releasing the mutex and resetting flags.\n */\n signal?: AbortSignal | undefined;\n /**\n * Per-file progress callback. Injected by the caller instead of imported\n * from the host's module state so the indexer can run inside a worker\n * thread (worker posts progress messages; inline host updates its state).\n */\n onProgress?: ((current: number, total: number) => void) | undefined;\n}\n\nasync function findSourceFiles(\n projectRoot: string,\n ignore: string[],\n isGitIgnored: IgnoreMatcher,\n signal?: AbortSignal | undefined,\n): Promise<string[]> {\n const results: string[] = [];\n const ignoreSet = new Set([...DEFAULT_IGNORE, ...ignore]);\n // compileGlob does not support brace expansion — use one pattern per extension\n const globs = [\n { ext: '.ts', pat: compileGlob('**/*.ts') },\n { ext: '.tsx', pat: compileGlob('**/*.tsx') },\n { ext: '.js', pat: compileGlob('**/*.js') },\n { ext: '.jsx', pat: compileGlob('**/*.jsx') },\n { ext: '.go', pat: compileGlob('**/*.go') },\n { ext: '.py', pat: compileGlob('**/*.py') },\n { ext: '.rs', pat: compileGlob('**/*.rs') },\n { ext: '.json', pat: compileGlob('**/*.json') },\n { ext: '.yaml', pat: compileGlob('**/*.yaml') },\n { ext: '.yml', pat: compileGlob('**/*.yml') },\n ];\n\n let dirCount = 0;\n\n const walk = async (dir: string): Promise<void> => {\n // Yield + abort check before every readdir so a cancelled indexer\n // doesn't descend deeper into the tree.\n throwIfAborted(signal);\n // Periodically yield the event loop so the main thread stays responsive\n // during deep directory walks (Node 22's fs.promises.readdir doesn't\n // accept AbortSignal, so we rely on cooperative polling).\n if (dirCount > 0 && dirCount % YIELD_EVERY_N === 0) {\n await yieldEventLoop();\n throwIfAborted(signal);\n }\n let entries: Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n dirCount++;\n\n for (const e of entries) {\n if (ignoreSet.has(e.name)) continue;\n const full = path.join(dir, e.name);\n // Normalize to forward-slash relative path for pattern matching\n const rel = path.relative(projectRoot, full).replace(/\\\\/g, '/');\n if (e.isDirectory()) {\n // Prune .gitignore'd directories before descending (skips node_modules,\n // build output, and any project-specific ignored dirs).\n if (isGitIgnored(rel, true)) continue;\n await walk(full);\n } else if (e.isFile()) {\n if (isGitIgnored(rel, false)) continue;\n const ext = path.extname(e.name);\n for (const { ext: extName, pat } of globs) {\n if (ext === extName && (pat.test(rel) || pat.test(e.name))) {\n results.push(full);\n break;\n }\n }\n }\n }\n };\n\n await walk(projectRoot);\n return results;\n}\n\n/** Dispatch to the correct parser based on language. */\nasync function parseFile(\n file: string,\n content: string,\n lang: string,\n): Promise<ReturnType<typeof parseTs>> {\n switch (lang) {\n case 'ts':\n case 'tsx':\n case 'js':\n case 'jsx':\n return parseTs({ file, content, lang: lang as 'ts' | 'tsx' | 'js' | 'jsx' });\n case 'go':\n return parseGo({ file, content, lang: 'go' });\n case 'py':\n return parsePy({ file, content, lang: 'py' });\n case 'rs':\n return parseRs({ file, content, lang: 'rs' });\n case 'json':\n return parseJson({ file, content, lang: 'json' });\n case 'yaml':\n return parseYaml({ file, content, lang: 'yaml' });\n default:\n return { file, lang: lang as 'ts' | 'tsx' | 'js' | 'jsx', symbols: [], mtimeMs: Date.now() };\n }\n}\n\n/** Run a full or incremental index and return statistics. */\nexport async function runIndexer(\n _ctx: Context,\n opts: IndexerOptions,\n): Promise<IndexResult> {\n const store = new IndexStore(opts.projectRoot, { indexDir: opts.indexDir });\n try {\n return await runIndexerWithStore(store, opts);\n } finally {\n // Always release the synchronous SQLite connection — an abort mid-run\n // (executor timeout, session teardown) previously leaked it.\n try {\n store.close();\n } catch {\n /* already closed */\n }\n }\n}\n\nasync function runIndexerWithStore(store: IndexStore, opts: IndexerOptions): Promise<IndexResult> {\n const { projectRoot, force = false, langs, ignore = [], signal } = opts;\n const startMs = Date.now();\n const errors: string[] = [];\n const langStats: Record<string, number> = {};\n let filesIndexed = 0;\n let symbolsIndexed = 0;\n\n // Honor the project-root .gitignore (skips node_modules, build output, and\n // any project-specific ignored paths) on top of the always-on DEFAULT_IGNORE.\n const isGitIgnored = await loadGitignoreMatcher(projectRoot);\n\n let files: string[];\n if (opts.files && opts.files.length > 0) {\n // Explicit file list (per-edit / watcher path): drop any that are gitignored\n // so an ignored file edited in the editor never enters the index.\n files = opts.files\n .map((f) => path.resolve(projectRoot, f))\n .filter((f) => !isGitIgnored(path.relative(projectRoot, f).replace(/\\\\/g, '/'), false));\n } else {\n files = await findSourceFiles(projectRoot, ignore, isGitIgnored, signal);\n }\n\n if (langs && langs.length > 0) {\n const langSet = new Set(langs);\n files = files.filter((f) => {\n const lang = detectLang(f);\n return lang ? langSet.has(lang) : false;\n });\n }\n\n if (force) store.clearAll();\n\n // Collect existing file metadata for incremental check\n const existingMeta: Map<string, FileMeta> = new Map();\n if (!force) {\n for (const meta of store.getAllFileMetas()) existingMeta.set(meta.file, meta);\n }\n\n for (let fi = 0; fi < files.length; fi++) {\n const file = expectDefined(files[fi]);\n\n // Report progress to the caller so UIs can show indexing status.\n opts.onProgress?.(fi + 1, files.length);\n\n // Yield the event loop periodically so the main thread stays responsive\n // (TUI rendering, input handling, etc.) during large index builds.\n // Also check for cancellation — the tool executor's timeout or a\n // session abort propagates through `signal`.\n if (fi > 0 && fi % YIELD_EVERY_N === 0) {\n await yieldEventLoop();\n throwIfAborted(signal);\n }\n\n let stat: Stats;\n try {\n // @types/node hasn't added `signal` to StatOptions yet (runtime\n // support added in Node 20.15+). Cast to the signature Node 22 uses.\n const statOpts = signal ? { signal } : {};\n stat = await (fs.stat as (path: string, opts: { signal?: AbortSignal }) => Promise<Stats>)(file, statOpts);\n } catch (e) {\n // If the signal fired, stop immediately — don't mutate the store.\n if (isAbortError(e)) throw e;\n store.deleteFile(file);\n continue;\n }\n if (!stat.isFile()) continue;\n\n const lang = detectLang(file);\n if (!lang) continue;\n\n const meta = existingMeta.get(file);\n if (!force && meta && meta.mtimeMs === Math.floor(stat.mtimeMs)) {\n langStats[lang] = (langStats[lang] ?? 0) + meta.symbolCount;\n symbolsIndexed += meta.symbolCount;\n filesIndexed++;\n continue;\n }\n\n // Refs first: deleteRefsForFile resolves the file's symbol ids via the\n // symbols table, so it must run before those symbols are deleted (otherwise\n // the lookup finds nothing and orphan refs are left behind).\n store.deleteRefsForFile(file);\n store.deleteSymbolsForFile(file);\n\n let content: string;\n try {\n content = await fs.readFile(file, { encoding: 'utf8', signal });\n } catch (e) {\n if (isAbortError(e)) throw e;\n errors.push(`read error: ${file}: ${e instanceof Error ? e.message : String(e)}`);\n continue;\n }\n\n let parsed: ReturnType<typeof parseTs>;\n try {\n parsed = await parseFile(file, content, lang);\n } catch (e) {\n errors.push(`parse error: ${file}: ${e instanceof Error ? e.message : String(e)}`);\n continue;\n }\n\n if (parsed.symbols.length === 0) {\n store.upsertFile({\n file,\n lang,\n mtimeMs: Math.floor(stat.mtimeMs),\n symbolCount: 0,\n lastIndexed: Date.now(),\n });\n filesIndexed++;\n continue;\n }\n\n // Allocate ids from MAX(id), not COUNT(*): incremental reindexes leave gaps,\n // so a count-based id would collide with a surviving row (symbols.id UNIQUE).\n const nextId = store.getMaxSymbolId() + 1;\n const symbolsWithIds: IndexSymbol[] = parsed.symbols.map((s, i) => ({ ...s, id: nextId + i }));\n store.insertSymbols(symbolsWithIds, nextId);\n const count = symbolsWithIds.length;\n symbolsIndexed += count;\n langStats[lang] = (langStats[lang] ?? 0) + count;\n\n // Insert cross-references for each symbol\n if (parsed.refs && parsed.refs.length > 0) {\n for (let i = 0; i < symbolsWithIds.length; i++) {\n const sym = expectDefined(symbolsWithIds[i]);\n const symRefs = parsed.refs.filter((r) => r.line === sym.line);\n if (symRefs.length > 0) {\n const refsWithFromId = symRefs.map((r) => ({ ...r, fromId: sym.id }));\n store.insertRefs(sym.id, refsWithFromId);\n }\n }\n }\n\n store.upsertFile({\n file,\n lang,\n mtimeMs: Math.floor(stat.mtimeMs),\n symbolCount: count,\n lastIndexed: Date.now(),\n });\n\n filesIndexed++;\n }\n\n // Remove stale entries for files deleted since last run\n for (const [file_] of existingMeta) {\n try {\n await fs.stat(file_);\n } catch {\n store.deleteFile(file_);\n }\n }\n\n const durationMs = Date.now() - startMs;\n store.setLastIndexed(Date.now());\n\n return {\n filesIndexed,\n symbolsIndexed,\n langStats,\n durationMs,\n errors,\n };\n}","/**\n * Execution-location-agnostic index operations.\n *\n * One implementation, two callers: the index worker thread (production —\n * synchronous SQLite and the TypeScript parser can never block the main\n * thread / terminal UI there) and the inline fallback inside the host (tests,\n * `WRONGSTACK_INDEX_INLINE=1`, or runtimes where the worker file is missing).\n *\n * Every operation opens its own short-lived IndexStore, exactly like the old\n * per-call code paths did — there is no connection state to share, which keeps\n * multi-project usage trivially correct and crash recovery simple.\n */\n\nimport type { Context } from '@wrongstack/core';\nimport { runIndexer } from './indexer.js';\nimport type { IndexResult, IndexStats, SymbolKind, SymbolLang } from './schema.js';\nimport type { IndexOpArgs, SearchOpArgs, SearchOpResult, StatsOpArgs } from './worker-protocol.js';\nimport { IndexStore } from './writer.js';\n\n/** A run with no live agent Context — `runIndexer` only reads `opts`. */\nfunction stubCtx(projectRoot: string): Context {\n return {\n projectRoot,\n cwd: projectRoot,\n messages: [],\n todos: [],\n readFiles: new Set<string>(),\n fileMtimes: new Map<string, number>(),\n } as unknown as Context;\n}\n\nexport interface ServiceHooks {\n signal?: AbortSignal | undefined;\n onProgress?: ((current: number, total: number) => void) | undefined;\n}\n\n/** Full or per-file index run. */\nexport async function indexService(\n args: IndexOpArgs,\n hooks: ServiceHooks = {},\n): Promise<IndexResult> {\n return runIndexer(stubCtx(args.projectRoot), {\n projectRoot: args.projectRoot,\n indexDir: args.indexDir,\n files: args.files,\n force: args.force,\n langs: args.langs,\n ignore: args.ignore,\n signal: hooks.signal,\n onProgress: hooks.onProgress,\n });\n}\n\n/** Ranked symbol search (FTS5 inside SQLite; BM25 fallback without FTS5). */\nexport function searchService(args: SearchOpArgs): SearchOpResult {\n const store = new IndexStore(args.projectRoot, { indexDir: args.indexDir });\n try {\n return store.searchRanked(\n args.query,\n {\n kind: args.kind as SymbolKind | undefined,\n lang: args.lang as SymbolLang | undefined,\n file: args.file,\n lspKind: args.lspKind,\n },\n args.limit,\n );\n } finally {\n store.close();\n }\n}\n\n/** Index health and statistics. */\nexport function statsService(args: StatsOpArgs): IndexStats {\n const store = new IndexStore(args.projectRoot, { indexDir: args.indexDir });\n try {\n return store.getStats();\n } finally {\n store.close();\n }\n}\n","/**\n * Index host — the main-thread coordinator for all codebase-index operations.\n *\n * Production mode runs every operation (full scans, per-file reindexes,\n * searches, stats) in a dedicated worker thread (`worker.ts`), so the\n * synchronous `node:sqlite` calls and the TypeScript parser can never block\n * the main event loop — the failure mode that used to freeze terminals is\n * structurally impossible. When the built worker file is not present (tests\n * run from source, exotic runtimes) or `WRONGSTACK_INDEX_INLINE=1` is set,\n * operations fall back to running inline through the same service layer.\n *\n * Concerns owned here, in front of either execution mode:\n *\n * 1. **Serialization** — every write run (startup scan, per-edit incremental,\n * external file-watch, manual reindex) goes through one process-wide\n * promise-chain mutex so two runs never race the same `index.db` writer.\n * 2. **Debounce** — rapid successive edits to the same file coalesce into a\n * single reindex, keyed per `(indexDir, file)`.\n * 3. **Watchdog** — every operation is raced against a timeout. In worker\n * mode a timeout hard-terminates the worker (it respawns lazily on the\n * next request); inline it aborts the run's signal. Either way the mutex\n * chain always advances and the promise always settles.\n * 4. **Circuit breaker** — repeated failures/timeouts pause indexing instead\n * of queuing more work behind a wedged pipeline. See circuit-breaker.ts.\n * 5. **State tracking** — ready/indexing/progress flags + change listeners\n * for the TUI status chip and the search/stats tools' gating.\n */\n\nimport * as fs from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { Worker } from 'node:worker_threads';\nimport {\n CircuitOpenError,\n type CircuitSnapshot,\n IndexTimeoutError,\n indexCircuitBreaker,\n} from './circuit-breaker.js';\nimport { indexService, searchService, statsService } from './index-service.js';\nimport type { IndexResult, IndexStats } from './schema.js';\nimport { detectLang } from './ts-parser.js';\nimport type {\n HostToWorker,\n IndexOpArgs,\n OpName,\n OpShapes,\n SearchOpArgs,\n SearchOpResult,\n StatsOpArgs,\n WorkerToHost,\n} from './worker-protocol.js';\n\n// ─── Watchdog timeouts ───────────────────────────────────────────────────────\n\n/** Watchdog timeout for a full (startup / manual) index run. */\nconst DEFAULT_FULL_INDEX_TIMEOUT_MS = 120_000;\n/** Watchdog timeout for a single-file incremental reindex. */\nconst DEFAULT_INCREMENTAL_TIMEOUT_MS = 30_000;\n/** Watchdog timeout for read operations (search / stats). */\nconst DEFAULT_QUERY_TIMEOUT_MS = 8_000;\n\n// ─── Indexing lifecycle state ─────────────────────────────────────────────────\n// Process-wide counters so codebase-search / codebase-stats can gate on\n// readiness and UIs can show an indexing indicator.\nlet _ready = false;\nlet _indexing = false;\nlet _currentFile = 0;\nlet _totalFiles = 0;\nlet _lastError: string | null = null;\n\n/** True once the first full-project index has completed (success or failure). */\nexport function isIndexReady(): boolean {\n return _ready;\n}\n\n/**\n * Mark the index as ready so downstream tools (codebase-search, codebase-stats)\n * don't gate on a startup index that never ran.\n */\nexport function setIndexReady(): void {\n _ready = true;\n}\n\n/** True while an index build is actively running. */\nexport function isIndexing(): boolean {\n return _indexing;\n}\n\n/** Current indexing progress: { currentFile, totalFiles, ready, indexing, circuit }. */\nexport function getIndexState(): {\n ready: boolean;\n indexing: boolean;\n currentFile: number;\n totalFiles: number;\n lastError: string | null;\n /** Circuit-breaker state — `open` means indexing is paused after repeated failures. */\n circuit: CircuitSnapshot;\n} {\n return {\n ready: _ready,\n indexing: _indexing,\n currentFile: _currentFile,\n totalFiles: _totalFiles,\n lastError: _lastError,\n circuit: indexCircuitBreaker.snapshot(),\n };\n}\n\n/**\n * Optional callback fired on every lifecycle transition (started, progress,\n * completed, failed). Plug into the event bus or a TUI dispatcher to surface\n * the indexing state in real time.\n */\ntype IndexStateListener = (state: ReturnType<typeof getIndexState>) => void;\nlet _listeners: IndexStateListener[] = [];\n\nexport function onIndexStateChange(listener: IndexStateListener): () => void {\n _listeners.push(listener);\n return () => {\n _listeners = _listeners.filter((l) => l !== listener);\n };\n}\n\nfunction emitState() {\n const state = getIndexState();\n for (const l of _listeners) l(state);\n}\n\nfunction setIndexProgress(current: number, total: number) {\n _currentFile = current;\n _totalFiles = total;\n emitState();\n}\n\n// ─── Worker management ───────────────────────────────────────────────────────\n\ninterface PendingRpc {\n resolve: (value: unknown) => void;\n reject: (err: unknown) => void;\n onProgress?: ((current: number, total: number) => void) | undefined;\n}\n\nlet worker: Worker | null = null;\nlet workerUnavailable = false;\nlet nextRpcId = 1;\nconst pending = new Map<number, PendingRpc>();\n\n/**\n * Locate the built worker file. The host is bundled into several entry points\n * (`dist/index.js`, `dist/builtin.js`, `dist/codebase-index/index.js`), so the\n * worker is probed at both relative locations. From source (vitest) neither\n * `.js` exists → inline mode, which keeps tests hermetic and mockable.\n */\nfunction resolveWorkerUrl(): URL | null {\n if (process.env['WRONGSTACK_INDEX_INLINE']) return null;\n for (const rel of ['./worker.js', './codebase-index/worker.js']) {\n try {\n const url = new URL(rel, import.meta.url);\n if (url.protocol === 'file:' && fs.existsSync(fileURLToPath(url))) return url;\n } catch {\n /* try the next candidate */\n }\n }\n return null;\n}\n\nfunction failAllPending(err: unknown): void {\n const entries = [...pending.values()];\n pending.clear();\n for (const p of entries) p.reject(err);\n}\n\nfunction ensureWorker(): Worker | null {\n if (worker) return worker;\n if (workerUnavailable) return null;\n const url = resolveWorkerUrl();\n if (!url) {\n workerUnavailable = true;\n return null;\n }\n try {\n const w = new Worker(url, { name: 'wstack-codebase-index' });\n // The worker must never keep the process alive on its own.\n w.unref();\n w.on('message', (msg: WorkerToHost) => {\n if (msg.type === 'progress') {\n pending.get(msg.id)?.onProgress?.(msg.current, msg.total);\n return;\n }\n const entry = pending.get(msg.id);\n if (!entry) return; // already timed out / cancelled\n pending.delete(msg.id);\n if (msg.ok) entry.resolve(msg.result);\n else entry.reject(new Error(msg.error));\n });\n w.on('error', (err) => {\n worker = null;\n failAllPending(err);\n });\n w.on('exit', () => {\n if (worker === w) worker = null;\n failAllPending(new Error('codebase-index worker exited'));\n });\n worker = w;\n return w;\n } catch {\n // Spawn failed (no worker_threads, sandbox, …) — fall back to inline for\n // the rest of the process lifetime.\n workerUnavailable = true;\n return null;\n }\n}\n\n/** Hard-kill a wedged worker. It respawns lazily on the next operation. */\nfunction terminateWorker(reason: unknown): void {\n const w = worker;\n worker = null;\n failAllPending(reason);\n if (w) void w.terminate().catch(() => {});\n}\n\n/**\n * Tear down the index host (worker + pending debounces). Call on process\n * shutdown; safe to call when nothing is running.\n */\nexport function shutdownCodebaseIndexHost(): void {\n cancelPendingReindexes();\n terminateWorker(new Error('codebase-index host shut down'));\n workerUnavailable = false; // a future call may spawn a fresh worker\n}\n\ninterface CallOpts {\n timeoutMs: number;\n signal?: AbortSignal | undefined;\n onProgress?: ((current: number, total: number) => void) | undefined;\n}\n\n/**\n * Run one operation, in the worker when available, inline otherwise. Both\n * paths share the watchdog: the returned promise ALWAYS settles within\n * `timeoutMs`, and a timeout in worker mode terminates the (possibly wedged\n * in synchronous code) worker — something an in-process watchdog can never do.\n */\nfunction callIndexOp<O extends OpName>(\n op: O,\n args: OpShapes[O]['args'],\n opts: CallOpts,\n): Promise<OpShapes[O]['result']> {\n const w = ensureWorker();\n if (!w) return callInline(op, args, opts);\n\n return new Promise<OpShapes[O]['result']>((resolve, reject) => {\n const id = nextRpcId++;\n\n const timer = setTimeout(() => {\n pending.delete(id);\n const err = new IndexTimeoutError(\n `Index ${op} exceeded its ${opts.timeoutMs}ms watchdog timeout`,\n );\n // A wedged worker (synchronous sqlite wait, pathological parse) cannot\n // be cooperatively cancelled — kill it; it respawns on the next call.\n terminateWorker(err);\n reject(err);\n }, opts.timeoutMs);\n timer.unref?.();\n\n const onAbort = () => {\n // Cooperative cancel; the worker aborts the op's signal and responds\n // with an error. The watchdog stays armed as the backstop.\n w.postMessage({ type: 'cancel', id } satisfies HostToWorker);\n };\n if (opts.signal?.aborted) onAbort();\n else opts.signal?.addEventListener('abort', onAbort, { once: true });\n\n const cleanup = () => {\n clearTimeout(timer);\n opts.signal?.removeEventListener('abort', onAbort);\n };\n pending.set(id, {\n resolve: (v) => {\n cleanup();\n resolve(v as OpShapes[O]['result']);\n },\n reject: (e) => {\n cleanup();\n reject(e);\n },\n onProgress: opts.onProgress,\n });\n\n w.postMessage({ type: 'request', id, op, args } satisfies HostToWorker);\n });\n}\n\n/** Inline fallback: same service code, raced against the same watchdog. */\nasync function callInline<O extends OpName>(\n op: O,\n args: OpShapes[O]['args'],\n opts: CallOpts,\n): Promise<OpShapes[O]['result']> {\n const ac = new AbortController();\n const onOuterAbort = () => ac.abort(opts.signal?.reason ?? new Error('Indexing cancelled'));\n if (opts.signal?.aborted) onOuterAbort();\n else opts.signal?.addEventListener('abort', onOuterAbort, { once: true });\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n const watchdog = new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n const err = new IndexTimeoutError(\n `Index ${op} exceeded its ${opts.timeoutMs}ms watchdog timeout`,\n );\n ac.abort(err);\n reject(err);\n }, opts.timeoutMs);\n timer.unref?.();\n });\n\n const job = async (): Promise<OpShapes[O]['result']> => {\n switch (op) {\n case 'index':\n return (await indexService(args as IndexOpArgs, {\n signal: ac.signal,\n onProgress: opts.onProgress,\n })) as OpShapes[O]['result'];\n case 'search':\n return searchService(args as SearchOpArgs) as OpShapes[O]['result'];\n case 'stats':\n return statsService(args as StatsOpArgs) as OpShapes[O]['result'];\n default:\n throw new Error(`unknown index op: ${String(op)}`);\n }\n };\n\n try {\n return await Promise.race([job(), watchdog]);\n } finally {\n if (timer) clearTimeout(timer);\n opts.signal?.removeEventListener('abort', onOuterAbort);\n }\n}\n\n// ─── Process-wide write mutex ────────────────────────────────────────────────\n// A single promise chain. Each enqueued job awaits the previous one's settle\n// (success OR failure) before running, so a thrown job never wedges the chain.\n// Only write runs (index) take the mutex; searches/stats are WAL reads.\nlet chain: Promise<unknown> = Promise.resolve();\n\nfunction withMutex<T>(job: () => Promise<T>): Promise<T> {\n const run = chain.then(job, job);\n // Keep the chain alive regardless of this job's outcome.\n chain = run.then(\n () => undefined,\n () => undefined,\n );\n return run;\n}\n\n/** Build the fail-fast error thrown while the circuit is open. */\nfunction circuitOpenError(): CircuitOpenError {\n const c = indexCircuitBreaker.snapshot();\n return new CircuitOpenError(\n 'Codebase indexing is temporarily paused after repeated failures' +\n (c.lastFailure ? ` (last: ${c.lastFailure})` : '') +\n (c.cooldownRemainingMs > 0\n ? `; auto-retry in ${Math.ceil(c.cooldownRemainingMs / 1000)}s`\n : '') +\n '. Use /codebase-reindex to retry now.',\n );\n}\n\n// ─── Debounce ────────────────────────────────────────────────────────────────\nconst DEFAULT_DEBOUNCE_MS = 400;\nconst debounceTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\nfunction debounceKey(indexDir: string | undefined, file: string): string {\n return `${indexDir ?? ''}|${file}`;\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/** True when the file's extension maps to a language the indexer can parse. */\nexport function isIndexableFile(filePath: string): boolean {\n return detectLang(filePath) !== null;\n}\n\n/**\n * Run a full-project scan and await it. Used at session start and by the manual\n * `/codebase-reindex` command. Incremental by default (unchanged files skipped\n * via mtime, so repeat runs are cheap); pass `force` to clear and rebuild.\n *\n * Sets the global `_ready` flag on completion so downstream tools know the\n * index is usable.\n */\n/** Pattern matching the SQLite UNIQUE constraint failure message. */\nfunction isUniqueConstraintError(err: unknown): boolean {\n if (err instanceof Error) {\n const msg = err.message.toLowerCase();\n return msg.includes('unique constraint') || msg.includes('UNIQUE constraint');\n }\n return false;\n}\n\nexport async function runStartupIndex(opts: {\n projectRoot: string;\n indexDir?: string | undefined;\n force?: boolean | undefined;\n langs?: string[] | undefined;\n signal?: AbortSignal | undefined;\n /** Watchdog timeout for the whole run. Default: 120s. */\n timeoutMs?: number | undefined;\n}): Promise<IndexResult> {\n // Circuit breaker: after repeated failures/timeouts, fail fast instead of\n // queuing yet another run behind a possibly-wedged pipeline.\n if (!indexCircuitBreaker.allowRequest()) throw circuitOpenError();\n\n _indexing = true;\n emitState();\n\n try {\n const result = await withMutex(() => {\n // Reset counters inside the mutex — if runStartupIndex is called twice\n // concurrently, the second caller must not clobber a running index's\n // progress counters.\n _currentFile = 0;\n _totalFiles = 0;\n _lastError = null;\n return callIndexOp(\n 'index',\n {\n projectRoot: opts.projectRoot,\n indexDir: opts.indexDir,\n force: opts.force,\n langs: opts.langs,\n },\n {\n timeoutMs: opts.timeoutMs ?? DEFAULT_FULL_INDEX_TIMEOUT_MS,\n signal: opts.signal,\n onProgress: setIndexProgress,\n },\n );\n });\n _ready = true;\n indexCircuitBreaker.recordSuccess();\n return result;\n } catch (err) {\n _lastError = err instanceof Error ? err.message : String(err);\n\n // Auto-recovery: UNIQUE constraint failures indicate database corruption\n // from a previous interrupted write (e.g., process killed mid-insert).\n // Retry with force=true to wipe and rebuild from source.\n if (isUniqueConstraintError(err) && !opts.force) {\n _lastError = null;\n const rebuildResult = await runStartupIndex({\n ...opts,\n force: true,\n });\n _ready = true;\n return rebuildResult;\n }\n\n _ready = true; // index is \"ready\" in the sense that we won't try again; downstream tools will see lastError\n // Caller-initiated aborts (session teardown, Ctrl+C) are not indexer\n // failures — only genuine errors and watchdog timeouts trip the breaker.\n if (!opts.signal?.aborted) indexCircuitBreaker.recordFailure(err);\n throw err;\n } finally {\n _indexing = false;\n emitState();\n }\n}\n\n/**\n * Debounced, fire-and-forget incremental reindex of specific files. Used by the\n * per-edit toolCall middleware and the external file watcher. Non-indexable\n * paths are dropped. Errors are reported via the optional `onError` callback and\n * never thrown to the caller (background work must not crash a turn).\n */\nexport function enqueueReindex(opts: {\n projectRoot: string;\n files: string[];\n indexDir?: string | undefined;\n debounceMs?: number | undefined;\n /** Watchdog timeout per file. Default: 30s. */\n timeoutMs?: number | undefined;\n onError?: ((err: unknown) => void) | undefined;\n}): void {\n const files = opts.files.filter(isIndexableFile);\n if (files.length === 0) return;\n const ms = opts.debounceMs ?? DEFAULT_DEBOUNCE_MS;\n\n for (const file of files) {\n const key = debounceKey(opts.indexDir, file);\n const existing = debounceTimers.get(key);\n if (existing) clearTimeout(existing);\n const timer = setTimeout(() => {\n debounceTimers.delete(key);\n // Checked at fire time (not enqueue time) so an edit made while the\n // circuit is open is dropped instead of queuing behind a wedged mutex.\n if (!indexCircuitBreaker.allowRequest()) {\n opts.onError?.(circuitOpenError());\n return;\n }\n void withMutex(() =>\n callIndexOp(\n 'index',\n { projectRoot: opts.projectRoot, files: [file], indexDir: opts.indexDir },\n { timeoutMs: opts.timeoutMs ?? DEFAULT_INCREMENTAL_TIMEOUT_MS },\n ),\n ).then(\n () => indexCircuitBreaker.recordSuccess(),\n (err) => {\n indexCircuitBreaker.recordFailure(err);\n opts.onError?.(err);\n },\n );\n }, ms);\n // Don't keep the event loop alive solely for a pending reindex.\n timer.unref?.();\n debounceTimers.set(key, timer);\n }\n}\n\n/** Cancel all pending debounced reindexes. For teardown / tests. */\nexport function cancelPendingReindexes(): void {\n for (const t of debounceTimers.values()) clearTimeout(t);\n debounceTimers.clear();\n}\n\n/**\n * Ranked symbol search against the index. The query runs in the index worker\n * (or inline in fallback mode) — the main thread never opens SQLite. Reads\n * don't take the write mutex (WAL readers don't block the writer) and don't\n * feed the circuit breaker; a wedged read still trips the watchdog, which\n * recycles the worker.\n */\nexport async function searchCodebaseIndex(\n args: SearchOpArgs,\n opts: { timeoutMs?: number | undefined; signal?: AbortSignal | undefined } = {},\n): Promise<SearchOpResult> {\n return callIndexOp('search', args, {\n timeoutMs: opts.timeoutMs ?? DEFAULT_QUERY_TIMEOUT_MS,\n signal: opts.signal,\n });\n}\n\n/** Index health/statistics, fetched off the main thread like searches. */\nexport async function codebaseIndexStats(\n args: StatsOpArgs,\n opts: { timeoutMs?: number | undefined; signal?: AbortSignal | undefined } = {},\n): Promise<IndexStats> {\n return callIndexOp('stats', args, {\n timeoutMs: opts.timeoutMs ?? DEFAULT_QUERY_TIMEOUT_MS,\n signal: opts.signal,\n });\n}\n","\nimport type { Tool } from '@wrongstack/core';\nimport { codebaseIndexDirOverride } from './writer.js';\nimport { isIndexing, runStartupIndex } from './background-indexer.js';\nimport { indexCircuitBreaker } from './circuit-breaker.js';\n\nexport const codebaseIndexTool: Tool<CodebaseIndexInput, CodebaseIndexOutput> = {\n name: 'codebase-index',\n category: 'Project',\n description:\n 'Build or incrementally update the project-wide symbol index. This powers fast codebase search and understanding. ' +\n 'By default it only processes files that have changed since the last indexing run.',\n usageHint:\n 'IMPORTANT FOR LARGE CODEBASES:\\n\\n' +\n '- First run (or after major changes): consider `force: true` for a clean rebuild.\\n' +\n '- Normal usage: call without arguments for fast incremental updates.\\n' +\n '- Use `langs` to restrict to specific languages if you only care about certain parts of the project.\\n' +\n 'This tool is relatively expensive — do not call it on every turn. Use it when the index is stale or before heavy codebase-search sessions.',\n permission: 'confirm',\n mutating: true,\n capabilities: ['fs.write.outside-project'],\n timeoutMs: 120_000,\n inputSchema: {\n type: 'object',\n properties: {\n force: {\n type: 'boolean',\n description: 'Force a full reindex — clears the index first and reindexes all files.',\n },\n langs: {\n type: 'array',\n items: { type: 'string' },\n description: 'Limit reindex to specific languages: ts, tsx, js, jsx, go, py, rs',\n },\n },\n },\n async execute(input, ctx, execOpts) {\n // If the startup index is still running, tell the agent to wait instead of\n // firing a second reindex that would just queue behind the mutex.\n if (isIndexing()) {\n return {\n filesIndexed: 0,\n symbolsIndexed: 0,\n langStats: {},\n durationMs: 0,\n errors: [],\n note: 'A full index is already in progress. Retry codebase-index after it completes (check codebase-stats).',\n };\n }\n\n // Circuit breaker: after repeated failures/timeouts indexing is paused.\n // Report instead of erroring so the agent can carry on without the index.\n const circuit = indexCircuitBreaker.snapshot();\n if (circuit.state === 'open' && circuit.cooldownRemainingMs > 0) {\n return {\n filesIndexed: 0,\n symbolsIndexed: 0,\n langStats: {},\n durationMs: 0,\n errors: [],\n note:\n `Codebase indexing is paused after repeated failures (last: ${circuit.lastFailure ?? 'unknown'}). ` +\n `Auto-retry possible in ${Math.ceil(circuit.cooldownRemainingMs / 1000)}s; the user can run /codebase-reindex to retry immediately.`,\n };\n }\n\n // Route through the background coordinator so the run shares the\n // process-wide mutex, the watchdog timeout, and breaker accounting with\n // the startup scan and live reindexes (a direct runIndexer call here used\n // to race them on the same SQLite file).\n return await runStartupIndex({\n projectRoot: ctx.projectRoot,\n force: input.force ?? false,\n langs: input.langs,\n indexDir: codebaseIndexDirOverride(ctx),\n signal: execOpts?.signal,\n });\n },\n};\n\n// ─── Types for tool I/O ────────────────────────────────────────────────────────\n\ninterface CodebaseIndexInput {\n force?: boolean | undefined;\n langs?: string[] | undefined;\n}\n\ninterface CodebaseIndexOutput {\n filesIndexed: number;\n symbolsIndexed: number;\n langStats: Record<string, number>;\n durationMs: number;\n errors: string[];\n /** Advisory note when the indexer was skipped (e.g. another index in progress). */\n note?: string | undefined;\n}","/**\n * `codebase-search` tool — search the symbol index with BM25 ranking.\n *\n * Usage: codebase-search({\n * query: string, // search terms\n * kind?: string, // class|function|interface|method|const|...\n * lang?: string, // ts|tsx|js|jsx|go|py|rs\n * file?: string, // filter to a specific file path (substring match)\n * limit?: number, // max results (default 20, max 100)\n * })\n *\n * Returns: [{ name, kind, lang, file, line, signature, snippet, score }, ...]\n *\n * The query executes in the index worker via FTS5 (`MATCH` + native `bm25()`)\n * — the main thread never opens SQLite, so a contended or wedged index can\n * slow this tool down but can never freeze the terminal.\n */\n\nimport type { Tool } from '@wrongstack/core';\nimport { getIndexState, searchCodebaseIndex } from './background-indexer.js';\nimport type { SearchResult } from './schema.js';\nimport { codebaseIndexDirOverride } from './writer.js';\nexport const codebaseSearchTool: Tool<CodebaseSearchInput, CodebaseSearchOutput> = {\n name: 'codebase-search',\n category: 'Project',\n description:\n 'Semantic/keyword search over the indexed codebase symbols (functions, classes, interfaces, etc.). Uses BM25 ranking. ' +\n 'Much more powerful and structured than raw `grep` for finding code by name or concept.',\n usageHint:\n 'PREFERRED FOR CODE UNDERSTANDING:\\n\\n' +\n '- Use when you need to find where something is defined or used by name.\\n' +\n '- `kind` filter is very useful (e.g. only functions or only interfaces).\\n' +\n '- Combine with `file` filter to scope to a specific directory or module.\\n' +\n 'This is generally better than `grep` when you are looking for symbols rather than arbitrary text patterns.',\n permission: 'auto',\n mutating: false,\n capabilities: ['fs.read'],\n timeoutMs: 10_000,\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Search query — searches symbol names, signatures, and doc comments',\n },\n kind: {\n type: 'string',\n description:\n 'Filter by symbol kind: class, function, interface, method, const, let, var, property, type, enum',\n },\n lang: {\n type: 'string',\n description: 'Filter by language: ts, tsx, js, jsx',\n },\n lspKind: {\n type: 'integer',\n description:\n 'Filter by LSP SymbolKind number (e.g. 5=Class, 12=Function, 11=Interface, 10=Enum)',\n },\n file: {\n type: 'string',\n description: 'Filter to files matching this path substring',\n },\n limit: {\n type: 'integer',\n description: 'Maximum results to return (default 20, max 100)',\n minimum: 1,\n maximum: 100,\n },\n },\n required: ['query'],\n },\n async execute(input, ctx, execOpts) {\n // Gate: if the index is still building or hasn't been built yet, return a\n // clear status instead of querying partial/inconsistent data.\n const state = getIndexState();\n if (!state.ready) {\n return {\n results: [],\n total: 0,\n query: input.query,\n indexStatus: state.indexing\n ? `Indexing in progress (${state.currentFile}/${state.totalFiles} files) — retry in a moment.`\n : 'Index not yet built. The codebase is being indexed at startup — search will be available shortly.',\n };\n }\n if (state.indexing) {\n return {\n results: [],\n total: 0,\n query: input.query,\n indexStatus: `Index refresh in progress (${state.currentFile}/${state.totalFiles} files). Results may be incomplete.`,\n };\n }\n if (state.lastError) {\n const circuit = state.circuit;\n const retryHint =\n circuit.state === 'open'\n ? `Indexing is paused (circuit open, retry in ${Math.ceil(circuit.cooldownRemainingMs / 1000)}s); the user can run /codebase-reindex to retry now.`\n : 'Try /codebase-reindex.';\n return {\n results: [],\n total: 0,\n query: input.query,\n indexStatus: `Index build failed: ${state.lastError}. ${retryHint}`,\n };\n }\n\n const limit = Math.min(input.limit ?? 20, 100);\n const { results, total } = await searchCodebaseIndex(\n {\n projectRoot: ctx.projectRoot,\n indexDir: codebaseIndexDirOverride(ctx),\n query: input.query,\n kind: input.kind,\n lang: input.lang,\n file: input.file,\n lspKind: input.lspKind,\n limit,\n },\n { signal: execOpts?.signal },\n );\n return { results, total, query: input.query };\n },\n};\n\n// ─── Types ─────────────────────────────────────────────────────────────────────\n\ninterface CodebaseSearchInput {\n query: string;\n kind?: string | undefined;\n lang?: string | undefined;\n file?: string | undefined;\n limit?: number | undefined;\n lspKind?: number | undefined;\n}\n\ninterface CodebaseSearchOutput {\n results: SearchResult[];\n total: number; // total candidates before limit\n query: string;\n /** Non-empty when the index blocked the search (not ready, indexing, failed). */\n indexStatus?: string | undefined;\n}\n","/**\n * `codebase-stats` tool — report index health and statistics.\n *\n * Usage: codebase-stats({})\n *\n * Returns: { totalSymbols, totalFiles, byLang, byKind, lastIndexed, sizeBytes, version }\n */\n\nimport type { Tool } from '@wrongstack/core';\nimport { codebaseIndexStats, getIndexState } from './background-indexer.js';\nimport { SCHEMA_VERSION } from './schema.js';\nimport { codebaseIndexDirOverride } from './writer.js';\n\nexport const codebaseStatsTool: Tool<Record<string, never>, CodebaseStatsOutput> = {\n name: 'codebase-stats',\n category: 'Project',\n description:\n 'Return health and statistics about the current symbol index (total symbols, files, language/kind breakdown, size, last update). Useful to decide whether to re-index.',\n usageHint:\n 'CALL BEFORE HEAVY CODEBASE-SEARCH WORK:\\n\\n' +\n '- Use to see if the index is up-to-date or needs a refresh.\\n' +\n '- No arguments required.\\n' +\n '- Helps avoid wasting tokens on searches against a stale index.\\n' +\n 'Lightweight and safe to call frequently.',\n permission: 'auto',\n mutating: false,\n capabilities: ['fs.read'],\n timeoutMs: 5_000,\n inputSchema: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n async execute(_input, ctx, execOpts) {\n const idxState = getIndexState();\n if (!idxState.ready) {\n return {\n totalSymbols: 0,\n totalFiles: 0,\n byLang: {},\n byKind: {},\n lastIndexed: null,\n sizeBytes: 0,\n indexPath: '',\n version: SCHEMA_VERSION,\n indexStatus: idxState.indexing\n ? `Indexing in progress (${idxState.currentFile}/${idxState.totalFiles} files).`\n : 'Index not yet built.',\n };\n }\n\n // Fetched via the index host (worker thread when available) — the main\n // thread never opens SQLite here.\n const stats = await codebaseIndexStats(\n { projectRoot: ctx.projectRoot, indexDir: codebaseIndexDirOverride(ctx) },\n { signal: execOpts?.signal },\n );\n\n if (idxState.indexing) {\n return {\n ...stats,\n indexStatus: `Index refresh in progress (${idxState.currentFile}/${idxState.totalFiles} files). Stats may be incomplete.`,\n };\n }\n\n const circuit = idxState.circuit;\n return {\n totalSymbols: stats.totalSymbols,\n totalFiles: stats.totalFiles,\n byLang: stats.byLang,\n byKind: stats.byKind,\n lastIndexed: stats.lastIndexed,\n sizeBytes: stats.sizeBytes,\n indexPath: stats.indexPath,\n version: stats.version,\n ...(circuit.state === 'open'\n ? {\n indexStatus:\n `Indexing is paused after repeated failures (last: ${circuit.lastFailure ?? 'unknown'}); ` +\n `auto-retry in ${Math.ceil(circuit.cooldownRemainingMs / 1000)}s, or run /codebase-reindex. Stats reflect the last successful build.`,\n }\n : {}),\n };\n },\n};\n\ninterface CodebaseStatsOutput {\n totalSymbols: number;\n totalFiles: number;\n byLang: Record<string, number>;\n byKind: Record<string, number>;\n lastIndexed: number | null;\n sizeBytes: number;\n indexPath: string;\n version: number;\n /** Non-empty when the index is not ready or is still building. */\n indexStatus?: string | undefined;\n}\n"]}