codesesh 1.0.7 → 1.0.8

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 (63) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-EYZ73CYP.js → chunk-AGUAXTKC.js} +2 -2
  3. package/dist/{chunk-VVCSQU5B.js → chunk-DHQPM5FF.js} +6 -6
  4. package/dist/chunk-DHQPM5FF.js.map +1 -0
  5. package/dist/{chunk-YEQTRALH.js → chunk-KVTLNX7V.js} +3 -3
  6. package/dist/chunk-KVTLNX7V.js.map +1 -0
  7. package/dist/{chunk-WIWK7BXS.js → chunk-L4G3LE7I.js} +25 -26
  8. package/dist/chunk-L4G3LE7I.js.map +1 -0
  9. package/dist/{chunk-SII3M66U.js → chunk-RBCCNCDO.js} +8 -8
  10. package/dist/chunk-RBCCNCDO.js.map +1 -0
  11. package/dist/{chunk-DE6UJMOY.js → chunk-V3HKVTIO.js} +3 -2
  12. package/dist/chunk-V3HKVTIO.js.map +1 -0
  13. package/dist/{chunk-QHWSZFRM.js → chunk-YLXHGL4S.js} +4 -4
  14. package/dist/chunk-YLXHGL4S.js.map +1 -0
  15. package/dist/{discovery-4WAEYSTR.js → discovery-KEZQU6RL.js} +5 -5
  16. package/dist/index.js +10 -10
  17. package/dist/index.js.map +1 -1
  18. package/dist/project-identity-worker.js +4 -4
  19. package/dist/scan-refresh-worker.js +6 -6
  20. package/dist/search-index-worker.js +6 -6
  21. package/dist/session-detail-worker.js +6 -6
  22. package/dist/smart-tag-worker.js +3 -3
  23. package/dist/web/assets/CustomTimeWindowDialog-z5xtqkBF.js +1 -0
  24. package/dist/web/assets/DetailLanding-CpV0jLmT.js +1 -0
  25. package/dist/web/assets/DialogTitle-B8zPwJB8.js +1 -0
  26. package/dist/web/assets/InteractiveReceipt-Bsj37HtN.js +1 -0
  27. package/dist/web/assets/OverviewScreen-B9qZqEQA.js +1 -0
  28. package/dist/web/assets/PrismHighlighter-DWS6Nx_X.js +6 -0
  29. package/dist/web/assets/Projects-oY3KCgS4.js +1 -0
  30. package/dist/web/assets/SearchResultsPanel-BAManMmt.js +1 -0
  31. package/dist/web/assets/SessionDetail-KSgkmLV7.js +53 -0
  32. package/dist/web/assets/SmartTagChips-BMP9pPRw.js +1 -0
  33. package/dist/web/assets/{api-ToidoNW6.js → api-CtZGdxlN.js} +1 -1
  34. package/dist/web/assets/index-BSLHxV0w.css +1 -0
  35. package/dist/web/assets/index-DNw59Qsn.js +1423 -0
  36. package/dist/web/assets/jsx-runtime-D3jfb0Ew.js +1 -0
  37. package/dist/web/assets/panel-DcOuALYX.js +1 -0
  38. package/dist/web/assets/session-indexes-DKukxoe1.js +4 -0
  39. package/dist/web/assets/translate-CLoII3EO.js +2 -0
  40. package/dist/web/assets/utils-Dk_44zMo.js +1 -0
  41. package/dist/web/index.html +9 -8
  42. package/package.json +2 -2
  43. package/dist/chunk-DE6UJMOY.js.map +0 -1
  44. package/dist/chunk-QHWSZFRM.js.map +0 -1
  45. package/dist/chunk-SII3M66U.js.map +0 -1
  46. package/dist/chunk-VVCSQU5B.js.map +0 -1
  47. package/dist/chunk-WIWK7BXS.js.map +0 -1
  48. package/dist/chunk-YEQTRALH.js.map +0 -1
  49. package/dist/web/assets/CustomTimeWindowDialog-CVURkiVO.js +0 -1
  50. package/dist/web/assets/InteractiveReceipt-DGC-xV7U.js +0 -1
  51. package/dist/web/assets/OverviewScreen-DoXrZ5qp.js +0 -1
  52. package/dist/web/assets/PrismHighlighter-02695Lmx.js +0 -6
  53. package/dist/web/assets/Projects-DZiYh6hp.js +0 -1
  54. package/dist/web/assets/SearchResultsPanel-CAQe8Di0.js +0 -1
  55. package/dist/web/assets/SessionDetail-Da8EBygt.js +0 -53
  56. package/dist/web/assets/index-Bl8pbRFj.js +0 -1423
  57. package/dist/web/assets/index-CRI1m3xN.css +0 -1
  58. package/dist/web/assets/jsx-runtime-B-hcVAMW.js +0 -1
  59. package/dist/web/assets/session-indexes-D5gps7K8.js +0 -4
  60. package/dist/web/assets/translate-BDFu3ZiK.js +0 -2
  61. package/dist/web/assets/utils-BIZi2up3.js +0 -1
  62. /package/dist/{chunk-EYZ73CYP.js.map → chunk-AGUAXTKC.js.map} +0 -0
  63. /package/dist/{discovery-4WAEYSTR.js.map → discovery-KEZQU6RL.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../core/src/contract/session.ts","../../core/src/utils/smart-tags.ts","../../core/src/utils/worker-log.ts","../../core/src/contract/session-reference.ts","../../core/src/contract/file-activity.ts","../../core/src/contract/events.ts","../../core/src/contract/calendar-day.ts","../../core/src/contract/project-identity.ts","../../core/src/contract/session-index.ts","../../core/src/contract/session-tree.ts","../../core/src/contract/api.ts","../../core/src/utils/file-activity.ts","../../core/src/utils/diagnostics.ts","../../core/src/utils/private-storage.ts","../../core/src/pricing/fetcher.ts","../../core/src/pricing/model-pricing.ts","../../core/src/pricing/models-dev.ts","../../core/src/pricing/data/snapshot.json","../../core/src/pricing/cost.ts","../../core/src/pricing/data/aliases.json","../../core/src/pricing/resolver.ts","../../core/src/utils/perf.ts","../../core/src/utils/jsonl.ts","../../core/src/utils/parse-cleanup.ts","../../core/src/utils/title-fallback.ts","../../core/src/utils/cost.ts","../../core/src/utils/narrow.ts","../../core/src/utils/session-normalization.ts","../../core/src/utils/sqlite.ts","../../core/src/contract/message-part.ts","../../core/src/contract/agent-catalog.ts"],"sourcesContent":["import type { ProjectIdentityKind } from \"./project-identity.js\";\nimport type { SessionIdentity, SessionReference } from \"./session-reference.js\";\n\nexport interface SessionStats {\n message_count: number;\n total_input_tokens: number;\n total_output_tokens: number;\n total_cost: number;\n cost_source?: CostSource;\n total_tokens?: number;\n total_cache_read_tokens?: number;\n total_cache_create_tokens?: number;\n}\n\nexport type CostSource = \"recorded\" | \"estimated\";\n\nexport const SMART_TAGS = [\n \"bugfix\",\n \"refactoring\",\n \"feature-dev\",\n \"testing\",\n \"docs\",\n \"git-ops\",\n \"build-deploy\",\n \"exploration\",\n \"planning\",\n] as const;\n\nexport type SmartTag = (typeof SMART_TAGS)[number];\n\nexport function isSmartTag(value: string): value is SmartTag {\n return SMART_TAGS.some((tag) => tag === value);\n}\n\nexport type FileActivityKind = \"read\" | \"edit\" | \"write\" | \"delete\";\n\nexport interface SessionFileActivity {\n reference: SessionReference;\n projectIdentityKey: string;\n path: string;\n kind: FileActivityKind;\n count: number;\n latestTime: number;\n}\n\nexport interface SessionFileActivityOccurrence {\n path: string;\n kind: FileActivityKind;\n time: number;\n tool_label: string;\n message_index: number;\n tool_index: number;\n}\n\nexport type { ProjectIdentityKind, ProjectIdentityRef } from \"./project-identity.js\";\n\nexport interface ProjectIdentity {\n kind: ProjectIdentityKind;\n key: string;\n displayName: string;\n}\n\nexport interface ProjectGroup {\n identityKind: ProjectIdentityKind;\n identityKey: string;\n displayName: string;\n sources: string[];\n sessionCount: number;\n lastActivity: number | null;\n}\n\nexport interface MessageTokens {\n input?: number;\n output?: number;\n reasoning?: number;\n cache_read?: number;\n cache_create?: number;\n}\n\nexport type ToolPartStatus = \"running\" | \"completed\" | \"error\";\n\nexport interface ToolPartState {\n status: ToolPartStatus;\n input?: unknown;\n output?: unknown;\n error?: unknown;\n metadata?: unknown;\n}\n\ninterface TimedMessagePart {\n time_created?: number;\n}\n\nexport interface TextPart extends TimedMessagePart {\n type: \"text\";\n text: string;\n}\n\nexport interface ReasoningPart extends TimedMessagePart {\n type: \"reasoning\";\n text: string;\n}\n\nexport interface PlanPart extends TimedMessagePart {\n type: \"plan\";\n text: string;\n approval_status: \"success\" | \"fail\";\n}\n\ninterface ImagePartBase extends TimedMessagePart {\n type: \"image\";\n mime_type?: string;\n}\n\nexport interface ImageDataPart extends ImagePartBase {\n data: string;\n mime_type: string;\n url?: string;\n}\n\nexport interface ImageUrlPart extends ImagePartBase {\n url: string;\n data?: string;\n}\n\nexport type ImagePart = ImageDataPart | ImageUrlPart;\n\nexport interface ToolPart extends TimedMessagePart {\n type: \"tool\";\n tool: string;\n title?: string;\n callID?: string;\n state: ToolPartState;\n}\n\nexport type MessagePart = TextPart | ToolPart | ReasoningPart | PlanPart | ImagePart;\n\nexport interface Message {\n id: string;\n role: \"user\" | \"assistant\" | \"tool\";\n agent?: string | null;\n time_created: number;\n time_completed?: number | null;\n mode?: string | null;\n model?: string | null;\n provider?: string | null;\n tokens?: MessageTokens;\n cost?: number;\n cost_source?: CostSource;\n parts: MessagePart[];\n subagent_id?: string;\n nickname?: string;\n /** Source-generated content displayed as a user message, rather than human input. */\n automated?: boolean;\n}\n\n/** Lightweight metadata for session listing */\nexport interface SessionHead extends SessionIdentity {\n title: string;\n display_title?: string;\n directory: string;\n parent_reference?: SessionReference;\n project_identity?: ProjectIdentity;\n project_identity_resolver_revision?: string;\n project_identity_input_signature?: string;\n time_created: number;\n time_updated?: number;\n stats: SessionStats;\n model_usage?: Record<string, number>;\n smart_tags?: SmartTag[];\n smart_tags_source_updated_at?: number;\n smart_tags_classifier_revision?: string;\n}\n\nexport interface IdentifiedSessionHead extends SessionHead {\n project_identity: ProjectIdentity;\n}\n\ntype InternalSessionHeadField =\n | \"model_usage\"\n | \"project_identity_resolver_revision\"\n | \"project_identity_input_signature\"\n | \"smart_tags_source_updated_at\"\n | \"smart_tags_classifier_revision\";\n\nexport type PublicSessionHead = Omit<SessionHead, InternalSessionHeadField>;\n\nexport type PublicIdentifiedSessionHead = Omit<IdentifiedSessionHead, InternalSessionHeadField>;\n\nexport interface SessionListPage {\n sessions: PublicIdentifiedSessionHead[];\n nextCursor?: string;\n}\n\nexport interface ReferencedSessionHead {\n reference: SessionReference;\n session: SessionHead;\n}\n\nexport interface PublicReferencedSessionHead {\n reference: SessionReference;\n session: PublicSessionHead;\n}\n\n/** Complete normalized content for replaying a Session */\nexport interface SessionDetail extends SessionIdentity {\n title: string;\n display_title?: string;\n directory: string;\n parent_reference?: SessionReference;\n project_identity?: ProjectIdentity;\n project_identity_resolver_revision?: string;\n project_identity_input_signature?: string;\n version?: string | null;\n detail_freshness?: \"fresh\" | \"stale\";\n time_created: number;\n time_updated?: number;\n summary_files?: unknown;\n stats: SessionStats;\n messages: Message[];\n message_cursor?: string;\n message_update?: \"reset\" | \"append\";\n smart_tags?: SmartTag[];\n smart_tags_source_updated_at?: number;\n smart_tags_classifier_revision?: string;\n file_activity?: SessionFileActivity[];\n}\n\nexport interface IdentifiedSessionDetail extends SessionDetail {\n project_identity: ProjectIdentity;\n}\n\nexport function assertIdentifiedSessionHead(\n session: SessionHead,\n): asserts session is IdentifiedSessionHead {\n if (session.project_identity) return;\n throw new Error(\n `Session ${session.reference.agentName}/${session.reference.sessionId} is missing project_identity`,\n );\n}\n\nexport function toPublicSessionHead<T extends SessionHead>(\n session: T,\n): Omit<T, InternalSessionHeadField> {\n const {\n model_usage: _modelUsage,\n project_identity_resolver_revision: _resolverRevision,\n project_identity_input_signature: _identityInputSignature,\n smart_tags_source_updated_at: _smartTagsSourceUpdatedAt,\n smart_tags_classifier_revision: _classifierRevision,\n ...publicSession\n } = session;\n return publicSession;\n}\n\nexport function toPublicReferencedSessionHead<T extends ReferencedSessionHead>(\n item: T,\n): Omit<T, \"session\"> & { session: PublicSessionHead } {\n return { ...item, session: toPublicSessionHead(item.session) };\n}\n","import type { MessagePart, SessionDetail, SmartTag, ToolPart } from \"../types/index.js\";\nimport { SMART_TAGS } from \"../contract/index.js\";\n\nexport const SMART_TAG_CLASSIFIER_REVISION = \"smart-tags-v1\";\n\nconst USER_RULES: Array<[SmartTag, RegExp]> = [\n [\"bugfix\", /\\b(fix|bug|error|crash|exception|fail(?:ed|ure)?)\\b|修复|错误|报错|崩溃|异常/i],\n [\"refactoring\", /\\b(refactor|rename|simplify|clean up|cleanup)\\b|重构|重命名|简化|清理/i],\n [\"feature-dev\", /\\b(add|create|implement|new|support|build)\\b|新增|创建|实现|增加|开发|支持/i],\n [\"docs\", /\\b(document|documentation|readme|docs?)\\b|文档|说明/i],\n];\n\nconst TESTING_COMMAND_RE = /\\b(pytest|vitest|jest|mocha|pnpm\\s+test|npm\\s+test|yarn\\s+test)\\b/i;\nconst GIT_COMMAND_RE = /\\bgit\\s+(push|commit|merge|branch|checkout|switch|rebase|tag)\\b/i;\nconst BUILD_DEPLOY_COMMAND_RE =\n /\\b((npm|pnpm|yarn|bun)\\s+(run\\s+)?build|docker|pm2|deploy|vercel|netlify)\\b/i;\nconst DOC_PATH_RE = /\\.(md|mdx|txt|rst|adoc)$/i;\nconst READ_TOOL_RE = /\\b(read|grep|glob|websearch|web_search|search|find|rg)\\b/i;\nconst EDIT_TOOL_RE = /\\b(edit|write|apply_patch|patch|multiedit|notebookedit)\\b/i;\nconst PLAN_TOOL_RE = /\\b(enterplanmode|taskcreate|update_plan|plan)\\b/i;\n\nexport function getSmartTagSourceTimestamp(\n session: Pick<SessionDetail, \"time_created\" | \"time_updated\">,\n): number {\n return session.time_updated ?? session.time_created;\n}\n\nexport function classifySessionTags(session: Pick<SessionDetail, \"messages\">): SmartTag[] {\n const tags = new Set<SmartTag>();\n let readToolCount = 0;\n let editToolCount = 0;\n\n for (const message of session.messages) {\n if (message.role === \"user\") {\n const text = message.parts.map(partText).join(\"\\n\");\n for (const [tag, pattern] of USER_RULES) {\n if (pattern.test(text)) tags.add(tag);\n }\n }\n\n for (const part of message.parts) {\n if (part.type === \"plan\") tags.add(\"planning\");\n if (part.type !== \"tool\") continue;\n\n const toolName = `${part.tool} ${part.title ?? \"\"}`;\n const toolPayload = stringifyToolPayload(part);\n\n if (PLAN_TOOL_RE.test(toolName)) tags.add(\"planning\");\n if (READ_TOOL_RE.test(toolName)) readToolCount += 1;\n if (EDIT_TOOL_RE.test(toolName)) editToolCount += 1;\n\n if (TESTING_COMMAND_RE.test(toolPayload)) tags.add(\"testing\");\n if (GIT_COMMAND_RE.test(toolPayload)) tags.add(\"git-ops\");\n if (BUILD_DEPLOY_COMMAND_RE.test(toolPayload)) tags.add(\"build-deploy\");\n if (hasEditedDocPath(part.state.input)) {\n tags.add(\"docs\");\n }\n }\n }\n\n if (readToolCount >= 3 && editToolCount <= 1) {\n tags.add(\"exploration\");\n }\n\n return SMART_TAGS.filter((tag) => tags.has(tag));\n}\n\nfunction partText(part: MessagePart): string {\n return part.type === \"text\" || part.type === \"reasoning\" || part.type === \"plan\" ? part.text : \"\";\n}\n\nfunction stringifyToolPayload(part: ToolPart): string {\n return [part.tool, part.title, valueToText(part.state)].filter(Boolean).join(\"\\n\");\n}\n\nfunction valueToText(value: unknown): string {\n if (value == null) return \"\";\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value);\n try {\n return JSON.stringify(value);\n } catch {\n return \"\";\n }\n}\n\nfunction hasEditedDocPath(value: unknown): boolean {\n if (value == null) return false;\n if (typeof value === \"string\") return DOC_PATH_RE.test(value);\n if (Array.isArray(value)) return value.some(hasEditedDocPath);\n if (typeof value !== \"object\") return false;\n\n const record = value as Record<string, unknown>;\n for (const key of [\"path\", \"file\", \"filePath\", \"file_path\", \"targetPath\", \"target_path\"]) {\n const raw = record[key];\n if (typeof raw === \"string\" && DOC_PATH_RE.test(raw)) return true;\n }\n\n return Object.values(record).some(hasEditedDocPath);\n}\n","export const WORKER_LOG_MESSAGE_TYPE = \"codesesh.worker-log\";\n\nexport type WorkerLogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport interface WorkerLogContext {\n request_id?: string;\n operation_id?: string;\n publication_id?: string;\n}\n\nexport interface WorkerLogMessage {\n type: typeof WORKER_LOG_MESSAGE_TYPE;\n ts: string;\n level: WorkerLogLevel;\n event: string;\n pid: number;\n threadId: number;\n context?: WorkerLogContext;\n data: Record<string, unknown>;\n}\n\nconst WORKER_LOG_CONTEXT_KEYS = new Set([\"request_id\", \"operation_id\", \"publication_id\"]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isLogContext(value: unknown): value is WorkerLogContext {\n if (!isRecord(value)) return false;\n return Object.entries(value).every(\n ([key, item]) =>\n WORKER_LOG_CONTEXT_KEYS.has(key) && typeof item === \"string\" && item.length <= 160,\n );\n}\n\nexport function isWorkerLogMessage(value: unknown): value is WorkerLogMessage {\n if (!isRecord(value) || value.type !== WORKER_LOG_MESSAGE_TYPE) return false;\n return (\n typeof value.ts === \"string\" &&\n value.ts.length > 0 &&\n (value.level === \"debug\" ||\n value.level === \"info\" ||\n value.level === \"warn\" ||\n value.level === \"error\") &&\n typeof value.event === \"string\" &&\n value.event.length > 0 &&\n Number.isSafeInteger(value.pid) &&\n Number(value.pid) > 0 &&\n Number.isSafeInteger(value.threadId) &&\n Number(value.threadId) >= 0 &&\n (value.context === undefined || isLogContext(value.context)) &&\n isRecord(value.data)\n );\n}\n","export interface SessionReference {\n readonly agentName: string;\n readonly sessionId: string;\n}\n\nexport interface SessionIdentity {\n readonly reference: SessionReference;\n}\n\nexport const UNKNOWN_AGENT_NAME = \"unknown\";\n\nexport function normalizeSessionReference(reference: SessionReference): SessionReference {\n return {\n agentName: reference.agentName.trim().toLowerCase(),\n sessionId: reference.sessionId,\n };\n}\n\nexport function parseSessionReference(value: string): SessionReference | null {\n const separatorIndex = value.indexOf(\"/\");\n if (separatorIndex <= 0 || separatorIndex === value.length - 1) return null;\n\n const agentName = value.slice(0, separatorIndex).trim().toLowerCase();\n if (!agentName) return null;\n return {\n agentName,\n sessionId: value.slice(separatorIndex + 1),\n };\n}\n\nexport function formatSessionReference(reference: SessionReference): string {\n const normalized = normalizeSessionReference(reference);\n return `${normalized.agentName}/${normalized.sessionId}`;\n}\n\n/** Canonical key for maps and sets keyed by session identity. */\nexport function getSessionReferenceKey(reference: SessionReference): string {\n return formatSessionReference(reference);\n}\n\nexport function createSessionIdentity(reference: SessionReference): SessionIdentity {\n return {\n reference: normalizeSessionReference(reference),\n };\n}\n\nexport function assertSessionIdentity(identity: SessionIdentity, agentName?: string): void {\n const normalized = normalizeSessionReference(identity.reference);\n const expectedAgentName = agentName?.trim().toLowerCase();\n if (identity.reference.agentName !== normalized.agentName) {\n throw new Error(\"Session reference is not normalized\");\n }\n if (expectedAgentName != null && normalized.agentName !== expectedAgentName) {\n throw new Error(\n `Session reference agent \"${normalized.agentName}\" does not match \"${expectedAgentName}\"`,\n );\n }\n}\n\nexport function getSessionAgentKey(session: Pick<SessionIdentity, \"reference\">): string {\n return normalizeSessionReference(session.reference).agentName;\n}\n\n/**\n * Canonical URL path for an agent. Callers must never concatenate the name\n * themselves: both routers match on the raw path, so an unencoded segment can\n * split, truncate, or turn into a query or fragment.\n */\nexport function agentRoutePath(agentName: string): string {\n return `/${encodeURIComponent(agentName.trim().toLowerCase())}`;\n}\n\n/**\n * Canonical URL path for a session reference, shared by web routes and HTTP\n * endpoints. Each segment is encoded independently, so an opaque id keeps `/`,\n * `?`, `#` and `%` intact through React Router and Hono alike.\n */\nexport function sessionRoutePath(reference: SessionReference): string {\n const normalized = normalizeSessionReference(reference);\n return `${agentRoutePath(normalized.agentName)}/${encodeURIComponent(normalized.sessionId)}`;\n}\n\n/** Same as {@link sessionRoutePath}, for callers holding a session head. */\nexport function getSessionRoutePath(session: Pick<SessionIdentity, \"reference\">): string {\n return sessionRoutePath(session.reference);\n}\n","import type {\n FileActivityKind,\n PublicReferencedSessionHead,\n SessionFileActivity,\n ToolPart,\n} from \"./session.js\";\n\nexport type FileActivityResult = SessionFileActivity & PublicReferencedSessionHead;\n\nexport interface FileToolOperation {\n kind: FileActivityKind;\n path: string;\n}\n\nconst FILE_TOOL_KINDS: Readonly<Record<string, FileActivityKind>> = {\n read: \"read\",\n read_file: \"read\",\n read_file_v2: \"read\",\n read_text_file: \"read\",\n readfile: \"read\",\n view_image: \"read\",\n apply_patch: \"edit\",\n edit: \"edit\",\n edit_file: \"edit\",\n edit_file_v2: \"edit\",\n editfile: \"edit\",\n multiedit: \"edit\",\n notebookedit: \"edit\",\n patch: \"edit\",\n search_replace: \"edit\",\n str_replace: \"edit\",\n create_file: \"write\",\n write: \"write\",\n write_file: \"write\",\n writefile: \"write\",\n delete: \"delete\",\n delete_file: \"delete\",\n};\n\nconst PATCH_KINDS: Readonly<Record<string, FileActivityKind>> = {\n edit_file: \"edit\",\n update_file: \"edit\",\n write_file: \"write\",\n delete_file: \"delete\",\n move_file: \"edit\",\n};\n\nfunction toRecord(value: unknown) {\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return {};\n}\n\nfunction looksLikeFilePath(value: string) {\n const text = value.trim();\n if (!text || text.length > 300 || text.includes(\"\\n\")) return false;\n if (/^[a-z]+:\\/\\//i.test(text) || /[<>{}]/.test(text)) return false;\n if (text.startsWith(\"/\") || text.startsWith(\"./\") || text.startsWith(\"../\")) return true;\n if (text.startsWith(\"~/\") || text.includes(\"/\") || text.includes(\"\\\\\")) return true;\n return /^[A-Za-z0-9_.@-]+\\.[A-Za-z0-9_-]+$/.test(text);\n}\n\nfunction isPathKey(key: string) {\n const normalized = key.trim().toLowerCase();\n if (!normalized) return false;\n if (\n normalized.includes(\"command\") ||\n normalized.includes(\"content\") ||\n normalized.includes(\"text\") ||\n normalized.includes(\"prompt\") ||\n normalized.includes(\"url\") ||\n normalized.includes(\"body\") ||\n normalized.includes(\"title\") ||\n normalized.includes(\"description\") ||\n normalized === \"cwd\" ||\n normalized === \"workdir\" ||\n normalized === \"directory\"\n ) {\n return false;\n }\n return normalized.includes(\"file\") || normalized.includes(\"path\");\n}\n\nfunction collectPaths(value: unknown, key: string, paths: Set<string>, depth = 0): void {\n if (value == null || depth > 4) return;\n if (typeof value === \"string\") {\n if (isPathKey(key) && looksLikeFilePath(value)) paths.add(value.trim());\n return;\n }\n if (Array.isArray(value)) {\n for (const item of value) collectPaths(item, key, paths, depth + 1);\n return;\n }\n if (typeof value === \"object\") {\n for (const [nestedKey, nested] of Object.entries(value as Record<string, unknown>)) {\n collectPaths(nested, nestedKey, paths, depth + 1);\n }\n }\n}\n\nfunction extractPatchOperations(input: unknown): FileToolOperation[] {\n const record = toRecord(input);\n const content = Array.isArray(input)\n ? input\n : Array.isArray(record.content)\n ? record.content\n : [];\n\n return content.flatMap((entry) => {\n const patch = toRecord(entry);\n const kind = typeof patch.type === \"string\" ? PATCH_KINDS[patch.type] : undefined;\n const pathValue = patch.path || patch.old_path;\n const path = typeof pathValue === \"string\" ? pathValue.trim() : \"\";\n return kind && path ? [{ kind, path }] : [];\n });\n}\n\nexport function classifyFileTool(part: Pick<ToolPart, \"tool\">): FileActivityKind | null {\n return FILE_TOOL_KINDS[part.tool.trim().toLowerCase()] ?? null;\n}\n\nexport function extractFileToolOperations(\n part: Pick<ToolPart, \"tool\" | \"state\">,\n): FileToolOperation[] {\n const patchOperations = extractPatchOperations(part.state.input);\n if (patchOperations.length > 0) return patchOperations;\n\n const kind = classifyFileTool(part);\n if (!kind) return [];\n\n const paths = new Set<string>();\n collectPaths(part.state.input, \"\", paths);\n return [...paths].map((path) => ({ kind, path }));\n}\n","import type { PublicReferencedSessionHead } from \"./session.js\";\nimport type { SessionReference } from \"./session-reference.js\";\n\nexport interface SessionsUpdatedEvent {\n type: \"sessions-updated\";\n changedAgents: string[];\n /** Exact new-session subset for consumers that project the global event into a local view. */\n newSessionRefs: SessionReference[];\n totalSessions: number;\n timestamp: number;\n changedSessionHeads: PublicReferencedSessionHead[];\n /** Unchanged hierarchy context; it must not count as an update or invalidate session detail. */\n projectionRelatedSessionHeads?: PublicReferencedSessionHead[];\n /** Canonical global order for affected activity-time ties. */\n projectionSessionOrder?: SessionReference[];\n removedSessionRefs: SessionReference[];\n}\n\nexport function mergeSessionsUpdatedEvents(\n previous: SessionsUpdatedEvent,\n next: SessionsUpdatedEvent,\n): SessionsUpdatedEvent {\n const changedSessionHeads = new Map<string, PublicReferencedSessionHead>();\n const projectionRelatedSessionHeads = new Map<string, PublicReferencedSessionHead>();\n const projectionSessionOrder = new Map<string, SessionReference>();\n const newSessionRefs = new Map<string, SessionReference>();\n const removedSessionRefs = new Map<string, SessionReference>();\n const sessionKey = (agentName: string, sessionId: string) => `${agentName}\\0${sessionId}`;\n const addChanged = (item: PublicReferencedSessionHead) => {\n const key = sessionKey(item.reference.agentName, item.reference.sessionId);\n removedSessionRefs.delete(key);\n projectionRelatedSessionHeads.delete(key);\n changedSessionHeads.set(key, item);\n };\n const addProjectionRelated = (item: PublicReferencedSessionHead) => {\n const key = sessionKey(item.reference.agentName, item.reference.sessionId);\n if (changedSessionHeads.has(key) || removedSessionRefs.has(key)) return;\n projectionRelatedSessionHeads.set(key, item);\n };\n const addNew = (item: SessionReference) => {\n const key = sessionKey(item.agentName, item.sessionId);\n removedSessionRefs.delete(key);\n newSessionRefs.set(key, item);\n };\n const addProjectionOrder = (item: SessionReference) => {\n const key = sessionKey(item.agentName, item.sessionId);\n projectionSessionOrder.delete(key);\n projectionSessionOrder.set(key, item);\n };\n const addRemoved = (item: SessionReference) => {\n const key = sessionKey(item.agentName, item.sessionId);\n changedSessionHeads.delete(key);\n projectionRelatedSessionHeads.delete(key);\n projectionSessionOrder.delete(key);\n newSessionRefs.delete(key);\n removedSessionRefs.set(key, item);\n };\n\n for (const item of previous.newSessionRefs) addNew(item);\n for (const item of previous.projectionRelatedSessionHeads ?? []) addProjectionRelated(item);\n for (const item of previous.projectionSessionOrder ?? []) addProjectionOrder(item);\n for (const item of previous.changedSessionHeads) addChanged(item);\n for (const item of previous.removedSessionRefs) addRemoved(item);\n for (const item of next.newSessionRefs) addNew(item);\n for (const item of next.projectionRelatedSessionHeads ?? []) addProjectionRelated(item);\n for (const item of next.projectionSessionOrder ?? []) addProjectionOrder(item);\n for (const item of next.changedSessionHeads) addChanged(item);\n for (const item of next.removedSessionRefs) addRemoved(item);\n\n return {\n type: \"sessions-updated\",\n changedAgents: Array.from(new Set([...previous.changedAgents, ...next.changedAgents])),\n newSessionRefs: [...newSessionRefs.values()],\n totalSessions: next.totalSessions,\n timestamp: next.timestamp,\n changedSessionHeads: [...changedSessionHeads.values()],\n projectionRelatedSessionHeads: [...projectionRelatedSessionHeads.values()],\n projectionSessionOrder: [...projectionSessionOrder.values()],\n removedSessionRefs: [...removedSessionRefs.values()],\n };\n}\n\nexport interface AgentScanStatus {\n agentName: string;\n status:\n | \"pending\"\n | \"scanning\"\n | \"finalizing\"\n | \"publish-queued\"\n | \"publishing\"\n | \"indexing\"\n | \"complete\"\n | \"failed\";\n completeness?: ScanCompletion[\"completeness\"];\n sourceFailureCount?: number;\n sourceFailureSummary?: string;\n error?: string;\n total?: number;\n processed?: number;\n sessions?: number;\n startedAt?: number;\n updatedAt: number;\n completedAt?: number;\n}\n\n/** Snapshot completeness is independent from whether the operation completed. */\nexport interface ScanCompletion {\n completeness: \"complete\" | \"partial\";\n sourceFailureCount?: number;\n sourceFailureSummary?: string;\n}\n\n/**\n * Full-history reconciliation runs independently of the main scan phase:\n * startup only syncs the display window, so a low-priority background pass\n * (capped at one agent at a time) periodically re-checks the rest of history.\n */\nexport interface BackfillProgress {\n phase?: \"scanning\" | \"finalizing\" | \"publish-queued\" | \"publishing\" | \"indexing\" | \"committing\";\n total?: number;\n processed?: number;\n sessions?: number;\n}\n\nexport interface BackfillStatus {\n active: boolean;\n pendingAgents: string[];\n currentAgent?: string;\n progress?: BackfillProgress;\n completedAgents: string[];\n failedAgents: string[];\n partialAgents?: Record<string, ScanCompletion>;\n}\n\nexport interface SearchIndexMaintenanceStatus {\n active: boolean;\n pendingAgents: string[];\n currentAgent?: string;\n remaining?: number;\n completedAgents: string[];\n failedAgents: string[];\n}\n\nexport interface ScanStatusEvent {\n type: \"scan-status\";\n active: boolean;\n phase: \"idle\" | \"publishing\" | \"indexing\" | \"initializing\" | \"scanning\";\n pendingAgents: string[];\n scanningAgents: string[];\n completedAgents: string[];\n agentStatuses: Record<string, AgentScanStatus>;\n totalAgents: number;\n startedAt?: number;\n updatedAt: number;\n completedAt?: number;\n backfill: BackfillStatus;\n searchIndexMaintenance?: SearchIndexMaintenanceStatus;\n}\n","/**\n * Local calendar days, the unit the dashboard and its time windows are defined\n * in. A calendar day is not a fixed duration: across a DST transition adjacent\n * local midnights are 23 or 25 hours apart, so stepping by a constant number of\n * milliseconds skips or repeats a day. Every helper here advances date fields\n * instead.\n */\n\n/** Local midnight of the calendar day containing `timestamp`. */\nexport function startOfCalendarDay(timestamp: number): number {\n const date = new Date(timestamp);\n return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();\n}\n\n/** Local midnight `days` calendar days from the day containing `timestamp`. */\nexport function addCalendarDays(timestamp: number, days: number): number {\n const date = new Date(timestamp);\n return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days).getTime();\n}\n\n/**\n * Parses a date-only value at its local calendar boundary. `undefined` means\n * the input is not date-only; `null` means it has the right shape but is not a\n * real calendar date.\n */\nexport function parseCalendarDayBoundary(\n value: string,\n boundary: \"start\" | \"end\",\n): number | null | undefined {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value);\n if (!match) return undefined;\n const year = Number(match[1]);\n const month = Number(match[2]) - 1;\n const day = Number(match[3]);\n const start = new Date(year, month, day);\n if (start.getFullYear() !== year || start.getMonth() !== month || start.getDate() !== day) {\n return null;\n }\n return boundary === \"start\" ? start.getTime() : addCalendarDays(start.getTime(), 1) - 1;\n}\n\n/** Days since the epoch for a local calendar date, counted on a fixed-length UTC grid. */\nfunction toCalendarDayNumber(timestamp: number): number {\n const date = new Date(timestamp);\n return Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) / 86_400_000;\n}\n\n/** Calendar days in the inclusive local range, at least 1. */\nexport function countCalendarDays(from: number, to: number): number {\n return Math.max(1, toCalendarDayNumber(to) - toCalendarDayNumber(from) + 1);\n}\n\n/** `YYYY-MM-DD` key for the local calendar day; the dashboard wire format. */\nexport function toCalendarDayKey(timestamp: number): string {\n const date = new Date(timestamp);\n return `${String(date.getFullYear()).padStart(4, \"0\")}-${String(date.getMonth() + 1).padStart(\n 2,\n \"0\",\n )}-${String(date.getDate()).padStart(2, \"0\")}`;\n}\n","/**\n * What a project identity is, independent of how it is discovered or displayed.\n *\n * The same facts used to be restated in five places: the kind union here, a kind\n * Set and `kind:key` encoding in the Node resolver, another `getProjectIdentityKey`\n * in the session index, a private group key in analytics, and a third copy in the\n * web adapter. Adding a kind meant editing all of them, and nothing failed if one\n * was missed.\n *\n * This module owns the closed set, the identity key, and identity comparison.\n * Discovering identities from the filesystem lives in `projects/identity.ts`;\n * encoding them into URLs lives in the web adapter. Both sit outside this one.\n */\n\n/**\n * Every kind of project identity, most specific first. The order is documentation,\n * not behavior. These values appear in SQLite rows and API responses, so they\n * cannot be renamed without a migration.\n */\nexport const PROJECT_IDENTITY_KINDS = [\n \"git_remote\",\n \"git_common_dir\",\n \"manifest_path\",\n \"synthetic\",\n \"path\",\n \"loose\",\n] as const;\n\nexport type ProjectIdentityKind = (typeof PROJECT_IDENTITY_KINDS)[number];\n\nexport interface ProjectIdentityRef {\n kind: ProjectIdentityKind;\n key: string;\n}\n\nconst KIND_LOOKUP = new Set<string>(PROJECT_IDENTITY_KINDS);\n\nexport function isProjectIdentityKind(value: string): value is ProjectIdentityKind {\n return KIND_LOOKUP.has(value);\n}\n\n/**\n * Stable key for grouping and lookup. This is not a URL: route encoding is a\n * separate adapter, and conflating the two would put an escaped key in storage.\n */\nexport function getProjectIdentityKey(identity: ProjectIdentityRef): string {\n return `${identity.kind}:${identity.key}`;\n}\n\nexport function matchesProjectIdentity(\n identity: ProjectIdentityRef | null | undefined,\n expected: ProjectIdentityRef,\n): boolean {\n return identity?.kind === expected.kind && identity.key === expected.key;\n}\n\n/** Key for one agent's slice of a project. */\nexport function getProjectAgentKey(projectIdentityKey: string, agentName: string): string {\n return `${projectIdentityKey}\\0${agentName.toLowerCase()}`;\n}\n","import type { ReferencedSessionHead, SessionHead } from \"./session.js\";\nimport { getProjectAgentKey, getProjectIdentityKey } from \"./project-identity.js\";\nimport { getSessionReferenceKey, type SessionReference } from \"./session-reference.js\";\n\nexport type SessionHeadChange = ReferencedSessionHead;\n\nexport type SessionHeadRemoval = SessionReference;\n\nexport interface CanonicalSessionIndex {\n sourceSessions: SessionHead[];\n sessionsByActivity: SessionHead[];\n byRouteKey: Map<string, SessionHead>;\n childrenByParentRouteKey: Map<string, SessionHead[]>;\n byAgent: Map<string, SessionHead[]>;\n byProjectIdentityKey: Map<string, SessionHead[]>;\n byProjectAgentKey: Map<string, SessionHead[]>;\n}\n\nexport function compareSessionActivityDesc(a: SessionHead, b: SessionHead): number {\n return (b.time_updated ?? b.time_created) - (a.time_updated ?? a.time_created);\n}\n\nexport function sortSessionsByActivity<T extends SessionHead>(sessions: T[]): T[] {\n for (let index = 1; index < sessions.length; index += 1) {\n if (compareSessionActivityDesc(sessions[index - 1]!, sessions[index]!) > 0) {\n return [...sessions].sort(compareSessionActivityDesc);\n }\n }\n return [...sessions];\n}\n\n/**\n * Merges shards that are each already sorted by activity, newest first.\n *\n * Callers must uphold that precondition — this does not re-sort. Ties resolve to\n * the earlier shard, which is what a stable `Array.sort` over the concatenation\n * would produce, so the result is element-for-element identical to\n * `sortSessionsByActivity(shards.flat())` at O(n·k) instead of O(n log n).\n */\nexport function mergeSortedSessions<T extends SessionHead>(shards: T[][]): T[] {\n const active = shards.filter((shard) => shard.length > 0);\n if (active.length === 0) return [];\n if (active.length === 1) return [...active[0]!];\n\n const total = active.reduce((sum, shard) => sum + shard.length, 0);\n const merged: T[] = [];\n const cursors = Array.from({ length: active.length }, () => 0);\n\n for (let position = 0; position < total; position += 1) {\n let pick = -1;\n for (let shard = 0; shard < active.length; shard += 1) {\n const cursor = cursors[shard]!;\n if (cursor >= active[shard]!.length) continue;\n if (\n pick === -1 ||\n compareSessionActivityDesc(active[shard]![cursor]!, active[pick]![cursors[pick]!]!) < 0\n ) {\n pick = shard;\n }\n }\n merged.push(active[pick]![cursors[pick]!]!);\n cursors[pick]! += 1;\n }\n\n return merged;\n}\n\n/** @deprecated Pass a SessionReference to getSessionReferenceKey instead. */\nexport function getSessionRouteKey(agentName: string, sessionId: string): string {\n return getSessionReferenceKey({ agentName, sessionId });\n}\n\nfunction pushMapValue<K, V>(map: Map<K, V[]>, key: K, value: V): void {\n const current = map.get(key);\n if (current) {\n current.push(value);\n } else {\n map.set(key, [value]);\n }\n}\n\nexport function createSessionIndex(sourceSessions: SessionHead[]): CanonicalSessionIndex {\n const byRouteKey = new Map<string, SessionHead>();\n const childrenByParentRouteKey = new Map<string, SessionHead[]>();\n const byAgent = new Map<string, SessionHead[]>();\n const byProjectIdentityKey = new Map<string, SessionHead[]>();\n const byProjectAgentKey = new Map<string, SessionHead[]>();\n\n for (const session of sourceSessions) {\n const routeKey = getSessionReferenceKey(session.reference);\n if (!byRouteKey.has(routeKey)) byRouteKey.set(routeKey, session);\n if (session.parent_reference) {\n pushMapValue(\n childrenByParentRouteKey,\n getSessionReferenceKey(session.parent_reference),\n session,\n );\n }\n }\n\n const sessionsByActivity = sortSessionsByActivity(sourceSessions);\n for (const session of sessionsByActivity) {\n const { agentName } = session.reference;\n pushMapValue(byAgent, agentName, session);\n\n const identity = session.project_identity;\n if (!identity?.key) continue;\n\n const projectIdentityKey = getProjectIdentityKey(identity);\n pushMapValue(byProjectIdentityKey, projectIdentityKey, session);\n pushMapValue(byProjectAgentKey, getProjectAgentKey(projectIdentityKey, agentName), session);\n }\n\n return {\n sourceSessions,\n sessionsByActivity,\n byRouteKey,\n childrenByParentRouteKey,\n byAgent,\n byProjectIdentityKey,\n byProjectAgentKey,\n };\n}\n\nexport function applySessionChanges(\n sessions: SessionHead[],\n changes: SessionHeadChange[],\n removals: SessionHeadRemoval[],\n): SessionHead[] {\n const byRouteKey = new Map<string, SessionHead>();\n for (const session of sessions) {\n byRouteKey.set(getSessionReferenceKey(session.reference), session);\n }\n\n for (const removal of removals) {\n byRouteKey.delete(getSessionReferenceKey(removal));\n }\n for (const change of changes) {\n byRouteKey.set(getSessionReferenceKey(change.reference), change.session);\n }\n\n return sortSessionsByActivity([...byRouteKey.values()]);\n}\n\nexport function updateSessionIndex(\n index: CanonicalSessionIndex,\n changes: SessionHeadChange[],\n removals: SessionHeadRemoval[],\n): CanonicalSessionIndex {\n return createSessionIndex(applySessionChanges(index.sourceSessions, changes, removals));\n}\n","/**\n * Parent/child structure over a session snapshot: mount classification,\n * inclusive stat rollups and calendar-day grouping. Everything here is a pure\n * derivation of `parent_reference` — the wire format carries no tree.\n */\nimport type { CostSource, ReferencedSessionHead, SessionHead } from \"./session.js\";\nimport { startOfCalendarDay, toCalendarDayKey } from \"./calendar-day.js\";\nimport {\n applySessionChanges,\n compareSessionActivityDesc,\n type SessionHeadChange,\n type SessionHeadRemoval,\n} from \"./session-index.js\";\nimport { getSessionReferenceKey, type SessionReference } from \"./session-reference.js\";\n\n/**\n * Where a session sits relative to its parent, with orphans distinguished\n * from mounted children.\n */\nexport type SessionMountState = \"root\" | \"mounted-child\" | \"orphan\";\n\nexport interface InclusiveSessionStats {\n messageCount: number;\n /** Raw `total_input_tokens`; cache reads/creates are part of it. */\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheCreateTokens: number;\n totalTokens: number;\n cost: number;\n /** Undefined while the subtree costs nothing; \"estimated\" wins over \"recorded\". */\n costSource?: CostSource;\n}\n\nexport interface SessionTreeNode {\n session: SessionHead;\n /** Direct children only, in the input array's order. */\n children: SessionTreeNode[];\n /** Total number of descendants at every depth. */\n descendantCount: number;\n /** stats rolled up over this node and every descendant. */\n inclusiveStats: InclusiveSessionStats;\n}\n\nexport interface SessionTree {\n /** Sessions with no parent_reference, in input order. */\n roots: SessionTreeNode[];\n /** Sessions whose parent is not present in the input (未挂载), in input order. */\n orphans: SessionTreeNode[];\n /** roots ∪ orphans, in input order — the set that owns the main axis. */\n entries: SessionTreeNode[];\n byRouteKey: Map<string, SessionTreeNode>;\n mountStateOf(session: SessionHead): SessionMountState;\n}\n\nexport interface SessionDayGroup {\n /** \"YYYY-MM-DD\" local calendar day. */\n dayKey: string;\n dayStart: number;\n nodes: SessionTreeNode[];\n mainCount: number;\n subCount: number;\n}\n\nfunction sessionKey(session: SessionHead): string {\n return getSessionReferenceKey(session.reference);\n}\n\nfunction parentKey(session: SessionHead): string | null {\n return session.parent_reference ? getSessionReferenceKey(session.parent_reference) : null;\n}\n\nfunction activityTime(session: SessionHead): number {\n return session.time_updated ?? session.time_created;\n}\n\nfunction hasActivityInWindow(session: SessionHead, from?: number, to?: number): boolean {\n const activity = activityTime(session);\n return (from == null || activity >= from) && (to == null || activity <= to);\n}\n\nfunction ownStats(session: SessionHead): InclusiveSessionStats {\n const stats = session.stats;\n const cost = stats.total_cost ?? 0;\n return {\n messageCount: stats.message_count,\n inputTokens: stats.total_input_tokens,\n outputTokens: stats.total_output_tokens,\n cacheReadTokens: stats.total_cache_read_tokens ?? 0,\n cacheCreateTokens: stats.total_cache_create_tokens ?? 0,\n totalTokens: stats.total_tokens ?? stats.total_input_tokens + stats.total_output_tokens,\n cost,\n costSource: cost > 0 ? (stats.cost_source ?? \"recorded\") : undefined,\n };\n}\n\nfunction addStats(target: InclusiveSessionStats, source: InclusiveSessionStats): void {\n target.messageCount += source.messageCount;\n target.inputTokens += source.inputTokens;\n target.outputTokens += source.outputTokens;\n target.cacheReadTokens += source.cacheReadTokens;\n target.cacheCreateTokens += source.cacheCreateTokens;\n target.totalTokens += source.totalTokens;\n target.cost += source.cost;\n if (source.costSource === \"estimated\") target.costSource = \"estimated\";\n}\n\n/**\n * Post-order rollup of `descendantCount` and `inclusiveStats` over one entry.\n * Folds children into each node's own stats in place, which is sound because a\n * node hangs off exactly one entry and every entry is rolled up once.\n */\nfunction rollUpSubtree(entry: SessionTreeNode): void {\n const order: SessionTreeNode[] = [];\n const pending = [entry];\n while (pending.length > 0) {\n const node = pending.pop()!;\n order.push(node);\n for (const child of node.children) pending.push(child);\n }\n\n for (let index = order.length - 1; index >= 0; index -= 1) {\n const node = order[index]!;\n const stats = node.inclusiveStats;\n let descendants = 0;\n for (const child of node.children) {\n descendants += 1 + child.descendantCount;\n addStats(stats, child.inclusiveStats);\n }\n if (stats.cost > 0 && stats.costSource == null) stats.costSource = \"recorded\";\n node.descendantCount = descendants;\n }\n}\n\nexport function buildSessionTree(sessions: SessionHead[]): SessionTree {\n const byRouteKey = new Map<string, SessionTreeNode>();\n for (const session of sessions) {\n const key = sessionKey(session);\n if (byRouteKey.has(key)) continue;\n byRouteKey.set(key, {\n session,\n children: [],\n descendantCount: 0,\n inclusiveStats: ownStats(session),\n });\n }\n const nodes = [...byRouteKey.values()];\n\n // A session whose parent chain re-enters itself can never reach a root, so it\n // is mounted nowhere. Memoized so the walk stays linear over long chains.\n const chainTerminates = new Map<string, boolean>();\n function reachesRoot(startKey: string): boolean {\n const path: string[] = [];\n const onPath = new Set<string>();\n let key: string | null = startKey;\n let terminates = true;\n\n while (key != null) {\n const memo = chainTerminates.get(key);\n if (memo != null) {\n terminates = memo;\n break;\n }\n if (onPath.has(key)) {\n terminates = false;\n break;\n }\n onPath.add(key);\n path.push(key);\n const parent = parentKey(byRouteKey.get(key)!.session);\n key = parent != null && byRouteKey.has(parent) ? parent : null;\n }\n\n for (const visited of path) chainTerminates.set(visited, terminates);\n return terminates;\n }\n\n const mountStates = new Map<string, SessionMountState>();\n const roots: SessionTreeNode[] = [];\n const orphans: SessionTreeNode[] = [];\n const entries: SessionTreeNode[] = [];\n\n for (const node of nodes) {\n const key = sessionKey(node.session);\n const parent = parentKey(node.session);\n const state: SessionMountState =\n parent == null\n ? \"root\"\n : byRouteKey.has(parent) && reachesRoot(key)\n ? \"mounted-child\"\n : \"orphan\";\n\n mountStates.set(key, state);\n if (state === \"mounted-child\") {\n byRouteKey.get(parent!)!.children.push(node);\n continue;\n }\n (state === \"root\" ? roots : orphans).push(node);\n entries.push(node);\n }\n\n for (const entry of entries) rollUpSubtree(entry);\n\n return {\n roots,\n orphans,\n entries,\n byRouteKey,\n mountStateOf(session) {\n return mountStates.get(sessionKey(session)) ?? (session.parent_reference ? \"orphan\" : \"root\");\n },\n };\n}\n\n/**\n * Groups top-level nodes by the calendar day of their activity time,\n * newest day first, newest node first.\n */\nexport function groupSessionsByCalendarDay(nodes: SessionTreeNode[]): SessionDayGroup[] {\n const groups = new Map<string, SessionDayGroup>();\n\n for (const node of nodes) {\n const activity = activityTime(node.session);\n const dayKey = toCalendarDayKey(activity);\n let group = groups.get(dayKey);\n if (!group) {\n group = {\n dayKey,\n dayStart: startOfCalendarDay(activity),\n nodes: [],\n mainCount: 0,\n subCount: 0,\n };\n groups.set(dayKey, group);\n }\n group.nodes.push(node);\n }\n\n const days = [...groups.values()];\n for (const group of days) {\n group.nodes.sort((a, b) => compareSessionActivityDesc(a.session, b.session));\n group.mainCount = group.nodes.length;\n group.subCount = group.nodes.reduce((sum, node) => sum + node.descendantCount, 0);\n }\n return days.sort((a, b) => b.dayStart - a.dayStart);\n}\n\n/**\n * Filters main-axis sessions (roots and orphans) by activity and keeps every\n * mounted descendant of a match. The input order is preserved so callers keep\n * their existing sort behavior.\n */\nexport function filterSessionTreeByActivityWindow<T extends SessionHead>(\n sessions: T[],\n from?: number,\n to?: number,\n tree?: SessionTree,\n): T[] {\n if (from == null && to == null) return sessions;\n\n if (tree === undefined && sessions.every((session) => hasActivityInWindow(session, from, to))) {\n return [...sessions];\n }\n\n const pending = filterSessionTreeEntriesByActivityWindow(\n tree ?? buildSessionTree(sessions),\n from,\n to,\n );\n\n const visible = new Set<string>();\n while (pending.length > 0) {\n const node = pending.pop()!;\n const key = sessionKey(node.session);\n if (visible.has(key)) continue;\n visible.add(key);\n for (const child of node.children) pending.push(child);\n }\n\n return sessions.filter((session) => visible.has(sessionKey(session)));\n}\n\nexport function filterSessionTreeEntriesByActivityWindow(\n tree: SessionTree,\n from?: number,\n to?: number,\n): SessionTreeNode[] {\n if (from == null && to == null) return tree.entries;\n return tree.entries.filter((node) => hasActivityInWindow(node.session, from, to));\n}\n\ninterface SessionHierarchyGraph {\n sessionsByKey: Map<string, SessionHead>;\n parentByKey: Map<string, string>;\n childrenByKey: Map<string, string[]>;\n}\n\nfunction createSessionHierarchyGraph(sessions: SessionHead[]): SessionHierarchyGraph {\n const sessionsByKey = new Map<string, SessionHead>();\n for (const session of sessions) {\n const key = sessionKey(session);\n if (!sessionsByKey.has(key)) sessionsByKey.set(key, session);\n }\n\n const parentByKey = new Map<string, string>();\n const childrenByKey = new Map<string, string[]>();\n for (const [key, session] of sessionsByKey) {\n const parent = parentKey(session);\n if (!parent || !sessionsByKey.has(parent)) continue;\n parentByKey.set(key, parent);\n const children = childrenByKey.get(parent);\n if (children) children.push(key);\n else childrenByKey.set(parent, [key]);\n }\n return { sessionsByKey, parentByKey, childrenByKey };\n}\n\nfunction collectAffectedHierarchyKeys(\n graph: SessionHierarchyGraph,\n seedKeys: Iterable<string>,\n includeAncestors: boolean,\n collected: Set<string>,\n): void {\n const visited = new Set<string>();\n const pending = [...seedKeys].filter((key) => graph.sessionsByKey.has(key));\n while (pending.length > 0) {\n const key = pending.pop()!;\n if (visited.has(key)) continue;\n visited.add(key);\n collected.add(key);\n for (const child of graph.childrenByKey.get(key) ?? []) pending.push(child);\n }\n\n if (!includeAncestors) return;\n const visitedAncestors = new Set<string>();\n for (const seed of seedKeys) {\n let key = graph.sessionsByKey.has(seed) ? seed : undefined;\n while (key && !visitedAncestors.has(key)) {\n visitedAncestors.add(key);\n collected.add(key);\n key = graph.parentByKey.get(key);\n }\n }\n}\n\nexport interface SessionProjectionContext {\n relatedSessionHeads: ReferencedSessionHead[];\n sessionOrder: SessionReference[];\n}\n\nexport function createSessionProjectionContext(\n previousSessions: SessionHead[],\n nextSessions: SessionHead[],\n changedSessionHeads: ReferencedSessionHead[],\n removedSessionRefs: SessionReference[],\n): SessionProjectionContext {\n const changedKeys = new Set(\n changedSessionHeads.map(({ reference }) => getSessionReferenceKey(reference)),\n );\n const removedKeys = removedSessionRefs.map(getSessionReferenceKey);\n const affectedKeys = new Set<string>();\n const previousGraph = createSessionHierarchyGraph(previousSessions);\n const nextGraph = createSessionHierarchyGraph(nextSessions);\n collectAffectedHierarchyKeys(previousGraph, changedKeys, true, affectedKeys);\n collectAffectedHierarchyKeys(nextGraph, changedKeys, true, affectedKeys);\n collectAffectedHierarchyKeys(previousGraph, removedKeys, false, affectedKeys);\n\n const emitted = new Set<string>();\n const relatedSessionHeads = nextSessions.flatMap((session) => {\n const key = sessionKey(session);\n if (!affectedKeys.has(key) || changedKeys.has(key) || emitted.has(key)) return [];\n emitted.add(key);\n return [\n {\n reference: session.reference,\n session,\n },\n ];\n });\n const affectedActivityTimes = new Set(\n [...changedSessionHeads, ...relatedSessionHeads].map(({ session }) => activityTime(session)),\n );\n const sessionOrder = nextSessions.flatMap((session) =>\n affectedActivityTimes.has(activityTime(session)) ? [session.reference] : [],\n );\n return { relatedSessionHeads, sessionOrder };\n}\n\nexport interface SessionWindowChanges {\n changedSessionHeads: SessionHeadChange[];\n projectionRelatedSessionHeads?: SessionHeadChange[];\n projectionSessionOrder?: SessionReference[];\n removedSessionRefs: SessionHeadRemoval[];\n from?: number;\n to?: number;\n}\n\nexport interface SessionWindowChangeResult {\n sessions: SessionHead[];\n visibleAddedSessions: number;\n visibleRemovedSessions: number;\n}\n\nexport function applySessionWindowChanges(\n sessions: SessionHead[],\n changes: SessionWindowChanges,\n): SessionWindowChangeResult {\n const previousKeys = new Set(sessions.map(sessionKey));\n const upserts = [\n ...(changes.projectionRelatedSessionHeads ?? []),\n ...changes.changedSessionHeads,\n ];\n const upsertsByKey = new Map(\n upserts.map((change) => [getSessionReferenceKey(change.reference), change]),\n );\n const sessionsByKey = new Map(sessions.map((session) => [sessionKey(session), session]));\n const orderedUpserts: SessionHeadChange[] = [];\n const reorderedRefs: SessionReference[] = [];\n for (const reference of changes.projectionSessionOrder ?? []) {\n const key = getSessionReferenceKey(reference);\n const change = upsertsByKey.get(key);\n const session = change?.session ?? sessionsByKey.get(key);\n if (!session) continue;\n orderedUpserts.push(change ?? { reference, session });\n reorderedRefs.push(reference);\n upsertsByKey.delete(key);\n }\n orderedUpserts.push(...upsertsByKey.values());\n const merged = applySessionChanges(sessions, orderedUpserts, [\n ...changes.removedSessionRefs,\n ...reorderedRefs,\n ]);\n const projected = filterSessionTreeByActivityWindow(merged, changes.from, changes.to);\n const nextKeys = new Set(projected.map(sessionKey));\n let visibleAddedSessions = 0;\n let visibleRemovedSessions = 0;\n for (const key of nextKeys) {\n if (!previousKeys.has(key)) visibleAddedSessions += 1;\n }\n for (const key of previousKeys) {\n if (!nextKeys.has(key)) visibleRemovedSessions += 1;\n }\n return { sessions: projected, visibleAddedSessions, visibleRemovedSessions };\n}\n","import type { CostSource, ProjectGroup } from \"./session.js\";\n\nexport const CODESESH_REQUEST_ID_HEADER = \"X-CodeSesh-Request-ID\";\nexport const CODESESH_OPERATION_ID_HEADER = \"X-CodeSesh-Operation-ID\";\n\nexport interface AppConfig {\n window: {\n from?: number;\n to?: number;\n days?: number;\n };\n}\n\nexport interface ApiProjectAgentStat {\n name: string;\n sessions: number;\n messages: number;\n tokens: number;\n cost: number;\n}\n\nexport interface ApiProjectGroup extends ProjectGroup {\n messages: number;\n tokens: number;\n cost: number;\n cost_source?: CostSource;\n agentStats: ApiProjectAgentStat[];\n}\n\nexport interface ApiProjectSummary {\n projects: number;\n sessions: number;\n tokens: number;\n cost: number;\n latestActivity: number | null;\n}\n\nexport interface ApiProjectPage {\n projects: ApiProjectGroup[];\n summary: ApiProjectSummary;\n nextCursor?: string;\n}\n","import type {\n Message,\n SessionFileActivity,\n SessionFileActivityOccurrence,\n ToolPart,\n} from \"../types/index.js\";\nimport { extractFileToolOperations } from \"../contract/file-activity.js\";\n\nfunction normalizeToolLabel(part: ToolPart) {\n if (part.title?.trim()) {\n return part.title.trim().replace(/^tool:\\s*/i, \"\");\n }\n if (part.tool.trim()) return part.tool.trim();\n return \"tool\";\n}\n\nexport function extractFileActivityOccurrences(\n messages: Message[],\n): SessionFileActivityOccurrence[] {\n const occurrences: SessionFileActivityOccurrence[] = [];\n\n messages.forEach((message, messageIndex) => {\n let toolIndex = 0;\n\n for (const part of message.parts) {\n if (part.type !== \"tool\") continue;\n\n const toolLabel = normalizeToolLabel(part);\n const time = part.time_created ?? message.time_created;\n const currentToolIndex = toolIndex;\n toolIndex += 1;\n\n for (const { kind, path } of extractFileToolOperations(part)) {\n occurrences.push({\n path,\n kind,\n time,\n tool_label: toolLabel,\n message_index: messageIndex,\n tool_index: currentToolIndex,\n });\n }\n }\n });\n\n return occurrences;\n}\n\nexport function summarizeFileActivity(\n agentName: string,\n sessionId: string,\n projectIdentityKey: string,\n occurrences: SessionFileActivityOccurrence[],\n): SessionFileActivity[] {\n const grouped = new Map<string, SessionFileActivity>();\n\n for (const occurrence of occurrences) {\n const key = `${occurrence.kind}\\0${occurrence.path}`;\n const current = grouped.get(key);\n if (current) {\n current.count += 1;\n current.latestTime = Math.max(current.latestTime, occurrence.time);\n continue;\n }\n\n grouped.set(key, {\n reference: { agentName, sessionId },\n projectIdentityKey,\n path: occurrence.path,\n kind: occurrence.kind,\n count: 1,\n latestTime: occurrence.time,\n });\n }\n\n return [...grouped.values()].sort((a, b) => {\n if (b.latestTime !== a.latestTime) return b.latestTime - a.latestTime;\n return a.path.localeCompare(b.path);\n });\n}\n\nexport function extractSessionFileActivity(\n agentName: string,\n sessionId: string,\n projectIdentityKey: string,\n messages: Message[],\n): SessionFileActivity[] {\n return summarizeFileActivity(\n agentName,\n sessionId,\n projectIdentityKey,\n extractFileActivityOccurrences(messages),\n );\n}\n","/**\n * Injectable diagnostics sink for core's failure paths. core stays\n * framework-agnostic (no logger dependency); hosts opt in by calling\n * setCoreDiagnostics once at startup. Default is a silent no-op so core's\n * behavior is unchanged for consumers that never inject one.\n */\n\nexport interface CoreDiagnostics {\n info?(event: string, detail?: Record<string, unknown>): void;\n warn(event: string, detail?: Record<string, unknown>): void;\n}\n\nlet diagnostics: CoreDiagnostics | null = null;\n\n/**\n * A host-injected sink that throws must not escape into core's own control\n * flow — e.g. abort a `FileSystemSessionSource.scan` loop or turn a cache\n * write's `catch { return null }` into an uncaught throw. Wrap once here so\n * every `diagnostics?.warn(...)` call site stays exception-safe for free.\n */\nfunction toSafeSink(sink: CoreDiagnostics): CoreDiagnostics {\n return {\n info(event, detail) {\n try {\n sink.info?.(event, detail);\n } catch {}\n },\n warn(event, detail) {\n try {\n sink.warn(event, detail);\n } catch {}\n },\n };\n}\n\nexport function setCoreDiagnostics(next: CoreDiagnostics | null): void {\n diagnostics = next ? toSafeSink(next) : null;\n}\n\nexport function getCoreDiagnostics(): CoreDiagnostics | null {\n return diagnostics;\n}\n","/**\n * Owner-only permissions for the files CodeSesh writes.\n *\n * The session cache holds full transcripts; state holds bookmarks and aliases;\n * logs hold project paths and error detail. All of them were created under the\n * process umask, which is commonly 022 — so 0755 directories and 0644 files. On\n * a shared machine with a traversable home, another user could read them.\n *\n * POSIX modes do not apply on Windows, where `chmod` is a no-op; access there is\n * governed by the profile directory's ACL.\n */\nimport { chmodSync, existsSync, mkdirSync, readdirSync, statSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport { getCoreDiagnostics } from \"./diagnostics.js\";\n\n/** Owner read/write/execute. */\nexport const PRIVATE_DIR_MODE = 0o700;\n/** Owner read/write. */\nexport const PRIVATE_FILE_MODE = 0o600;\n\n/** Sidecars SQLite creates next to a database, which carry the same data. */\nconst SQLITE_SIDECAR_SUFFIXES = [\"-wal\", \"-shm\", \"-journal\"];\n\nconst isPosix = process.platform !== \"win32\";\n\nfunction reportChmodFailure(path: string, error: unknown): void {\n getCoreDiagnostics()?.warn(\"storage.permissions_failed\", {\n path,\n message: error instanceof Error ? error.message : String(error),\n });\n}\n\n/** Narrows an existing path's permissions, reporting rather than throwing. */\nfunction restrict(path: string, mode: number): void {\n if (!isPosix || !existsSync(path)) return;\n try {\n // Skip the syscall when it would not change anything.\n if ((statSync(path).mode & 0o777) === mode) return;\n chmodSync(path, mode);\n } catch (error) {\n reportChmodFailure(path, error);\n }\n}\n\n/**\n * Creates a directory only its owner can enter, and tightens it if it existed.\n *\n * A failed mkdir propagates — the caller has nowhere to store anything. A failed\n * chmod does not: the directory is usable, just not as private as intended, and\n * that is reported instead.\n */\nexport function ensurePrivateDirectory(path: string): void {\n mkdirSync(path, { recursive: true, mode: PRIVATE_DIR_MODE });\n // `recursive` skips the mode for a directory that already existed.\n restrict(path, PRIVATE_DIR_MODE);\n}\n\n/** Narrows a file CodeSesh owns to owner-only. */\nexport function restrictPrivateFile(path: string): void {\n restrict(path, PRIVATE_FILE_MODE);\n}\n\n/**\n * Tightens files already in a directory — those written before this policy\n * existed, or by an older version. The caller names exactly what it owns, so\n * the sweep never reaches beyond CodeSesh's own files.\n */\nexport function restrictExistingPrivateFiles(\n directory: string,\n owns: (name: string) => boolean,\n): void {\n try {\n for (const entry of readdirSync(directory)) {\n if (owns(entry)) restrictPrivateFile(join(directory, entry));\n }\n } catch (error) {\n reportChmodFailure(directory, error);\n }\n}\n\n/** Databases whose neighbouring backups have already been swept this process. */\nconst sweptBackupsFor = new Set<string>();\n\n/** A backup holds the same rows as the database it came from. */\nfunction restrictExistingBackups(dbPath: string): void {\n if (sweptBackupsFor.has(dbPath)) return;\n sweptBackupsFor.add(dbPath);\n\n const prefix = `${basename(dbPath)}.`;\n restrictExistingPrivateFiles(\n dirname(dbPath),\n (name) => name.startsWith(prefix) && name.endsWith(\".bak\"),\n );\n}\n\n/**\n * Narrows a database, any sidecar SQLite has created, and backups left beside\n * it. Call after opening: the sidecars do not exist until the connection is\n * established.\n */\nexport function restrictPrivateDatabase(dbPath: string): void {\n restrictPrivateFile(dbPath);\n for (const suffix of SQLITE_SIDECAR_SUFFIXES) restrictPrivateFile(`${dbPath}${suffix}`);\n restrictExistingBackups(dbPath);\n}\n","import { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { ensurePrivateDirectory, restrictPrivateFile } from \"../utils/private-storage.js\";\nimport { getCoreDiagnostics } from \"../utils/diagnostics.js\";\nimport { MODELS_DEV_URL, parseModelsDevPricing } from \"./models-dev.js\";\nimport { normalizeModelKey, type ModelPricing } from \"./model-pricing.js\";\nexport { normalizeModelKey, type ModelPricing } from \"./model-pricing.js\";\nimport snapshotData from \"./data/snapshot.json\";\n\ntype SnapshotEntry = [number, number, number | null, number | null, number?, number?];\n\nconst CACHE_TTL_MS = 60 * 60 * 1000;\nconst WEB_SEARCH_COST = 0.01;\nconst REFRESH_TIMEOUT_MS = 10_000;\n\n/**\n * A published set of prices. Estimates read one generation for as long as they\n * need it: a refresh landing mid-scan used to mean the first sessions of a scan\n * were priced differently from the last, with no record of which applied.\n */\nexport interface PricingGeneration {\n id: number;\n pricing: Map<string, ModelPricing>;\n}\n\nlet published = createPricingGeneration(loadSnapshot());\n/** A completed refresh waiting for a safe point to become current. */\nlet pending: Map<string, ModelPricing> | null = null;\nlet refreshInFlight: Promise<boolean> | null = null;\npublished = readDiskCache() ?? published;\n\nfunction createPricingGeneration(pricing: Map<string, ModelPricing>): PricingGeneration {\n const hash = createHash(\"sha256\");\n const entries = [...pricing.entries()].sort(([left], [right]) =>\n left < right ? -1 : left > right ? 1 : 0,\n );\n for (const [name, modelPricing] of entries) {\n hash.update(name);\n hash.update(\"\\0\");\n hash.update(JSON.stringify(modelPricing));\n hash.update(\"\\n\");\n }\n\n return {\n id: Number.parseInt(hash.digest(\"hex\").slice(0, 13), 16) || 1,\n pricing,\n };\n}\n\nfunction costNumber(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) && value >= 0 ? value : undefined;\n}\n\nfunction getCacheDir() {\n return join(homedir(), \".cache\", \"codesesh\");\n}\n\nfunction getCachePath() {\n return join(getCacheDir(), \"models-dev-pricing.json\");\n}\n\nfunction loadSnapshot(): Map<string, ModelPricing> {\n const map = new Map<string, ModelPricing>();\n const snapshot = snapshotData as unknown as Record<string, SnapshotEntry>;\n for (const [name, entry] of Object.entries(snapshot)) {\n const [input, output, cacheCreate, cacheRead, reasoning, webSearch] = entry;\n indexPricing(map, name, {\n inputCostPerToken: input,\n outputCostPerToken: output,\n cacheCreateCostPerToken: cacheCreate ?? input * 1.25,\n cacheReadCostPerToken: cacheRead ?? input * 0.1,\n reasoningCostPerToken: reasoning ?? output,\n webSearchCostPerRequest: webSearch ?? WEB_SEARCH_COST,\n });\n }\n return map;\n}\n\nfunction normalizePricing(raw: unknown): ModelPricing | null {\n if (raw === null || typeof raw !== \"object\" || Array.isArray(raw)) return null;\n const values = raw as Record<string, unknown>;\n const input = costNumber(values[\"inputCostPerToken\"]);\n const output = costNumber(values[\"outputCostPerToken\"]);\n if (input === undefined || output === undefined) return null;\n\n return {\n inputCostPerToken: input,\n outputCostPerToken: output,\n cacheCreateCostPerToken: costNumber(values[\"cacheCreateCostPerToken\"]) ?? input * 1.25,\n cacheReadCostPerToken: costNumber(values[\"cacheReadCostPerToken\"]) ?? input * 0.1,\n reasoningCostPerToken: costNumber(values[\"reasoningCostPerToken\"]) ?? output,\n webSearchCostPerRequest: costNumber(values[\"webSearchCostPerRequest\"]) ?? WEB_SEARCH_COST,\n };\n}\n\nfunction indexPricing(map: Map<string, ModelPricing>, name: string, pricing: ModelPricing) {\n const normalized = normalizeModelKey(name);\n map.set(normalized, pricing);\n\n const slashIndex = normalized.indexOf(\"/\");\n if (slashIndex >= 0) {\n const stripped = normalized.slice(slashIndex + 1);\n if (!map.has(stripped)) map.set(stripped, pricing);\n }\n}\n\ninterface PricingCache {\n timestamp: number;\n data: Record<string, Record<string, unknown>>;\n}\n\nfunction readDiskCache(requireFresh = false): PricingGeneration | null {\n const path = getCachePath();\n if (!existsSync(path)) return null;\n\n try {\n const cached = JSON.parse(readFileSync(path, \"utf-8\")) as PricingCache;\n if (!Number.isFinite(cached.timestamp) || cached.timestamp > Date.now()) return null;\n if (requireFresh && Date.now() - cached.timestamp >= CACHE_TTL_MS) return null;\n if (cached.data == null || typeof cached.data !== \"object\" || Array.isArray(cached.data)) {\n return null;\n }\n\n const next = loadSnapshot();\n let validEntries = 0;\n for (const [name, rawPricing] of Object.entries(cached.data)) {\n const pricing = normalizePricing(rawPricing);\n if (!pricing) continue;\n next.set(normalizeModelKey(name), pricing);\n validEntries++;\n }\n return validEntries > 0 ? createPricingGeneration(next) : null;\n } catch {\n return null;\n }\n}\n\nexport function getPricingRegistry(): Map<string, ModelPricing> {\n return published.pricing;\n}\n\n/** The generation estimates are currently reading. */\nexport function getPricingGeneration(): PricingGeneration {\n return published;\n}\n\n/** Aligns an isolated worker with the generation selected by its parent. */\nexport function synchronizePricingGeneration(expectedId: number): void {\n if (!Number.isSafeInteger(expectedId) || expectedId < 1) {\n throw new Error(`Invalid pricing generation: ${expectedId}`);\n }\n if (published.id === expectedId) return;\n\n const cached = readDiskCache();\n if (cached?.id !== expectedId) {\n throw new Error(\n `Pricing generation ${expectedId} is unavailable (current ${published.id}, cached ${cached?.id ?? \"none\"})`,\n );\n }\n\n published = cached;\n getCoreDiagnostics()?.info?.(\"pricing.generation.synchronized\", {\n generation: published.id,\n models: published.pricing.size,\n });\n}\n\n/**\n * Makes a completed refresh current. Owners call this between scans, never\n * during one, so a scan cannot span two generations.\n */\nexport function publishPendingPricing(): boolean {\n if (!pending) return false;\n\n const next = createPricingGeneration(pending);\n if (!writeDiskCacheAtomically(getCachePath(), next)) return false;\n\n published = next;\n pending = null;\n getCoreDiagnostics()?.info?.(\"pricing.generation.published\", {\n generation: published.id,\n models: published.pricing.size,\n });\n return true;\n}\n\n/** Whether a refresh is waiting to be published. */\nexport function hasPendingPricing(): boolean {\n return pending !== null;\n}\n\nexport function hasBillablePricing(pricing: ModelPricing): boolean {\n return (\n pricing.inputCostPerToken > 0 ||\n pricing.outputCostPerToken > 0 ||\n pricing.cacheReadCostPerToken > 0 ||\n pricing.cacheCreateCostPerToken > 0\n );\n}\n\n/** Replaces the cache in one step, so an interrupted write cannot truncate it. */\nfunction writeDiskCacheAtomically(path: string, generation: PricingGeneration): boolean {\n const temporaryPath = `${path}.${process.pid}.tmp`;\n const payload = JSON.stringify({\n timestamp: Date.now(),\n data: Object.fromEntries(generation.pricing),\n });\n try {\n ensurePrivateDirectory(getCacheDir());\n writeFileSync(temporaryPath, payload);\n restrictPrivateFile(temporaryPath);\n renameSync(temporaryPath, path);\n return true;\n } catch (error) {\n rmSync(temporaryPath, { force: true });\n getCoreDiagnostics()?.warn(\"pricing.cache_write_failed\", {\n message: error instanceof Error ? error.message : String(error),\n });\n return false;\n }\n}\n\nexport interface RefreshPricingOptions {\n /** Abort the request when it outlives a startup's patience. */\n signal?: AbortSignal;\n timeoutMs?: number;\n}\n\n/**\n * Fetches prices into a pending generation. It does not become current until\n * {@link publishPendingPricing}, so an in-flight scan keeps the prices it\n * started with.\n */\nexport function refreshPricingCache(options: RefreshPricingOptions = {}): Promise<boolean> {\n refreshInFlight ??= fetchPricing(options).finally(() => {\n refreshInFlight = null;\n });\n return refreshInFlight;\n}\n\nasync function fetchPricing(options: RefreshPricingOptions): Promise<boolean> {\n if (pending || readDiskCache(true)) return false;\n\n const timeout = AbortSignal.timeout(options.timeoutMs ?? REFRESH_TIMEOUT_MS);\n const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;\n\n getCoreDiagnostics()?.info?.(\"pricing.refresh.started\", { generation: published.id });\n try {\n const response = await fetch(MODELS_DEV_URL, { signal });\n if (!response.ok) return false;\n const remote = parseModelsDevPricing(await response.json());\n if (remote.size === 0) return false;\n\n const next = loadSnapshot();\n for (const [name, pricing] of remote.entries()) {\n next.set(name, pricing);\n }\n\n pending = next;\n getCoreDiagnostics()?.info?.(\"pricing.refresh.completed\", {\n generation: published.id,\n models: next.size,\n });\n return true;\n } catch (error) {\n getCoreDiagnostics()?.warn(\"pricing.refresh.failed\", {\n generation: published.id,\n aborted: signal.aborted,\n message: error instanceof Error ? error.message : String(error),\n });\n return false;\n }\n}\n","export interface ModelPricing {\n inputCostPerToken: number;\n outputCostPerToken: number;\n cacheCreateCostPerToken: number;\n cacheReadCostPerToken: number;\n reasoningCostPerToken: number;\n webSearchCostPerRequest: number;\n}\n\nexport function normalizeModelKey(key: string): string {\n return key.trim().toLowerCase().replaceAll(\"_\", \"-\");\n}\n","import { normalizeModelKey, type ModelPricing } from \"./model-pricing.js\";\n\nexport const MODELS_DEV_URL = \"https://models.dev/api.json\";\n\nconst ORIGINAL_PROVIDERS = new Set([\n \"anthropic\",\n \"openai\",\n \"google\",\n \"deepseek\",\n \"moonshotai\",\n \"minimax\",\n \"mistral\",\n \"xai\",\n \"cohere\",\n \"zai\",\n \"zhipuai\",\n \"alibaba\",\n \"meta\",\n \"stepfun\",\n]);\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction perToken(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) && value >= 0\n ? value / 1_000_000\n : undefined;\n}\n\nexport function parseModelsDevPricing(data: unknown): Map<string, ModelPricing> {\n const providers = Object.entries(record(data) ?? {}).sort(\n ([a], [b]) =>\n Number(ORIGINAL_PROVIDERS.has(b)) - Number(ORIGINAL_PROVIDERS.has(a)) || a.localeCompare(b),\n );\n const qualified = new Map<string, ModelPricing>();\n const aliases = new Map<string, ModelPricing>();\n for (const [provider, rawProvider] of providers) {\n const models = record(record(rawProvider)?.[\"models\"]);\n for (const [model, rawModel] of Object.entries(models ?? {})) {\n const cost = record(record(rawModel)?.[\"cost\"]);\n if (!cost) continue;\n const input = perToken(cost[\"input\"]);\n const output = perToken(cost[\"output\"]);\n if (input === undefined || output === undefined) continue;\n const pricing: ModelPricing = {\n inputCostPerToken: input,\n outputCostPerToken: output,\n cacheCreateCostPerToken: perToken(cost[\"cache_write\"]) ?? input,\n cacheReadCostPerToken: perToken(cost[\"cache_read\"]) ?? input,\n reasoningCostPerToken: output,\n webSearchCostPerRequest: 0.01,\n };\n qualified.set(normalizeModelKey(`${provider}/${model}`), pricing);\n const name = normalizeModelKey(model);\n if (!aliases.has(name)) aliases.set(name, pricing);\n }\n }\n return new Map([...aliases, ...qualified]);\n}\n","{\n \"claude-3-5-haiku\": [8e-7, 0.000004, 0.000001, 8e-8],\n \"claude-3-5-sonnet\": [0.000003, 0.000015, 0.00000375, 3e-7],\n \"claude-3-7-sonnet\": [0.000003, 0.000015, 0.00000375, 3e-7],\n \"claude-haiku-4-5\": [0.000001, 0.000005, 0.00000125, 1e-7],\n \"claude-sonnet-4\": [0.000003, 0.000015, 0.00000375, 3e-7],\n \"claude-sonnet-4-5\": [0.000003, 0.000015, 0.00000375, 3e-7],\n \"claude-sonnet-4-6\": [0.000003, 0.000015, 0.00000375, 3e-7],\n \"claude-opus-4\": [0.000015, 0.000075, 0.00001875, 0.0000015],\n \"claude-opus-4-1\": [0.000015, 0.000075, 0.00001875, 0.0000015],\n \"claude-opus-4-5\": [0.000005, 0.000025, 0.00000625, 5e-7],\n \"claude-opus-4-6\": [0.000005, 0.000025, 0.00000625, 5e-7],\n \"claude-opus-4-7\": [0.000005, 0.000025, 0.00000625, 5e-7],\n \"anthropic/claude-sonnet-4-5\": [0.000003, 0.000015, 0.00000375, 3e-7],\n \"anthropic/claude-sonnet-4-6\": [0.000003, 0.000015, 0.00000375, 3e-7],\n \"anthropic/claude-opus-4-6\": [0.000005, 0.000025, 0.00000625, 5e-7],\n \"gpt-4.1\": [0.000002, 0.000008, null, 5e-7],\n \"gpt-4.1-mini\": [4e-7, 0.0000016, null, 1e-7],\n \"gpt-4.1-nano\": [1e-7, 4e-7, null, 2.5e-8],\n \"gpt-4o\": [0.0000025, 0.00001, null, 0.00000125],\n \"gpt-4o-mini\": [1.5e-7, 6e-7, null, 7.5e-8],\n \"gpt-5\": [0.00000125, 0.00001, null, 1.25e-7],\n \"gpt-5.1\": [0.00000125, 0.00001, null, 1.25e-7],\n \"gpt-5.1-codex\": [0.00000125, 0.00001, null, 1.25e-7],\n \"gpt-5.1-codex-mini\": [2.5e-7, 0.000002, null, 2.5e-8],\n \"gpt-5.2\": [0.00000175, 0.000014, null, 1.75e-7],\n \"gpt-5.2-codex\": [0.00000175, 0.000014, null, 1.75e-7],\n \"gpt-5.3-codex\": [0.00000175, 0.000014, null, 1.75e-7],\n \"gpt-5.4\": [0.0000025, 0.000015, null, 2.5e-7],\n \"gpt-5.4-mini\": [7.5e-7, 0.0000045, null, 7.5e-8],\n \"gpt-5.4-nano\": [2e-7, 0.00000125, null, 2e-8],\n \"gpt-5.5\": [0.000005, 0.00003, null, 5e-7],\n \"gpt-5-mini\": [2.5e-7, 0.000002, null, 2.5e-8],\n \"gpt-5-nano\": [5e-8, 4e-7, null, 5e-9],\n \"moonshotai/kimi-k2-0905\": [6e-7, 0.0000025, null, null],\n \"moonshotai/kimi-k2-instruct\": [5.7e-7, 0.0000023, null, null],\n \"moonshotai/kimi-k2-thinking\": [6e-7, 0.0000025, null, null],\n \"deepseek-chat\": [2.8e-7, 4.2e-7, null, 2.8e-8],\n \"deepseek-reasoner\": [2.8e-7, 4.2e-7, null, 2.8e-8],\n \"qwen3-coder-480b-a35b-instruct\": [3e-7, 0.0000013, null, null],\n \"gemini-2.5-pro\": [0.00000125, 0.00001, null, 1.25e-7],\n \"gemini-2.5-flash\": [3e-7, 0.0000025, null, 3e-8]\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { CostSource, Message, MessageTokens, SessionStats } from \"../types/index.js\";\nimport { pricingResolver } from \"./resolver.js\";\n\nexport interface CostUsage extends MessageTokens {\n web_search_requests?: number;\n}\n\nexport interface CostEstimate {\n cost: number;\n source: CostSource;\n}\n\nfunction positive(value: number | undefined): number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0 ? value : 0;\n}\n\nconst pricingMissCapture = new AsyncLocalStorage<Set<string>>();\n\nexport const PRICING_CAPTURE_EPOCH = \"pricing-capture-v1\";\n\n/** Whether a model that previously produced a zero estimate is now billable. */\nexport function pricingBecameAvailable(unpricedModels: unknown): boolean {\n if (!Array.isArray(unpricedModels)) return false;\n return unpricedModels.some(\n (model) => typeof model === \"string\" && pricingResolver.resolve(model) !== null,\n );\n}\n\n/**\n * Records which models {@link estimateCostForTokens} failed to price during\n * `run`. Cached session heads carry these misses so they can be re-parsed once\n * pricing for those models becomes available.\n */\ninterface PricingMissCaptureResult<T> {\n result: T;\n unpricedModels: string[];\n}\n\nexport function capturePricingMisses<T>(\n run: () => Promise<T>,\n): Promise<PricingMissCaptureResult<T>>;\nexport function capturePricingMisses<T>(run: () => T): PricingMissCaptureResult<T>;\nexport function capturePricingMisses<T>(\n run: () => T | Promise<T>,\n): PricingMissCaptureResult<T> | Promise<PricingMissCaptureResult<T>> {\n const capture = new Set<string>();\n const result = pricingMissCapture.run(capture, run);\n if (result instanceof Promise) {\n return result.then((resolved) => ({ result: resolved, unpricedModels: [...capture] }));\n }\n return { result, unpricedModels: [...capture] };\n}\n\nexport function estimateCostForTokens(\n model: string | null | undefined,\n usage: CostUsage | undefined,\n): CostEstimate | null {\n if (!model || !usage) return null;\n\n const pricing = pricingResolver.resolve(model);\n if (!pricing) {\n pricingMissCapture.getStore()?.add(model);\n return null;\n }\n\n const cacheRead = positive(usage.cache_read);\n const cacheCreate = positive(usage.cache_create);\n const input = Math.max(0, positive(usage.input) - cacheRead - cacheCreate);\n const output = positive(usage.output);\n const reasoning = positive(usage.reasoning);\n const webSearchRequests = positive(usage.web_search_requests);\n\n const cost =\n input * pricing.inputCostPerToken +\n output * pricing.outputCostPerToken +\n reasoning * pricing.reasoningCostPerToken +\n cacheRead * pricing.cacheReadCostPerToken +\n cacheCreate * pricing.cacheCreateCostPerToken +\n webSearchRequests * pricing.webSearchCostPerRequest;\n\n return cost > 0 ? { cost: Number(cost.toFixed(8)), source: \"estimated\" } : null;\n}\n\nexport function applyMessageCost(message: Message): void {\n if ((message.cost ?? 0) > 0) {\n message.cost_source = \"recorded\";\n return;\n }\n\n const estimate = estimateCostForTokens(message.model, message.tokens);\n if (!estimate) return;\n\n message.cost = estimate.cost;\n message.cost_source = estimate.source;\n}\n\nexport function applyMessageCosts(messages: Message[]): { totalCost: number; source?: CostSource } {\n let totalCost = 0;\n let source: CostSource | undefined;\n\n for (const message of messages) {\n applyMessageCost(message);\n const cost = message.cost ?? 0;\n if (cost <= 0) continue;\n\n totalCost += cost;\n if (message.cost_source === \"estimated\") source = \"estimated\";\n else if (!source) source = \"recorded\";\n }\n\n return { totalCost: Number(totalCost.toFixed(8)), source };\n}\n\nexport function withEstimatedSessionCost<T extends SessionStats>(\n stats: T,\n model: string | null | undefined,\n): T {\n if (stats.total_cost > 0) {\n return { ...stats, cost_source: stats.cost_source ?? \"recorded\" };\n }\n\n const estimate = estimateCostForTokens(model, {\n input: stats.total_input_tokens,\n output: stats.total_output_tokens,\n cache_read: stats.total_cache_read_tokens,\n cache_create: stats.total_cache_create_tokens,\n });\n if (!estimate) return stats;\n\n return { ...stats, total_cost: estimate.cost, cost_source: estimate.source };\n}\n","{\n \"anthropic--claude-4.6-opus\": \"claude-opus-4-6\",\n \"anthropic--claude-4.6-sonnet\": \"claude-sonnet-4-6\",\n \"claude-4.6-sonnet\": \"claude-sonnet-4-6\",\n \"anthropic--claude-4.5-opus\": \"claude-opus-4-5\",\n \"anthropic--claude-4.5-sonnet\": \"claude-sonnet-4-5\",\n \"anthropic--claude-4.5-haiku\": \"claude-haiku-4-5\",\n \"claude-4.5-sonnet-thinking\": \"claude-sonnet-4-5\",\n \"claude-4-sonnet-thinking\": \"claude-sonnet-4-5\",\n \"claude-4-opus\": \"claude-opus-4-5\",\n \"cursor-auto\": \"claude-sonnet-4-5\",\n \"cursor-agent-auto\": \"claude-sonnet-4-5\",\n \"copilot-auto\": \"claude-sonnet-4-5\",\n \"copilot-openai-auto\": \"gpt-5.3-codex\",\n \"copilot-anthropic-auto\": \"claude-sonnet-4-5\",\n \"kimi-for-coding\": \"moonshotai/kimi-k2-0905\",\n \"kimi-k2.5\": \"moonshotai/kimi-k2-0905\",\n \"moonshot-cn/kimi-k2.5\": \"moonshotai/kimi-k2-0905\",\n \"gpt-5-codex\": \"gpt-5\",\n \"gpt-5.1-codex-high\": \"gpt-5.3-codex\",\n \"gpt-5.2-low\": \"gpt-5.2\"\n}\n","import aliasesData from \"./data/aliases.json\";\nimport {\n getPricingRegistry,\n hasBillablePricing,\n normalizeModelKey,\n type ModelPricing,\n} from \"./fetcher.js\";\n\nconst BUILTIN_ALIASES = Object.fromEntries(\n Object.entries(aliasesData as Record<string, string>).map(([key, value]) => [\n normalizeModelKey(key),\n normalizeModelKey(value),\n ]),\n);\n\nfunction stripVersion(model: string): string {\n return model.replace(/@.*$/, \"\").replace(/-\\d{8}$/, \"\");\n}\n\nfunction stripProviderPrefix(model: string): string {\n const parts = model.split(\"/\");\n return parts[parts.length - 1] ?? model;\n}\n\nfunction resolveAlias(model: string): string {\n return BUILTIN_ALIASES[model] ?? model;\n}\n\nfunction getCandidates(rawModel: string): string[] {\n const withPrefix = stripVersion(normalizeModelKey(rawModel));\n const stripped = stripProviderPrefix(withPrefix);\n const aliased = resolveAlias(stripped);\n const candidates = [\n withPrefix,\n resolveAlias(withPrefix),\n stripped,\n aliased,\n `anthropic/${stripped}`,\n `openai/${stripped}`,\n `openrouter/openai/${stripped}`,\n `openrouter/anthropic/${stripped}`,\n `moonshotai/${stripped}`,\n `novita/moonshotai/${stripped}`,\n ];\n\n return [...new Set(candidates.filter(Boolean))];\n}\n\nfunction lookupCandidate(model: string, registry: Map<string, ModelPricing>) {\n const direct = registry.get(model);\n if (direct && hasBillablePricing(direct)) return direct;\n\n const alias = resolveAlias(model);\n if (alias !== model) {\n const aliased = registry.get(alias);\n if (aliased && hasBillablePricing(aliased)) return aliased;\n }\n\n return null;\n}\n\nfunction fuzzyLookup(model: string, registry: Map<string, ModelPricing>) {\n const direct = registry.get(model);\n if (direct && hasBillablePricing(direct)) return direct;\n\n for (let index = model.length - 1; index >= 0; index--) {\n if (model[index] !== \"-\" && model[index] !== \"@\") continue;\n const pricing = registry.get(model.slice(0, index));\n if (pricing && hasBillablePricing(pricing)) return pricing;\n }\n return null;\n}\n\nexport interface PricingResolver {\n resolve(rawModelName: string): ModelPricing | null;\n}\n\nexport const pricingResolver: PricingResolver = {\n resolve(rawModelName: string): ModelPricing | null {\n const registry = getPricingRegistry();\n const exact = registry.get(normalizeModelKey(rawModelName));\n if (exact && hasBillablePricing(exact)) return exact;\n const candidates = getCandidates(rawModelName);\n\n for (const candidate of candidates) {\n const pricing = lookupCandidate(candidate, registry);\n if (pricing) return pricing;\n }\n\n for (const candidate of candidates) {\n const pricing = fuzzyLookup(candidate, registry);\n if (pricing) return pricing;\n }\n\n return null;\n },\n};\n","/**\n * 性能追踪工具 - 用于测量启动过程中的各个阶段耗时\n */\n\nexport interface PerfMarker {\n name: string;\n startTime: number;\n endTime?: number;\n duration?: number;\n children: PerfMarker[];\n parent?: PerfMarker;\n}\n\nclass PerfTracer {\n private rootMarkers: PerfMarker[] = [];\n private activeStack: PerfMarker[] = [];\n private enabled = false;\n\n enable() {\n this.enabled = true;\n }\n\n start(name: string): PerfMarker {\n const marker: PerfMarker = {\n name,\n startTime: performance.now(),\n children: [],\n };\n\n if (!this.enabled) return marker;\n\n const parent = this.activeStack[this.activeStack.length - 1];\n if (parent) {\n marker.parent = parent;\n parent.children.push(marker);\n } else {\n this.rootMarkers.push(marker);\n }\n\n this.activeStack.push(marker);\n return marker;\n }\n\n end(marker?: PerfMarker): void {\n if (!this.enabled) return;\n\n const target = marker ?? this.activeStack[this.activeStack.length - 1];\n if (!target) return;\n\n target.endTime = performance.now();\n target.duration = target.endTime - target.startTime;\n\n // Pop until we remove the target\n while (this.activeStack.length > 0) {\n const popped = this.activeStack.pop();\n if (popped === target) break;\n }\n }\n\n measure<T>(name: string, fn: () => T): T {\n const marker = this.start(name);\n try {\n return fn();\n } finally {\n this.end(marker);\n }\n }\n\n async measureAsync<T>(name: string, fn: () => Promise<T>): Promise<T> {\n const marker = this.start(name);\n try {\n return await fn();\n } finally {\n this.end(marker);\n }\n }\n\n getReport(): string {\n if (!this.enabled) return \"Performance tracing disabled\";\n\n const lines: string[] = [];\n lines.push(\"\\n=== Performance Report ===\\n\");\n\n for (const marker of this.rootMarkers) {\n this.formatMarker(marker, 0, lines);\n }\n\n return lines.join(\"\\n\");\n }\n\n private formatMarker(marker: PerfMarker, depth: number, lines: string[]): void {\n const indent = \" \".repeat(depth);\n const duration = marker.duration?.toFixed(2) ?? \"?\";\n lines.push(`${indent}${marker.name}: ${duration}ms`);\n\n for (const child of marker.children) {\n this.formatMarker(child, depth + 1, lines);\n }\n }\n\n reset(): void {\n this.rootMarkers = [];\n this.activeStack = [];\n }\n}\n\nexport const perf = new PerfTracer();\n","import { closeSync, openSync, readSync } from \"node:fs\";\nimport { StringDecoder } from \"node:string_decoder\";\nimport { getCoreDiagnostics } from \"./diagnostics.js\";\n\nconst READ_CHUNK_BYTES = 1 << 20;\n\nexport function* parseJsonlLines(content: string): Generator<Record<string, unknown>> {\n let total = 0;\n let skipped = 0;\n for (const line of content.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n total += 1;\n try {\n yield JSON.parse(trimmed) as Record<string, unknown>;\n } catch {\n skipped += 1;\n }\n }\n // Reported after the generator is fully drained — a consumer that breaks\n // out of the loop early (e.g. to grab just the first line) never reaches\n // this point, so its skipped count goes unreported.\n if (skipped > 0) {\n getCoreDiagnostics()?.warn(\"agent.jsonl_lines_skipped\", { skipped, total });\n }\n}\n\n/**\n * Streams trimmed non-empty lines chunk by chunk so a session log is never\n * held in memory at once. Codex rollout files can exceed 400 MB; loading them\n * with readFileSync + split doubles that as UTF-16 strings and OOMs the\n * scan-refresh worker.\n */\nexport function* readJsonlFileLines(\n filePath: string,\n chunkBytes = READ_CHUNK_BYTES,\n): Generator<string> {\n const fd = openSync(filePath, \"r\");\n try {\n const buffer = Buffer.alloc(chunkBytes);\n // StringDecoder buffers multi-byte UTF-8 sequences split across chunks.\n const decoder = new StringDecoder(\"utf8\");\n // Chunks of the record currently being assembled, joined once when its line\n // break arrives. Concatenating onto a string instead would re-copy the whole\n // partial record on every chunk — quadratic on the multi-megabyte single-line\n // records agent logs routinely contain.\n let pending: string[] = [];\n let bytesRead = readSync(fd, buffer, 0, chunkBytes, -1);\n while (bytesRead > 0) {\n const decoded = decoder.write(buffer.subarray(0, bytesRead));\n const lastBreak = decoded.lastIndexOf(\"\\n\");\n if (lastBreak === -1) {\n if (decoded) pending.push(decoded);\n } else {\n pending.push(decoded.slice(0, lastBreak));\n const complete = pending.join(\"\");\n pending = [decoded.slice(lastBreak + 1)];\n for (const line of complete.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed) yield trimmed;\n }\n }\n bytesRead = readSync(fd, buffer, 0, chunkBytes, -1);\n }\n pending.push(decoder.end());\n const tail = pending.join(\"\").trim();\n if (tail) yield tail;\n } finally {\n closeSync(fd);\n }\n}\n\nexport function* readJsonlFile(filePath: string): Generator<Record<string, unknown>> {\n let total = 0;\n let skipped = 0;\n for (const line of readJsonlFileLines(filePath)) {\n total += 1;\n try {\n yield JSON.parse(line) as Record<string, unknown>;\n } catch {\n skipped += 1;\n }\n }\n // Same early-return caveat as parseJsonlLines above.\n if (skipped > 0) {\n getCoreDiagnostics()?.warn(\"agent.jsonl_lines_skipped\", { skipped, total, filePath });\n }\n}\n","const INTERNAL_BLOCK_TAGS = [\n \"command-message\",\n \"command-name\",\n \"local-command-caveat\",\n \"local-command-stdout\",\n \"system-reminder\",\n];\n\nconst TRANSPARENT_TAGS = [\"command-args\"];\n\nconst INTERNAL_EVENT_TYPES = new Set([\n \"progress\",\n \"file history snapshot\",\n \"file-history snapshot\",\n \"file_history snapshot\",\n \"queue operation\",\n \"queue-operation\",\n \"queue_operation\",\n \"last prompt\",\n \"last-prompt\",\n \"last_prompt\",\n]);\n\nfunction blockTagPattern(tag: string): RegExp {\n return new RegExp(`<${tag}\\\\b[^>]*>[\\\\s\\\\S]*?<\\\\/${tag}>`, \"gi\");\n}\n\nfunction blockTagLinePattern(tag: string): RegExp {\n return new RegExp(\n `(^|\\\\r?\\\\n)[ \\\\t]*<${tag}\\\\b[^>]*>[\\\\s\\\\S]*?<\\\\/${tag}>[ \\\\t]*(?:\\\\r?\\\\n|$)`,\n \"gi\",\n );\n}\n\nfunction openBlockTagPattern(tag: string): RegExp {\n return new RegExp(`\\\\n*<${tag}\\\\b[^>]*>[\\\\s\\\\S]*$`, \"gi\");\n}\n\nfunction looseTagPattern(tag: string): RegExp {\n return new RegExp(`<\\\\/?${tag}\\\\b[^>]*>`, \"gi\");\n}\n\nexport function isInternalEventType(value: unknown): boolean {\n if (typeof value !== \"string\") return false;\n const normalized = value.trim().toLowerCase().replace(/[_-]+/g, \" \");\n return INTERNAL_EVENT_TYPES.has(normalized);\n}\n\nexport function cleanDisplayText(text: string): string | null {\n let cleaned = text;\n\n for (const tag of INTERNAL_BLOCK_TAGS) {\n cleaned = cleaned.replace(blockTagLinePattern(tag), \"$1\");\n cleaned = cleaned.replace(blockTagPattern(tag), \"\");\n cleaned = cleaned.replace(openBlockTagPattern(tag), \"\");\n }\n\n for (const tag of INTERNAL_BLOCK_TAGS) {\n cleaned = cleaned.replace(looseTagPattern(tag), \"\");\n }\n\n for (const tag of TRANSPARENT_TAGS) {\n cleaned = cleaned.replace(looseTagPattern(tag), \"\");\n }\n\n cleaned = cleaned.replace(/[ \\t]+(?=\\r?\\n|$)/g, \"\").replace(/(?:\\r?\\n)+$/g, \"\");\n\n return cleaned.trim() ? cleaned : null;\n}\n\nexport function firstVisibleLine(text: string): string | null {\n const cleaned = cleanDisplayText(text);\n if (!cleaned) return null;\n return (\n cleaned\n .split(\"\\n\")\n .find((line) => line.trim())\n ?.trim() ?? null\n );\n}\n","import { basename } from \"node:path\";\nimport { cleanDisplayText } from \"./parse-cleanup.js\";\n\nconst TITLE_MAX_LENGTH = 100;\nconst UNTITLED_SESSION = \"Untitled Session\";\n\n/** Normalize extracted title text for display. */\nexport function normalizeTitleText(text: string): string | null {\n const visible =\n cleanDisplayText(text)\n ?.split(\"\\n\")\n .find((line) => line.trim())\n ?.trim() ?? null;\n if (!visible) return null;\n const cleaned = visible.replace(/\\s+/g, \" \").trim();\n if (!cleaned) return null;\n return cleaned.slice(0, TITLE_MAX_LENGTH);\n}\n\n/** Return a stable basename for fallback title. */\nexport function basenameTitle(path: string | null | undefined): string | null {\n if (!path) return null;\n const normalized = path.trim().replace(/[/\\\\]+$/, \"\");\n if (!normalized) return null;\n const name = basename(normalized).trim();\n return name || null;\n}\n\n/** Resolve final session title from explicit, message, and directory fallbacks. */\nexport function resolveSessionTitle(\n explicit: string | null | undefined,\n message: string | null | undefined,\n directory: string | null | undefined,\n): string {\n for (const candidate of [explicit, message, directory]) {\n if (candidate) {\n const normalized = normalizeTitleText(candidate);\n if (normalized) return normalized;\n }\n }\n return UNTITLED_SESSION;\n}\n","import type { MessageTokens } from \"../types/index.js\";\nimport { estimateCostForTokens } from \"../pricing/index.js\";\n\nexport function estimateTokenCost(\n model: string | null | undefined,\n tokens?: MessageTokens,\n): number | null {\n return estimateCostForTokens(model, tokens)?.cost ?? null;\n}\n","import { getCoreDiagnostics } from \"./diagnostics.js\";\n\n/** Narrow to a plain object (excludes arrays and null); undefined on mismatch. */\nexport function asRecord(value: unknown): Record<string, unknown> | undefined {\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return undefined;\n}\n\n/** Narrow to a string; undefined on mismatch. */\nexport function asString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\n/** Narrow to a finite number (rejects NaN/Infinity); undefined on mismatch. */\nexport function asNumber(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\n/** Narrow to an array; undefined on mismatch. */\nexport function asArray(value: unknown): unknown[] | undefined {\n return Array.isArray(value) ? value : undefined;\n}\n\n/**\n * Parses JSON text to a plain object; undefined on parse failure or a\n * non-object shape (e.g. array, string, null). Callers that need drift\n * reporting compose this with `narrowField`.\n */\nexport function safeParseJsonRecord(json: string): Record<string, unknown> | undefined {\n let raw: unknown;\n try {\n raw = JSON.parse(json);\n } catch {\n return undefined;\n }\n return asRecord(raw);\n}\n\nconst reportedFieldMismatches = new Set<string>();\n\n/**\n * Reports a field shape mismatch once per (agentName, field) for the life of\n * the process — an upstream format drift hits every line of a session file,\n * and warning per line would flood the diagnostics sink for no added signal.\n */\nexport function reportFieldMismatch(agentName: string, field: string): void {\n const key = `${agentName}\\0${field}`;\n if (reportedFieldMismatches.has(key)) return;\n reportedFieldMismatches.add(key);\n getCoreDiagnostics()?.warn(\"agent.field_shape_mismatch\", { agentName, field });\n}\n\n/**\n * Narrows a field's value with `narrow`, reporting once via\n * `reportFieldMismatch` when the field is present but narrowing fails.\n * `undefined`/`null` mean the field is absent (null-as-absent) and return\n * undefined silently — that's a normal shape, not drift.\n */\nexport function narrowField<T>(\n agent: string,\n field: string,\n value: unknown,\n narrow: (v: unknown) => T | undefined,\n): T | undefined {\n if (value === undefined || value === null) return undefined;\n const result = narrow(value);\n if (result === undefined) reportFieldMismatch(agent, field);\n return result;\n}\n","import type { Message, MessagePart } from \"../types/index.js\";\nimport {\n cleanDisplayText,\n isInternalEventType as isRawInternalEventType,\n} from \"./parse-cleanup.js\";\nimport { normalizeTitleText } from \"./title-fallback.js\";\n\nexport function isInternalEventType(value: unknown): boolean {\n return isRawInternalEventType(value);\n}\n\nexport function cleanInternalText(text: string): string {\n return cleanDisplayText(text) ?? \"\";\n}\n\nfunction cleanUnknown(value: unknown): unknown {\n if (typeof value === \"string\") return cleanInternalText(value);\n if (Array.isArray(value)) return value.map(cleanUnknown);\n if (!value || typeof value !== \"object\") return value;\n\n const cleaned: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(value)) {\n cleaned[key] = cleanUnknown(child);\n }\n return cleaned;\n}\n\nexport function cleanMessagePart(part: MessagePart): MessagePart | null {\n if (part.type === \"text\" || part.type === \"reasoning\" || part.type === \"plan\") {\n const text = cleanInternalText(part.text);\n return text ? { ...part, text } : null;\n }\n if (part.type !== \"tool\") return part;\n\n const title = part.title ? cleanInternalText(part.title) : \"\";\n const state = {\n ...part.state,\n ...(part.state.input !== undefined ? { input: cleanUnknown(part.state.input) } : {}),\n ...(part.state.output !== undefined ? { output: cleanUnknown(part.state.output) } : {}),\n ...(part.state.error !== undefined ? { error: cleanUnknown(part.state.error) } : {}),\n ...(part.state.metadata !== undefined ? { metadata: cleanUnknown(part.state.metadata) } : {}),\n };\n const { title: _title, ...withoutTitle } = part;\n return {\n ...withoutTitle,\n ...(title ? { title } : {}),\n state,\n };\n}\n\nexport function cleanMessageParts(parts: MessagePart[]): MessagePart[] {\n return parts.flatMap((part) => {\n const cleaned = cleanMessagePart(part);\n return cleaned ? [cleaned] : [];\n });\n}\n\nexport function cleanParsedMessage(message: Message): Message | null {\n const parts = cleanMessageParts(message.parts);\n const hasUsage =\n (message.cost ?? 0) > 0 || Object.values(message.tokens ?? {}).some((value) => value > 0);\n if (parts.length === 0 && !hasUsage) return null;\n return { ...message, parts };\n}\n\nexport function cleanParsedMessages(messages: Message[]): Message[] {\n return messages.flatMap((message) => {\n const cleaned = cleanParsedMessage(message);\n return cleaned ? [cleaned] : [];\n });\n}\n\nexport function firstUserMessageTitle(messages: Message[]): string | null {\n for (const message of messages) {\n if (message.role !== \"user\") continue;\n for (const part of message.parts) {\n if (part.type !== \"text\") continue;\n const title = normalizeTitleText(cleanInternalText(part.text));\n if (title) return title;\n }\n }\n return null;\n}\n","/**\n * SQLite helper — graceful degradation if better-sqlite3 is unavailable.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport { getCoreDiagnostics } from \"./diagnostics.js\";\nimport {\n ensurePrivateDirectory,\n restrictPrivateDatabase,\n restrictPrivateFile,\n} from \"./private-storage.js\";\n\ninterface SQLiteStatement {\n all(...params: unknown[]): DatabaseRow[];\n get(...params: unknown[]): DatabaseRow | undefined;\n /** Streams rows so a large result set never has to be materialized at once. */\n iterate(...params: unknown[]): IterableIterator<DatabaseRow>;\n run(...params: unknown[]): unknown;\n}\n\ninterface SQLiteTransaction {\n (...params: unknown[]): unknown;\n}\n\nexport interface SQLiteTransactionRunner<T extends SQLiteTransaction> {\n (...params: Parameters<T>): ReturnType<T>;\n /**\n * BEGIN IMMEDIATE: takes the write lock up front so busy_timeout governs the\n * wait. A deferred write transaction that reads first can die instantly with\n * SQLITE_BUSY_SNAPSHOT when another connection commits in between.\n */\n immediate(...params: Parameters<T>): ReturnType<T>;\n}\n\ninterface SQLitePragmaCapable {\n pragma(sql: string): unknown;\n}\n\ntype SQLiteDatabaseConstructor = (\n path: string,\n options?: { readonly?: boolean },\n) => SQLiteDatabase & SQLitePragmaCapable;\n\nconst SQLITE_BUSY_TIMEOUT_MS = 5000;\n\nlet DatabaseConstructor: SQLiteDatabaseConstructor | null = null;\nlet loadErrorMessage: string | null = null;\n\ntry {\n const require = createRequire(import.meta.url);\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const mod = require(\"better-sqlite3\");\n DatabaseConstructor = (\n typeof mod === \"function\" ? mod : (mod as { default?: unknown }).default\n ) as SQLiteDatabaseConstructor;\n} catch (error) {\n // better-sqlite3 not installed — adapters that need SQLite will gracefully skip.\n // This module body evaluates before a host has a chance to call\n // setCoreDiagnostics, so reporting here would always be dropped — defer the\n // warn to reportUnavailableOnce(), called from the first actual open attempt.\n loadErrorMessage = error instanceof Error ? error.message : String(error);\n}\n\nlet unavailableReported = false;\n\nfunction reportUnavailableOnce(): void {\n if (unavailableReported) return;\n unavailableReported = true;\n getCoreDiagnostics()?.warn(\"sqlite.unavailable\", { message: loadErrorMessage });\n}\n\nexport interface DatabaseRow {\n [key: string]: unknown;\n}\n\nexport interface SQLiteDatabase {\n prepare(sql: string): SQLiteStatement;\n function(\n name: string,\n options: { deterministic?: boolean },\n callback: (...params: unknown[]) => unknown,\n ): void;\n exec(sql: string): void;\n transaction<T extends SQLiteTransaction>(fn: T): SQLiteTransactionRunner<T>;\n close(): void;\n}\n\nexport interface SchemaMigration {\n version: number;\n destructive?: boolean;\n migrate(db: SQLiteDatabase): void;\n}\n\nexport interface RunSchemaMigrationsOptions {\n dbPath: string;\n currentVersion: number;\n targetVersion: number;\n migrations: SchemaMigration[];\n backupTables: string[];\n backupLabel: string;\n}\n\nexport class SchemaMigrationPlanError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SchemaMigrationPlanError\";\n }\n}\n\nfunction validateSchemaVersion(value: number, label: string): void {\n if (Number.isSafeInteger(value) && value >= 0) return;\n throw new SchemaMigrationPlanError(`${label} must be a non-negative safe integer`);\n}\n\nfunction validateMigrationPlan(options: RunSchemaMigrationsOptions): void {\n let previousVersion = -1;\n let reachesTarget = false;\n\n for (const migration of options.migrations) {\n if (!Number.isSafeInteger(migration.version) || migration.version < 0) {\n throw new SchemaMigrationPlanError(\n `${options.backupLabel} migration version must be a non-negative safe integer`,\n );\n }\n if (migration.version <= previousVersion) {\n throw new SchemaMigrationPlanError(\n `${options.backupLabel} migrations must be ordered by strictly increasing version`,\n );\n }\n previousVersion = migration.version;\n reachesTarget ||= migration.version === options.targetVersion;\n }\n\n if (!reachesTarget) {\n throw new SchemaMigrationPlanError(\n `${options.backupLabel} has no migration for target version ${options.targetVersion}`,\n );\n }\n}\n\nfunction quoteIdentifier(value: string): string {\n return `\"${value.replaceAll('\"', '\"\"')}\"`;\n}\n\nfunction quoteSqlString(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\nfunction isInMemoryPath(dbPath: string): boolean {\n return (\n dbPath === \":memory:\" || dbPath.startsWith(\"file::memory:\") || dbPath.includes(\"mode=memory\")\n );\n}\n\nexport function getUserVersion(db: SQLiteDatabase): number {\n const row = db.prepare(\"PRAGMA user_version\").get() as DatabaseRow | undefined;\n return Number(row?.user_version ?? 0);\n}\n\nexport function setUserVersion(db: SQLiteDatabase, version: number): void {\n db.exec(`PRAGMA user_version = ${Math.trunc(version)}`);\n}\n\nexport function tableExists(db: SQLiteDatabase, tableName: string): boolean {\n const row = db\n .prepare(\n `\n SELECT 1 AS value\n FROM sqlite_master\n WHERE name = ? AND type IN ('table', 'view')\n LIMIT 1\n `,\n )\n .get(tableName) as DatabaseRow | undefined;\n return row !== undefined;\n}\n\nexport function columnExists(db: SQLiteDatabase, tableName: string, columnName: string): boolean {\n if (!tableExists(db, tableName)) {\n return false;\n }\n\n const rows = db.prepare(`PRAGMA table_info(${quoteIdentifier(tableName)})`).all();\n return rows.some((row) => String(row.name) === columnName);\n}\n\nexport function tableHasRows(db: SQLiteDatabase, tableName: string): boolean {\n if (!tableExists(db, tableName)) {\n return false;\n }\n\n const row = db.prepare(`SELECT 1 AS value FROM ${quoteIdentifier(tableName)} LIMIT 1`).get() as\n | DatabaseRow\n | undefined;\n return row !== undefined;\n}\n\nexport function backupDatabase(db: SQLiteDatabase, dbPath: string, label: string): string | null {\n if (isInMemoryPath(dbPath)) {\n return null;\n }\n\n const timestamp = new Date(Date.now()).toISOString().replaceAll(\":\", \"\").replaceAll(\".\", \"-\");\n let backupPath = join(dirname(dbPath), `${basename(dbPath)}.${timestamp}.${label}.bak`);\n for (let counter = 1; existsSync(backupPath); counter += 1) {\n backupPath = join(dirname(dbPath), `${basename(dbPath)}.${timestamp}.${label}.${counter}.bak`);\n }\n db.exec(`VACUUM INTO ${quoteSqlString(backupPath)}`);\n // A fresh inode does not inherit the source database's mode.\n restrictPrivateFile(backupPath);\n return backupPath;\n}\n\nexport function backupDatabaseIfPopulated(\n db: SQLiteDatabase,\n dbPath: string,\n label: string,\n tables: string[],\n): string | null {\n if (!tables.some((table) => tableHasRows(db, table))) {\n return null;\n }\n\n return backupDatabase(db, dbPath, label);\n}\n\nexport function runSchemaMigrations(\n db: SQLiteDatabase,\n options: RunSchemaMigrationsOptions,\n): string[] {\n const backups: string[] = [];\n let currentVersion = options.currentVersion;\n validateSchemaVersion(currentVersion, `${options.backupLabel} current version`);\n validateSchemaVersion(options.targetVersion, `${options.backupLabel} target version`);\n if (currentVersion >= options.targetVersion) return backups;\n validateMigrationPlan(options);\n\n for (const migration of options.migrations) {\n if (migration.version <= currentVersion) {\n continue;\n }\n if (migration.version > options.targetVersion) {\n break;\n }\n\n const fromVersion = currentVersion;\n const startedAt = performance.now();\n getCoreDiagnostics()?.info?.(\"sqlite.migration.started\", {\n label: options.backupLabel,\n from_version: fromVersion,\n to_version: migration.version,\n destructive: migration.destructive ?? false,\n });\n\n try {\n let backupCreated = false;\n if (migration.destructive) {\n const backupPath = backupDatabaseIfPopulated(\n db,\n options.dbPath,\n options.backupLabel,\n options.backupTables,\n );\n if (backupPath) {\n backups.push(backupPath);\n backupCreated = true;\n }\n }\n\n const apply = db.transaction(() => {\n migration.migrate(db);\n setUserVersion(db, migration.version);\n });\n apply.immediate();\n currentVersion = migration.version;\n getCoreDiagnostics()?.info?.(\"sqlite.migration.completed\", {\n label: options.backupLabel,\n from_version: fromVersion,\n to_version: migration.version,\n destructive: migration.destructive ?? false,\n backup_created: backupCreated,\n duration_ms: Math.round(performance.now() - startedAt),\n });\n } catch (error) {\n getCoreDiagnostics()?.warn(\"sqlite.migration.failed\", {\n label: options.backupLabel,\n from_version: fromVersion,\n to_version: migration.version,\n destructive: migration.destructive ?? false,\n duration_ms: Math.round(performance.now() - startedAt),\n message: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n }\n\n if (currentVersion !== options.targetVersion) {\n throw new SchemaMigrationPlanError(\n `${options.backupLabel} stopped at version ${currentVersion}, expected ${options.targetVersion}`,\n );\n }\n\n return backups;\n}\n\n/**\n * Open a SQLite database in read-only mode.\n * Returns null if better-sqlite3 is unavailable or the file can't be opened.\n */\nexport function openDbReadOnly(dbPath: string): SQLiteDatabase | null {\n if (!DatabaseConstructor) {\n reportUnavailableOnce();\n return null;\n }\n try {\n const db = DatabaseConstructor(dbPath, { readonly: true });\n try {\n db.pragma(`busy_timeout = ${SQLITE_BUSY_TIMEOUT_MS}`);\n } catch {\n // The handle remains usable when SQLite rejects connection-level tuning.\n }\n return db;\n } catch (error) {\n getCoreDiagnostics()?.warn(\"sqlite.open_failed\", {\n dbPath,\n readonly: true,\n message: error instanceof Error ? error.message : String(error),\n });\n return null;\n }\n}\n\nexport function openDb(dbPath: string): SQLiteDatabase | null {\n if (!DatabaseConstructor) {\n reportUnavailableOnce();\n return null;\n }\n try {\n ensurePrivateDirectory(dirname(dbPath));\n // TEMP tables can hold a full corpus of staged publication payloads, so they\n // must spill to disk next to the database rather than to a $TMPDIR that may\n // be RAM-backed.\n if (!isInMemoryPath(dbPath)) process.env.SQLITE_TMPDIR ||= dirname(dbPath);\n const db = DatabaseConstructor(dbPath);\n // The sidecars only exist once the connection is established.\n restrictPrivateDatabase(dbPath);\n try {\n // busy_timeout first: if a later pragma throws, writes must still wait for\n // concurrent writers instead of failing instantly with SQLITE_BUSY.\n db.pragma(`busy_timeout = ${SQLITE_BUSY_TIMEOUT_MS}`);\n db.pragma(\"journal_mode = WAL\");\n db.pragma(\"synchronous = NORMAL\");\n db.pragma(\"foreign_keys = ON\");\n db.pragma(\"temp_store = FILE\");\n } catch {\n // The database remains usable when SQLite rejects connection-level tuning.\n }\n return db;\n } catch (error) {\n getCoreDiagnostics()?.warn(\"sqlite.open_failed\", {\n dbPath,\n readonly: false,\n message: error instanceof Error ? error.message : String(error),\n });\n return null;\n }\n}\n\n/**\n * Check if SQLite support is available.\n */\nexport function isSqliteAvailable(): boolean {\n return DatabaseConstructor !== null;\n}\n","import type {\n ImagePart,\n MessagePart,\n PlanPart,\n ToolPart,\n ToolPartState,\n ToolPartStatus,\n} from \"./session.js\";\n\nfunction toRecord(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction optionalString(value: unknown): string | undefined {\n return typeof value === \"string\" && value ? value : undefined;\n}\n\nfunction optionalTime(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction timeField(time_created: number | undefined) {\n return time_created === undefined ? {} : { time_created };\n}\n\nfunction firstDefined(...values: unknown[]): unknown {\n return values.find((value) => value !== undefined);\n}\n\nfunction normalizeStatus(\n state: Record<string, unknown>,\n output: unknown,\n error: unknown,\n): ToolPartStatus {\n const status = state.status;\n if (status === \"running\" || status === \"completed\" || status === \"error\") return status;\n if (status === \"success\") return \"completed\";\n if (error != null) return \"error\";\n if (output !== undefined) return \"completed\";\n return \"running\";\n}\n\nfunction normalizeMetadata(state: Record<string, unknown>): unknown {\n const rawMetadata = state.metadata ?? state.meta;\n const extras = Object.fromEntries(\n Object.entries(state).filter(\n ([key]) =>\n ![\"status\", \"input\", \"arguments\", \"output\", \"result\", \"error\", \"metadata\", \"meta\"].includes(\n key,\n ),\n ),\n );\n if (Object.keys(extras).length === 0) return rawMetadata;\n\n const metadata = toRecord(rawMetadata);\n return metadata ? { ...metadata, ...extras } : extras;\n}\n\nfunction normalizeToolState(value: unknown, legacyPart: Record<string, unknown>): ToolPartState {\n const state = toRecord(value) ?? {};\n const input = firstDefined(state.input, state.arguments, legacyPart.input);\n const output = firstDefined(state.output, state.result, legacyPart.output);\n const error = state.error;\n const metadata = normalizeMetadata(state);\n\n return {\n status: normalizeStatus(state, output, error),\n ...(input !== undefined ? { input } : {}),\n ...(output !== undefined ? { output } : {}),\n ...(error !== undefined ? { error } : {}),\n ...(metadata !== undefined ? { metadata } : {}),\n };\n}\n\nfunction planText(value: unknown): string {\n if (typeof value === \"string\") return value;\n const record = toRecord(value);\n if (!record) return \"\";\n return planText(record.text ?? record.plan ?? record.content);\n}\n\nfunction normalizePlanPart(\n value: Record<string, unknown>,\n time_created: number | undefined,\n): PlanPart | null {\n const approval_status = value.approval_status === \"fail\" ? \"fail\" : \"success\";\n const text = planText(value.text ?? (approval_status === \"fail\" ? value.output : value.input));\n return text ? { type: \"plan\", text, approval_status, ...timeField(time_created) } : null;\n}\n\nfunction normalizeImagePart(\n value: Record<string, unknown>,\n time_created: number | undefined,\n): ImagePart | null {\n const data = optionalString(value.data);\n const url = optionalString(value.url);\n const mime_type = optionalString(value.mime_type);\n\n if (data && mime_type) {\n return {\n type: \"image\",\n data,\n mime_type,\n ...(url ? { url } : {}),\n ...timeField(time_created),\n };\n }\n if (url) {\n return {\n type: \"image\",\n url,\n ...(data ? { data } : {}),\n ...(mime_type ? { mime_type } : {}),\n ...timeField(time_created),\n };\n }\n return null;\n}\n\nfunction normalizeToolPart(\n value: Record<string, unknown>,\n time_created: number | undefined,\n): ToolPart | null {\n const title = optionalString(value.title);\n const callID = optionalString(value.callID);\n const tool = optionalString(value.tool)?.trim() || title?.replace(/^tool:\\s*/i, \"\").trim();\n if (!tool) return null;\n\n return {\n type: \"tool\",\n tool,\n ...(title ? { title } : {}),\n ...(callID ? { callID } : {}),\n state: normalizeToolState(value.state, value),\n ...timeField(time_created),\n };\n}\n\nfunction normalizeMessagePart(value: unknown): MessagePart | null {\n const part = toRecord(value);\n if (!part) return null;\n const time_created = optionalTime(part.time_created);\n\n if (part.type === \"text\" || part.type === \"reasoning\") {\n if (typeof part.text !== \"string\") return null;\n return { type: part.type, text: part.text, ...timeField(time_created) };\n }\n if (part.type === \"plan\") return normalizePlanPart(part, time_created);\n if (part.type === \"image\") return normalizeImagePart(part, time_created);\n if (part.type === \"tool\") return normalizeToolPart(part, time_created);\n return null;\n}\n\nexport function normalizeMessageParts(value: unknown): MessagePart[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap((part) => {\n const normalized = normalizeMessagePart(part);\n return normalized ? [normalized] : [];\n });\n}\n","export type AgentSourceKind = \"filesystem\" | \"sqlite\";\n\nexport type AgentToolStrategy = \"custom\" | \"default\";\n\nexport interface AgentCatalogEntry {\n name: string;\n displayName: string;\n icon: string;\n /** Brand-colored icons render as-is instead of inheriting the current text color. */\n iconColored?: boolean;\n sourceKind: AgentSourceKind;\n resumeCommandPrefix: string | null;\n toolStrategy: AgentToolStrategy;\n}\n\nexport const AGENT_CATALOG = [\n {\n name: \"claudecode\",\n displayName: \"Claude Code\",\n icon: \"/icon/agent/claudecode.svg\",\n iconColored: true,\n sourceKind: \"filesystem\",\n resumeCommandPrefix: \"claude --resume\",\n toolStrategy: \"custom\",\n },\n {\n name: \"cursor\",\n displayName: \"Cursor\",\n icon: \"/icon/agent/cursor.svg\",\n sourceKind: \"sqlite\",\n resumeCommandPrefix: null,\n toolStrategy: \"custom\",\n },\n {\n name: \"kimi\",\n displayName: \"Kimi-Cli\",\n icon: \"/icon/agent/kimi.svg\",\n sourceKind: \"filesystem\",\n resumeCommandPrefix: \"kimi -r\",\n toolStrategy: \"custom\",\n },\n {\n name: \"kimi-code\",\n displayName: \"Kimi-Code\",\n icon: \"/icon/agent/kimi.svg\",\n sourceKind: \"filesystem\",\n resumeCommandPrefix: \"kimi -r\",\n toolStrategy: \"custom\",\n },\n {\n name: \"codex\",\n displayName: \"Codex\",\n icon: \"/icon/agent/codex.svg\",\n sourceKind: \"filesystem\",\n resumeCommandPrefix: \"codex resume\",\n toolStrategy: \"custom\",\n },\n {\n name: \"grok\",\n displayName: \"Grok\",\n icon: \"/icon/agent/grok.svg\",\n sourceKind: \"filesystem\",\n resumeCommandPrefix: \"grok --resume\",\n toolStrategy: \"custom\",\n },\n {\n name: \"pi\",\n displayName: \"Pi\",\n icon: \"/icon/agent/pi.svg\",\n sourceKind: \"filesystem\",\n resumeCommandPrefix: \"pi --session\",\n toolStrategy: \"custom\",\n },\n {\n name: \"opencode\",\n displayName: \"OpenCode\",\n icon: \"/icon/agent/opencode.svg\",\n sourceKind: \"sqlite\",\n resumeCommandPrefix: \"opencode -s\",\n toolStrategy: \"custom\",\n },\n {\n name: \"zcode\",\n displayName: \"ZCode\",\n icon: \"/icon/agent/zcode.svg\",\n sourceKind: \"sqlite\",\n resumeCommandPrefix: null,\n toolStrategy: \"custom\",\n },\n {\n name: \"dsh\",\n displayName: \"DSH\",\n icon: \"/icon/agent/dsh.svg\",\n iconColored: true,\n sourceKind: \"filesystem\",\n // DSH delegates launch arguments to installation-specific profiles.\n resumeCommandPrefix: null,\n toolStrategy: \"custom\",\n },\n] as const satisfies readonly AgentCatalogEntry[];\n\nexport type AgentName = (typeof AGENT_CATALOG)[number][\"name\"];\n\nexport function getAgentCatalogEntry(name: AgentName): AgentCatalogEntry {\n const entry = AGENT_CATALOG.find((candidate) => candidate.name === name);\n if (!entry) throw new Error(`Unknown agent catalog entry: ${name}`);\n return entry;\n}\n"],"mappings":";;;AAgBO,IAAM,aAAa;EACxB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AACF;AAIO,SAAS,WAAW,OAAkC;AAC3D,SAAO,WAAW,KAAK,CAAC,QAAQ,QAAQ,KAAK;AAC/C;AAwMO,SAAS,4BACd,SAC0C;AAC1C,MAAI,QAAQ,iBAAkB;AAC9B,QAAM,IAAI;IACR,WAAW,QAAQ,UAAU,SAAS,IAAI,QAAQ,UAAU,SAAS;EACvE;AACF;AAEO,SAAS,oBACd,SACmC;AACnC,QAAM;IACJ,aAAa;IACb,oCAAoC;IACpC,kCAAkC;IAClC,8BAA8B;IAC9B,gCAAgC;IAChC,GAAG;EACL,IAAI;AACJ,SAAO;AACT;AAEO,SAAS,8BACd,MACqD;AACrD,SAAO,EAAE,GAAG,MAAM,SAAS,oBAAoB,KAAK,OAAO,EAAE;AAC/D;;;AChQO,IAAM,gCAAgC;AAE7C,IAAM,aAAwC;EAC5C,CAAC,UAAU,qEAAqE;EAChF,CAAC,eAAe,+DAA+D;EAC/E,CAAC,eAAe,iEAAiE;EACjF,CAAC,QAAQ,kDAAkD;AAC7D;AAEA,IAAM,qBAAqB;AAC3B,IAAM,iBAAiB;AACvB,IAAM,0BACJ;AACF,IAAM,cAAc;AACpB,IAAM,eAAe;AACrB,IAAM,eAAe;AACrB,IAAM,eAAe;AAEd,SAAS,2BACd,SACQ;AACR,SAAO,QAAQ,gBAAgB,QAAQ;AACzC;AAEO,SAAS,oBAAoB,SAAsD;AACxF,QAAM,OAAO,oBAAI,IAAc;AAC/B,MAAI,gBAAgB;AACpB,MAAI,gBAAgB;AAEpB,aAAW,WAAW,QAAQ,UAAU;AACtC,QAAI,QAAQ,SAAS,QAAQ;AAC3B,YAAM,OAAO,QAAQ,MAAM,IAAI,QAAQ,EAAE,KAAK,IAAI;AAClD,iBAAW,CAAC,KAAK,OAAO,KAAK,YAAY;AACvC,YAAI,QAAQ,KAAK,IAAI,EAAG,MAAK,IAAI,GAAG;MACtC;IACF;AAEA,eAAW,QAAQ,QAAQ,OAAO;AAChC,UAAI,KAAK,SAAS,OAAQ,MAAK,IAAI,UAAU;AAC7C,UAAI,KAAK,SAAS,OAAQ;AAE1B,YAAM,WAAW,GAAG,KAAK,IAAI,IAAI,KAAK,SAAS,EAAE;AACjD,YAAM,cAAc,qBAAqB,IAAI;AAE7C,UAAI,aAAa,KAAK,QAAQ,EAAG,MAAK,IAAI,UAAU;AACpD,UAAI,aAAa,KAAK,QAAQ,EAAG,kBAAiB;AAClD,UAAI,aAAa,KAAK,QAAQ,EAAG,kBAAiB;AAElD,UAAI,mBAAmB,KAAK,WAAW,EAAG,MAAK,IAAI,SAAS;AAC5D,UAAI,eAAe,KAAK,WAAW,EAAG,MAAK,IAAI,SAAS;AACxD,UAAI,wBAAwB,KAAK,WAAW,EAAG,MAAK,IAAI,cAAc;AACtE,UAAI,iBAAiB,KAAK,MAAM,KAAK,GAAG;AACtC,aAAK,IAAI,MAAM;MACjB;IACF;EACF;AAEA,MAAI,iBAAiB,KAAK,iBAAiB,GAAG;AAC5C,SAAK,IAAI,aAAa;EACxB;AAEA,SAAO,WAAW,OAAO,CAAC,QAAQ,KAAK,IAAI,GAAG,CAAC;AACjD;AAEA,SAAS,SAAS,MAA2B;AAC3C,SAAO,KAAK,SAAS,UAAU,KAAK,SAAS,eAAe,KAAK,SAAS,SAAS,KAAK,OAAO;AACjG;AAEA,SAAS,qBAAqB,MAAwB;AACpD,SAAO,CAAC,KAAK,MAAM,KAAK,OAAO,YAAY,KAAK,KAAK,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AACnF;AAEA,SAAS,YAAY,OAAwB;AAC3C,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAW,QAAO,OAAO,KAAK;AAChF,MAAI;AACF,WAAO,KAAK,UAAU,KAAK;EAC7B,QAAQ;AACN,WAAO;EACT;AACF;AAEA,SAAS,iBAAiB,OAAyB;AACjD,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,OAAO,UAAU,SAAU,QAAO,YAAY,KAAK,KAAK;AAC5D,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,KAAK,gBAAgB;AAC5D,MAAI,OAAO,UAAU,SAAU,QAAO;AAEtC,QAAMA,UAAS;AACf,aAAW,OAAO,CAAC,QAAQ,QAAQ,YAAY,aAAa,cAAc,aAAa,GAAG;AACxF,UAAM,MAAMA,QAAO,GAAG;AACtB,QAAI,OAAO,QAAQ,YAAY,YAAY,KAAK,GAAG,EAAG,QAAO;EAC/D;AAEA,SAAO,OAAO,OAAOA,OAAM,EAAE,KAAK,gBAAgB;AACpD;ACnGO,IAAM,0BAA0B;AAqBvC,IAAM,0BAA0B,oBAAI,IAAI,CAAC,cAAc,gBAAgB,gBAAgB,CAAC;AAExF,SAAS,SAAS,OAAkD;AAClE,SAAO,SAAS,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC3E;AAEA,SAAS,aAAa,OAA2C;AAC/D,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,SAAO,OAAO,QAAQ,KAAK,EAAE;IAC3B,CAAC,CAAC,KAAK,IAAI,MACT,wBAAwB,IAAI,GAAG,KAAK,OAAO,SAAS,YAAY,KAAK,UAAU;EACnF;AACF;AAEO,SAAS,mBAAmB,OAA2C;AAC5E,MAAI,CAAC,SAAS,KAAK,KAAK,MAAM,SAAS,wBAAyB,QAAO;AACvE,SACE,OAAO,MAAM,OAAO,YACpB,MAAM,GAAG,SAAS,MACjB,MAAM,UAAU,WACf,MAAM,UAAU,UAChB,MAAM,UAAU,UAChB,MAAM,UAAU,YAClB,OAAO,MAAM,UAAU,YACvB,MAAM,MAAM,SAAS,KACrB,OAAO,cAAc,MAAM,GAAG,KAC9B,OAAO,MAAM,GAAG,IAAI,KACpB,OAAO,cAAc,MAAM,QAAQ,KACnC,OAAO,MAAM,QAAQ,KAAK,MACzB,MAAM,YAAY,UAAa,aAAa,MAAM,OAAO,MAC1D,SAAS,MAAM,IAAI;AAEvB;;;AC1CO,SAAS,0BAA0B,WAA+C;AACvF,SAAO;IACL,WAAW,UAAU,UAAU,KAAK,EAAE,YAAY;IAClD,WAAW,UAAU;EACvB;AACF;AAcO,SAAS,uBAAuB,WAAqC;AAC1E,QAAM,aAAa,0BAA0B,SAAS;AACtD,SAAO,GAAG,WAAW,SAAS,IAAI,WAAW,SAAS;AACxD;AAGO,SAAS,uBAAuB,WAAqC;AAC1E,SAAO,uBAAuB,SAAS;AACzC;AAEO,SAAS,sBAAsB,WAA8C;AAClF,SAAO;IACL,WAAW,0BAA0B,SAAS;EAChD;AACF;AAEO,SAAS,sBAAsB,UAA2B,WAA0B;AACzF,QAAM,aAAa,0BAA0B,SAAS,SAAS;AAC/D,QAAM,oBAAoB,WAAW,KAAK,EAAE,YAAY;AACxD,MAAI,SAAS,UAAU,cAAc,WAAW,WAAW;AACzD,UAAM,IAAI,MAAM,qCAAqC;EACvD;AACA,MAAI,qBAAqB,QAAQ,WAAW,cAAc,mBAAmB;AAC3E,UAAM,IAAI;MACR,4BAA4B,WAAW,SAAS,qBAAqB,iBAAiB;IACxF;EACF;AACF;AAEO,SAAS,mBAAmB,SAAqD;AACtF,SAAO,0BAA0B,QAAQ,SAAS,EAAE;AACtD;AAOO,SAAS,eAAe,WAA2B;AACxD,SAAO,IAAI,mBAAmB,UAAU,KAAK,EAAE,YAAY,CAAC,CAAC;AAC/D;AAOO,SAAS,iBAAiB,WAAqC;AACpE,QAAM,aAAa,0BAA0B,SAAS;AACtD,SAAO,GAAG,eAAe,WAAW,SAAS,CAAC,IAAI,mBAAmB,WAAW,SAAS,CAAC;AAC5F;;;AClEA,IAAM,kBAA8D;EAClE,MAAM;EACN,WAAW;EACX,cAAc;EACd,gBAAgB;EAChB,UAAU;EACV,YAAY;EACZ,aAAa;EACb,MAAM;EACN,WAAW;EACX,cAAc;EACd,UAAU;EACV,WAAW;EACX,cAAc;EACd,OAAO;EACP,gBAAgB;EAChB,aAAa;EACb,aAAa;EACb,OAAO;EACP,YAAY;EACZ,WAAW;EACX,QAAQ;EACR,aAAa;AACf;AAEA,IAAM,cAA0D;EAC9D,WAAW;EACX,aAAa;EACb,YAAY;EACZ,aAAa;EACb,WAAW;AACb;AAEA,SAAS,SAAS,OAAgB;AAChC,MAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AAC/D,WAAO;EACT;AACA,SAAO,CAAC;AACV;AAEA,SAAS,kBAAkB,OAAe;AACxC,QAAM,OAAO,MAAM,KAAK;AACxB,MAAI,CAAC,QAAQ,KAAK,SAAS,OAAO,KAAK,SAAS,IAAI,EAAG,QAAO;AAC9D,MAAI,gBAAgB,KAAK,IAAI,KAAK,SAAS,KAAK,IAAI,EAAG,QAAO;AAC9D,MAAI,KAAK,WAAW,GAAG,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,WAAW,KAAK,EAAG,QAAO;AACpF,MAAI,KAAK,WAAW,IAAI,KAAK,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,IAAI,EAAG,QAAO;AAC/E,SAAO,qCAAqC,KAAK,IAAI;AACvD;AAEA,SAAS,UAAU,KAAa;AAC9B,QAAM,aAAa,IAAI,KAAK,EAAE,YAAY;AAC1C,MAAI,CAAC,WAAY,QAAO;AACxB,MACE,WAAW,SAAS,SAAS,KAC7B,WAAW,SAAS,SAAS,KAC7B,WAAW,SAAS,MAAM,KAC1B,WAAW,SAAS,QAAQ,KAC5B,WAAW,SAAS,KAAK,KACzB,WAAW,SAAS,MAAM,KAC1B,WAAW,SAAS,OAAO,KAC3B,WAAW,SAAS,aAAa,KACjC,eAAe,SACf,eAAe,aACf,eAAe,aACf;AACA,WAAO;EACT;AACA,SAAO,WAAW,SAAS,MAAM,KAAK,WAAW,SAAS,MAAM;AAClE;AAEA,SAAS,aAAa,OAAgB,KAAa,OAAoB,QAAQ,GAAS;AACtF,MAAI,SAAS,QAAQ,QAAQ,EAAG;AAChC,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,UAAU,GAAG,KAAK,kBAAkB,KAAK,EAAG,OAAM,IAAI,MAAM,KAAK,CAAC;AACtE;EACF;AACA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,eAAW,QAAQ,MAAO,cAAa,MAAM,KAAK,OAAO,QAAQ,CAAC;AAClE;EACF;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,eAAW,CAAC,WAAW,MAAM,KAAK,OAAO,QAAQ,KAAgC,GAAG;AAClF,mBAAa,QAAQ,WAAW,OAAO,QAAQ,CAAC;IAClD;EACF;AACF;AAEA,SAAS,uBAAuB,OAAqC;AACnE,QAAMC,UAAS,SAAS,KAAK;AAC7B,QAAM,UAAU,MAAM,QAAQ,KAAK,IAC/B,QACA,MAAM,QAAQA,QAAO,OAAO,IAC1BA,QAAO,UACP,CAAC;AAEP,SAAO,QAAQ,QAAQ,CAAC,UAAU;AAChC,UAAM,QAAQ,SAAS,KAAK;AAC5B,UAAM,OAAO,OAAO,MAAM,SAAS,WAAW,YAAY,MAAM,IAAI,IAAI;AACxE,UAAM,YAAY,MAAM,QAAQ,MAAM;AACtC,UAAM,OAAO,OAAO,cAAc,WAAW,UAAU,KAAK,IAAI;AAChE,WAAO,QAAQ,OAAO,CAAC,EAAE,MAAM,KAAK,CAAC,IAAI,CAAC;EAC5C,CAAC;AACH;AAEO,SAAS,iBAAiB,MAAuD;AACtF,SAAO,gBAAgB,KAAK,KAAK,KAAK,EAAE,YAAY,CAAC,KAAK;AAC5D;AAEO,SAAS,0BACd,MACqB;AACrB,QAAM,kBAAkB,uBAAuB,KAAK,MAAM,KAAK;AAC/D,MAAI,gBAAgB,SAAS,EAAG,QAAO;AAEvC,QAAM,OAAO,iBAAiB,IAAI;AAClC,MAAI,CAAC,KAAM,QAAO,CAAC;AAEnB,QAAM,QAAQ,oBAAI,IAAY;AAC9B,eAAa,KAAK,MAAM,OAAO,IAAI,KAAK;AACxC,SAAO,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,KAAK,EAAE;AAClD;ACpHO,SAAS,2BACd,UACA,MACsB;AACtB,QAAM,sBAAsB,oBAAI,IAAyC;AACzE,QAAM,gCAAgC,oBAAI,IAAyC;AACnF,QAAM,yBAAyB,oBAAI,IAA8B;AACjE,QAAM,iBAAiB,oBAAI,IAA8B;AACzD,QAAM,qBAAqB,oBAAI,IAA8B;AAC7D,QAAMC,cAAa,CAAC,WAAmB,cAAsB,GAAG,SAAS,KAAK,SAAS;AACvF,QAAM,aAAa,CAAC,SAAsC;AACxD,UAAM,MAAMA,YAAW,KAAK,UAAU,WAAW,KAAK,UAAU,SAAS;AACzE,uBAAmB,OAAO,GAAG;AAC7B,kCAA8B,OAAO,GAAG;AACxC,wBAAoB,IAAI,KAAK,IAAI;EACnC;AACA,QAAM,uBAAuB,CAAC,SAAsC;AAClE,UAAM,MAAMA,YAAW,KAAK,UAAU,WAAW,KAAK,UAAU,SAAS;AACzE,QAAI,oBAAoB,IAAI,GAAG,KAAK,mBAAmB,IAAI,GAAG,EAAG;AACjE,kCAA8B,IAAI,KAAK,IAAI;EAC7C;AACA,QAAM,SAAS,CAAC,SAA2B;AACzC,UAAM,MAAMA,YAAW,KAAK,WAAW,KAAK,SAAS;AACrD,uBAAmB,OAAO,GAAG;AAC7B,mBAAe,IAAI,KAAK,IAAI;EAC9B;AACA,QAAM,qBAAqB,CAAC,SAA2B;AACrD,UAAM,MAAMA,YAAW,KAAK,WAAW,KAAK,SAAS;AACrD,2BAAuB,OAAO,GAAG;AACjC,2BAAuB,IAAI,KAAK,IAAI;EACtC;AACA,QAAM,aAAa,CAAC,SAA2B;AAC7C,UAAM,MAAMA,YAAW,KAAK,WAAW,KAAK,SAAS;AACrD,wBAAoB,OAAO,GAAG;AAC9B,kCAA8B,OAAO,GAAG;AACxC,2BAAuB,OAAO,GAAG;AACjC,mBAAe,OAAO,GAAG;AACzB,uBAAmB,IAAI,KAAK,IAAI;EAClC;AAEA,aAAW,QAAQ,SAAS,eAAgB,QAAO,IAAI;AACvD,aAAW,QAAQ,SAAS,iCAAiC,CAAC,EAAG,sBAAqB,IAAI;AAC1F,aAAW,QAAQ,SAAS,0BAA0B,CAAC,EAAG,oBAAmB,IAAI;AACjF,aAAW,QAAQ,SAAS,oBAAqB,YAAW,IAAI;AAChE,aAAW,QAAQ,SAAS,mBAAoB,YAAW,IAAI;AAC/D,aAAW,QAAQ,KAAK,eAAgB,QAAO,IAAI;AACnD,aAAW,QAAQ,KAAK,iCAAiC,CAAC,EAAG,sBAAqB,IAAI;AACtF,aAAW,QAAQ,KAAK,0BAA0B,CAAC,EAAG,oBAAmB,IAAI;AAC7E,aAAW,QAAQ,KAAK,oBAAqB,YAAW,IAAI;AAC5D,aAAW,QAAQ,KAAK,mBAAoB,YAAW,IAAI;AAE3D,SAAO;IACL,MAAM;IACN,eAAe,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,SAAS,eAAe,GAAG,KAAK,aAAa,CAAC,CAAC;IACrF,gBAAgB,CAAC,GAAG,eAAe,OAAO,CAAC;IAC3C,eAAe,KAAK;IACpB,WAAW,KAAK;IAChB,qBAAqB,CAAC,GAAG,oBAAoB,OAAO,CAAC;IACrD,+BAA+B,CAAC,GAAG,8BAA8B,OAAO,CAAC;IACzE,wBAAwB,CAAC,GAAG,uBAAuB,OAAO,CAAC;IAC3D,oBAAoB,CAAC,GAAG,mBAAmB,OAAO,CAAC;EACrD;AACF;ACvEO,SAAS,mBAAmB,WAA2B;AAC5D,QAAM,OAAO,IAAI,KAAK,SAAS;AAC/B,SAAO,IAAI,KAAK,KAAK,YAAY,GAAG,KAAK,SAAS,GAAG,KAAK,QAAQ,CAAC,EAAE,QAAQ;AAC/E;AAGO,SAAS,gBAAgB,WAAmB,MAAsB;AACvE,QAAM,OAAO,IAAI,KAAK,SAAS;AAC/B,SAAO,IAAI,KAAK,KAAK,YAAY,GAAG,KAAK,SAAS,GAAG,KAAK,QAAQ,IAAI,IAAI,EAAE,QAAQ;AACtF;AAOO,SAAS,yBACd,OACA,UAC2B;AAC3B,QAAM,QAAQ,4BAA4B,KAAK,KAAK;AACpD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,OAAO,OAAO,MAAM,CAAC,CAAC;AAC5B,QAAM,QAAQ,OAAO,MAAM,CAAC,CAAC,IAAI;AACjC,QAAM,MAAM,OAAO,MAAM,CAAC,CAAC;AAC3B,QAAM,QAAQ,IAAI,KAAK,MAAM,OAAO,GAAG;AACvC,MAAI,MAAM,YAAY,MAAM,QAAQ,MAAM,SAAS,MAAM,SAAS,MAAM,QAAQ,MAAM,KAAK;AACzF,WAAO;EACT;AACA,SAAO,aAAa,UAAU,MAAM,QAAQ,IAAI,gBAAgB,MAAM,QAAQ,GAAG,CAAC,IAAI;AACxF;AAGA,SAAS,oBAAoB,WAA2B;AACtD,QAAM,OAAO,IAAI,KAAK,SAAS;AAC/B,SAAO,KAAK,IAAI,KAAK,YAAY,GAAG,KAAK,SAAS,GAAG,KAAK,QAAQ,CAAC,IAAI;AACzE;AAGO,SAAS,kBAAkB,MAAc,IAAoB;AAClE,SAAO,KAAK,IAAI,GAAG,oBAAoB,EAAE,IAAI,oBAAoB,IAAI,IAAI,CAAC;AAC5E;AAGO,SAAS,iBAAiB,WAA2B;AAC1D,QAAM,OAAO,IAAI,KAAK,SAAS;AAC/B,SAAO,GAAG,OAAO,KAAK,YAAY,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,EAAE;IACnF;IACA;EACF,CAAC,IAAI,OAAO,KAAK,QAAQ,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC;AAC9C;ACxCO,IAAM,yBAAyB;EACpC;EACA;EACA;EACA;EACA;EACA;AACF;AASA,IAAM,cAAc,IAAI,IAAY,sBAAsB;AAEnD,SAAS,sBAAsB,OAA6C;AACjF,SAAO,YAAY,IAAI,KAAK;AAC9B;AAMO,SAAS,sBAAsB,UAAsC;AAC1E,SAAO,GAAG,SAAS,IAAI,IAAI,SAAS,GAAG;AACzC;AAEO,SAAS,uBACd,UACA,UACS;AACT,SAAO,UAAU,SAAS,SAAS,QAAQ,SAAS,QAAQ,SAAS;AACvE;AAGO,SAAS,mBAAmB,oBAA4B,WAA2B;AACxF,SAAO,GAAG,kBAAkB,KAAK,UAAU,YAAY,CAAC;AAC1D;ACzCO,SAAS,2BAA2B,GAAgB,GAAwB;AACjF,UAAQ,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE;AACnE;AAEO,SAAS,uBAA8C,UAAoB;AAChF,WAAS,QAAQ,GAAG,QAAQ,SAAS,QAAQ,SAAS,GAAG;AACvD,QAAI,2BAA2B,SAAS,QAAQ,CAAC,GAAI,SAAS,KAAK,CAAE,IAAI,GAAG;AAC1E,aAAO,CAAC,GAAG,QAAQ,EAAE,KAAK,0BAA0B;IACtD;EACF;AACA,SAAO,CAAC,GAAG,QAAQ;AACrB;AAUO,SAAS,oBAA2C,QAAoB;AAC7E,QAAM,SAAS,OAAO,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AACxD,MAAI,OAAO,WAAW,EAAG,QAAO,CAAC;AACjC,MAAI,OAAO,WAAW,EAAG,QAAO,CAAC,GAAG,OAAO,CAAC,CAAE;AAE9C,QAAM,QAAQ,OAAO,OAAO,CAAC,KAAK,UAAU,MAAM,MAAM,QAAQ,CAAC;AACjE,QAAM,SAAc,CAAC;AACrB,QAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,OAAO,OAAO,GAAG,MAAM,CAAC;AAE7D,WAAS,WAAW,GAAG,WAAW,OAAO,YAAY,GAAG;AACtD,QAAI,OAAO;AACX,aAAS,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;AACrD,YAAM,SAAS,QAAQ,KAAK;AAC5B,UAAI,UAAU,OAAO,KAAK,EAAG,OAAQ;AACrC,UACE,SAAS,MACT,2BAA2B,OAAO,KAAK,EAAG,MAAM,GAAI,OAAO,IAAI,EAAG,QAAQ,IAAI,CAAE,CAAE,IAAI,GACtF;AACA,eAAO;MACT;IACF;AACA,WAAO,KAAK,OAAO,IAAI,EAAG,QAAQ,IAAI,CAAE,CAAE;AAC1C,YAAQ,IAAI,KAAM;EACpB;AAEA,SAAO;AACT;AAOA,SAAS,aAAmB,KAAkB,KAAQ,OAAgB;AACpE,QAAM,UAAU,IAAI,IAAI,GAAG;AAC3B,MAAI,SAAS;AACX,YAAQ,KAAK,KAAK;EACpB,OAAO;AACL,QAAI,IAAI,KAAK,CAAC,KAAK,CAAC;EACtB;AACF;AAEO,SAAS,mBAAmB,gBAAsD;AACvF,QAAM,aAAa,oBAAI,IAAyB;AAChD,QAAM,2BAA2B,oBAAI,IAA2B;AAChE,QAAM,UAAU,oBAAI,IAA2B;AAC/C,QAAM,uBAAuB,oBAAI,IAA2B;AAC5D,QAAM,oBAAoB,oBAAI,IAA2B;AAEzD,aAAW,WAAW,gBAAgB;AACpC,UAAM,WAAW,uBAAuB,QAAQ,SAAS;AACzD,QAAI,CAAC,WAAW,IAAI,QAAQ,EAAG,YAAW,IAAI,UAAU,OAAO;AAC/D,QAAI,QAAQ,kBAAkB;AAC5B;QACE;QACA,uBAAuB,QAAQ,gBAAgB;QAC/C;MACF;IACF;EACF;AAEA,QAAM,qBAAqB,uBAAuB,cAAc;AAChE,aAAW,WAAW,oBAAoB;AACxC,UAAM,EAAE,UAAU,IAAI,QAAQ;AAC9B,iBAAa,SAAS,WAAW,OAAO;AAExC,UAAM,WAAW,QAAQ;AACzB,QAAI,CAAC,UAAU,IAAK;AAEpB,UAAM,qBAAqB,sBAAsB,QAAQ;AACzD,iBAAa,sBAAsB,oBAAoB,OAAO;AAC9D,iBAAa,mBAAmB,mBAAmB,oBAAoB,SAAS,GAAG,OAAO;EAC5F;AAEA,SAAO;IACL;IACA;IACA;IACA;IACA;IACA;IACA;EACF;AACF;AC1DA,SAAS,WAAW,SAA8B;AAChD,SAAO,uBAAuB,QAAQ,SAAS;AACjD;AAEA,SAAS,UAAU,SAAqC;AACtD,SAAO,QAAQ,mBAAmB,uBAAuB,QAAQ,gBAAgB,IAAI;AACvF;AAEA,SAAS,aAAa,SAA8B;AAClD,SAAO,QAAQ,gBAAgB,QAAQ;AACzC;AAEA,SAAS,oBAAoB,SAAsB,MAAe,IAAsB;AACtF,QAAM,WAAW,aAAa,OAAO;AACrC,UAAQ,QAAQ,QAAQ,YAAY,UAAU,MAAM,QAAQ,YAAY;AAC1E;AAEA,SAAS,SAAS,SAA6C;AAC7D,QAAM,QAAQ,QAAQ;AACtB,QAAM,OAAO,MAAM,cAAc;AACjC,SAAO;IACL,cAAc,MAAM;IACpB,aAAa,MAAM;IACnB,cAAc,MAAM;IACpB,iBAAiB,MAAM,2BAA2B;IAClD,mBAAmB,MAAM,6BAA6B;IACtD,aAAa,MAAM,gBAAgB,MAAM,qBAAqB,MAAM;IACpE;IACA,YAAY,OAAO,IAAK,MAAM,eAAe,aAAc;EAC7D;AACF;AAEA,SAAS,SAAS,QAA+B,QAAqC;AACpF,SAAO,gBAAgB,OAAO;AAC9B,SAAO,eAAe,OAAO;AAC7B,SAAO,gBAAgB,OAAO;AAC9B,SAAO,mBAAmB,OAAO;AACjC,SAAO,qBAAqB,OAAO;AACnC,SAAO,eAAe,OAAO;AAC7B,SAAO,QAAQ,OAAO;AACtB,MAAI,OAAO,eAAe,YAAa,QAAO,aAAa;AAC7D;AAOA,SAAS,cAAc,OAA8B;AACnD,QAAM,QAA2B,CAAC;AAClC,QAAMC,WAAU,CAAC,KAAK;AACtB,SAAOA,SAAQ,SAAS,GAAG;AACzB,UAAM,OAAOA,SAAQ,IAAI;AACzB,UAAM,KAAK,IAAI;AACf,eAAW,SAAS,KAAK,SAAU,CAAAA,SAAQ,KAAK,KAAK;EACvD;AAEA,WAAS,QAAQ,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;AACzD,UAAM,OAAO,MAAM,KAAK;AACxB,UAAM,QAAQ,KAAK;AACnB,QAAI,cAAc;AAClB,eAAW,SAAS,KAAK,UAAU;AACjC,qBAAe,IAAI,MAAM;AACzB,eAAS,OAAO,MAAM,cAAc;IACtC;AACA,QAAI,MAAM,OAAO,KAAK,MAAM,cAAc,KAAM,OAAM,aAAa;AACnE,SAAK,kBAAkB;EACzB;AACF;AAEO,SAAS,iBAAiB,UAAsC;AACrE,QAAM,aAAa,oBAAI,IAA6B;AACpD,aAAW,WAAW,UAAU;AAC9B,UAAM,MAAM,WAAW,OAAO;AAC9B,QAAI,WAAW,IAAI,GAAG,EAAG;AACzB,eAAW,IAAI,KAAK;MAClB;MACA,UAAU,CAAC;MACX,iBAAiB;MACjB,gBAAgB,SAAS,OAAO;IAClC,CAAC;EACH;AACA,QAAM,QAAQ,CAAC,GAAG,WAAW,OAAO,CAAC;AAIrC,QAAM,kBAAkB,oBAAI,IAAqB;AACjD,WAAS,YAAY,UAA2B;AAC9C,UAAM,OAAiB,CAAC;AACxB,UAAM,SAAS,oBAAI,IAAY;AAC/B,QAAI,MAAqB;AACzB,QAAI,aAAa;AAEjB,WAAO,OAAO,MAAM;AAClB,YAAM,OAAO,gBAAgB,IAAI,GAAG;AACpC,UAAI,QAAQ,MAAM;AAChB,qBAAa;AACb;MACF;AACA,UAAI,OAAO,IAAI,GAAG,GAAG;AACnB,qBAAa;AACb;MACF;AACA,aAAO,IAAI,GAAG;AACd,WAAK,KAAK,GAAG;AACb,YAAM,SAAS,UAAU,WAAW,IAAI,GAAG,EAAG,OAAO;AACrD,YAAM,UAAU,QAAQ,WAAW,IAAI,MAAM,IAAI,SAAS;IAC5D;AAEA,eAAW,WAAW,KAAM,iBAAgB,IAAI,SAAS,UAAU;AACnE,WAAO;EACT;AAEA,QAAM,cAAc,oBAAI,IAA+B;AACvD,QAAM,QAA2B,CAAC;AAClC,QAAM,UAA6B,CAAC;AACpC,QAAM,UAA6B,CAAC;AAEpC,aAAW,QAAQ,OAAO;AACxB,UAAM,MAAM,WAAW,KAAK,OAAO;AACnC,UAAM,SAAS,UAAU,KAAK,OAAO;AACrC,UAAM,QACJ,UAAU,OACN,SACA,WAAW,IAAI,MAAM,KAAK,YAAY,GAAG,IACvC,kBACA;AAER,gBAAY,IAAI,KAAK,KAAK;AAC1B,QAAI,UAAU,iBAAiB;AAC7B,iBAAW,IAAI,MAAO,EAAG,SAAS,KAAK,IAAI;AAC3C;IACF;AACA,KAAC,UAAU,SAAS,QAAQ,SAAS,KAAK,IAAI;AAC9C,YAAQ,KAAK,IAAI;EACnB;AAEA,aAAW,SAAS,QAAS,eAAc,KAAK;AAEhD,SAAO;IACL;IACA;IACA;IACA;IACA,aAAa,SAAS;AACpB,aAAO,YAAY,IAAI,WAAW,OAAO,CAAC,MAAM,QAAQ,mBAAmB,WAAW;IACxF;EACF;AACF;AAwCO,SAAS,kCACd,UACA,MACA,IACA,MACK;AACL,MAAI,QAAQ,QAAQ,MAAM,KAAM,QAAO;AAEvC,MAAI,SAAS,UAAa,SAAS,MAAM,CAAC,YAAY,oBAAoB,SAAS,MAAM,EAAE,CAAC,GAAG;AAC7F,WAAO,CAAC,GAAG,QAAQ;EACrB;AAEA,QAAMC,WAAU;IACd,QAAQ,iBAAiB,QAAQ;IACjC;IACA;EACF;AAEA,QAAM,UAAU,oBAAI,IAAY;AAChC,SAAOA,SAAQ,SAAS,GAAG;AACzB,UAAM,OAAOA,SAAQ,IAAI;AACzB,UAAM,MAAM,WAAW,KAAK,OAAO;AACnC,QAAI,QAAQ,IAAI,GAAG,EAAG;AACtB,YAAQ,IAAI,GAAG;AACf,eAAW,SAAS,KAAK,SAAU,CAAAA,SAAQ,KAAK,KAAK;EACvD;AAEA,SAAO,SAAS,OAAO,CAAC,YAAY,QAAQ,IAAI,WAAW,OAAO,CAAC,CAAC;AACtE;AAEO,SAAS,yCACd,MACA,MACA,IACmB;AACnB,MAAI,QAAQ,QAAQ,MAAM,KAAM,QAAO,KAAK;AAC5C,SAAO,KAAK,QAAQ,OAAO,CAAC,SAAS,oBAAoB,KAAK,SAAS,MAAM,EAAE,CAAC;AAClF;AAQA,SAAS,4BAA4B,UAAgD;AACnF,QAAM,gBAAgB,oBAAI,IAAyB;AACnD,aAAW,WAAW,UAAU;AAC9B,UAAM,MAAM,WAAW,OAAO;AAC9B,QAAI,CAAC,cAAc,IAAI,GAAG,EAAG,eAAc,IAAI,KAAK,OAAO;EAC7D;AAEA,QAAM,cAAc,oBAAI,IAAoB;AAC5C,QAAM,gBAAgB,oBAAI,IAAsB;AAChD,aAAW,CAAC,KAAK,OAAO,KAAK,eAAe;AAC1C,UAAM,SAAS,UAAU,OAAO;AAChC,QAAI,CAAC,UAAU,CAAC,cAAc,IAAI,MAAM,EAAG;AAC3C,gBAAY,IAAI,KAAK,MAAM;AAC3B,UAAM,WAAW,cAAc,IAAI,MAAM;AACzC,QAAI,SAAU,UAAS,KAAK,GAAG;QAC1B,eAAc,IAAI,QAAQ,CAAC,GAAG,CAAC;EACtC;AACA,SAAO,EAAE,eAAe,aAAa,cAAc;AACrD;AAEA,SAAS,6BACP,OACA,UACA,kBACA,WACM;AACN,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAMA,WAAU,CAAC,GAAG,QAAQ,EAAE,OAAO,CAAC,QAAQ,MAAM,cAAc,IAAI,GAAG,CAAC;AAC1E,SAAOA,SAAQ,SAAS,GAAG;AACzB,UAAM,MAAMA,SAAQ,IAAI;AACxB,QAAI,QAAQ,IAAI,GAAG,EAAG;AACtB,YAAQ,IAAI,GAAG;AACf,cAAU,IAAI,GAAG;AACjB,eAAW,SAAS,MAAM,cAAc,IAAI,GAAG,KAAK,CAAC,EAAG,CAAAA,SAAQ,KAAK,KAAK;EAC5E;AAEA,MAAI,CAAC,iBAAkB;AACvB,QAAM,mBAAmB,oBAAI,IAAY;AACzC,aAAW,QAAQ,UAAU;AAC3B,QAAI,MAAM,MAAM,cAAc,IAAI,IAAI,IAAI,OAAO;AACjD,WAAO,OAAO,CAAC,iBAAiB,IAAI,GAAG,GAAG;AACxC,uBAAiB,IAAI,GAAG;AACxB,gBAAU,IAAI,GAAG;AACjB,YAAM,MAAM,YAAY,IAAI,GAAG;IACjC;EACF;AACF;AAOO,SAAS,+BACd,kBACA,cACA,qBACA,oBAC0B;AAC1B,QAAM,cAAc,IAAI;IACtB,oBAAoB,IAAI,CAAC,EAAE,UAAU,MAAM,uBAAuB,SAAS,CAAC;EAC9E;AACA,QAAM,cAAc,mBAAmB,IAAI,sBAAsB;AACjE,QAAM,eAAe,oBAAI,IAAY;AACrC,QAAM,gBAAgB,4BAA4B,gBAAgB;AAClE,QAAM,YAAY,4BAA4B,YAAY;AAC1D,+BAA6B,eAAe,aAAa,MAAM,YAAY;AAC3E,+BAA6B,WAAW,aAAa,MAAM,YAAY;AACvE,+BAA6B,eAAe,aAAa,OAAO,YAAY;AAE5E,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,sBAAsB,aAAa,QAAQ,CAAC,YAAY;AAC5D,UAAM,MAAM,WAAW,OAAO;AAC9B,QAAI,CAAC,aAAa,IAAI,GAAG,KAAK,YAAY,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,EAAG,QAAO,CAAC;AAChF,YAAQ,IAAI,GAAG;AACf,WAAO;MACL;QACE,WAAW,QAAQ;QACnB;MACF;IACF;EACF,CAAC;AACD,QAAM,wBAAwB,IAAI;IAChC,CAAC,GAAG,qBAAqB,GAAG,mBAAmB,EAAE,IAAI,CAAC,EAAE,QAAQ,MAAM,aAAa,OAAO,CAAC;EAC7F;AACA,QAAM,eAAe,aAAa;IAAQ,CAAC,YACzC,sBAAsB,IAAI,aAAa,OAAO,CAAC,IAAI,CAAC,QAAQ,SAAS,IAAI,CAAC;EAC5E;AACA,SAAO,EAAE,qBAAqB,aAAa;AAC7C;AChYO,IAAM,6BAA6B;AACnC,IAAM,+BAA+B;;;ACK5C,SAAS,mBAAmB,MAAgB;AAC1C,MAAI,KAAK,OAAO,KAAK,GAAG;AACtB,WAAO,KAAK,MAAM,KAAK,EAAE,QAAQ,cAAc,EAAE;EACnD;AACA,MAAI,KAAK,KAAK,KAAK,EAAG,QAAO,KAAK,KAAK,KAAK;AAC5C,SAAO;AACT;AAEO,SAAS,+BACd,UACiC;AACjC,QAAM,cAA+C,CAAC;AAEtD,WAAS,QAAQ,CAAC,SAAS,iBAAiB;AAC1C,QAAI,YAAY;AAEhB,eAAW,QAAQ,QAAQ,OAAO;AAChC,UAAI,KAAK,SAAS,OAAQ;AAE1B,YAAM,YAAY,mBAAmB,IAAI;AACzC,YAAM,OAAO,KAAK,gBAAgB,QAAQ;AAC1C,YAAM,mBAAmB;AACzB,mBAAa;AAEb,iBAAW,EAAE,MAAM,KAAK,KAAK,0BAA0B,IAAI,GAAG;AAC5D,oBAAY,KAAK;UACf;UACA;UACA;UACA,YAAY;UACZ,eAAe;UACf,YAAY;QACd,CAAC;MACH;IACF;EACF,CAAC;AAED,SAAO;AACT;AAEO,SAAS,sBACd,WACA,WACA,oBACA,aACuB;AACvB,QAAM,UAAU,oBAAI,IAAiC;AAErD,aAAW,cAAc,aAAa;AACpC,UAAM,MAAM,GAAG,WAAW,IAAI,KAAK,WAAW,IAAI;AAClD,UAAM,UAAU,QAAQ,IAAI,GAAG;AAC/B,QAAI,SAAS;AACX,cAAQ,SAAS;AACjB,cAAQ,aAAa,KAAK,IAAI,QAAQ,YAAY,WAAW,IAAI;AACjE;IACF;AAEA,YAAQ,IAAI,KAAK;MACf,WAAW,EAAE,WAAW,UAAU;MAClC;MACA,MAAM,WAAW;MACjB,MAAM,WAAW;MACjB,OAAO;MACP,YAAY,WAAW;IACzB,CAAC;EACH;AAEA,SAAO,CAAC,GAAG,QAAQ,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM;AAC1C,QAAI,EAAE,eAAe,EAAE,WAAY,QAAO,EAAE,aAAa,EAAE;AAC3D,WAAO,EAAE,KAAK,cAAc,EAAE,IAAI;EACpC,CAAC;AACH;AAEO,SAAS,2BACd,WACA,WACA,oBACA,UACuB;AACvB,SAAO;IACL;IACA;IACA;IACA,+BAA+B,QAAQ;EACzC;AACF;;;AElFA,SAAS,WAAW,YAAY,WAAW,aAAa,gBAAgB;AACxE,SAAS,UAAU,SAAS,YAAY;ADAxC,IAAI,cAAsC;AAQ1C,SAAS,WAAW,MAAwC;AAC1D,SAAO;IACL,KAAK,OAAO,QAAQ;AAClB,UAAI;AACF,aAAK,OAAO,OAAO,MAAM;MAC3B,QAAQ;MAAC;IACX;IACA,KAAK,OAAO,QAAQ;AAClB,UAAI;AACF,aAAK,KAAK,OAAO,MAAM;MACzB,QAAQ;MAAC;IACX;EACF;AACF;AAEO,SAAS,mBAAmB,MAAoC;AACrE,gBAAc,OAAO,WAAW,IAAI,IAAI;AAC1C;AAEO,SAAS,qBAA6C;AAC3D,SAAO;AACT;ACzBO,IAAM,mBAAmB;AAEzB,IAAM,oBAAoB;AAGjC,IAAM,0BAA0B,CAAC,QAAQ,QAAQ,UAAU;AAE3D,IAAM,UAAU,QAAQ,aAAa;AAErC,SAAS,mBAAmB,MAAc,OAAsB;AAC9D,qBAAmB,GAAG,KAAK,8BAA8B;IACvD;IACA,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EAChE,CAAC;AACH;AAGA,SAAS,SAAS,MAAc,MAAoB;AAClD,MAAI,CAAC,WAAW,CAAC,WAAW,IAAI,EAAG;AACnC,MAAI;AAEF,SAAK,SAAS,IAAI,EAAE,OAAO,SAAW,KAAM;AAC5C,cAAU,MAAM,IAAI;EACtB,SAAS,OAAO;AACd,uBAAmB,MAAM,KAAK;EAChC;AACF;AASO,SAAS,uBAAuB,MAAoB;AACzD,YAAU,MAAM,EAAE,WAAW,MAAM,MAAM,iBAAiB,CAAC;AAE3D,WAAS,MAAM,gBAAgB;AACjC;AAGO,SAAS,oBAAoB,MAAoB;AACtD,WAAS,MAAM,iBAAiB;AAClC;AAOO,SAAS,6BACd,WACA,MACM;AACN,MAAI;AACF,eAAW,SAAS,YAAY,SAAS,GAAG;AAC1C,UAAI,KAAK,KAAK,EAAG,qBAAoB,KAAK,WAAW,KAAK,CAAC;IAC7D;EACF,SAAS,OAAO;AACd,uBAAmB,WAAW,KAAK;EACrC;AACF;AAGA,IAAM,kBAAkB,oBAAI,IAAY;AAGxC,SAAS,wBAAwB,QAAsB;AACrD,MAAI,gBAAgB,IAAI,MAAM,EAAG;AACjC,kBAAgB,IAAI,MAAM;AAE1B,QAAM,SAAS,GAAG,SAAS,MAAM,CAAC;AAClC;IACE,QAAQ,MAAM;IACd,CAAC,SAAS,KAAK,WAAW,MAAM,KAAK,KAAK,SAAS,MAAM;EAC3D;AACF;AAOO,SAAS,wBAAwB,QAAsB;AAC5D,sBAAoB,MAAM;AAC1B,aAAW,UAAU,wBAAyB,qBAAoB,GAAG,MAAM,GAAG,MAAM,EAAE;AACtF,0BAAwB,MAAM;AAChC;;;ACxGA,SAAS,kBAAkB;AAC3B,SAAS,cAAAC,aAAY,cAAc,YAAY,QAAQ,qBAAqB;AAC5E,SAAS,eAAe;AACxB,SAAS,QAAAC,aAAY;AIHrB,SAAS,yBAAyB;AHS3B,SAAS,kBAAkB,KAAqB;AACrD,SAAO,IAAI,KAAK,EAAE,YAAY,EAAE,WAAW,KAAK,GAAG;AACrD;ACTO,IAAM,iBAAiB;AAE9B,IAAM,qBAAqB,oBAAI,IAAI;EACjC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AACF,CAAC;AAED,SAAS,OAAO,OAAgD;AAC9D,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IACrE,QACD;AACN;AAEA,SAAS,SAAS,OAAoC;AACpD,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,SAAS,IACnE,QAAQ,MACR;AACN;AAEO,SAAS,sBAAsB,MAA0C;AAC9E,QAAM,YAAY,OAAO,QAAQ,OAAO,IAAI,KAAK,CAAC,CAAC,EAAE;IACnD,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MACN,OAAO,mBAAmB,IAAI,CAAC,CAAC,IAAI,OAAO,mBAAmB,IAAI,CAAC,CAAC,KAAK,EAAE,cAAc,CAAC;EAC9F;AACA,QAAM,YAAY,oBAAI,IAA0B;AAChD,QAAM,UAAU,oBAAI,IAA0B;AAC9C,aAAW,CAAC,UAAU,WAAW,KAAK,WAAW;AAC/C,UAAM,SAAS,OAAO,OAAO,WAAW,IAAI,QAAQ,CAAC;AACrD,eAAW,CAAC,OAAO,QAAQ,KAAK,OAAO,QAAQ,UAAU,CAAC,CAAC,GAAG;AAC5D,YAAM,OAAO,OAAO,OAAO,QAAQ,IAAI,MAAM,CAAC;AAC9C,UAAI,CAAC,KAAM;AACX,YAAM,QAAQ,SAAS,KAAK,OAAO,CAAC;AACpC,YAAM,SAAS,SAAS,KAAK,QAAQ,CAAC;AACtC,UAAI,UAAU,UAAa,WAAW,OAAW;AACjD,YAAM,UAAwB;QAC5B,mBAAmB;QACnB,oBAAoB;QACpB,yBAAyB,SAAS,KAAK,aAAa,CAAC,KAAK;QAC1D,uBAAuB,SAAS,KAAK,YAAY,CAAC,KAAK;QACvD,uBAAuB;QACvB,yBAAyB;MAC3B;AACA,gBAAU,IAAI,kBAAkB,GAAG,QAAQ,IAAI,KAAK,EAAE,GAAG,OAAO;AAChE,YAAM,OAAO,kBAAkB,KAAK;AACpC,UAAI,CAAC,QAAQ,IAAI,IAAI,EAAG,SAAQ,IAAI,MAAM,OAAO;IACnD;EACF;AACA,SAAO,IAAI,IAAI,CAAC,GAAG,SAAS,GAAG,SAAS,CAAC;AAC3C;AC9DA,IAAA,mBAAA;EACE,oBAAoB,CAAC,MAAM,MAAU,MAAU,IAAI;EACnD,qBAAqB,CAAC,MAAU,OAAU,QAAY,IAAI;EAC1D,qBAAqB,CAAC,MAAU,OAAU,QAAY,IAAI;EAC1D,oBAAoB,CAAC,MAAU,MAAU,QAAY,IAAI;EACzD,mBAAmB,CAAC,MAAU,OAAU,QAAY,IAAI;EACxD,qBAAqB,CAAC,MAAU,OAAU,QAAY,IAAI;EAC1D,qBAAqB,CAAC,MAAU,OAAU,QAAY,IAAI;EAC1D,iBAAiB,CAAC,OAAU,OAAU,SAAY,KAAS;EAC3D,mBAAmB,CAAC,OAAU,OAAU,SAAY,KAAS;EAC7D,mBAAmB,CAAC,MAAU,OAAU,QAAY,IAAI;EACxD,mBAAmB,CAAC,MAAU,OAAU,QAAY,IAAI;EACxD,mBAAmB,CAAC,MAAU,OAAU,QAAY,IAAI;EACxD,+BAA+B,CAAC,MAAU,OAAU,QAAY,IAAI;EACpE,+BAA+B,CAAC,MAAU,OAAU,QAAY,IAAI;EACpE,6BAA6B,CAAC,MAAU,OAAU,QAAY,IAAI;EAClE,WAAW,CAAC,MAAU,MAAU,MAAM,IAAI;EAC1C,gBAAgB,CAAC,MAAM,OAAW,MAAM,IAAI;EAC5C,gBAAgB,CAAC,MAAM,MAAM,MAAM,KAAM;EACzC,UAAU,CAAC,OAAW,MAAS,MAAM,MAAU;EAC/C,eAAe,CAAC,OAAQ,MAAM,MAAM,KAAM;EAC1C,SAAS,CAAC,QAAY,MAAS,MAAM,MAAO;EAC5C,WAAW,CAAC,QAAY,MAAS,MAAM,MAAO;EAC9C,iBAAiB,CAAC,QAAY,MAAS,MAAM,MAAO;EACpD,sBAAsB,CAAC,OAAQ,MAAU,MAAM,KAAM;EACrD,WAAW,CAAC,QAAY,OAAU,MAAM,MAAO;EAC/C,iBAAiB,CAAC,QAAY,OAAU,MAAM,MAAO;EACrD,iBAAiB,CAAC,QAAY,OAAU,MAAM,MAAO;EACrD,WAAW,CAAC,OAAW,OAAU,MAAM,KAAM;EAC7C,gBAAgB,CAAC,OAAQ,OAAW,MAAM,KAAM;EAChD,gBAAgB,CAAC,MAAM,QAAY,MAAM,IAAI;EAC7C,WAAW,CAAC,MAAU,MAAS,MAAM,IAAI;EACzC,cAAc,CAAC,OAAQ,MAAU,MAAM,KAAM;EAC7C,cAAc,CAAC,MAAM,MAAM,MAAM,IAAI;EACrC,2BAA2B,CAAC,MAAM,OAAW,MAAM,IAAI;EACvD,+BAA+B,CAAC,OAAQ,OAAW,MAAM,IAAI;EAC7D,+BAA+B,CAAC,MAAM,OAAW,MAAM,IAAI;EAC3D,iBAAiB,CAAC,OAAQ,OAAQ,MAAM,KAAM;EAC9C,qBAAqB,CAAC,OAAQ,OAAQ,MAAM,KAAM;EAClD,kCAAkC,CAAC,MAAM,OAAW,MAAM,IAAI;EAC9D,kBAAkB,CAAC,QAAY,MAAS,MAAM,MAAO;EACrD,oBAAoB,CAAC,MAAM,OAAW,MAAM,IAAI;AAClD;AH7BA,IAAM,eAAe,KAAK,KAAK;AAC/B,IAAM,kBAAkB;AACxB,IAAM,qBAAqB;AAY3B,IAAI,YAAY,wBAAwB,aAAa,CAAC;AAEtD,IAAI,UAA4C;AAChD,IAAI,kBAA2C;AAC/C,YAAY,cAAc,KAAK;AAE/B,SAAS,wBAAwB,SAAuD;AACtF,QAAM,OAAO,WAAW,QAAQ;AAChC,QAAM,UAAU,CAAC,GAAG,QAAQ,QAAQ,CAAC,EAAE;IAAK,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,MACzD,OAAO,QAAQ,KAAK,OAAO,QAAQ,IAAI;EACzC;AACA,aAAW,CAAC,MAAM,YAAY,KAAK,SAAS;AAC1C,SAAK,OAAO,IAAI;AAChB,SAAK,OAAO,IAAI;AAChB,SAAK,OAAO,KAAK,UAAU,YAAY,CAAC;AACxC,SAAK,OAAO,IAAI;EAClB;AAEA,SAAO;IACL,IAAI,OAAO,SAAS,KAAK,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE,GAAG,EAAE,KAAK;IAC5D;EACF;AACF;AAEA,SAAS,WAAW,OAAoC;AACtD,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,SAAS,IAAI,QAAQ;AACrF;AAEA,SAAS,cAAc;AACrB,SAAOA,MAAK,QAAQ,GAAG,UAAU,UAAU;AAC7C;AAEA,SAAS,eAAe;AACtB,SAAOA,MAAK,YAAY,GAAG,yBAAyB;AACtD;AAEA,SAAS,eAA0C;AACjD,QAAM,MAAM,oBAAI,IAA0B;AAC1C,QAAM,WAAW;AACjB,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACpD,UAAM,CAAC,OAAO,QAAQ,aAAa,WAAW,WAAW,SAAS,IAAI;AACtE,iBAAa,KAAK,MAAM;MACtB,mBAAmB;MACnB,oBAAoB;MACpB,yBAAyB,eAAe,QAAQ;MAChD,uBAAuB,aAAa,QAAQ;MAC5C,uBAAuB,aAAa;MACpC,yBAAyB,aAAa;IACxC,CAAC;EACH;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,KAAmC;AAC3D,MAAI,QAAQ,QAAQ,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,EAAG,QAAO;AAC1E,QAAM,SAAS;AACf,QAAM,QAAQ,WAAW,OAAO,mBAAmB,CAAC;AACpD,QAAM,SAAS,WAAW,OAAO,oBAAoB,CAAC;AACtD,MAAI,UAAU,UAAa,WAAW,OAAW,QAAO;AAExD,SAAO;IACL,mBAAmB;IACnB,oBAAoB;IACpB,yBAAyB,WAAW,OAAO,yBAAyB,CAAC,KAAK,QAAQ;IAClF,uBAAuB,WAAW,OAAO,uBAAuB,CAAC,KAAK,QAAQ;IAC9E,uBAAuB,WAAW,OAAO,uBAAuB,CAAC,KAAK;IACtE,yBAAyB,WAAW,OAAO,yBAAyB,CAAC,KAAK;EAC5E;AACF;AAEA,SAAS,aAAa,KAAgC,MAAc,SAAuB;AACzF,QAAM,aAAa,kBAAkB,IAAI;AACzC,MAAI,IAAI,YAAY,OAAO;AAE3B,QAAM,aAAa,WAAW,QAAQ,GAAG;AACzC,MAAI,cAAc,GAAG;AACnB,UAAM,WAAW,WAAW,MAAM,aAAa,CAAC;AAChD,QAAI,CAAC,IAAI,IAAI,QAAQ,EAAG,KAAI,IAAI,UAAU,OAAO;EACnD;AACF;AAOA,SAAS,cAAc,eAAe,OAAiC;AACrE,QAAM,OAAO,aAAa;AAC1B,MAAI,CAACD,YAAW,IAAI,EAAG,QAAO;AAE9B,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,aAAa,MAAM,OAAO,CAAC;AACrD,QAAI,CAAC,OAAO,SAAS,OAAO,SAAS,KAAK,OAAO,YAAY,KAAK,IAAI,EAAG,QAAO;AAChF,QAAI,gBAAgB,KAAK,IAAI,IAAI,OAAO,aAAa,aAAc,QAAO;AAC1E,QAAI,OAAO,QAAQ,QAAQ,OAAO,OAAO,SAAS,YAAY,MAAM,QAAQ,OAAO,IAAI,GAAG;AACxF,aAAO;IACT;AAEA,UAAM,OAAO,aAAa;AAC1B,QAAI,eAAe;AACnB,eAAW,CAAC,MAAM,UAAU,KAAK,OAAO,QAAQ,OAAO,IAAI,GAAG;AAC5D,YAAM,UAAU,iBAAiB,UAAU;AAC3C,UAAI,CAAC,QAAS;AACd,WAAK,IAAI,kBAAkB,IAAI,GAAG,OAAO;AACzC;IACF;AACA,WAAO,eAAe,IAAI,wBAAwB,IAAI,IAAI;EAC5D,QAAQ;AACN,WAAO;EACT;AACF;AAEO,SAAS,qBAAgD;AAC9D,SAAO,UAAU;AACnB;AAGO,SAAS,uBAA0C;AACxD,SAAO;AACT;AAGO,SAAS,6BAA6B,YAA0B;AACrE,MAAI,CAAC,OAAO,cAAc,UAAU,KAAK,aAAa,GAAG;AACvD,UAAM,IAAI,MAAM,+BAA+B,UAAU,EAAE;EAC7D;AACA,MAAI,UAAU,OAAO,WAAY;AAEjC,QAAM,SAAS,cAAc;AAC7B,MAAI,QAAQ,OAAO,YAAY;AAC7B,UAAM,IAAI;MACR,sBAAsB,UAAU,4BAA4B,UAAU,EAAE,YAAY,QAAQ,MAAM,MAAM;IAC1G;EACF;AAEA,cAAY;AACZ,qBAAmB,GAAG,OAAO,mCAAmC;IAC9D,YAAY,UAAU;IACtB,QAAQ,UAAU,QAAQ;EAC5B,CAAC;AACH;AAMO,SAAS,wBAAiC;AAC/C,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,OAAO,wBAAwB,OAAO;AAC5C,MAAI,CAAC,yBAAyB,aAAa,GAAG,IAAI,EAAG,QAAO;AAE5D,cAAY;AACZ,YAAU;AACV,qBAAmB,GAAG,OAAO,gCAAgC;IAC3D,YAAY,UAAU;IACtB,QAAQ,UAAU,QAAQ;EAC5B,CAAC;AACD,SAAO;AACT;AAOO,SAAS,mBAAmB,SAAgC;AACjE,SACE,QAAQ,oBAAoB,KAC5B,QAAQ,qBAAqB,KAC7B,QAAQ,wBAAwB,KAChC,QAAQ,0BAA0B;AAEtC;AAGA,SAAS,yBAAyB,MAAc,YAAwC;AACtF,QAAM,gBAAgB,GAAG,IAAI,IAAI,QAAQ,GAAG;AAC5C,QAAM,UAAU,KAAK,UAAU;IAC7B,WAAW,KAAK,IAAI;IACpB,MAAM,OAAO,YAAY,WAAW,OAAO;EAC7C,CAAC;AACD,MAAI;AACF,2BAAuB,YAAY,CAAC;AACpC,kBAAc,eAAe,OAAO;AACpC,wBAAoB,aAAa;AACjC,eAAW,eAAe,IAAI;AAC9B,WAAO;EACT,SAAS,OAAO;AACd,WAAO,eAAe,EAAE,OAAO,KAAK,CAAC;AACrC,uBAAmB,GAAG,KAAK,8BAA8B;MACvD,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;IAChE,CAAC;AACD,WAAO;EACT;AACF;AAaO,SAAS,oBAAoB,UAAiC,CAAC,GAAqB;AACzF,sBAAoB,aAAa,OAAO,EAAE,QAAQ,MAAM;AACtD,sBAAkB;EACpB,CAAC;AACD,SAAO;AACT;AAEA,eAAe,aAAa,SAAkD;AAC5E,MAAI,WAAW,cAAc,IAAI,EAAG,QAAO;AAE3C,QAAM,UAAU,YAAY,QAAQ,QAAQ,aAAa,kBAAkB;AAC3E,QAAM,SAAS,QAAQ,SAAS,YAAY,IAAI,CAAC,QAAQ,QAAQ,OAAO,CAAC,IAAI;AAE7E,qBAAmB,GAAG,OAAO,2BAA2B,EAAE,YAAY,UAAU,GAAG,CAAC;AACpF,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,gBAAgB,EAAE,OAAO,CAAC;AACvD,QAAI,CAAC,SAAS,GAAI,QAAO;AACzB,UAAM,SAAS,sBAAsB,MAAM,SAAS,KAAK,CAAC;AAC1D,QAAI,OAAO,SAAS,EAAG,QAAO;AAE9B,UAAM,OAAO,aAAa;AAC1B,eAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,GAAG;AAC9C,WAAK,IAAI,MAAM,OAAO;IACxB;AAEA,cAAU;AACV,uBAAmB,GAAG,OAAO,6BAA6B;MACxD,YAAY,UAAU;MACtB,QAAQ,KAAK;IACf,CAAC;AACD,WAAO;EACT,SAAS,OAAO;AACd,uBAAmB,GAAG,KAAK,0BAA0B;MACnD,YAAY,UAAU;MACtB,SAAS,OAAO;MAChB,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;IAChE,CAAC;AACD,WAAO;EACT;AACF;AKlRA,IAAA,kBAAA;EACE,8BAA8B;EAC9B,gCAAgC;EAChC,qBAAqB;EACrB,8BAA8B;EAC9B,gCAAgC;EAChC,+BAA+B;EAC/B,8BAA8B;EAC9B,4BAA4B;EAC5B,iBAAiB;EACjB,eAAe;EACf,qBAAqB;EACrB,gBAAgB;EAChB,uBAAuB;EACvB,0BAA0B;EAC1B,mBAAmB;EACnB,aAAa;EACb,yBAAyB;EACzB,eAAe;EACf,sBAAsB;EACtB,eAAe;AACjB;ACbA,IAAM,kBAAkB,OAAO;EAC7B,OAAO,QAAQ,eAAqC,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;IAC1E,kBAAkB,GAAG;IACrB,kBAAkB,KAAK;EACzB,CAAC;AACH;AAEA,SAAS,aAAa,OAAuB;AAC3C,SAAO,MAAM,QAAQ,QAAQ,EAAE,EAAE,QAAQ,WAAW,EAAE;AACxD;AAEA,SAAS,oBAAoB,OAAuB;AAClD,QAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,SAAO,MAAM,MAAM,SAAS,CAAC,KAAK;AACpC;AAEA,SAAS,aAAa,OAAuB;AAC3C,SAAO,gBAAgB,KAAK,KAAK;AACnC;AAEA,SAAS,cAAc,UAA4B;AACjD,QAAM,aAAa,aAAa,kBAAkB,QAAQ,CAAC;AAC3D,QAAM,WAAW,oBAAoB,UAAU;AAC/C,QAAM,UAAU,aAAa,QAAQ;AACrC,QAAM,aAAa;IACjB;IACA,aAAa,UAAU;IACvB;IACA;IACA,aAAa,QAAQ;IACrB,UAAU,QAAQ;IAClB,qBAAqB,QAAQ;IAC7B,wBAAwB,QAAQ;IAChC,cAAc,QAAQ;IACtB,qBAAqB,QAAQ;EAC/B;AAEA,SAAO,CAAC,GAAG,IAAI,IAAI,WAAW,OAAO,OAAO,CAAC,CAAC;AAChD;AAEA,SAAS,gBAAgB,OAAe,UAAqC;AAC3E,QAAM,SAAS,SAAS,IAAI,KAAK;AACjC,MAAI,UAAU,mBAAmB,MAAM,EAAG,QAAO;AAEjD,QAAM,QAAQ,aAAa,KAAK;AAChC,MAAI,UAAU,OAAO;AACnB,UAAM,UAAU,SAAS,IAAI,KAAK;AAClC,QAAI,WAAW,mBAAmB,OAAO,EAAG,QAAO;EACrD;AAEA,SAAO;AACT;AAEA,SAAS,YAAY,OAAe,UAAqC;AACvE,QAAM,SAAS,SAAS,IAAI,KAAK;AACjC,MAAI,UAAU,mBAAmB,MAAM,EAAG,QAAO;AAEjD,WAAS,QAAQ,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS;AACtD,QAAI,MAAM,KAAK,MAAM,OAAO,MAAM,KAAK,MAAM,IAAK;AAClD,UAAM,UAAU,SAAS,IAAI,MAAM,MAAM,GAAG,KAAK,CAAC;AAClD,QAAI,WAAW,mBAAmB,OAAO,EAAG,QAAO;EACrD;AACA,SAAO;AACT;AAMO,IAAM,kBAAmC;EAC9C,QAAQ,cAA2C;AACjD,UAAM,WAAW,mBAAmB;AACpC,UAAM,QAAQ,SAAS,IAAI,kBAAkB,YAAY,CAAC;AAC1D,QAAI,SAAS,mBAAmB,KAAK,EAAG,QAAO;AAC/C,UAAM,aAAa,cAAc,YAAY;AAE7C,eAAW,aAAa,YAAY;AAClC,YAAM,UAAU,gBAAgB,WAAW,QAAQ;AACnD,UAAI,QAAS,QAAO;IACtB;AAEA,eAAW,aAAa,YAAY;AAClC,YAAM,UAAU,YAAY,WAAW,QAAQ;AAC/C,UAAI,QAAS,QAAO;IACtB;AAEA,WAAO;EACT;AACF;AFnFA,SAAS,SAAS,OAAmC;AACnD,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,QAAQ,IAAI,QAAQ;AACpF;AAEA,IAAM,qBAAqB,IAAI,kBAA+B;AAEvD,IAAM,wBAAwB;AAG9B,SAAS,uBAAuB,gBAAkC;AACvE,MAAI,CAAC,MAAM,QAAQ,cAAc,EAAG,QAAO;AAC3C,SAAO,eAAe;IACpB,CAAC,UAAU,OAAO,UAAU,YAAY,gBAAgB,QAAQ,KAAK,MAAM;EAC7E;AACF;AAgBO,SAAS,qBACd,KACoE;AACpE,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,SAAS,mBAAmB,IAAI,SAAS,GAAG;AAClD,MAAI,kBAAkB,SAAS;AAC7B,WAAO,OAAO,KAAK,CAAC,cAAc,EAAE,QAAQ,UAAU,gBAAgB,CAAC,GAAG,OAAO,EAAE,EAAE;EACvF;AACA,SAAO,EAAE,QAAQ,gBAAgB,CAAC,GAAG,OAAO,EAAE;AAChD;AAEO,SAAS,sBACd,OACA,OACqB;AACrB,MAAI,CAAC,SAAS,CAAC,MAAO,QAAO;AAE7B,QAAM,UAAU,gBAAgB,QAAQ,KAAK;AAC7C,MAAI,CAAC,SAAS;AACZ,uBAAmB,SAAS,GAAG,IAAI,KAAK;AACxC,WAAO;EACT;AAEA,QAAM,YAAY,SAAS,MAAM,UAAU;AAC3C,QAAM,cAAc,SAAS,MAAM,YAAY;AAC/C,QAAM,QAAQ,KAAK,IAAI,GAAG,SAAS,MAAM,KAAK,IAAI,YAAY,WAAW;AACzE,QAAM,SAAS,SAAS,MAAM,MAAM;AACpC,QAAM,YAAY,SAAS,MAAM,SAAS;AAC1C,QAAM,oBAAoB,SAAS,MAAM,mBAAmB;AAE5D,QAAM,OACJ,QAAQ,QAAQ,oBAChB,SAAS,QAAQ,qBACjB,YAAY,QAAQ,wBACpB,YAAY,QAAQ,wBACpB,cAAc,QAAQ,0BACtB,oBAAoB,QAAQ;AAE9B,SAAO,OAAO,IAAI,EAAE,MAAM,OAAO,KAAK,QAAQ,CAAC,CAAC,GAAG,QAAQ,YAAY,IAAI;AAC7E;;;AIlFA,SAAS,WAAW,UAAU,gBAAgB;AAC9C,SAAS,qBAAqB;AED9B,SAAS,YAAAE,iBAAgB;AHazB,IAAM,aAAN,MAAiB;EACP,cAA4B,CAAC;EAC7B,cAA4B,CAAC;EAC7B,UAAU;EAElB,SAAS;AACP,SAAK,UAAU;EACjB;EAEA,MAAM,MAA0B;AAC9B,UAAM,SAAqB;MACzB;MACA,WAAW,YAAY,IAAI;MAC3B,UAAU,CAAC;IACb;AAEA,QAAI,CAAC,KAAK,QAAS,QAAO;AAE1B,UAAM,SAAS,KAAK,YAAY,KAAK,YAAY,SAAS,CAAC;AAC3D,QAAI,QAAQ;AACV,aAAO,SAAS;AAChB,aAAO,SAAS,KAAK,MAAM;IAC7B,OAAO;AACL,WAAK,YAAY,KAAK,MAAM;IAC9B;AAEA,SAAK,YAAY,KAAK,MAAM;AAC5B,WAAO;EACT;EAEA,IAAI,QAA2B;AAC7B,QAAI,CAAC,KAAK,QAAS;AAEnB,UAAM,SAAS,UAAU,KAAK,YAAY,KAAK,YAAY,SAAS,CAAC;AACrE,QAAI,CAAC,OAAQ;AAEb,WAAO,UAAU,YAAY,IAAI;AACjC,WAAO,WAAW,OAAO,UAAU,OAAO;AAG1C,WAAO,KAAK,YAAY,SAAS,GAAG;AAClC,YAAM,SAAS,KAAK,YAAY,IAAI;AACpC,UAAI,WAAW,OAAQ;IACzB;EACF;EAEA,QAAW,MAAc,IAAgB;AACvC,UAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,QAAI;AACF,aAAO,GAAG;IACZ,UAAA;AACE,WAAK,IAAI,MAAM;IACjB;EACF;EAEA,MAAM,aAAgB,MAAc,IAAkC;AACpE,UAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,QAAI;AACF,aAAO,MAAM,GAAG;IAClB,UAAA;AACE,WAAK,IAAI,MAAM;IACjB;EACF;EAEA,YAAoB;AAClB,QAAI,CAAC,KAAK,QAAS,QAAO;AAE1B,UAAM,QAAkB,CAAC;AACzB,UAAM,KAAK,gCAAgC;AAE3C,eAAW,UAAU,KAAK,aAAa;AACrC,WAAK,aAAa,QAAQ,GAAG,KAAK;IACpC;AAEA,WAAO,MAAM,KAAK,IAAI;EACxB;EAEQ,aAAa,QAAoB,OAAe,OAAuB;AAC7E,UAAM,SAAS,KAAK,OAAO,KAAK;AAChC,UAAM,WAAW,OAAO,UAAU,QAAQ,CAAC,KAAK;AAChD,UAAM,KAAK,GAAG,MAAM,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI;AAEnD,eAAW,SAAS,OAAO,UAAU;AACnC,WAAK,aAAa,OAAO,QAAQ,GAAG,KAAK;IAC3C;EACF;EAEA,QAAc;AACZ,SAAK,cAAc,CAAC;AACpB,SAAK,cAAc,CAAC;EACtB;AACF;AAEO,IAAM,OAAO,IAAI,WAAW;ACtGnC,IAAM,mBAAmB,KAAK;AAEvB,UAAU,gBAAgB,SAAqD;AACpF,MAAI,QAAQ;AACZ,MAAI,UAAU;AACd,aAAW,QAAQ,QAAQ,MAAM,IAAI,GAAG;AACtC,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,CAAC,QAAS;AACd,aAAS;AACT,QAAI;AACF,YAAM,KAAK,MAAM,OAAO;IAC1B,QAAQ;AACN,iBAAW;IACb;EACF;AAIA,MAAI,UAAU,GAAG;AACf,uBAAmB,GAAG,KAAK,6BAA6B,EAAE,SAAS,MAAM,CAAC;EAC5E;AACF;AAQO,UAAU,mBACf,UACA,aAAa,kBACM;AACnB,QAAM,KAAK,SAAS,UAAU,GAAG;AACjC,MAAI;AACF,UAAM,SAAS,OAAO,MAAM,UAAU;AAEtC,UAAM,UAAU,IAAI,cAAc,MAAM;AAKxC,QAAIC,WAAoB,CAAC;AACzB,QAAI,YAAY,SAAS,IAAI,QAAQ,GAAG,YAAY,EAAE;AACtD,WAAO,YAAY,GAAG;AACpB,YAAM,UAAU,QAAQ,MAAM,OAAO,SAAS,GAAG,SAAS,CAAC;AAC3D,YAAM,YAAY,QAAQ,YAAY,IAAI;AAC1C,UAAI,cAAc,IAAI;AACpB,YAAI,QAAS,CAAAA,SAAQ,KAAK,OAAO;MACnC,OAAO;AACL,QAAAA,SAAQ,KAAK,QAAQ,MAAM,GAAG,SAAS,CAAC;AACxC,cAAM,WAAWA,SAAQ,KAAK,EAAE;AAChC,QAAAA,WAAU,CAAC,QAAQ,MAAM,YAAY,CAAC,CAAC;AACvC,mBAAW,QAAQ,SAAS,MAAM,IAAI,GAAG;AACvC,gBAAM,UAAU,KAAK,KAAK;AAC1B,cAAI,QAAS,OAAM;QACrB;MACF;AACA,kBAAY,SAAS,IAAI,QAAQ,GAAG,YAAY,EAAE;IACpD;AACA,IAAAA,SAAQ,KAAK,QAAQ,IAAI,CAAC;AAC1B,UAAM,OAAOA,SAAQ,KAAK,EAAE,EAAE,KAAK;AACnC,QAAI,KAAM,OAAM;EAClB,UAAA;AACE,cAAU,EAAE;EACd;AACF;AAEO,UAAU,cAAc,UAAsD;AACnF,MAAI,QAAQ;AACZ,MAAI,UAAU;AACd,aAAW,QAAQ,mBAAmB,QAAQ,GAAG;AAC/C,aAAS;AACT,QAAI;AACF,YAAM,KAAK,MAAM,IAAI;IACvB,QAAQ;AACN,iBAAW;IACb;EACF;AAEA,MAAI,UAAU,GAAG;AACf,uBAAmB,GAAG,KAAK,6BAA6B,EAAE,SAAS,OAAO,SAAS,CAAC;EACtF;AACF;ACvFA,IAAM,sBAAsB;EAC1B;EACA;EACA;EACA;EACA;AACF;AAEA,IAAM,mBAAmB,CAAC,cAAc;AAExC,IAAM,uBAAuB,oBAAI,IAAI;EACnC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AACF,CAAC;AAED,SAAS,gBAAgB,KAAqB;AAC5C,SAAO,IAAI,OAAO,IAAI,GAAG,0BAA0B,GAAG,KAAK,IAAI;AACjE;AAEA,SAAS,oBAAoB,KAAqB;AAChD,SAAO,IAAI;IACT,sBAAsB,GAAG,0BAA0B,GAAG;IACtD;EACF;AACF;AAEA,SAAS,oBAAoB,KAAqB;AAChD,SAAO,IAAI,OAAO,QAAQ,GAAG,uBAAuB,IAAI;AAC1D;AAEA,SAAS,gBAAgB,KAAqB;AAC5C,SAAO,IAAI,OAAO,QAAQ,GAAG,aAAa,IAAI;AAChD;AAEO,SAAS,oBAAoB,OAAyB;AAC3D,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,aAAa,MAAM,KAAK,EAAE,YAAY,EAAE,QAAQ,UAAU,GAAG;AACnE,SAAO,qBAAqB,IAAI,UAAU;AAC5C;AAEO,SAAS,iBAAiB,MAA6B;AAC5D,MAAI,UAAU;AAEd,aAAW,OAAO,qBAAqB;AACrC,cAAU,QAAQ,QAAQ,oBAAoB,GAAG,GAAG,IAAI;AACxD,cAAU,QAAQ,QAAQ,gBAAgB,GAAG,GAAG,EAAE;AAClD,cAAU,QAAQ,QAAQ,oBAAoB,GAAG,GAAG,EAAE;EACxD;AAEA,aAAW,OAAO,qBAAqB;AACrC,cAAU,QAAQ,QAAQ,gBAAgB,GAAG,GAAG,EAAE;EACpD;AAEA,aAAW,OAAO,kBAAkB;AAClC,cAAU,QAAQ,QAAQ,gBAAgB,GAAG,GAAG,EAAE;EACpD;AAEA,YAAU,QAAQ,QAAQ,sBAAsB,EAAE,EAAE,QAAQ,gBAAgB,EAAE;AAE9E,SAAO,QAAQ,KAAK,IAAI,UAAU;AACpC;ACjEA,IAAM,mBAAmB;AACzB,IAAM,mBAAmB;AAGlB,SAAS,mBAAmB,MAA6B;AAC9D,QAAM,UACJ,iBAAiB,IAAI,GACjB,MAAM,IAAI,EACX,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,GACzB,KAAK,KAAK;AAChB,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,UAAU,QAAQ,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAClD,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO,QAAQ,MAAM,GAAG,gBAAgB;AAC1C;AAGO,SAAS,cAAc,MAAgD;AAC5E,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,aAAa,KAAK,KAAK,EAAE,QAAQ,WAAW,EAAE;AACpD,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,OAAOD,UAAS,UAAU,EAAE,KAAK;AACvC,SAAO,QAAQ;AACjB;AAGO,SAAS,oBACd,UACA,SACA,WACQ;AACR,aAAW,aAAa,CAAC,UAAU,SAAS,SAAS,GAAG;AACtD,QAAI,WAAW;AACb,YAAM,aAAa,mBAAmB,SAAS;AAC/C,UAAI,WAAY,QAAO;IACzB;EACF;AACA,SAAO;AACT;ACtCO,SAAS,kBACd,OACA,QACe;AACf,SAAO,sBAAsB,OAAO,MAAM,GAAG,QAAQ;AACvD;ACLO,SAAS,SAAS,OAAqD;AAC5E,MAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AAC/D,WAAO;EACT;AACA,SAAO;AACT;AAGO,SAAS,SAAS,OAAoC;AAC3D,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAGO,SAAS,SAAS,OAAoC;AAC3D,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,QAAQ;AACvE;AAGO,SAAS,QAAQ,OAAuC;AAC7D,SAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ;AACxC;AAOO,SAAS,oBAAoB,MAAmD;AACrF,MAAI;AACJ,MAAI;AACF,UAAM,KAAK,MAAM,IAAI;EACvB,QAAQ;AACN,WAAO;EACT;AACA,SAAO,SAAS,GAAG;AACrB;AAEA,IAAM,0BAA0B,oBAAI,IAAY;AAOzC,SAAS,oBAAoB,WAAmB,OAAqB;AAC1E,QAAM,MAAM,GAAG,SAAS,KAAK,KAAK;AAClC,MAAI,wBAAwB,IAAI,GAAG,EAAG;AACtC,0BAAwB,IAAI,GAAG;AAC/B,qBAAmB,GAAG,KAAK,8BAA8B,EAAE,WAAW,MAAM,CAAC;AAC/E;AAQO,SAAS,YACd,OACA,OACA,OACA,QACe;AACf,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,QAAM,SAAS,OAAO,KAAK;AAC3B,MAAI,WAAW,OAAW,qBAAoB,OAAO,KAAK;AAC1D,SAAO;AACT;AC/DO,SAASE,qBAAoB,OAAyB;AAC3D,SAAO,oBAAuB,KAAK;AACrC;AAEO,SAAS,kBAAkB,MAAsB;AACtD,SAAO,iBAAiB,IAAI,KAAK;AACnC;AAEA,SAAS,aAAa,OAAyB;AAC7C,MAAI,OAAO,UAAU,SAAU,QAAO,kBAAkB,KAAK;AAC7D,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,YAAY;AACvD,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAEhD,QAAM,UAAmC,CAAC;AAC1C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,YAAQ,GAAG,IAAI,aAAa,KAAK;EACnC;AACA,SAAO;AACT;AAEO,SAAS,iBAAiB,MAAuC;AACtE,MAAI,KAAK,SAAS,UAAU,KAAK,SAAS,eAAe,KAAK,SAAS,QAAQ;AAC7E,UAAM,OAAO,kBAAkB,KAAK,IAAI;AACxC,WAAO,OAAO,EAAE,GAAG,MAAM,KAAK,IAAI;EACpC;AACA,MAAI,KAAK,SAAS,OAAQ,QAAO;AAEjC,QAAM,QAAQ,KAAK,QAAQ,kBAAkB,KAAK,KAAK,IAAI;AAC3D,QAAM,QAAQ;IACZ,GAAG,KAAK;IACR,GAAI,KAAK,MAAM,UAAU,SAAY,EAAE,OAAO,aAAa,KAAK,MAAM,KAAK,EAAE,IAAI,CAAC;IAClF,GAAI,KAAK,MAAM,WAAW,SAAY,EAAE,QAAQ,aAAa,KAAK,MAAM,MAAM,EAAE,IAAI,CAAC;IACrF,GAAI,KAAK,MAAM,UAAU,SAAY,EAAE,OAAO,aAAa,KAAK,MAAM,KAAK,EAAE,IAAI,CAAC;IAClF,GAAI,KAAK,MAAM,aAAa,SAAY,EAAE,UAAU,aAAa,KAAK,MAAM,QAAQ,EAAE,IAAI,CAAC;EAC7F;AACA,QAAM,EAAE,OAAO,QAAQ,GAAG,aAAa,IAAI;AAC3C,SAAO;IACL,GAAG;IACH,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;IACzB;EACF;AACF;AAEO,SAAS,kBAAkB,OAAqC;AACrE,SAAO,MAAM,QAAQ,CAAC,SAAS;AAC7B,UAAM,UAAU,iBAAiB,IAAI;AACrC,WAAO,UAAU,CAAC,OAAO,IAAI,CAAC;EAChC,CAAC;AACH;AAEO,SAAS,mBAAmB,SAAkC;AACnE,QAAM,QAAQ,kBAAkB,QAAQ,KAAK;AAC7C,QAAM,YACH,QAAQ,QAAQ,KAAK,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,QAAQ,CAAC;AAC1F,MAAI,MAAM,WAAW,KAAK,CAAC,SAAU,QAAO;AAC5C,SAAO,EAAE,GAAG,SAAS,MAAM;AAC7B;AAEO,SAAS,oBAAoB,UAAgC;AAClE,SAAO,SAAS,QAAQ,CAAC,YAAY;AACnC,UAAM,UAAU,mBAAmB,OAAO;AAC1C,WAAO,UAAU,CAAC,OAAO,IAAI,CAAC;EAChC,CAAC;AACH;AAEO,SAAS,sBAAsB,UAAoC;AACxE,aAAW,WAAW,UAAU;AAC9B,QAAI,QAAQ,SAAS,OAAQ;AAC7B,eAAW,QAAQ,QAAQ,OAAO;AAChC,UAAI,KAAK,SAAS,OAAQ;AAC1B,YAAM,QAAQ,mBAAmB,kBAAkB,KAAK,IAAI,CAAC;AAC7D,UAAI,MAAO,QAAO;IACpB;EACF;AACA,SAAO;AACT;;;AC9EA,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,YAAAC,WAAU,WAAAC,UAAS,QAAAC,aAAY;AACxC,SAAS,qBAAqB;AAuC9B,IAAM,yBAAyB;AAE/B,IAAI,sBAAwD;AAC5D,IAAI,mBAAkC;AAEtC,IAAI;AACF,QAAMC,WAAU,cAAc,YAAY,GAAG;AAE7C,QAAM,MAAMA,SAAQ,gBAAgB;AACpC,wBACE,OAAO,QAAQ,aAAa,MAAO,IAA8B;AAErE,SAAS,OAAO;AAKd,qBAAmB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E;AAEA,IAAI,sBAAsB;AAE1B,SAAS,wBAA8B;AACrC,MAAI,oBAAqB;AACzB,wBAAsB;AACtB,qBAAmB,GAAG,KAAK,sBAAsB,EAAE,SAAS,iBAAiB,CAAC;AAChF;AAiCO,IAAM,2BAAN,cAAuC,MAAM;EAClD,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;EACd;AACF;AAEA,SAAS,sBAAsB,OAAe,OAAqB;AACjE,MAAI,OAAO,cAAc,KAAK,KAAK,SAAS,EAAG;AAC/C,QAAM,IAAI,yBAAyB,GAAG,KAAK,sCAAsC;AACnF;AAEA,SAAS,sBAAsB,SAA2C;AACxE,MAAI,kBAAkB;AACtB,MAAI,gBAAgB;AAEpB,aAAW,aAAa,QAAQ,YAAY;AAC1C,QAAI,CAAC,OAAO,cAAc,UAAU,OAAO,KAAK,UAAU,UAAU,GAAG;AACrE,YAAM,IAAI;QACR,GAAG,QAAQ,WAAW;MACxB;IACF;AACA,QAAI,UAAU,WAAW,iBAAiB;AACxC,YAAM,IAAI;QACR,GAAG,QAAQ,WAAW;MACxB;IACF;AACA,sBAAkB,UAAU;AAC5B,sBAAkB,UAAU,YAAY,QAAQ;EAClD;AAEA,MAAI,CAAC,eAAe;AAClB,UAAM,IAAI;MACR,GAAG,QAAQ,WAAW,wCAAwC,QAAQ,aAAa;IACrF;EACF;AACF;AAEA,SAAS,gBAAgB,OAAuB;AAC9C,SAAO,IAAI,MAAM,WAAW,KAAK,IAAI,CAAC;AACxC;AAEA,SAAS,eAAe,OAAuB;AAC7C,SAAO,IAAI,MAAM,WAAW,KAAK,IAAI,CAAC;AACxC;AAEA,SAAS,eAAe,QAAyB;AAC/C,SACE,WAAW,cAAc,OAAO,WAAW,eAAe,KAAK,OAAO,SAAS,aAAa;AAEhG;AAEO,SAAS,eAAe,IAA4B;AACzD,QAAM,MAAM,GAAG,QAAQ,qBAAqB,EAAE,IAAI;AAClD,SAAO,OAAO,KAAK,gBAAgB,CAAC;AACtC;AAEO,SAAS,eAAe,IAAoB,SAAuB;AACxE,KAAG,KAAK,yBAAyB,KAAK,MAAM,OAAO,CAAC,EAAE;AACxD;AAEO,SAAS,YAAY,IAAoB,WAA4B;AAC1E,QAAM,MAAM,GACT;IACC;;;;;;EAMF,EACC,IAAI,SAAS;AAChB,SAAO,QAAQ;AACjB;AAEO,SAAS,aAAa,IAAoB,WAAmB,YAA6B;AAC/F,MAAI,CAAC,YAAY,IAAI,SAAS,GAAG;AAC/B,WAAO;EACT;AAEA,QAAM,OAAO,GAAG,QAAQ,qBAAqB,gBAAgB,SAAS,CAAC,GAAG,EAAE,IAAI;AAChF,SAAO,KAAK,KAAK,CAAC,QAAQ,OAAO,IAAI,IAAI,MAAM,UAAU;AAC3D;AAEO,SAAS,aAAa,IAAoB,WAA4B;AAC3E,MAAI,CAAC,YAAY,IAAI,SAAS,GAAG;AAC/B,WAAO;EACT;AAEA,QAAM,MAAM,GAAG,QAAQ,0BAA0B,gBAAgB,SAAS,CAAC,UAAU,EAAE,IAAI;AAG3F,SAAO,QAAQ;AACjB;AAEO,SAAS,eAAe,IAAoB,QAAgB,OAA8B;AAC/F,MAAI,eAAe,MAAM,GAAG;AAC1B,WAAO;EACT;AAEA,QAAM,YAAY,IAAI,KAAK,KAAK,IAAI,CAAC,EAAE,YAAY,EAAE,WAAW,KAAK,EAAE,EAAE,WAAW,KAAK,GAAG;AAC5F,MAAI,aAAaD,MAAKD,SAAQ,MAAM,GAAG,GAAGD,UAAS,MAAM,CAAC,IAAI,SAAS,IAAI,KAAK,MAAM;AACtF,WAAS,UAAU,GAAGD,YAAW,UAAU,GAAG,WAAW,GAAG;AAC1D,iBAAaG,MAAKD,SAAQ,MAAM,GAAG,GAAGD,UAAS,MAAM,CAAC,IAAI,SAAS,IAAI,KAAK,IAAI,OAAO,MAAM;EAC/F;AACA,KAAG,KAAK,eAAe,eAAe,UAAU,CAAC,EAAE;AAEnD,sBAAoB,UAAU;AAC9B,SAAO;AACT;AAEO,SAAS,0BACd,IACA,QACA,OACA,QACe;AACf,MAAI,CAAC,OAAO,KAAK,CAAC,UAAU,aAAa,IAAI,KAAK,CAAC,GAAG;AACpD,WAAO;EACT;AAEA,SAAO,eAAe,IAAI,QAAQ,KAAK;AACzC;AAEO,SAAS,oBACd,IACA,SACU;AACV,QAAM,UAAoB,CAAC;AAC3B,MAAI,iBAAiB,QAAQ;AAC7B,wBAAsB,gBAAgB,GAAG,QAAQ,WAAW,kBAAkB;AAC9E,wBAAsB,QAAQ,eAAe,GAAG,QAAQ,WAAW,iBAAiB;AACpF,MAAI,kBAAkB,QAAQ,cAAe,QAAO;AACpD,wBAAsB,OAAO;AAE7B,aAAW,aAAa,QAAQ,YAAY;AAC1C,QAAI,UAAU,WAAW,gBAAgB;AACvC;IACF;AACA,QAAI,UAAU,UAAU,QAAQ,eAAe;AAC7C;IACF;AAEA,UAAM,cAAc;AACpB,UAAM,YAAY,YAAY,IAAI;AAClC,uBAAmB,GAAG,OAAO,4BAA4B;MACvD,OAAO,QAAQ;MACf,cAAc;MACd,YAAY,UAAU;MACtB,aAAa,UAAU,eAAe;IACxC,CAAC;AAED,QAAI;AACF,UAAI,gBAAgB;AACpB,UAAI,UAAU,aAAa;AACzB,cAAM,aAAa;UACjB;UACA,QAAQ;UACR,QAAQ;UACR,QAAQ;QACV;AACA,YAAI,YAAY;AACd,kBAAQ,KAAK,UAAU;AACvB,0BAAgB;QAClB;MACF;AAEA,YAAM,QAAQ,GAAG,YAAY,MAAM;AACjC,kBAAU,QAAQ,EAAE;AACpB,uBAAe,IAAI,UAAU,OAAO;MACtC,CAAC;AACD,YAAM,UAAU;AAChB,uBAAiB,UAAU;AAC3B,yBAAmB,GAAG,OAAO,8BAA8B;QACzD,OAAO,QAAQ;QACf,cAAc;QACd,YAAY,UAAU;QACtB,aAAa,UAAU,eAAe;QACtC,gBAAgB;QAChB,aAAa,KAAK,MAAM,YAAY,IAAI,IAAI,SAAS;MACvD,CAAC;IACH,SAAS,OAAO;AACd,yBAAmB,GAAG,KAAK,2BAA2B;QACpD,OAAO,QAAQ;QACf,cAAc;QACd,YAAY,UAAU;QACtB,aAAa,UAAU,eAAe;QACtC,aAAa,KAAK,MAAM,YAAY,IAAI,IAAI,SAAS;QACrD,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;MAChE,CAAC;AACD,YAAM;IACR;EACF;AAEA,MAAI,mBAAmB,QAAQ,eAAe;AAC5C,UAAM,IAAI;MACR,GAAG,QAAQ,WAAW,uBAAuB,cAAc,cAAc,QAAQ,aAAa;IAChG;EACF;AAEA,SAAO;AACT;AAMO,SAAS,eAAe,QAAuC;AACpE,MAAI,CAAC,qBAAqB;AACxB,0BAAsB;AACtB,WAAO;EACT;AACA,MAAI;AACF,UAAM,KAAK,oBAAoB,QAAQ,EAAE,UAAU,KAAK,CAAC;AACzD,QAAI;AACF,SAAG,OAAO,kBAAkB,sBAAsB,EAAE;IACtD,QAAQ;IAER;AACA,WAAO;EACT,SAAS,OAAO;AACd,uBAAmB,GAAG,KAAK,sBAAsB;MAC/C;MACA,UAAU;MACV,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;IAChE,CAAC;AACD,WAAO;EACT;AACF;AAEO,SAAS,OAAO,QAAuC;AAC5D,MAAI,CAAC,qBAAqB;AACxB,0BAAsB;AACtB,WAAO;EACT;AACA,MAAI;AACF,2BAAuBC,SAAQ,MAAM,CAAC;AAItC,QAAI,CAAC,eAAe,MAAM,EAAG,SAAQ,IAAI,kBAAkBA,SAAQ,MAAM;AACzE,UAAM,KAAK,oBAAoB,MAAM;AAErC,4BAAwB,MAAM;AAC9B,QAAI;AAGF,SAAG,OAAO,kBAAkB,sBAAsB,EAAE;AACpD,SAAG,OAAO,oBAAoB;AAC9B,SAAG,OAAO,sBAAsB;AAChC,SAAG,OAAO,mBAAmB;AAC7B,SAAG,OAAO,mBAAmB;IAC/B,QAAQ;IAER;AACA,WAAO;EACT,SAAS,OAAO;AACd,uBAAmB,GAAG,KAAK,sBAAsB;MAC/C;MACA,UAAU;MACV,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;IAChE,CAAC;AACD,WAAO;EACT;AACF;AAKO,SAAS,oBAA6B;AAC3C,SAAO,wBAAwB;AACjC;;;AC9WA,SAASG,UAAS,OAAgD;AAChE,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IACrE,QACD;AACN;AAEA,SAAS,eAAe,OAAoC;AAC1D,SAAO,OAAO,UAAU,YAAY,QAAQ,QAAQ;AACtD;AAEA,SAAS,aAAa,OAAoC;AACxD,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,QAAQ;AACvE;AAEA,SAAS,UAAU,cAAkC;AACnD,SAAO,iBAAiB,SAAY,CAAC,IAAI,EAAE,aAAa;AAC1D;AAEA,SAAS,gBAAgB,QAA4B;AACnD,SAAO,OAAO,KAAK,CAAC,UAAU,UAAU,MAAS;AACnD;AAEA,SAAS,gBACP,OACA,QACA,OACgB;AAChB,QAAM,SAAS,MAAM;AACrB,MAAI,WAAW,aAAa,WAAW,eAAe,WAAW,QAAS,QAAO;AACjF,MAAI,WAAW,UAAW,QAAO;AACjC,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,WAAW,OAAW,QAAO;AACjC,SAAO;AACT;AAEA,SAAS,kBAAkB,OAAyC;AAClE,QAAM,cAAc,MAAM,YAAY,MAAM;AAC5C,QAAM,SAAS,OAAO;IACpB,OAAO,QAAQ,KAAK,EAAE;MACpB,CAAC,CAAC,GAAG,MACH,CAAC,CAAC,UAAU,SAAS,aAAa,UAAU,UAAU,SAAS,YAAY,MAAM,EAAE;QACjF;MACF;IACJ;EACF;AACA,MAAI,OAAO,KAAK,MAAM,EAAE,WAAW,EAAG,QAAO;AAE7C,QAAM,WAAWA,UAAS,WAAW;AACrC,SAAO,WAAW,EAAE,GAAG,UAAU,GAAG,OAAO,IAAI;AACjD;AAEA,SAAS,mBAAmB,OAAgB,YAAoD;AAC9F,QAAM,QAAQA,UAAS,KAAK,KAAK,CAAC;AAClC,QAAM,QAAQ,aAAa,MAAM,OAAO,MAAM,WAAW,WAAW,KAAK;AACzE,QAAM,SAAS,aAAa,MAAM,QAAQ,MAAM,QAAQ,WAAW,MAAM;AACzE,QAAM,QAAQ,MAAM;AACpB,QAAM,WAAW,kBAAkB,KAAK;AAExC,SAAO;IACL,QAAQ,gBAAgB,OAAO,QAAQ,KAAK;IAC5C,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC;IACvC,GAAI,WAAW,SAAY,EAAE,OAAO,IAAI,CAAC;IACzC,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC;IACvC,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;EAC/C;AACF;AAEA,SAAS,SAAS,OAAwB;AACxC,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAMC,UAASD,UAAS,KAAK;AAC7B,MAAI,CAACC,QAAQ,QAAO;AACpB,SAAO,SAASA,QAAO,QAAQA,QAAO,QAAQA,QAAO,OAAO;AAC9D;AAEA,SAAS,kBACP,OACA,cACiB;AACjB,QAAM,kBAAkB,MAAM,oBAAoB,SAAS,SAAS;AACpE,QAAM,OAAO,SAAS,MAAM,SAAS,oBAAoB,SAAS,MAAM,SAAS,MAAM,MAAM;AAC7F,SAAO,OAAO,EAAE,MAAM,QAAQ,MAAM,iBAAiB,GAAG,UAAU,YAAY,EAAE,IAAI;AACtF;AAEA,SAAS,mBACP,OACA,cACkB;AAClB,QAAM,OAAO,eAAe,MAAM,IAAI;AACtC,QAAM,MAAM,eAAe,MAAM,GAAG;AACpC,QAAM,YAAY,eAAe,MAAM,SAAS;AAEhD,MAAI,QAAQ,WAAW;AACrB,WAAO;MACL,MAAM;MACN;MACA;MACA,GAAI,MAAM,EAAE,IAAI,IAAI,CAAC;MACrB,GAAG,UAAU,YAAY;IAC3B;EACF;AACA,MAAI,KAAK;AACP,WAAO;MACL,MAAM;MACN;MACA,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;MACvB,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;MACjC,GAAG,UAAU,YAAY;IAC3B;EACF;AACA,SAAO;AACT;AAEA,SAAS,kBACP,OACA,cACiB;AACjB,QAAM,QAAQ,eAAe,MAAM,KAAK;AACxC,QAAM,SAAS,eAAe,MAAM,MAAM;AAC1C,QAAM,OAAO,eAAe,MAAM,IAAI,GAAG,KAAK,KAAK,OAAO,QAAQ,cAAc,EAAE,EAAE,KAAK;AACzF,MAAI,CAAC,KAAM,QAAO;AAElB,SAAO;IACL,MAAM;IACN;IACA,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;IACzB,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;IAC3B,OAAO,mBAAmB,MAAM,OAAO,KAAK;IAC5C,GAAG,UAAU,YAAY;EAC3B;AACF;AAEA,SAAS,qBAAqB,OAAoC;AAChE,QAAM,OAAOD,UAAS,KAAK;AAC3B,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,eAAe,aAAa,KAAK,YAAY;AAEnD,MAAI,KAAK,SAAS,UAAU,KAAK,SAAS,aAAa;AACrD,QAAI,OAAO,KAAK,SAAS,SAAU,QAAO;AAC1C,WAAO,EAAE,MAAM,KAAK,MAAM,MAAM,KAAK,MAAM,GAAG,UAAU,YAAY,EAAE;EACxE;AACA,MAAI,KAAK,SAAS,OAAQ,QAAO,kBAAkB,MAAM,YAAY;AACrE,MAAI,KAAK,SAAS,QAAS,QAAO,mBAAmB,MAAM,YAAY;AACvE,MAAI,KAAK,SAAS,OAAQ,QAAO,kBAAkB,MAAM,YAAY;AACrE,SAAO;AACT;AAEO,SAAS,sBAAsB,OAA+B;AACnE,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACnC,SAAO,MAAM,QAAQ,CAAC,SAAS;AAC7B,UAAM,aAAa,qBAAqB,IAAI;AAC5C,WAAO,aAAa,CAAC,UAAU,IAAI,CAAC;EACtC,CAAC;AACH;;;AClJO,IAAM,gBAAgB;EAC3B;IACE,MAAM;IACN,aAAa;IACb,MAAM;IACN,aAAa;IACb,YAAY;IACZ,qBAAqB;IACrB,cAAc;EAChB;EACA;IACE,MAAM;IACN,aAAa;IACb,MAAM;IACN,YAAY;IACZ,qBAAqB;IACrB,cAAc;EAChB;EACA;IACE,MAAM;IACN,aAAa;IACb,MAAM;IACN,YAAY;IACZ,qBAAqB;IACrB,cAAc;EAChB;EACA;IACE,MAAM;IACN,aAAa;IACb,MAAM;IACN,YAAY;IACZ,qBAAqB;IACrB,cAAc;EAChB;EACA;IACE,MAAM;IACN,aAAa;IACb,MAAM;IACN,YAAY;IACZ,qBAAqB;IACrB,cAAc;EAChB;EACA;IACE,MAAM;IACN,aAAa;IACb,MAAM;IACN,YAAY;IACZ,qBAAqB;IACrB,cAAc;EAChB;EACA;IACE,MAAM;IACN,aAAa;IACb,MAAM;IACN,YAAY;IACZ,qBAAqB;IACrB,cAAc;EAChB;EACA;IACE,MAAM;IACN,aAAa;IACb,MAAM;IACN,YAAY;IACZ,qBAAqB;IACrB,cAAc;EAChB;EACA;IACE,MAAM;IACN,aAAa;IACb,MAAM;IACN,YAAY;IACZ,qBAAqB;IACrB,cAAc;EAChB;EACA;IACE,MAAM;IACN,aAAa;IACb,MAAM;IACN,aAAa;IACb,YAAY;;IAEZ,qBAAqB;IACrB,cAAc;EAChB;AACF;AAIO,SAAS,qBAAqB,MAAoC;AACvE,QAAM,QAAQ,cAAc,KAAK,CAAC,cAAc,UAAU,SAAS,IAAI;AACvE,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,gCAAgC,IAAI,EAAE;AAClE,SAAO;AACT;","names":["record","record","sessionKey","pending","pending","existsSync","join","basename","pending","isInternalEventType","existsSync","basename","dirname","join","require","toRecord","record"]}