@basou/cli 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3594 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/approval.ts","../src/lib/error-render.ts","../src/commands/decision.ts","../src/commands/decisions.ts","../src/commands/exec.ts","../src/commands/handoff.ts","../src/commands/init.ts","../src/commands/run.ts","../src/commands/session.ts","../src/commands/status.ts","../src/commands/task.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { Command } from \"commander\";\nimport { registerApprovalCommand } from \"./commands/approval.js\";\nimport { registerDecisionCommand } from \"./commands/decision.js\";\nimport { registerDecisionsCommand } from \"./commands/decisions.js\";\nimport { registerExecCommand } from \"./commands/exec.js\";\nimport { registerHandoffCommand } from \"./commands/handoff.js\";\nimport { registerInitCommand } from \"./commands/init.js\";\nimport { registerRunCommand } from \"./commands/run.js\";\nimport { registerSessionCommand } from \"./commands/session.js\";\nimport { registerStatusCommand } from \"./commands/status.js\";\nimport { registerTaskCommand } from \"./commands/task.js\";\nimport { isVerbose, renderCliError } from \"./lib/error-render.js\";\n\n// Read the CLI release version directly from the sibling package.json so\n// `basou --version` cannot drift past a future package-bump (the v0.2/v0.3\n// releases both shipped with a stale \"0.1.0\" constant before the dynamic\n// read landed). The relative path is stable across the dev (src/index.ts\n// → src/../package.json) and built (dist/index.js → dist/../package.json)\n// layouts, since both files sit one directory below the package root.\nconst require = createRequire(import.meta.url);\nconst pkg = require(\"../package.json\") as { version: string };\nconst BASOU_CLI_VERSION = pkg.version;\n\nconst program = new Command();\nprogram\n .name(\"basou\")\n .description(\"Provenance layer for AI development\")\n .version(BASOU_CLI_VERSION)\n // Required so that `basou exec` (and any other passThroughOptions\n // subcommand) can forward unknown flags to the wrapped child.\n .enablePositionalOptions();\n\nregisterInitCommand(program);\nregisterStatusCommand(program);\nregisterExecCommand(program);\nregisterRunCommand(program);\nregisterSessionCommand(program);\nregisterApprovalCommand(program);\nregisterDecisionCommand(program);\nregisterTaskCommand(program);\nregisterHandoffCommand(program);\nregisterDecisionsCommand(program);\n\nprogram.parseAsync(process.argv).catch((err: unknown) => {\n // Top-level safety net: never print the Error object directly because\n // Node's util.inspect recursively expands `error.cause`, which can carry\n // absolute paths from native fs errors. Delegates to the shared pathless\n // renderer; verbose mode is gated on BASOU_DEBUG only since the failure\n // bypassed the subcommand handler that owns the `-v` flag.\n renderCliError(err, { verbose: isVerbose(undefined) });\n process.exit(1);\n});\n","import { unlink } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n type Approval,\n type ApprovalLocation,\n ApprovalSchema,\n type ApprovalStatus,\n ApprovalStatusSchema,\n type BasouPaths,\n type Event,\n appendEvent,\n assertBasouRootSafe,\n basouPaths,\n enumerateApprovals,\n findErrorCode,\n isLazyExpired,\n linkYamlFile,\n loadApproval,\n prefixedUlid,\n readYamlFile,\n replayEvents,\n resolveRepositoryRoot,\n} from \"@basou/core\";\nimport type { Command } from \"commander\";\nimport { isVerbose, printReplayWarning, renderCliError } from \"../lib/error-render.js\";\n\nconst APPR_PREFIX = \"appr_\";\nconst SHORT_ID_BASE_LEN = 6;\nconst SHORT_ID_MAX_LEN = 26; // ULID body length\nconst ACTION_KEY_DETAIL_MAX_LEN = 60;\nconst REASON_TEXT_MAX_LEN = 80;\n\nconst STATUS_VALUES = ApprovalStatusSchema.options;\n\nexport type ApprovalListOptions = {\n json?: boolean;\n status?: ApprovalStatus;\n verbose?: boolean;\n};\n\nexport type ApprovalShowOptions = {\n json?: boolean;\n verbose?: boolean;\n};\n\nexport type ApprovalApproveOptions = {\n note?: string;\n verbose?: boolean;\n};\n\nexport type ApprovalRejectOptions = {\n reason: string;\n verbose?: boolean;\n};\n\nexport type ApprovalContext = {\n /** Defaults to `process.cwd()`. Injectable for tests. */\n cwd?: string;\n};\n\ntype ApprovalListRecord = {\n approval: Approval;\n location: ApprovalLocation;\n lazyExpired: boolean;\n};\n\n/**\n * Wire `basou approval list / show / approve / reject` onto `program`.\n *\n * The `approval` group is registered up front so future subcommands\n * (`cancel`, `recover`) added in later steps slot under the same group\n * without changing the externally visible CLI surface.\n */\nexport function registerApprovalCommand(program: Command): void {\n const approval = program\n .command(\"approval\")\n .description(\"Manage Basou approval requests under .basou/approvals/\");\n\n approval\n .command(\"list\")\n .description(\"List approvals across pending and resolved (newest first)\")\n .option(\"--json\", \"Output the list as a JSON array\")\n .option(\n \"--status <state>\",\n `Filter by approval status (one of: ${STATUS_VALUES.join(\", \")})`,\n parseApprovalStatus,\n )\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (options: ApprovalListOptions) => {\n await runApprovalList(options);\n });\n\n approval\n .command(\"show <id>\")\n .description(\"Show an approval's metadata and related events\")\n .option(\"--json\", \"Output the approval and events as JSON\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (id: string, options: ApprovalShowOptions) => {\n await runApprovalShow(id, options);\n });\n\n approval\n .command(\"approve <id>\")\n .description(\"Approve a pending approval\")\n .option(\"--note <text>\", \"Optional note to attach to the approval_approved event\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (id: string, options: ApprovalApproveOptions) => {\n await runApprovalApprove(id, options);\n });\n\n approval\n .command(\"reject <id>\")\n .description(\"Reject a pending approval\")\n .requiredOption(\"--reason <text>\", \"Reason for rejection (required)\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (id: string, options: ApprovalRejectOptions) => {\n await runApprovalReject(id, options);\n });\n}\n\n// === list ===\n\n/**\n * Programmatic entry for `basou approval list` that owns process exit\n * state. Tests targeting only the success path or the thrown error should\n * prefer {@link doRunApprovalList}.\n */\nexport async function runApprovalList(\n options: ApprovalListOptions,\n ctx: ApprovalContext = {},\n): Promise<void> {\n try {\n await doRunApprovalList(options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options) });\n process.exitCode = 1;\n }\n}\n\n/**\n * Pure runner for `approval list`. Throws on any failure with a pathless\n * message; native errors are attached as `cause` for verbose surfacing.\n */\nexport async function doRunApprovalList(\n options: ApprovalListOptions,\n ctx: ApprovalContext,\n): Promise<void> {\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForApproval(cwd, \"list\");\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n\n const ids = await enumerateApprovals(paths);\n // A single `now` shared across every record so that two reads on the\n // same boundary instant cannot disagree (e.g. one record flagged expired\n // and another not when both straddle the same `expires_at`).\n const now = new Date();\n const records: ApprovalListRecord[] = [];\n\n // Resolve dedupe set: id appearing in both directories → prefer resolved\n // and surface a stderr warning about the stale pending entry.\n const resolvedSet = new Set(ids.resolved);\n for (const id of ids.pending) {\n if (resolvedSet.has(id)) {\n console.error(`Warning: stale pending entry for ${shortId(id)}; resolved version preferred`);\n continue;\n }\n const rec = await readApprovalListRecord(paths, id, \"pending\", now);\n if (rec !== null) records.push(rec);\n }\n for (const id of ids.resolved) {\n const rec = await readApprovalListRecord(paths, id, \"resolved\", now);\n if (rec !== null) records.push(rec);\n }\n\n records.sort((a, b) => Date.parse(b.approval.created_at) - Date.parse(a.approval.created_at));\n\n const filtered =\n options.status !== undefined\n ? records.filter((r) => r.approval.status === options.status)\n : records;\n\n if (filtered.length === 0) {\n printNoApprovals(options);\n return;\n }\n\n if (options.json === true) {\n console.log(\n JSON.stringify(\n filtered.map((r) => ({ ...r.approval, lazy_expired: r.lazyExpired })),\n null,\n 2,\n ),\n );\n } else {\n printApprovalListText(filtered);\n }\n}\n\nasync function readApprovalListRecord(\n paths: BasouPaths,\n id: string,\n location: ApprovalLocation,\n now: Date,\n): Promise<ApprovalListRecord | null> {\n const filePath = join(paths.approvals[location], `${id}.yaml`);\n let raw: unknown;\n try {\n raw = await readYamlFile(filePath);\n } catch (error: unknown) {\n console.error(`Skipped ${shortId(id)}: ${describeReadError(error)}`);\n return null;\n }\n const parse = ApprovalSchema.safeParse(raw);\n if (!parse.success) {\n console.error(`Skipped ${shortId(id)}: invalid approval schema`);\n return null;\n }\n if (parse.data.id !== id) {\n // Surface a stderr warning rather than dropping silently so an operator\n // can spot the corrupted entry from `basou approval list`.\n console.error(`Skipped ${shortId(id)}: filename and YAML body id disagree`);\n return null;\n }\n const approval = parse.data;\n return { approval, location, lazyExpired: isLazyExpired(approval, now) };\n}\n\n// === show ===\n\nexport async function runApprovalShow(\n idInput: string,\n options: ApprovalShowOptions,\n ctx: ApprovalContext = {},\n): Promise<void> {\n try {\n await doRunApprovalShow(idInput, options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options) });\n process.exitCode = 1;\n }\n}\n\nexport async function doRunApprovalShow(\n idInput: string,\n options: ApprovalShowOptions,\n ctx: ApprovalContext,\n): Promise<void> {\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForApproval(cwd, \"show\");\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n\n const { id } = await resolveApprovalId(paths, idInput);\n const loaded = await loadApproval(paths, id);\n if (loaded === null) {\n throw new Error(`Approval not found: ${idInput}`);\n }\n\n // events.jsonl I/O failure throws \"Failed to read events.jsonl\" and is\n // converted to exit 1 by the wrapping try/catch — partial / malformed /\n // schema warnings stream through onWarning.\n const sessionDir = join(paths.sessions, loaded.approval.session_id);\n const relatedEvents: Event[] = [];\n for await (const ev of replayEvents(sessionDir, {\n onWarning: (w) => printReplayWarning(w, loaded.approval.session_id),\n })) {\n if (isApprovalEvent(ev) && ev.approval_id === id) {\n relatedEvents.push(ev);\n }\n }\n\n const now = new Date();\n const lazyExpired = isLazyExpired(loaded.approval, now);\n\n if (options.json === true) {\n console.log(\n JSON.stringify(\n {\n approval: { ...loaded.approval, lazy_expired: lazyExpired },\n events: relatedEvents,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n printApprovalShowText(loaded.approval, loaded.location, relatedEvents, lazyExpired);\n}\n\n// === approve / reject ===\n\nexport async function runApprovalApprove(\n idInput: string,\n options: ApprovalApproveOptions,\n ctx: ApprovalContext = {},\n): Promise<void> {\n try {\n await doRunApprovalResolve(idInput, options, ctx, \"approve\");\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options) });\n process.exitCode = 1;\n }\n}\n\nexport async function runApprovalReject(\n idInput: string,\n options: ApprovalRejectOptions,\n ctx: ApprovalContext = {},\n): Promise<void> {\n try {\n await doRunApprovalResolve(idInput, options, ctx, \"reject\");\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options) });\n process.exitCode = 1;\n }\n}\n\nasync function doRunApprovalResolve(\n idInput: string,\n options: ApprovalApproveOptions | ApprovalRejectOptions,\n ctx: ApprovalContext,\n decision: \"approve\" | \"reject\",\n): Promise<void> {\n if (decision === \"reject\") {\n const reason = (options as ApprovalRejectOptions).reason;\n if (reason.length === 0) {\n throw new Error(\"--reason must not be empty\");\n }\n }\n\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForApproval(cwd, decision);\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n\n // Step D-2: resolve id (search both directories).\n const { id, location } = await resolveApprovalId(paths, idInput);\n\n // Step D-3: a resolved-side hit means there is nothing left to decide.\n if (location === \"resolved\") {\n throw new Error(`Approval already resolved: ${idInput}`);\n }\n\n // Step D-4: read + parse the pending YAML.\n const pendingPath = join(paths.approvals.pending, `${id}.yaml`);\n let pendingRaw: unknown;\n try {\n pendingRaw = await readYamlFile(pendingPath);\n } catch (error: unknown) {\n if (error instanceof Error && error.message === \"YAML file not found\") {\n throw new Error(`Approval not found: ${idInput}`);\n }\n throw new Error(\"Failed to read approval\", { cause: error });\n }\n // Wrap zod's parse so a malformed pending YAML surfaces through the\n // pathless `Failed to read approval` contract instead of leaking a raw\n // ZodError through the rendered output.\n const approvalParse = ApprovalSchema.safeParse(pendingRaw);\n if (!approvalParse.success) {\n throw new Error(\"Failed to read approval\", { cause: approvalParse.error });\n }\n const approval = approvalParse.data;\n // Defensive id check (matches loadApproval): filename id and body id\n // must agree, otherwise we'd resolve one approval while emitting events\n // for another.\n if (approval.id !== id) {\n throw new Error(\"Failed to read approval\", {\n cause: new Error(`Approval id mismatch: filename id ${id} vs YAML body id ${approval.id}`),\n });\n }\n // A pending-side YAML whose status is no longer `pending` means the\n // file was corrupted (or hand-edited mid-resolution). Refuse to fire a\n // second resolution event for it.\n if (approval.status !== \"pending\") {\n throw new Error(`Approval status mismatch: pending YAML has status=${approval.status}`);\n }\n\n // Step D-5: events.jsonl fence — if a resolution event already exists\n // for this approval, refuse to fire a second one. This guards the\n // crash-mid-orchestration window where step 8 succeeded but step 10\n // failed (events.jsonl is the source-of-truth, not the YAML mirror).\n const sessionDir = join(paths.sessions, approval.session_id);\n for await (const ev of replayEvents(sessionDir, {\n onWarning: (w) => printReplayWarning(w, approval.session_id),\n })) {\n if (\n isApprovalEvent(ev) &&\n ev.approval_id === approval.id &&\n (ev.type === \"approval_approved\" ||\n ev.type === \"approval_rejected\" ||\n ev.type === \"approval_expired\")\n ) {\n throw new Error(`Approval already resolved (per events.jsonl): ${idInput}`);\n }\n }\n\n // Step D-6: lazy expire state-fence. No event is fired here; the\n // approval_expired event is reserved for a later step that owns\n // expiry-side orchestration.\n const now = new Date();\n if (isLazyExpired(approval, now)) {\n throw new Error(`Approval already expired: ${idInput}`);\n }\n\n // Step D-7: prepare event id + occurred_at (shared with step 9 below).\n const occurredAt = now.toISOString();\n const eventId = prefixedUlid(\"evt\");\n\n // Step D-8: append the resolution event to events.jsonl. After this\n // point the trail is committed; subsequent failures must not roll back\n // the event because that would break the source-of-truth invariant.\n if (decision === \"approve\") {\n const note = (options as ApprovalApproveOptions).note ?? null;\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n id: eventId,\n session_id: approval.session_id,\n occurred_at: occurredAt,\n source: \"local-cli\",\n type: \"approval_approved\",\n approval_id: approval.id,\n resolver: \"local-cli\",\n note,\n });\n } else {\n const reason = (options as ApprovalRejectOptions).reason;\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n id: eventId,\n session_id: approval.session_id,\n occurred_at: occurredAt,\n source: \"local-cli\",\n type: \"approval_rejected\",\n approval_id: approval.id,\n resolver: \"local-cli\",\n reason,\n });\n }\n\n // Step D-9: build the resolved-side YAML body in memory.\n const resolvedApproval: Approval =\n decision === \"approve\"\n ? {\n ...approval,\n status: \"approved\",\n resolver: \"local-cli\",\n resolved_at: occurredAt,\n note: (options as ApprovalApproveOptions).note ?? null,\n }\n : {\n ...approval,\n status: \"rejected\",\n resolver: \"local-cli\",\n resolved_at: occurredAt,\n rejection_reason: (options as ApprovalRejectOptions).reason,\n };\n\n // Step D-10: create-only write. linkYamlFile fails fast with EEXIST if a\n // concurrent resolver already populated the resolved-side YAML — the\n // events.jsonl fence above should have caught it first, so reaching\n // EEXIST here implies a near-simultaneous race we surface explicitly.\n const resolvedPath = join(paths.approvals.resolved, `${id}.yaml`);\n try {\n await linkYamlFile(resolvedPath, resolvedApproval);\n } catch (error: unknown) {\n const cause = error instanceof Error ? error.cause : undefined;\n if (cause instanceof Error && (cause as Error & { code?: unknown }).code === \"EEXIST\") {\n throw new Error(\"Approval already resolved at the same time\", { cause });\n }\n throw error;\n }\n\n // Step D-11: best-effort unlink of the pending YAML. The trail and the\n // resolved-side YAML are already consistent at this point; a leftover\n // pending entry is reconciled by the next `approval list`'s dedupe.\n try {\n await unlink(pendingPath);\n } catch {\n console.error(\n `Warning: failed to unlink pending entry for ${shortId(id)}; events.jsonl is consistent`,\n );\n }\n\n // Step D-12: success message.\n const verb = decision === \"approve\" ? \"Approved\" : \"Rejected\";\n console.log(`${verb} approval ${shortId(id)}`);\n}\n\n// === helpers ===\n\nasync function resolveApprovalId(\n paths: BasouPaths,\n input: string,\n): Promise<{ id: string; location: ApprovalLocation }> {\n const trimmed = input.trim();\n if (trimmed.length === 0) {\n throw new Error(\"Approval id is empty\");\n }\n const normalized = trimmed.startsWith(APPR_PREFIX) ? trimmed : `${APPR_PREFIX}${trimmed}`;\n // Reject prefix-only input so a bare prefix cannot match an arbitrary\n // approval via `startsWith`.\n if (normalized.length <= APPR_PREFIX.length) {\n throw new Error(`Approval not found: ${input}`);\n }\n\n const enumeration = await enumerateApprovals(paths);\n\n // Aggregate by full id so a duplicate (same id in both pending and\n // resolved) collapses to one entry with location=resolved (preferred).\n const byId = new Map<string, ApprovalLocation>();\n for (const id of enumeration.pending) {\n if (id.startsWith(normalized)) byId.set(id, \"pending\");\n }\n for (const id of enumeration.resolved) {\n if (!id.startsWith(normalized)) continue;\n if (byId.get(id) === \"pending\") {\n // Same full id present on both sides: resolved wins, surface a warning.\n console.error(`Warning: stale pending entry for ${shortId(id)}; resolved version preferred`);\n }\n byId.set(id, \"resolved\");\n }\n\n if (byId.size === 0) {\n throw new Error(`Approval not found: ${input}`);\n }\n if (byId.size > 1) {\n throw new Error(\n `Ambiguous approval id '${input}': matched ${byId.size} approvals. Disambiguate with a longer prefix.`,\n );\n }\n const first = byId.entries().next().value;\n if (first === undefined) {\n throw new Error(`Approval not found: ${input}`);\n }\n const [id, location] = first;\n return { id, location };\n}\n\nfunction isApprovalEvent(ev: Event): ev is Event & { approval_id: string } {\n return (\n ev.type === \"approval_requested\" ||\n ev.type === \"approval_approved\" ||\n ev.type === \"approval_rejected\" ||\n ev.type === \"approval_expired\"\n );\n}\n\nfunction printApprovalListText(records: ApprovalListRecord[]): void {\n // Grow the SHORT_ID column on collision. The dedupe in doRunApprovalList\n // already collapsed duplicates by full id, so feeding only the unique\n // ids here is correct.\n const allIds = records.map((r) => r.approval.id);\n const shortLen = computeUniquePrefixLen(allIds);\n const rows = records.map((r) => {\n const sid = sliceShort(r.approval.id, shortLen);\n const status = r.lazyExpired ? `${r.approval.status} (expired)` : r.approval.status;\n const risk = r.approval.risk_level;\n const action = r.approval.action.kind;\n const createdAt = r.approval.created_at;\n const reason = truncate(r.approval.reason, REASON_TEXT_MAX_LEN);\n return { sid, status, risk, action, createdAt, reason };\n });\n\n const widths = {\n sid: maxLen(\n rows.map((r) => r.sid),\n \"SHORT_ID\".length,\n ),\n status: maxLen(\n rows.map((r) => r.status),\n \"STATUS\".length,\n ),\n risk: maxLen(\n rows.map((r) => r.risk),\n \"RISK\".length,\n ),\n action: maxLen(\n rows.map((r) => r.action),\n \"ACTION\".length,\n ),\n createdAt: maxLen(\n rows.map((r) => r.createdAt),\n \"CREATED_AT\".length,\n ),\n };\n\n console.log(\n `${pad(\"SHORT_ID\", widths.sid)} ${pad(\"STATUS\", widths.status)} ${pad(\"RISK\", widths.risk)} ${pad(\"ACTION\", widths.action)} ${pad(\"CREATED_AT\", widths.createdAt)} REASON`,\n );\n for (const row of rows) {\n console.log(\n `${pad(row.sid, widths.sid)} ${pad(row.status, widths.status)} ${pad(row.risk, widths.risk)} ${pad(row.action, widths.action)} ${pad(row.createdAt, widths.createdAt)} ${row.reason}`,\n );\n }\n}\n\nfunction printApprovalShowText(\n approval: Approval,\n _location: ApprovalLocation,\n events: readonly Event[],\n lazyExpired: boolean,\n): void {\n console.log(`Approval: ${approval.id} (status: ${approval.status})`);\n console.log(`Session: ${approval.session_id}`);\n console.log(`Created at: ${approval.created_at}`);\n console.log(`Risk level: ${approval.risk_level}`);\n console.log(`Action: ${formatActionLine(approval.action)}`);\n console.log(`Reason: ${approval.reason}`);\n const expiresLabel = formatExpiresLabel(approval.expires_at, lazyExpired);\n console.log(`Expires at: ${expiresLabel}`);\n console.log(`Resolver: ${approval.resolver ?? \"(none)\"}`);\n console.log(`Resolved at: ${approval.resolved_at ?? \"(none)\"}`);\n console.log(`Note: ${approval.note ?? \"(none)\"}`);\n console.log(`Rejection reason: ${approval.rejection_reason ?? \"(none)\"}`);\n\n console.log(\"\");\n console.log(`Related events: ${events.length} total`);\n for (const ev of events) {\n console.log(` ${formatApprovalEventLine(ev)}`);\n }\n}\n\nfunction formatActionLine(action: { kind: string } & Record<string, unknown>): string {\n const extras: string[] = [];\n for (const [key, value] of Object.entries(action)) {\n if (key === \"kind\") continue;\n if (typeof value !== \"string\") continue;\n extras.push(`${key}=\"${truncate(value, ACTION_KEY_DETAIL_MAX_LEN)}\"`);\n if (extras.length >= 2) break;\n }\n return extras.length === 0 ? action.kind : `${action.kind} (${extras.join(\", \")})`;\n}\n\nfunction formatExpiresLabel(expiresAt: string | null, lazyExpired: boolean): string {\n if (expiresAt === null) return \"(none)\";\n return lazyExpired ? `${expiresAt} (expired)` : expiresAt;\n}\n\nfunction formatApprovalEventLine(ev: Event): string {\n const summary = approvalEventSummary(ev);\n return `${ev.occurred_at} [${ev.source}] ${ev.type} ${summary}`;\n}\n\nfunction approvalEventSummary(ev: Event): string {\n switch (ev.type) {\n case \"approval_requested\":\n return `${ev.action.kind} risk=${ev.risk_level}`;\n case \"approval_approved\":\n return ev.resolver !== undefined ? `by ${ev.resolver}` : \"(approved)\";\n case \"approval_rejected\":\n return ev.resolver !== undefined ? `by ${ev.resolver}: ${ev.reason}` : ev.reason;\n case \"approval_expired\":\n return `approval=${ev.approval_id}`;\n default:\n // Other event types are filtered out before reaching this helper.\n return \"\";\n }\n}\n\nfunction shortId(id: string): string {\n return sliceShort(id, SHORT_ID_BASE_LEN);\n}\n\n// Known Basou prefixed-id leading tokens. Strip whichever applies so that\n// a session id passed through the warning handler renders as the bare\n// ULID prefix (matching what session.ts already emits) instead of leaving\n// the `ses_` head in the truncated short id.\nconst KNOWN_ID_PREFIXES = [\"appr_\", \"ses_\", \"evt_\", \"ws_\", \"task_\", \"decision_\"] as const;\n\nfunction sliceShort(id: string, len: number): string {\n for (const prefix of KNOWN_ID_PREFIXES) {\n if (id.startsWith(prefix)) {\n return id.slice(prefix.length, prefix.length + len);\n }\n }\n return id.slice(0, len);\n}\n\nfunction computeUniquePrefixLen(ids: readonly string[]): number {\n if (ids.length <= 1) return SHORT_ID_BASE_LEN;\n for (let len = SHORT_ID_BASE_LEN; len <= SHORT_ID_MAX_LEN; len += 2) {\n const seen = new Set<string>();\n let collided = false;\n for (const id of ids) {\n const key = sliceShort(id, len);\n if (seen.has(key)) {\n collided = true;\n break;\n }\n seen.add(key);\n }\n if (!collided) return len;\n }\n return SHORT_ID_MAX_LEN;\n}\n\nfunction pad(value: string, width: number): string {\n return value.length >= width ? value : value + \" \".repeat(width - value.length);\n}\n\nfunction maxLen(values: readonly string[], floor: number): number {\n let max = floor;\n for (const v of values) if (v.length > max) max = v.length;\n return max;\n}\n\nfunction truncate(value: string, maxLength: number): string {\n if (value.length <= maxLength) return value;\n return `${value.slice(0, maxLength - 3)}...`;\n}\n\nasync function resolveRepositoryRootForApproval(\n cwd: string,\n subcmd: \"list\" | \"show\" | \"approve\" | \"reject\",\n): Promise<string> {\n try {\n return await resolveRepositoryRoot(cwd);\n } catch (error: unknown) {\n if (error instanceof Error && error.message === \"Not a git repository\") {\n throw new Error(\n `Not a git repository. Run 'git init' first, then re-run 'basou approval ${subcmd}'.`,\n { cause: error },\n );\n }\n throw error;\n }\n}\n\nasync function assertWorkspaceInitialized(basouRoot: string): Promise<void> {\n try {\n await assertBasouRootSafe(basouRoot);\n } catch (error: unknown) {\n if (findErrorCode(error, \"ENOENT\")) {\n throw new Error(\"Workspace not initialized. Run 'basou init' first.\");\n }\n throw error;\n }\n}\n\nfunction describeReadError(error: unknown): string {\n if (error instanceof Error) {\n if (error.message === \"YAML file not found\") return \"approval YAML not found\";\n if (error.message === \"Failed to parse YAML content\") return \"invalid YAML\";\n return error.message;\n }\n return String(error);\n}\n\nfunction parseApprovalStatus(raw: string): ApprovalStatus {\n const result = ApprovalStatusSchema.safeParse(raw);\n if (!result.success) {\n throw new Error(`Invalid approval status: ${raw}. Valid values: ${STATUS_VALUES.join(\", \")}`);\n }\n return result.data;\n}\n\nfunction printNoApprovals(options: ApprovalListOptions): void {\n if (options.json === true) {\n console.log(\"[]\");\n } else {\n console.log(\"No approvals found.\");\n }\n}\n","import {\n FailedToFinalizeError,\n type ReplayWarning,\n type SessionSkipReason,\n type TaskSkipReason,\n} from \"@basou/core\";\n\n// ============================================================================\n// Short-id helpers\n// ============================================================================\n\nconst SES_PREFIX = \"ses_\";\nconst TASK_PREFIX = \"task_\";\nconst SHORT_ID_LEN = 6;\n\n/**\n * Strip the `ses_` prefix and slice the first {@link SHORT_ID_LEN} chars of\n * the ULID body for human-readable session identification in CLI output.\n * IDs without the prefix are sliced from offset 0.\n */\nexport function shortSessionId(id: string): string {\n if (id.startsWith(SES_PREFIX))\n return id.slice(SES_PREFIX.length, SES_PREFIX.length + SHORT_ID_LEN);\n return id.slice(0, SHORT_ID_LEN);\n}\n\n/**\n * Same as {@link shortSessionId} but for `task_<ULID>` ids.\n */\nexport function shortTaskId(id: string): string {\n if (id.startsWith(TASK_PREFIX))\n return id.slice(TASK_PREFIX.length, TASK_PREFIX.length + SHORT_ID_LEN);\n return id.slice(0, SHORT_ID_LEN);\n}\n\n// ============================================================================\n// Verbose mode detection\n// ============================================================================\n\n/**\n * Unified verbose-mode predicate: `options.verbose === true` OR the\n * `BASOU_DEBUG=1` environment variable. CLI surfaces use this everywhere\n * the verbose error / cause label rendering needs a yes/no answer.\n */\nexport function isVerbose(options: { verbose?: boolean } | undefined): boolean {\n return options?.verbose === true || process.env.BASOU_DEBUG === \"1\";\n}\n\n// ============================================================================\n// Cause-chain walk (pathless)\n// ============================================================================\n\nconst CAUSE_CHAIN_MAX_DEPTH = 4;\n\n/**\n * Walk the cause chain (up to {@link CAUSE_CHAIN_MAX_DEPTH} hops) and return\n * the first errno-style `code` found, falling back to the deepest\n * constructor name. The value goes into `Caused by: <label>` so verbose\n * output stays pathless even when capability layers wrap native errors.\n *\n * Returns `undefined` when `error.cause` is not itself an Error (= no chain\n * to walk).\n */\nexport function extractCauseLabel(error: Error): string | undefined {\n let current: unknown = error.cause;\n let constructorName: string | undefined;\n for (let depth = 0; depth < CAUSE_CHAIN_MAX_DEPTH; depth += 1) {\n if (!(current instanceof Error)) break;\n const code = (current as Error & { code?: unknown }).code;\n if (typeof code === \"string\" && code.length > 0) return code;\n constructorName = current.constructor.name;\n current = current.cause;\n }\n return constructorName;\n}\n\n// ============================================================================\n// Pluggable classifier interface\n// ============================================================================\n\n/**\n * Plug-in for command-specific error rendering. {@link renderCliError}\n * invokes every classifier whose {@link match} returns true and emits each\n * line returned by {@link additionalLines} after the main `error.message`\n * line. Classifiers MUST keep their lines pathless — no absolute paths, no\n * `cause.message` echo.\n */\nexport interface ErrorClassifier {\n match(error: Error): boolean;\n additionalLines(error: Error): readonly string[];\n}\n\n/**\n * Shared classifier for {@link FailedToFinalizeError}. Both `task.ts` and\n * `decision.ts` need exactly the same two warning lines — the session.yaml\n * status update failed AFTER the target event was already written, so the\n * operator must NOT retry the command.\n */\nexport const failedToFinalizeClassifier: ErrorClassifier = {\n match: (error) => error instanceof FailedToFinalizeError,\n additionalLines: (error) => {\n const e = error as FailedToFinalizeError;\n const sid = shortSessionId(e.sessionId);\n // `targetEventIds[0]` is the operator-facing anchor event (= the\n // `decision_recorded` / `task_created` / `task_reconciled` event the\n // command was meant to produce). Multi-target ad-hoc sessions (e.g.\n // `task new --status done` which adds `task_status_changed`) carry the\n // additional ids in `targetEventIds[1..]`; one anchor is enough for the\n // do-not-rerun warning.\n const anchor = e.targetEventIds[0];\n return [\n `Recorded ${anchor} in session ${sid}; do not rerun`,\n \"Warning: session.yaml status update failed; events.jsonl is consistent\",\n ];\n },\n};\n\n// ============================================================================\n// Generic CLI error renderer\n// ============================================================================\n\n/**\n * Render an unknown thrown value to stderr without leaking absolute paths.\n *\n * Always prints `error.message` first, then any classifier-emitted lines,\n * and finally — in verbose mode — a single `Caused by: <label>` line where\n * `<label>` is the first errno code found while walking `error.cause` (or\n * the deepest constructor name as a fallback). The error's `cause.message`\n * is intentionally never printed because Node's native fs errors embed\n * absolute paths there.\n *\n * Non-Error values are coerced via `String(error)` so the catch-all fallback\n * in `program.parseAsync().catch(...)` still produces something readable.\n */\nexport function renderCliError(\n error: unknown,\n options: { verbose: boolean; classifiers?: readonly ErrorClassifier[] },\n): void {\n if (!(error instanceof Error)) {\n console.error(String(error));\n return;\n }\n console.error(error.message);\n for (const classifier of options.classifiers ?? []) {\n if (classifier.match(error)) {\n for (const line of classifier.additionalLines(error)) console.error(line);\n }\n }\n if (options.verbose) {\n const label = extractCauseLabel(error);\n if (label !== undefined) console.error(`Caused by: ${label}`);\n }\n}\n\n// ============================================================================\n// Warning surface helpers\n// ============================================================================\n\n/**\n * Print a `ReplayWarning` on stderr in the canonical short form used by\n * every command that consumes the event-replay stream (= task / handoff /\n * decisions / etc.). The session id is shortened via {@link shortSessionId}\n * for readability.\n */\nexport function printReplayWarning(warning: ReplayWarning, sessionId: string): void {\n const short = shortSessionId(sessionId);\n switch (warning.kind) {\n case \"partial_trailing_line\":\n console.error(`Warning: ignored partial trailing line in ${short}/events.jsonl`);\n break;\n case \"malformed_json\":\n console.error(\n `Warning: skipped malformed JSON at line ${warning.line} in ${short}/events.jsonl`,\n );\n break;\n case \"schema_violation\":\n console.error(\n `Warning: skipped invalid event at line ${warning.line} in ${short}/events.jsonl`,\n );\n break;\n }\n}\n\n/**\n * Print a session-skip warning in the \"scan\" form used by handoff / decisions\n * generators: `events_jsonl_unreadable` is mapped to the standardised\n * suspect-check warning used elsewhere in the CLI, every other reason falls\n * through to a generic `Skipped <sid>: <reason>` form preserving the raw\n * enum value.\n */\nexport function printSessionSkip(sid: string, reason: SessionSkipReason): void {\n const short = shortSessionId(sid);\n if (reason === \"events_jsonl_unreadable\") {\n console.error(`Warning: skipped suspect check for ${short}: events.jsonl unreadable`);\n } else {\n console.error(`Skipped ${short}: ${reason}`);\n }\n}\n\n/**\n * Print a session-skip warning in the \"list\" form used by `session list`.\n * Each reason is mapped to a user-friendly English phrase rather than the\n * raw enum value. `events_jsonl_unreadable` shares the wording produced by\n * {@link printSessionSkip} so the CLI surface stays consistent across\n * subcommands.\n */\nexport function printSessionListSkip(sid: string, reason: SessionSkipReason): void {\n const short = shortSessionId(sid);\n switch (reason) {\n case \"session_yaml_missing\":\n console.error(`Skipped ${short}: session.yaml not found`);\n break;\n case \"session_yaml_invalid\":\n console.error(`Skipped ${short}: invalid session schema`);\n break;\n case \"events_jsonl_unreadable\":\n console.error(`Warning: skipped suspect check for ${short}: events.jsonl unreadable`);\n break;\n }\n}\n\n/**\n * Print a task-skip warning shared between `task list` (which sees a\n * narrowed {@link TaskSkipReason} enum) and handoff / decisions generators\n * (which may forward an arbitrary reason string). Accepts a plain `string`\n * so both shapes route through the same renderer.\n */\nexport function printTaskSkip(taskId: string, reason: TaskSkipReason | string): void {\n console.error(`Skipped ${shortTaskId(taskId)}: ${reason}`);\n}\n","import {\n type Event,\n type PrefixedId,\n type SessionStatus,\n acquireLock,\n appendEventToExistingSession,\n assertBasouRootSafe,\n basouPaths,\n createAdHocSessionWithEvent,\n findErrorCode,\n prefixedUlid,\n readManifest,\n resolveRepositoryRoot,\n resolveSessionId,\n} from \"@basou/core\";\nimport { type Command, InvalidArgumentError } from \"commander\";\nimport {\n failedToFinalizeClassifier,\n isVerbose,\n renderCliError,\n shortSessionId,\n} from \"../lib/error-render.js\";\n\n// Raised from the original 40-char cap to 80 chars so a long decision\n// title (= the most common ad-hoc trigger) retains its core information\n// without being truncated. 80 chars still fits comfortably in\n// single-column session list / handoff renderings. Operator feedback\n// from real-world long-title outliers may revisit this value.\nconst LABEL_TITLE_MAX = 80;\nconst LABEL_TRUNCATE_HEAD = LABEL_TITLE_MAX - 3;\n\nexport type DecisionRecordOptions = {\n title: string;\n rationale?: string;\n rejectedReason?: string;\n alternative?: string[];\n linkedEvent?: string[];\n linkedFile?: string[];\n session?: string;\n json?: boolean;\n verbose?: boolean;\n};\n\nexport type DecisionContext = {\n /** Defaults to `process.cwd()`. Injectable for tests. */\n cwd?: string;\n /** Defaults to `() => new Date()`. Injectable for tests. */\n nowProvider?: () => Date;\n};\n\n/**\n * Wire `basou decision record` onto `program`. The `decision` group only\n * contains the write-side `record` subcommand in v0.1; list/show inspectors\n * are deferred to a v0.3+ follow-up.\n */\nexport function registerDecisionCommand(program: Command): void {\n const decision = program\n .command(\"decision\")\n .description(\"Record human-authored decisions as events\");\n\n decision\n .command(\"record\")\n .description(\"Record a decision_recorded event\")\n .requiredOption(\"--title <text>\", \"Decision title\", parseTitle)\n .option(\"--rationale <text>\", \"Rationale for the decision\", parseRationale)\n .option(\n \"--rejected-reason <text>\",\n \"Reason rejected alternatives were not chosen\",\n parseRejectedReason,\n )\n .option(\n \"--alternative <text>\",\n \"Alternative considered (repeatable: --alternative yup --alternative joi)\",\n collectAlternative,\n [] as string[],\n )\n .option(\n \"--linked-event <event_id>\",\n \"Related event id (repeatable). Schema only checks the prefix; existence is verified at render time.\",\n collectLinkedEvent,\n [] as string[],\n )\n .option(\n \"--linked-file <path>\",\n \"Related file path (repeatable). Path is opaque; existence is verified at render time.\",\n collectLinkedFile,\n [] as string[],\n )\n .option(\n \"--session <session_id>\",\n \"Attach to an existing session; otherwise an ad-hoc session is created\",\n )\n .option(\"--json\", \"Output the result as JSON\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (options: DecisionRecordOptions) => {\n await runDecisionRecord(options);\n });\n}\n\n/**\n * Programmatic entry for `basou decision record`. Owns process exit state.\n * Tests targeting the success path or the thrown error should prefer\n * {@link doRunDecisionRecord}.\n */\nexport async function runDecisionRecord(\n options: DecisionRecordOptions,\n ctx: DecisionContext = {},\n): Promise<void> {\n try {\n await doRunDecisionRecord(options, ctx);\n } catch (error: unknown) {\n renderCliError(error, {\n verbose: isVerbose(options),\n classifiers: [failedToFinalizeClassifier],\n });\n process.exitCode = 1;\n }\n}\n\nexport async function doRunDecisionRecord(\n options: DecisionRecordOptions,\n ctx: DecisionContext,\n): Promise<void> {\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForDecision(cwd);\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n\n const now = ctx.nowProvider !== undefined ? ctx.nowProvider() : new Date();\n const occurredAt = now.toISOString();\n const decisionId = prefixedUlid(\"decision\");\n\n const rich = pickRichFields(options);\n\n if (options.session !== undefined) {\n const sessionId = await resolveSessionId(paths, options.session);\n const sesId = sessionId as PrefixedId<\"ses\">;\n // Per-session lock guards the session.yaml status read + events.jsonl\n // append window against a concurrent writer (`basou session note`,\n // another `decision record --session`, or an attach-flavoured task\n // command). `appendEventToExistingSession` itself holds no lock; the\n // caller owns the critical section.\n const sessionLock = await acquireLock(paths, \"session\", sesId);\n let result: Awaited<ReturnType<typeof appendEventToExistingSession>>;\n try {\n result = await appendEventToExistingSession({\n paths,\n sessionId: sesId,\n eventBuilder: (eventId) =>\n buildDecisionEvent({\n eventId,\n sessionId: sesId,\n decisionId,\n title: options.title,\n occurredAt,\n rich,\n }),\n });\n } finally {\n await sessionLock.release();\n }\n printDecisionResult(options, {\n mode: \"attached\",\n sessionId,\n decisionId,\n eventId: result.eventId,\n sessionStatus: result.sessionStatus,\n title: options.title,\n rich,\n });\n return;\n }\n\n const manifest = await readManifest(paths);\n const adHoc = await createAdHocSessionWithEvent({\n paths,\n manifest,\n label: buildAdHocLabel(options.title),\n occurredAt,\n sessionSource: \"human\",\n workingDirectory: repositoryRoot,\n invocation: {\n command: \"basou decision record\",\n args: [\"--title\", options.title],\n },\n targetEventBuilders: [\n (sessionId, eventId) =>\n buildDecisionEvent({\n eventId,\n sessionId,\n decisionId,\n title: options.title,\n occurredAt,\n rich,\n }),\n ],\n });\n printDecisionResult(options, {\n mode: \"ad-hoc\",\n sessionId: adHoc.sessionId,\n decisionId,\n eventId: adHoc.targetEventIds[0] as string,\n sessionStatus: \"completed\",\n title: options.title,\n rich,\n });\n}\n\ntype RichDecisionFields = {\n rationale?: string;\n rejected_reason?: string;\n alternatives?: string[];\n linked_events?: string[];\n linked_files?: string[];\n};\n\nfunction pickRichFields(options: DecisionRecordOptions): RichDecisionFields {\n const out: RichDecisionFields = {};\n if (options.rationale !== undefined) out.rationale = options.rationale;\n if (options.rejectedReason !== undefined) out.rejected_reason = options.rejectedReason;\n if (options.alternative !== undefined && options.alternative.length > 0) {\n out.alternatives = [...options.alternative];\n }\n if (options.linkedEvent !== undefined && options.linkedEvent.length > 0) {\n out.linked_events = [...options.linkedEvent];\n }\n if (options.linkedFile !== undefined && options.linkedFile.length > 0) {\n out.linked_files = [...options.linkedFile];\n }\n return out;\n}\n\nfunction buildDecisionEvent(input: {\n eventId: PrefixedId<\"evt\">;\n sessionId: PrefixedId<\"ses\">;\n decisionId: PrefixedId<\"decision\">;\n title: string;\n occurredAt: string;\n rich: RichDecisionFields;\n}): Event {\n return {\n schema_version: \"0.1.0\",\n id: input.eventId,\n session_id: input.sessionId,\n occurred_at: input.occurredAt,\n source: \"local-cli\",\n type: \"decision_recorded\",\n decision_id: input.decisionId,\n title: input.title,\n ...(input.rich.rationale !== undefined ? { rationale: input.rich.rationale } : {}),\n ...(input.rich.alternatives !== undefined ? { alternatives: input.rich.alternatives } : {}),\n ...(input.rich.rejected_reason !== undefined\n ? { rejected_reason: input.rich.rejected_reason }\n : {}),\n ...(input.rich.linked_events !== undefined\n ? { linked_events: input.rich.linked_events as Array<`evt_${string}`> }\n : {}),\n ...(input.rich.linked_files !== undefined ? { linked_files: input.rich.linked_files } : {}),\n };\n}\n\nfunction buildAdHocLabel(title: string): string {\n const truncated =\n title.length > LABEL_TITLE_MAX ? `${title.slice(0, LABEL_TRUNCATE_HEAD)}...` : title;\n return `Ad-hoc decision: ${truncated}`;\n}\n\nfunction parseTitle(raw: string): string {\n if (raw.length === 0) {\n throw new InvalidArgumentError(\"Title must not be empty\");\n }\n return raw;\n}\n\nfunction parseRationale(raw: string): string {\n if (raw.length === 0) {\n throw new InvalidArgumentError(\"Rationale must not be empty\");\n }\n return raw;\n}\n\nfunction parseRejectedReason(raw: string): string {\n if (raw.length === 0) {\n throw new InvalidArgumentError(\"Rejected reason must not be empty\");\n }\n return raw;\n}\n\nfunction collectAlternative(value: string, prev: string[]): string[] {\n if (value.length === 0) {\n throw new InvalidArgumentError(\"Alternative must not be empty\");\n }\n return prev.concat(value);\n}\n\nconst EVENT_ID_RE = /^evt_[A-Z0-9]+$/;\n\nfunction collectLinkedEvent(value: string, prev: string[]): string[] {\n if (!EVENT_ID_RE.test(value)) {\n throw new InvalidArgumentError(`Linked event id must match evt_<ULID>, got '${value}'`);\n }\n return prev.concat(value);\n}\n\nfunction collectLinkedFile(value: string, prev: string[]): string[] {\n if (value.length === 0) {\n throw new InvalidArgumentError(\"Linked file path must not be empty\");\n }\n if (value.length > 4096) {\n throw new InvalidArgumentError(\"Linked file path exceeds 4096 chars\");\n }\n return prev.concat(value);\n}\n\ntype DecisionPrintInput = {\n mode: \"ad-hoc\" | \"attached\";\n sessionId: string;\n decisionId: string;\n eventId: string;\n sessionStatus: SessionStatus;\n title: string;\n rich: RichDecisionFields;\n};\n\nfunction printDecisionResult(options: DecisionRecordOptions, result: DecisionPrintInput): void {\n const sid = shortSessionId(result.sessionId);\n if (options.json === true) {\n const payload: Record<string, unknown> = {\n decision_id: result.decisionId,\n event_id: result.eventId,\n session_id: result.sessionId,\n session_status: result.sessionStatus,\n mode: result.mode,\n title: result.title,\n };\n // Rich fields are now persisted into the decision_recorded event, so\n // they appear in the JSON summary as-is (the old `rationale_saved:\n // false` indicator is gone).\n if (result.rich.rationale !== undefined) payload.rationale = result.rich.rationale;\n if (result.rich.alternatives !== undefined) payload.alternatives = result.rich.alternatives;\n if (result.rich.rejected_reason !== undefined) {\n payload.rejected_reason = result.rich.rejected_reason;\n }\n if (result.rich.linked_events !== undefined) payload.linked_events = result.rich.linked_events;\n if (result.rich.linked_files !== undefined) payload.linked_files = result.rich.linked_files;\n console.log(JSON.stringify(payload));\n return;\n }\n const rationaleSuffix =\n result.rich.rationale !== undefined ? ` (rationale: ${result.rich.rationale})` : \"\";\n if (result.mode === \"ad-hoc\") {\n console.log(`Recorded ${result.decisionId} in ad-hoc session ${sid}${rationaleSuffix}`);\n } else {\n console.log(\n `Recorded ${result.decisionId} in session ${sid} (${result.sessionStatus})${rationaleSuffix}`,\n );\n }\n}\n\nasync function resolveRepositoryRootForDecision(cwd: string): Promise<string> {\n try {\n return await resolveRepositoryRoot(cwd);\n } catch (error: unknown) {\n if (error instanceof Error && error.message === \"Not a git repository\") {\n throw new Error(\n \"Not a git repository. Run 'git init' first, then re-run 'basou decision record'.\",\n { cause: error },\n );\n }\n throw error;\n }\n}\n\nasync function assertWorkspaceInitialized(basouRoot: string): Promise<void> {\n try {\n await assertBasouRootSafe(basouRoot);\n } catch (error: unknown) {\n if (findErrorCode(error, \"ENOENT\")) {\n throw new Error(\"Workspace not initialized. Run 'basou init' first.\");\n }\n throw error;\n }\n}\n","import {\n assertBasouRootSafe,\n basouPaths,\n findErrorCode,\n readMarkdownFile,\n renderDecisions,\n renderWithMarkers,\n resolveRepositoryRoot,\n writeMarkdownFile,\n} from \"@basou/core\";\nimport type { Command } from \"commander\";\nimport {\n isVerbose,\n printReplayWarning,\n printSessionSkip,\n renderCliError,\n} from \"../lib/error-render.js\";\n\nexport type DecisionsGenerateOptions = { verbose?: boolean };\n\nexport type DecisionsContext = {\n cwd?: string;\n nowProvider?: () => Date;\n};\n\n/** Wire `basou decisions generate` onto `program`. Mirrors `handoff` exactly. */\nexport function registerDecisionsCommand(program: Command): void {\n const decisions = program\n .command(\"decisions\")\n .description(\"Generate or inspect .basou/decisions.md\");\n\n decisions\n .command(\"generate\")\n .description(\"Regenerate .basou/decisions.md from recorded decision events\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (opts: DecisionsGenerateOptions) => {\n await runDecisionsGenerate(opts);\n });\n}\n\nexport async function runDecisionsGenerate(\n options: DecisionsGenerateOptions,\n ctx: DecisionsContext = {},\n): Promise<void> {\n try {\n await doRunDecisionsGenerate(options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options) });\n process.exitCode = 1;\n }\n}\n\nexport async function doRunDecisionsGenerate(\n options: DecisionsGenerateOptions,\n ctx: DecisionsContext,\n): Promise<void> {\n void options;\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForDecisions(cwd);\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n\n const nowIso = (ctx.nowProvider?.() ?? new Date()).toISOString();\n const result = await renderDecisions({\n paths,\n nowIso,\n onWarning: (w, sid) => printReplayWarning(w, sid),\n onSessionSkip: (sid, reason) => printSessionSkip(sid, reason),\n });\n\n const existing = await readMarkdownFile(paths.files.decisions);\n const finalBody = renderWithMarkers(existing, result.body, \"decisions.md\");\n await writeMarkdownFile(paths.files.decisions, finalBody);\n\n console.log(`Generated .basou/decisions.md (decisions: ${result.decisionCount})`);\n}\n\nasync function resolveRepositoryRootForDecisions(cwd: string): Promise<string> {\n try {\n return await resolveRepositoryRoot(cwd);\n } catch (error: unknown) {\n if (error instanceof Error && error.message === \"Not a git repository\") {\n throw new Error(\n \"Not a git repository. Run 'git init' first, then re-run 'basou decisions generate'.\",\n { cause: error },\n );\n }\n throw error;\n }\n}\n\nasync function assertWorkspaceInitialized(basouRoot: string): Promise<void> {\n try {\n await assertBasouRootSafe(basouRoot);\n } catch (error: unknown) {\n if (findErrorCode(error, \"ENOENT\")) {\n throw new Error(\"Workspace not initialized. Run 'basou init' first.\");\n }\n throw error;\n }\n}\n","import type { ChildProcess } from \"node:child_process\";\nimport { mkdir } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport {\n ChildProcessRunner,\n type PrefixedId,\n type ProcessRunner,\n type RunResult,\n type Session,\n SessionSchema,\n assertBasouRootSafe,\n basouPaths,\n appendEvent as coreAppendEvent,\n getSnapshot,\n overwriteYamlFile,\n parseDuration,\n prefixedUlid,\n readManifest,\n readYamlFile,\n resolveRepositoryRoot,\n sanitizeWorkingDirectory,\n writeYamlFile,\n} from \"@basou/core\";\nimport type { Command } from \"commander\";\nimport { isVerbose, renderCliError } from \"../lib/error-render.js\";\n\ntype AppendEventFn = typeof coreAppendEvent;\n\n/**\n * `basou exec` orchestration: spawn an arbitrary child as a single new\n * Basou session and record its lifecycle (session_started, optional\n * git_snapshot pre, status_changed, command_executed, optional git_snapshot\n * post, status_changed, session_ended) to `events.jsonl`.\n *\n * Output is forwarded to the parent's terminal (`capture: \"none\"`); raw\n * stdout/stderr is intentionally not stored in events.jsonl or `.basou/raw/`.\n */\nexport type ExecOptions = {\n timeout?: string;\n cwd?: string;\n // commander turns `--no-snapshot` into `snapshot: false`. The default\n // (no flag) leaves this `undefined` (treated as `true` downstream).\n snapshot?: boolean;\n verbose?: boolean;\n};\n\ntype ExecContext = {\n runner?: ProcessRunner;\n now?: () => Date;\n // events.jsonl writer override. Tests use this to verify that appendEvent\n // failures during git_snapshot propagate as exec failures (see\n // tryAppendGitSnapshot below) instead of being swallowed into a skip warning.\n appendEvent?: AppendEventFn;\n // Last-resort SIGKILL hook installation hook. Tests capture the handler\n // installed on `process.on(\"exit\", ...)` and trigger it manually to verify\n // that activeChild is killed when the parent exits abnormally.\n onExitHookInstalled?: (handler: () => void) => void;\n};\n\nexport function registerExecCommand(program: Command): void {\n program\n .command(\"exec <command> [args...]\")\n .description(\"Execute a command and record it as a Basou session\")\n // Pass through unknown options/flags after the command name to the\n // child so callers can write `basou exec npm test --watch` instead of\n // `basou exec -- npm test --watch`. basou's own options (--timeout,\n // --no-snapshot, --cwd, -v) must come before the command name.\n .passThroughOptions()\n .option(\"--timeout <duration>\", \"Kill the child after this duration (e.g. 30s, 5m, 1h)\")\n .option(\"--no-snapshot\", \"Skip git_snapshot before/after the command\")\n .option(\"--cwd <path>\", \"Run from a Basou root other than process.cwd()\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (command: string, args: string[], options: ExecOptions) => {\n try {\n const exitCode = await runExec(command, args, options);\n process.exit(exitCode);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options) });\n process.exit(1);\n }\n });\n}\n\nexport async function runExec(\n command: string,\n args: string[],\n options: ExecOptions,\n ctx: ExecContext = {},\n): Promise<number> {\n const runner = ctx.runner ?? new ChildProcessRunner();\n const now = ctx.now ?? (() => new Date());\n const appendEvent: AppendEventFn = ctx.appendEvent ?? coreAppendEvent;\n const cwd = options.cwd ?? process.cwd();\n\n // 0. timeout option fail-fast: invalid timeout never creates a session.\n const timeout_ms = options.timeout !== undefined ? parseDuration(options.timeout) : undefined;\n\n // 1. Resolve repository root before touching anything; matches existing\n // init/status semantics so subdir invocations still find `.basou/`.\n const repoRoot = await resolveRepositoryRootForExec(cwd);\n const paths = basouPaths(repoRoot);\n\n // 2. Workspace safety check (caller responsibility).\n await assertBasouRootSafe(paths.root);\n\n // 3. Read manifest to bind session.workspace_id.\n const manifest = await readManifest(paths);\n\n // 4. Build a fresh session and persist its initial state.\n const sessionId = prefixedUlid(\"ses\");\n const sessionDir = join(paths.sessions, sessionId);\n await mkdir(sessionDir, { recursive: true });\n\n const startedAt = now().toISOString();\n const sessionYamlPath = join(sessionDir, \"session.yaml\");\n const session = buildInitialSession({\n id: sessionId,\n command,\n args,\n cwd,\n workspaceId: manifest.workspace.id,\n startedAt,\n });\n await writeYamlFile(sessionYamlPath, session);\n\n // 5. session_started.\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"session_started\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: startedAt,\n source: \"terminal-recording\",\n });\n\n // 6. Optional pre-execute git_snapshot.\n if (options.snapshot !== false) {\n await tryAppendGitSnapshot(sessionDir, sessionId, repoRoot, now, appendEvent);\n }\n\n // 7. status_changed: initialized -> running.\n const runningAt = now().toISOString();\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"session_status_changed\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: runningAt,\n source: \"terminal-recording\",\n from: \"initialized\",\n to: \"running\",\n });\n await mutateSessionYaml(sessionYamlPath, (s) => {\n s.session.status = \"running\";\n });\n\n // 8. Transient signal hooks: SIGINT / SIGTERM / exit. The exit hook is\n // a synchronous last-resort SIGKILL if the parent exits abnormally.\n const controller = new AbortController();\n let signalReceived: NodeJS.Signals | null = null;\n let activeChild: ChildProcess | null = null;\n const signalHandler = (sig: NodeJS.Signals) => {\n if (signalReceived !== null) return;\n signalReceived = sig;\n controller.abort();\n };\n const exitHandler = () => {\n if (activeChild !== null) {\n try {\n activeChild.kill(\"SIGKILL\");\n } catch {\n // swallow: best-effort cleanup\n }\n }\n };\n // Bind explicit signal names so `process.emit(\"SIGINT\")` etc. produce the\n // right `received_signal` regardless of Node's listener-arg conventions.\n const onSigInt = () => signalHandler(\"SIGINT\");\n const onSigTerm = () => signalHandler(\"SIGTERM\");\n process.on(\"SIGINT\", onSigInt);\n process.on(\"SIGTERM\", onSigTerm);\n process.on(\"exit\", exitHandler);\n // Allow tests to capture the exit handler and trigger the activeChild\n // SIGKILL fallback synchronously without faking `process.emit(\"exit\")`.\n ctx.onExitHookInstalled?.(exitHandler);\n\n let result: RunResult;\n try {\n try {\n result = await runner.run(command, args, {\n cwd,\n capture: \"none\",\n ...(timeout_ms !== undefined ? { timeout_ms } : {}),\n signal: controller.signal,\n onSpawn: (child) => {\n activeChild = child;\n },\n });\n } catch (spawnError: unknown) {\n // Spawn-time error / pre-aborted / validation error: tear down the\n // session as failed before propagating so events.jsonl and session.yaml\n // are consistent even on error.\n await finalizeSessionAsFailed(sessionDir, sessionYamlPath, sessionId, appendEvent, {\n command,\n args,\n cwd,\n occurredAt: now().toISOString(),\n signalReceived,\n });\n throw spawnError;\n }\n } finally {\n process.off(\"SIGINT\", onSigInt);\n process.off(\"SIGTERM\", onSigTerm);\n process.off(\"exit\", exitHandler);\n activeChild = null;\n }\n\n const endedAt = now().toISOString();\n\n // 9. command_executed (with parent received_signal vs child terminating signal).\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"command_executed\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: endedAt,\n source: \"terminal-recording\",\n command,\n args,\n cwd,\n exit_code: result.exit_code,\n ...(result.signal !== null ? { signal: result.signal } : {}),\n ...(signalReceived !== null ? { received_signal: signalReceived } : {}),\n duration_ms: result.duration_ms,\n });\n\n // 10. Optional post-execute git_snapshot (after command_executed so the\n // event sequence reads chronologically: pre-snapshot, run, post-snapshot).\n if (options.snapshot !== false) {\n await tryAppendGitSnapshot(sessionDir, sessionId, repoRoot, now, appendEvent);\n }\n\n const finalStatus = decideFinalStatus(result, signalReceived);\n\n // 11. status_changed: running -> final.\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"session_status_changed\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: endedAt,\n source: \"terminal-recording\",\n from: \"running\",\n to: finalStatus,\n });\n\n // 12. session_ended.\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"session_ended\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: endedAt,\n source: \"terminal-recording\",\n ...(result.exit_code !== null ? { exit_code: result.exit_code } : {}),\n });\n\n // 13. Final session.yaml update (status / ended_at / invocation.exit_code).\n await mutateSessionYaml(sessionYamlPath, (s) => {\n s.session.status = finalStatus;\n s.session.ended_at = endedAt;\n s.session.invocation.exit_code = result.exit_code;\n });\n\n if (result.exit_code !== null) {\n return result.exit_code;\n }\n return signalToExitCode(signalReceived ?? result.signal);\n}\n\nfunction decideFinalStatus(\n result: { exit_code: number | null; signal: NodeJS.Signals | null },\n signalReceived: NodeJS.Signals | null,\n): \"completed\" | \"failed\" | \"interrupted\" {\n if (signalReceived === \"SIGINT\" || signalReceived === \"SIGTERM\") return \"interrupted\";\n if (result.signal === \"SIGINT\" || result.signal === \"SIGTERM\" || result.signal === \"SIGKILL\") {\n return \"interrupted\";\n }\n if (result.exit_code === 0) return \"completed\";\n return \"failed\";\n}\n\nconst SIGNUM_MAP: Record<string, number> = {\n SIGHUP: 1,\n SIGINT: 2,\n SIGQUIT: 3,\n SIGKILL: 9,\n SIGTERM: 15,\n};\n\nfunction signalToExitCode(sig: NodeJS.Signals | null): number {\n if (sig === null) return 1;\n const num = SIGNUM_MAP[sig] ?? 1;\n return 128 + num;\n}\n\nasync function tryAppendGitSnapshot(\n sessionDir: string,\n sessionId: string,\n repoRoot: string,\n now: () => Date,\n appendEvent: AppendEventFn,\n): Promise<void> {\n // Stage 1: snapshot acquisition. Capability-level failures (no git repo,\n // git binary missing, no commits) are recoverable and downgrade to a skip\n // warning. The session continues and events.jsonl simply lacks this\n // git_snapshot entry.\n let snapshot: Awaited<ReturnType<typeof getSnapshot>>;\n try {\n snapshot = await getSnapshot(repoRoot);\n } catch (error: unknown) {\n console.warn(normalizeGitSnapshotSkipMessage(error));\n return;\n }\n // Stage 2: events.jsonl append. Schema validation / disk failures here are\n // NOT a \"snapshot capability\" miss — they would corrupt the events.jsonl\n // integrity contract (the fixed 7-event sequence when snapshot is on). We\n // intentionally do NOT swallow these; let them propagate so the exec call\n // fails loudly instead of producing a session that looks successful but\n // has missing or partial events.\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"git_snapshot\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: now().toISOString(),\n source: \"git-capability\",\n ...snapshot,\n });\n}\n\nfunction normalizeGitSnapshotSkipMessage(error: unknown): string {\n if (!(error instanceof Error)) {\n return `git_snapshot skipped: ${String(error)}`;\n }\n const msg = error.message;\n if (msg === \"Not a git repository\") {\n return \"git_snapshot skipped: not in a git repository\";\n }\n if (msg === \"Git executable not found in PATH. Install git first.\") {\n return \"git_snapshot skipped: git executable not found\";\n }\n if (msg === \"No commits in repository\") {\n return \"git_snapshot skipped: no commits in repository\";\n }\n return `git_snapshot skipped: ${msg}`;\n}\n\nfunction buildInitialSession(input: {\n id: PrefixedId<\"ses\">;\n command: string;\n args: string[];\n cwd: string;\n workspaceId: PrefixedId<\"ws\">;\n startedAt: string;\n}): Session {\n const cmdline = [input.command, ...input.args].join(\" \");\n return {\n schema_version: \"0.1.0\",\n session: {\n id: input.id,\n label: `basou exec ${cmdline} (${input.startedAt})`,\n task_id: null,\n workspace_id: input.workspaceId,\n source: { kind: \"terminal\", version: \"0.1.0\" },\n started_at: input.startedAt,\n status: \"initialized\",\n working_directory: sanitizeWorkingDirectory(input.cwd, { homedir: homedir() }),\n invocation: {\n command: input.command,\n args: [...input.args],\n exit_code: null,\n },\n related_files: [],\n events_log: \"events.jsonl\",\n },\n };\n}\n\nasync function mutateSessionYaml(\n filePath: string,\n mutator: (session: Session) => void,\n): Promise<void> {\n const raw = await readYamlFile(filePath);\n const parsed = SessionSchema.parse(raw);\n mutator(parsed);\n // Re-validate after mutation to catch drift, then overwrite atomically.\n const validated = SessionSchema.parse(parsed);\n await overwriteYamlFile(filePath, validated);\n}\n\nasync function finalizeSessionAsFailed(\n sessionDir: string,\n sessionYamlPath: string,\n sessionId: string,\n appendEvent: AppendEventFn,\n ctx: {\n command: string;\n args: string[];\n cwd: string;\n occurredAt: string;\n signalReceived: NodeJS.Signals | null;\n },\n): Promise<void> {\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"command_executed\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: ctx.occurredAt,\n source: \"terminal-recording\",\n command: ctx.command,\n args: ctx.args,\n cwd: ctx.cwd,\n exit_code: null,\n signal: null,\n ...(ctx.signalReceived !== null ? { received_signal: ctx.signalReceived } : {}),\n duration_ms: 0,\n });\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"session_status_changed\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: ctx.occurredAt,\n source: \"terminal-recording\",\n from: \"running\",\n to: \"failed\",\n });\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"session_ended\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: ctx.occurredAt,\n source: \"terminal-recording\",\n });\n await mutateSessionYaml(sessionYamlPath, (s) => {\n s.session.status = \"failed\";\n s.session.ended_at = ctx.occurredAt;\n s.session.invocation.exit_code = null;\n });\n}\n\nasync function resolveRepositoryRootForExec(cwd: string): Promise<string> {\n try {\n return await resolveRepositoryRoot(cwd);\n } catch (error: unknown) {\n if (error instanceof Error && error.message === \"Not a git repository\") {\n throw new Error(\"Not a git repository. Run 'git init' first, then re-run 'basou exec'.\", {\n cause: error,\n });\n }\n throw error;\n }\n}\n","import {\n assertBasouRootSafe,\n basouPaths,\n findErrorCode,\n readMarkdownFile,\n renderHandoff,\n renderWithMarkers,\n resolveRepositoryRoot,\n writeMarkdownFile,\n} from \"@basou/core\";\nimport type { Command } from \"commander\";\nimport {\n isVerbose,\n printReplayWarning,\n printSessionSkip,\n printTaskSkip,\n renderCliError,\n} from \"../lib/error-render.js\";\n\nexport type HandoffGenerateOptions = { verbose?: boolean };\n\nexport type HandoffContext = {\n /** Defaults to `process.cwd()`. Injectable for tests. */\n cwd?: string;\n /** Defaults to `() => new Date()`. Injectable for tests. */\n nowProvider?: () => Date;\n};\n\n/**\n * Wire `basou handoff generate` onto `program`. The `handoff` group is\n * registered up front so future subcommands (e.g. `show`) can slot under\n * the same group without breaking the CLI surface.\n */\nexport function registerHandoffCommand(program: Command): void {\n const handoff = program.command(\"handoff\").description(\"Generate or inspect .basou/handoff.md\");\n\n handoff\n .command(\"generate\")\n .description(\"Regenerate .basou/handoff.md from current session state\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (opts: HandoffGenerateOptions) => {\n await runHandoffGenerate(opts);\n });\n}\n\n/**\n * Programmatic entry that owns `process.exitCode`. Tests that only care\n * about the happy path or a thrown error should prefer {@link doRunHandoffGenerate}.\n */\nexport async function runHandoffGenerate(\n options: HandoffGenerateOptions,\n ctx: HandoffContext = {},\n): Promise<void> {\n try {\n await doRunHandoffGenerate(options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options) });\n process.exitCode = 1;\n }\n}\n\n/**\n * Pure runner for `handoff generate`. Throws on any failure with a pathless\n * message; native errors are attached as `cause` for verbose surfacing.\n */\nexport async function doRunHandoffGenerate(\n options: HandoffGenerateOptions,\n ctx: HandoffContext,\n): Promise<void> {\n void options;\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForHandoff(cwd);\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n\n const nowIso = (ctx.nowProvider?.() ?? new Date()).toISOString();\n const result = await renderHandoff({\n paths,\n nowIso,\n onWarning: (w, sid) => printReplayWarning(w, sid),\n onSessionSkip: (sid, reason) => printSessionSkip(sid, reason),\n onTaskSkip: (taskId, reason) => printTaskSkip(taskId, reason),\n });\n\n const existing = await readMarkdownFile(paths.files.handoff);\n const finalBody = renderWithMarkers(existing, result.body, \"handoff.md\");\n await writeMarkdownFile(paths.files.handoff, finalBody);\n\n console.log(\n `Generated .basou/handoff.md (sessions: ${result.sessionCount}, tasks: ${result.taskCount}, decisions: ${result.decisionCount}, pending approvals: ${result.pendingApprovalsCount})`,\n );\n}\n\nasync function resolveRepositoryRootForHandoff(cwd: string): Promise<string> {\n try {\n return await resolveRepositoryRoot(cwd);\n } catch (error: unknown) {\n if (error instanceof Error && error.message === \"Not a git repository\") {\n throw new Error(\n \"Not a git repository. Run 'git init' first, then re-run 'basou handoff generate'.\",\n { cause: error },\n );\n }\n throw error;\n }\n}\n\nasync function assertWorkspaceInitialized(basouRoot: string): Promise<void> {\n try {\n await assertBasouRootSafe(basouRoot);\n } catch (error: unknown) {\n if (findErrorCode(error, \"ENOENT\")) {\n throw new Error(\"Workspace not initialized. Run 'basou init' first.\");\n }\n throw error;\n }\n}\n","import { basename } from \"node:path\";\nimport {\n appendBasouGitignore,\n createManifest,\n ensureBasouDirectory,\n resolveRepositoryRoot,\n tryRemoteUrl,\n writeManifest,\n} from \"@basou/core\";\nimport type { Command } from \"commander\";\nimport { extractCauseLabel, isVerbose, renderCliError } from \"../lib/error-render.js\";\n\nexport type InitOptions = {\n name?: string;\n projectName?: string;\n projectDescription?: string;\n repoUrl?: string;\n force?: boolean;\n verbose?: boolean;\n};\n\nexport type InitContext = {\n /** Defaults to `process.cwd()`. Injectable for tests. */\n cwd?: string;\n};\n\n/**\n * Register `basou init` on a commander program. The `--repo-url \"\"` (empty\n * string) form is the documented way to set `project.repository_url` to\n * `null` explicitly; omitting `--repo-url` falls back to\n * `git config --local remote.origin.url` and finally to omission.\n */\nexport function registerInitCommand(program: Command): void {\n program\n .command(\"init\")\n .description(\"Initialize a Basou workspace at the current Git repository root\")\n .option(\"--name <name>\", \"Workspace name (defaults to the repository directory name)\")\n .option(\"--project-name <name>\", \"Project display name\")\n .option(\"--project-description <description>\", \"Project description\")\n .option(\n \"--repo-url <url>\",\n \"Repository URL (defaults to git remote.origin.url; pass empty string for null)\",\n )\n .option(\"-f, --force\", \"Overwrite an existing manifest\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (options: InitOptions) => {\n await runInit(options);\n });\n}\n\n/**\n * Programmatic entry that mutates process state (`exitCode`, stderr).\n * Exported for tests, but tests should prefer {@link doRunInit} so they are\n * not coupled to process global state.\n */\nexport async function runInit(options: InitOptions, ctx: InitContext = {}): Promise<void> {\n try {\n await doRunInit(options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options) });\n process.exitCode = 1;\n }\n}\n\n/**\n * Pure runner: resolves inputs, calls core APIs, prints the success line.\n * On any failure throws an Error whose `message` is pathless and whose\n * `cause` MAY contain a native fs error. Exported for tests so they can\n * assert on thrown errors without touching `process.exitCode`.\n */\nexport async function doRunInit(options: InitOptions, ctx: InitContext): Promise<void> {\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForInit(cwd);\n const workspaceName = options.name ?? basename(repositoryRoot);\n\n // --repo-url > git config --local remote.origin.url > omit\n // --repo-url \"\" => explicit null\n let repositoryUrl: string | null | undefined;\n if (options.repoUrl !== undefined) {\n repositoryUrl = options.repoUrl === \"\" ? null : options.repoUrl;\n } else {\n repositoryUrl = await tryRemoteUrl(repositoryRoot);\n }\n\n const paths = await ensureBasouDirectory(repositoryRoot);\n const manifest = createManifest({\n workspaceName,\n ...(options.projectName !== undefined ? { projectName: options.projectName } : {}),\n ...(options.projectDescription !== undefined\n ? { projectDescription: options.projectDescription }\n : {}),\n ...(repositoryUrl !== undefined ? { repositoryUrl } : {}),\n });\n\n await writeManifest(paths, manifest, { force: options.force === true });\n\n // .gitignore は best-effort: 失敗しても init 全体は成功とみなす。\n // 「既存 Git repo で安全に実行できる」という完了条件を担保するため、\n // permission denied 等で manifest だけ書けて .gitignore が書けない\n // ケースでも基本機能は使える。\n try {\n await appendBasouGitignore(repositoryRoot);\n } catch (error: unknown) {\n renderGitignoreWarning(error, isVerbose(options));\n }\n\n console.log(`Initialized Basou workspace: ${manifest.workspace.id}`);\n}\n\n/**\n * Render a non-fatal warning when `.gitignore` cannot be updated. Mirrors\n * the pathless contract enforced by {@link renderCliError} — never prints\n * `error.cause.message` because native fs errors embed the absolute path\n * in it.\n */\nfunction renderGitignoreWarning(error: unknown, verbose: boolean): void {\n const baseMessage = error instanceof Error ? error.message : String(error);\n // The fallback hint is intentionally `dist`-only-portable: it does not\n // reference the Basou planning repo or any in-repo doc path, since the\n // CLI is published independently of `docs/`.\n console.error(\n `Warning: Could not update .gitignore (${baseMessage}). Add Basou's default .gitignore block manually.`,\n );\n if (verbose && error instanceof Error) {\n const label = extractCauseLabel(error);\n if (label !== undefined) console.error(`Caused by: ${label}`);\n }\n}\n\n/**\n * Wrap the core git capability so the CLI surfaces the command-specific\n * \"Run 'git init' first, then re-run 'basou init'.\" suffix while the\n * capability layer remains command-agnostic.\n */\nasync function resolveRepositoryRootForInit(cwd: string): Promise<string> {\n try {\n return await resolveRepositoryRoot(cwd);\n } catch (error: unknown) {\n if (error instanceof Error && error.message === \"Not a git repository\") {\n throw new Error(\"Not a git repository. Run 'git init' first, then re-run 'basou init'.\", {\n cause: error,\n });\n }\n throw error;\n }\n}\n","import type { ChildProcess } from \"node:child_process\";\nimport { mkdir } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport {\n ChildProcessRunner,\n type DiffResult,\n type GitSnapshot,\n type PrefixedId,\n type ProcessRunner,\n type RunResult,\n type Session,\n SessionSchema,\n assertBasouRootSafe,\n basouPaths,\n claudeCodeAdapterMetadata,\n appendEvent as coreAppendEvent,\n getDiff,\n getSnapshot,\n overwriteYamlFile,\n prefixedUlid,\n readManifest,\n readYamlFile,\n resolveClaudeCodeCommand,\n resolveRepositoryRoot,\n sanitizeRelatedFiles,\n sanitizeWorkingDirectory,\n writeYamlFile,\n} from \"@basou/core\";\nimport type { Command } from \"commander\";\nimport { isVerbose, renderCliError } from \"../lib/error-render.js\";\n\ntype AppendEventFn = typeof coreAppendEvent;\ntype ResolveCommandFn = typeof resolveClaudeCodeCommand;\ntype GetDiffFn = typeof getDiff;\n\n/**\n * `basou run claude-code` orchestration: spawn claude-code as a single new\n * Basou session and record its lifecycle (session_started, optional\n * git_snapshot pre, status_changed, command_executed, optional git_snapshot\n * post, file_changed × N, status_changed, session_ended) to events.jsonl.\n *\n * The child inherits the parent's stdio (`capture: \"none\"`) so that\n * claude-code's interactive TTY remains usable; raw stdout/stderr is\n * intentionally NOT captured into events.jsonl or `.basou/raw/` in v0.1.\n */\nexport type RunOptions = {\n // commander turns `--no-snapshot` into `snapshot: false`. The default\n // (no flag) leaves this `undefined` (treated as `true` downstream).\n snapshot?: boolean;\n cwd?: string;\n verbose?: boolean;\n};\n\nexport type RunContext = {\n runner?: ProcessRunner;\n now?: () => Date;\n appendEvent?: AppendEventFn;\n onExitHookInstalled?: (handler: () => void) => void;\n // Override the claude-code PATH lookup. Tests use this to skip real\n // `which` invocations and force success / failure deterministically.\n resolveCommand?: ResolveCommandFn;\n // Override the git diff capability. Tests use this to force capability\n // failure deterministically without rewriting the git fixture state.\n getDiff?: GetDiffFn;\n};\n\n/**\n * Wire the `basou run` command group into `program`. The optional `ctx` is\n * passed through to `runClaudeCode` so tests can intercept the action callback\n * (fake runner, fake clock, deterministic resolveCommand / getDiff). Production\n * callers omit it.\n *\n * Basou options (`--no-snapshot`, `--cwd`, `-v`) are defined on both the\n * `run` group and the inner `claude-code` subcommand. commander's\n * `passThroughOptions()` only forwards UNKNOWN options to args, so a\n * group-only definition would make `basou run claude-code --no-snapshot`\n * crash with \"unknown option\". Duplicating the definitions lets the option\n * be recognized regardless of position; only `--`-separated args go to the\n * child. v0.2+ adapter additions (codex / gemini) should consider\n * extracting a common-option helper rather than re-duplicating.\n */\nexport function registerRunCommand(program: Command, ctx: RunContext = {}): void {\n const runCommand = program\n .command(\"run\")\n .description(\"Run an AI coding tool through Basou as a tracked session\")\n // Required so the inner `claude-code` subcommand can pass through\n // arguments after `--` to the child without commander interpreting them\n // as run-group options.\n .enablePositionalOptions()\n .option(\"--no-snapshot\", \"Skip git_snapshot before/after the session\")\n .option(\"--cwd <path>\", \"Run from a Basou root other than process.cwd()\")\n .option(\"-v, --verbose\", \"Show error causes\");\n\n runCommand\n .command(\"claude-code [args...]\")\n .description(\"Run Claude Code CLI as a Basou-tracked session\")\n // Same options redeclared on the subsubcommand so they are recognized\n // when placed AFTER `claude-code` as well; see the function comment.\n .option(\"--no-snapshot\", \"Skip git_snapshot before/after the session\")\n .option(\"--cwd <path>\", \"Run from a Basou root other than process.cwd()\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .passThroughOptions()\n .action(async (args: string[], options: RunOptions, command: Command) => {\n const parentOptions = (command.parent?.opts() ?? {}) as RunOptions;\n // Both layers default `snapshot` to `true` when --no-snapshot is\n // omitted, so a naive spread would let the subsubcommand's default\n // overwrite a `--no-snapshot` set on the parent. Take a logical AND\n // instead: snapshot stays on only when neither layer disables it.\n const snapshotOn = parentOptions.snapshot !== false && options.snapshot !== false;\n const merged: RunOptions = {\n ...parentOptions,\n ...options,\n snapshot: snapshotOn,\n };\n try {\n const exitCode = await runClaudeCode(args, merged, ctx);\n process.exit(exitCode);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(merged) });\n process.exit(1);\n }\n });\n}\n\nexport async function runClaudeCode(\n args: string[],\n options: RunOptions,\n ctx: RunContext = {},\n): Promise<number> {\n const runner = ctx.runner ?? new ChildProcessRunner();\n const now = ctx.now ?? (() => new Date());\n const appendEvent: AppendEventFn = ctx.appendEvent ?? coreAppendEvent;\n const resolveCommand: ResolveCommandFn = ctx.resolveCommand ?? resolveClaudeCodeCommand;\n const getDiffFn: GetDiffFn = ctx.getDiff ?? getDiff;\n\n // 1. Resolve the claude-code executable BEFORE any side-effect: a missing\n // CLI is a user installation issue, not something worth recording as a\n // Basou session. Failure here leaves no sessions/<id>/ entry behind.\n const { command } = await resolveCommand();\n\n const cwd = options.cwd ?? process.cwd();\n\n // 2. Resolve repository root (entry-fail when not in a git repo).\n const repoRoot = await resolveRepositoryRootForRun(cwd);\n const paths = basouPaths(repoRoot);\n\n // 3. Workspace safety check.\n await assertBasouRootSafe(paths.root);\n\n // 4. Read manifest to bind session.workspace_id.\n const manifest = await readManifest(paths);\n\n // 5. Build a fresh session and persist its initial state.\n const sessionId = prefixedUlid(\"ses\");\n const sessionDir = join(paths.sessions, sessionId);\n await mkdir(sessionDir, { recursive: true });\n\n const startedAt = now().toISOString();\n const sessionYamlPath = join(sessionDir, \"session.yaml\");\n const session = buildInitialSession({\n id: sessionId,\n command,\n args,\n cwd: repoRoot,\n workspaceId: manifest.workspace.id,\n startedAt,\n });\n await writeYamlFile(sessionYamlPath, session);\n\n // 6. session_started.\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"session_started\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: startedAt,\n source: claudeCodeAdapterMetadata.kind,\n });\n\n // 7. Optional pre-execute git_snapshot.\n let preSnapshot: GitSnapshot | null = null;\n if (options.snapshot !== false) {\n preSnapshot = await tryAppendGitSnapshot(sessionDir, sessionId, repoRoot, now, appendEvent);\n }\n\n // 8. status_changed: initialized -> running.\n const runningAt = now().toISOString();\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"session_status_changed\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: runningAt,\n source: claudeCodeAdapterMetadata.kind,\n from: \"initialized\",\n to: \"running\",\n });\n await mutateSessionYaml(sessionYamlPath, (s) => {\n s.session.status = \"running\";\n });\n\n // 9. Transient signal hooks (SIGINT / SIGTERM / exit). The exit hook is a\n // last-resort SIGKILL if the parent dies abnormally.\n const controller = new AbortController();\n let signalReceived: NodeJS.Signals | null = null;\n let activeChild: ChildProcess | null = null;\n const signalHandler = (sig: NodeJS.Signals) => {\n if (signalReceived !== null) return;\n signalReceived = sig;\n controller.abort();\n };\n const exitHandler = () => {\n if (activeChild !== null) {\n try {\n activeChild.kill(\"SIGKILL\");\n } catch {\n // best-effort cleanup\n }\n }\n };\n const onSigInt = () => signalHandler(\"SIGINT\");\n const onSigTerm = () => signalHandler(\"SIGTERM\");\n process.on(\"SIGINT\", onSigInt);\n process.on(\"SIGTERM\", onSigTerm);\n process.on(\"exit\", exitHandler);\n ctx.onExitHookInstalled?.(exitHandler);\n\n // 10-11. runner.run() execute (capture: \"none\" inherits the parent stdio so\n // claude-code keeps a real TTY). Spawn-time errors finalize the\n // session as failed and propagate the error.\n let result: RunResult;\n try {\n try {\n result = await runner.run(command, args, {\n cwd: repoRoot,\n capture: \"none\",\n signal: controller.signal,\n onSpawn: (child) => {\n activeChild = child;\n },\n });\n } catch (spawnError: unknown) {\n await finalizeSessionAsFailed(sessionDir, sessionYamlPath, sessionId, appendEvent, {\n command,\n args,\n cwd: repoRoot,\n occurredAt: now().toISOString(),\n signalReceived,\n });\n throw spawnError;\n }\n } finally {\n process.off(\"SIGINT\", onSigInt);\n process.off(\"SIGTERM\", onSigTerm);\n process.off(\"exit\", exitHandler);\n activeChild = null;\n }\n\n const endedAt = now().toISOString();\n\n // 12. command_executed (parent received_signal vs child terminating signal).\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"command_executed\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: endedAt,\n source: \"terminal-recording\",\n command,\n args,\n cwd: repoRoot,\n exit_code: result.exit_code,\n ...(result.signal !== null ? { signal: result.signal } : {}),\n ...(signalReceived !== null ? { received_signal: signalReceived } : {}),\n duration_ms: result.duration_ms,\n });\n\n // 13. Optional post-execute git_snapshot.\n let postSnapshot: GitSnapshot | null = null;\n if (options.snapshot !== false) {\n postSnapshot = await tryAppendGitSnapshot(sessionDir, sessionId, repoRoot, now, appendEvent);\n }\n\n // 14-15. file_changed events derived from getDiff(preHead, postHead). Only\n // committed changes appear here; dirty (staged/unstaged/untracked)\n // edits are surfaced via session.yaml.related_files instead.\n let diff: DiffResult | null = null;\n if (preSnapshot !== null && postSnapshot !== null) {\n diff = await tryAppendFileChangedEvents(\n sessionDir,\n sessionId,\n repoRoot,\n preSnapshot.head,\n postSnapshot.head,\n now().toISOString(),\n appendEvent,\n getDiffFn,\n );\n }\n\n // 16. Compute related_files = pre+post snapshot ∪ diff (sorted, deduped).\n // Then sanitize so /Users/<u>/projects/foo/... is stored relative to\n // the session's working_directory; system paths outside both bases\n // stay verbatim. Git output is usually repo-relative already, but the\n // sanitizer is idempotent and cheap so we run it unconditionally\n // against the very subset of paths that ever reach session.yaml.\n const rawRelated = computeRelatedFiles(preSnapshot, postSnapshot, diff);\n const relatedFiles = sanitizeRelatedFiles(rawRelated, {\n workingDirectory: repoRoot,\n homedir: homedir(),\n }).sanitized;\n\n const finalStatus = decideFinalStatus(result, signalReceived);\n\n // 17-18. status_changed: running -> final.\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"session_status_changed\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: endedAt,\n source: claudeCodeAdapterMetadata.kind,\n from: \"running\",\n to: finalStatus,\n });\n\n // 19. session_ended.\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"session_ended\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: endedAt,\n source: claudeCodeAdapterMetadata.kind,\n ...(result.exit_code !== null ? { exit_code: result.exit_code } : {}),\n });\n\n // 20. Final session.yaml update (status / ended_at / invocation.exit_code /\n // related_files).\n await mutateSessionYaml(sessionYamlPath, (s) => {\n s.session.status = finalStatus;\n s.session.ended_at = endedAt;\n s.session.invocation.exit_code = result.exit_code;\n s.session.related_files = relatedFiles;\n });\n\n if (result.exit_code !== null) return result.exit_code;\n return signalToExitCode(signalReceived ?? result.signal);\n}\n\nfunction decideFinalStatus(\n result: { exit_code: number | null; signal: NodeJS.Signals | null },\n signalReceived: NodeJS.Signals | null,\n): \"completed\" | \"failed\" | \"interrupted\" {\n if (signalReceived === \"SIGINT\" || signalReceived === \"SIGTERM\") return \"interrupted\";\n if (result.signal === \"SIGINT\" || result.signal === \"SIGTERM\" || result.signal === \"SIGKILL\") {\n return \"interrupted\";\n }\n if (result.exit_code === 0) return \"completed\";\n return \"failed\";\n}\n\nconst SIGNUM_MAP: Record<string, number> = {\n SIGHUP: 1,\n SIGINT: 2,\n SIGQUIT: 3,\n SIGKILL: 9,\n SIGTERM: 15,\n};\n\nfunction signalToExitCode(sig: NodeJS.Signals | null): number {\n if (sig === null) return 1;\n const num = SIGNUM_MAP[sig] ?? 1;\n return 128 + num;\n}\n\nasync function tryAppendGitSnapshot(\n sessionDir: string,\n sessionId: string,\n repoRoot: string,\n now: () => Date,\n appendEvent: AppendEventFn,\n): Promise<GitSnapshot | null> {\n // Stage 1: capability acquisition. Capability-level failures (no git\n // repository, git binary missing, no commits) downgrade to a skip warning;\n // events.jsonl simply lacks this git_snapshot entry.\n let snapshot: GitSnapshot;\n try {\n snapshot = await getSnapshot(repoRoot);\n } catch (error: unknown) {\n console.warn(normalizeGitSnapshotSkipMessage(error));\n return null;\n }\n // Stage 2: events.jsonl append. Failures here would corrupt the events.jsonl\n // integrity contract; let them propagate so the run fails loudly rather\n // than producing a session that looks successful but is actually missing\n // events.\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"git_snapshot\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: now().toISOString(),\n source: \"git-capability\",\n ...snapshot,\n });\n return snapshot;\n}\n\nasync function tryAppendFileChangedEvents(\n sessionDir: string,\n sessionId: string,\n repoRoot: string,\n baseRef: string,\n headRef: string,\n occurredAt: string,\n appendEvent: AppendEventFn,\n getDiffFn: GetDiffFn,\n): Promise<DiffResult | null> {\n // Stage 1: capability acquisition (same skip-vs-fail split as\n // tryAppendGitSnapshot).\n let diff: DiffResult;\n try {\n diff = await getDiffFn(repoRoot, baseRef, headRef);\n } catch (error: unknown) {\n console.warn(normalizeFileChangedSkipMessage(error));\n return null;\n }\n // Stage 2: per-path appendEvent. Schema validation / disk failures here\n // are NOT a capability miss; let them propagate.\n for (const change of diff.changed_files) {\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"file_changed\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: occurredAt,\n source: \"git-capability\",\n path: change.path,\n change_type: change.status,\n ...(change.old_path !== undefined ? { old_path: change.old_path } : {}),\n });\n }\n return diff;\n}\n\nfunction computeRelatedFiles(\n preSnapshot: GitSnapshot | null,\n postSnapshot: GitSnapshot | null,\n diff: DiffResult | null,\n): string[] {\n const set = new Set<string>();\n for (const snap of [preSnapshot, postSnapshot]) {\n if (snap === null) continue;\n for (const p of snap.staged) set.add(p);\n for (const p of snap.unstaged) set.add(p);\n for (const p of snap.untracked) set.add(p);\n }\n if (diff !== null) {\n for (const change of diff.changed_files) set.add(change.path);\n }\n return [...set].sort();\n}\n\nfunction normalizeGitSnapshotSkipMessage(error: unknown): string {\n if (!(error instanceof Error)) {\n return `git_snapshot skipped: ${String(error)}`;\n }\n const msg = error.message;\n if (msg === \"Not a git repository\") return \"git_snapshot skipped: not in a git repository\";\n if (msg === \"Git executable not found in PATH. Install git first.\") {\n return \"git_snapshot skipped: git executable not found\";\n }\n if (msg === \"No commits in repository\") return \"git_snapshot skipped: no commits in repository\";\n return `git_snapshot skipped: ${msg}`;\n}\n\nfunction normalizeFileChangedSkipMessage(error: unknown): string {\n if (!(error instanceof Error)) {\n return `file_changed skipped: ${String(error)}`;\n }\n const msg = error.message;\n if (msg === \"Not a git repository\") return \"file_changed skipped: not in a git repository\";\n if (msg === \"Git executable not found in PATH. Install git first.\") {\n return \"file_changed skipped: git executable not found\";\n }\n if (msg === \"Invalid ref\") return \"file_changed skipped: invalid git ref\";\n if (msg === \"Failed to compute git diff\")\n return \"file_changed skipped: failed to compute git diff\";\n return `file_changed skipped: ${msg}`;\n}\n\nfunction buildInitialSession(input: {\n id: PrefixedId<\"ses\">;\n command: string;\n args: string[];\n cwd: string;\n workspaceId: PrefixedId<\"ws\">;\n startedAt: string;\n}): Session {\n const cmdline = [input.command, ...input.args].join(\" \");\n return {\n schema_version: \"0.1.0\",\n session: {\n id: input.id,\n label: `basou run ${cmdline} (${input.startedAt})`,\n task_id: null,\n workspace_id: input.workspaceId,\n source: { ...claudeCodeAdapterMetadata },\n started_at: input.startedAt,\n status: \"initialized\",\n working_directory: sanitizeWorkingDirectory(input.cwd, { homedir: homedir() }),\n invocation: {\n command: input.command,\n args: [...input.args],\n exit_code: null,\n },\n related_files: [],\n events_log: \"events.jsonl\",\n },\n };\n}\n\nasync function mutateSessionYaml(\n filePath: string,\n mutator: (session: Session) => void,\n): Promise<void> {\n const raw = await readYamlFile(filePath);\n const parsed = SessionSchema.parse(raw);\n mutator(parsed);\n const validated = SessionSchema.parse(parsed);\n await overwriteYamlFile(filePath, validated);\n}\n\nasync function finalizeSessionAsFailed(\n sessionDir: string,\n sessionYamlPath: string,\n sessionId: string,\n appendEvent: AppendEventFn,\n ctx: {\n command: string;\n args: string[];\n cwd: string;\n occurredAt: string;\n signalReceived: NodeJS.Signals | null;\n },\n): Promise<void> {\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"command_executed\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: ctx.occurredAt,\n source: \"terminal-recording\",\n command: ctx.command,\n args: ctx.args,\n cwd: ctx.cwd,\n exit_code: null,\n signal: null,\n ...(ctx.signalReceived !== null ? { received_signal: ctx.signalReceived } : {}),\n duration_ms: 0,\n });\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"session_status_changed\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: ctx.occurredAt,\n source: claudeCodeAdapterMetadata.kind,\n from: \"running\",\n to: \"failed\",\n });\n await appendEvent(sessionDir, {\n schema_version: \"0.1.0\",\n type: \"session_ended\",\n id: prefixedUlid(\"evt\"),\n session_id: sessionId,\n occurred_at: ctx.occurredAt,\n source: claudeCodeAdapterMetadata.kind,\n });\n await mutateSessionYaml(sessionYamlPath, (s) => {\n s.session.status = \"failed\";\n s.session.ended_at = ctx.occurredAt;\n s.session.invocation.exit_code = null;\n });\n}\n\nasync function resolveRepositoryRootForRun(cwd: string): Promise<string> {\n try {\n return await resolveRepositoryRoot(cwd);\n } catch (error: unknown) {\n if (error instanceof Error && error.message === \"Not a git repository\") {\n throw new Error(\"Not a git repository. Run 'git init' first, then re-run 'basou run'.\", {\n cause: error,\n });\n }\n throw error;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { basename, isAbsolute, join, relative } from \"node:path\";\nimport {\n type Event,\n type ImportSessionOptions,\n type ImportSessionResult,\n type Session,\n SessionImportPayloadSchema,\n SessionSchema,\n type SessionStatus,\n SessionStatusSchema,\n acquireLock,\n appendEventToExistingSession,\n assertBasouRootSafe,\n basouPaths,\n findErrorCode,\n importSessionFromJson,\n loadSessionEntries,\n readAllEvents,\n readManifest,\n readYamlFile,\n resolveRepositoryRoot,\n resolveSessionId,\n resolveTaskId,\n} from \"@basou/core\";\nimport { type Command, InvalidArgumentError } from \"commander\";\nimport {\n isVerbose,\n printReplayWarning,\n printSessionListSkip,\n renderCliError,\n} from \"../lib/error-render.js\";\n\nconst SES_PREFIX = \"ses_\";\nconst TASK_PREFIX = \"task_\";\nconst SHORT_ID_BASE_LEN = 6;\nconst SHORT_ID_MAX_LEN = 26; // ULID body length\n\nconst STATUS_VALUES = SessionStatusSchema.options;\n\nexport type SessionListOptions = {\n json?: boolean;\n status?: SessionStatus;\n verbose?: boolean;\n};\n\nexport type SessionShowOptions = {\n json?: boolean;\n events?: boolean;\n last?: number;\n fullPath?: boolean;\n verbose?: boolean;\n};\n\nexport type SessionContext = {\n /** Defaults to `process.cwd()`. Injectable for tests. */\n cwd?: string;\n};\n\ntype SessionListRecord = {\n sessionId: string;\n session: Session;\n suspect: boolean;\n suspectReason: string | null;\n};\n\n/**\n * Wire `basou session list` and `basou session show <id>` onto `program`.\n *\n * The `session` group is registered up front so future subcommands\n * (`note`, `import`) added in later steps slot under the same group without\n * changing the externally visible CLI surface.\n */\nexport function registerSessionCommand(program: Command): void {\n const session = program\n .command(\"session\")\n .description(\"Inspect Basou sessions stored under .basou/sessions/\");\n\n session\n .command(\"list\")\n .description(\"List sessions in the current workspace (newest first)\")\n .option(\"--json\", \"Output the list as a JSON array\")\n .option(\n \"--status <state>\",\n `Filter by session status (one of: ${STATUS_VALUES.join(\", \")})`,\n parseSessionStatus,\n )\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (options: SessionListOptions) => {\n await runSessionList(options);\n });\n\n session\n .command(\"show <id>\")\n .description(\"Show a session's metadata and recent events\")\n .option(\"--json\", \"Output the session and events as JSON\")\n .option(\"--events\", \"List all events instead of just the trailing few\")\n .option(\"--last <n>\", \"Number of trailing events to display (default: 5)\", parsePositiveInt)\n .option(\n \"--full-path\",\n \"Show working_directory as an absolute path instead of repository-relative\",\n )\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (id: string, options: SessionShowOptions) => {\n await runSessionShow(id, options);\n });\n\n session\n .command(\"import\")\n .description(\"Import a session from a JSON file\")\n .requiredOption(\"--format <format>\", \"Input format (currently only 'json')\", parseImportFormat)\n .requiredOption(\"--from <path>\", \"Path to the input JSON file\")\n .option(\"--label <text>\", \"Override the session label\", parseLabelOverride)\n .option(\"--task <task_id>\", \"Override the session task_id\", parseTaskIdOverride)\n .option(\"--dry-run\", \"Validate input only; do not write to disk\")\n .option(\"--json\", \"Output the result as JSON\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (options: SessionImportOptions) => {\n await runSessionImport(options);\n });\n\n session\n .command(\"note <session_id>\")\n .description(\"Append a note_added event to an existing session\")\n .option(\"--body <text>\", \"Note body (inline)\", parseNoteBodyOption)\n .option(\"--from-file <path>\", \"Read note body from a file\")\n .option(\"--json\", \"Output the result as JSON\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (sessionIdInput: string, options: SessionNoteOptions) => {\n await runSessionNote(sessionIdInput, options);\n });\n}\n\n/**\n * Programmatic entry for `basou session list` that owns process exit state.\n * Tests targeting only the success path or the thrown error should prefer\n * {@link doRunSessionList}.\n */\nexport async function runSessionList(\n options: SessionListOptions,\n ctx: SessionContext = {},\n): Promise<void> {\n try {\n await doRunSessionList(options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options) });\n process.exitCode = 1;\n }\n}\n\n/**\n * Pure runner for `session list`. Throws on any failure with a pathless\n * message; native errors are attached as `cause` for verbose surfacing.\n */\nexport async function doRunSessionList(\n options: SessionListOptions,\n ctx: SessionContext,\n): Promise<void> {\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForSession(cwd, \"list\");\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n\n // Orchestration is delegated to core's `loadSessionEntries`. To preserve\n // the existing stderr surface (\"Skipped <sid>: <reason>\" and\n // \"Warning: skipped suspect check for <sid>: events.jsonl unreadable\"),\n // map onSkip / onWarning on the CLI side.\n const now = new Date();\n const records: SessionListRecord[] = (\n await loadSessionEntries(paths, {\n now,\n onWarning: (w, sid) => printReplayWarning(w, sid),\n onSkip: (sid, reason) => printSessionListSkip(sid, reason),\n })\n ).map((entry) => ({\n sessionId: entry.sessionId,\n session: entry.session,\n suspect: entry.suspect,\n suspectReason: entry.suspectReason,\n }));\n\n if (records.length === 0) {\n printNoSessions(options);\n return;\n }\n\n // started_at desc using Date.parse to normalize across timezone offsets;\n // a lexicographic compare would swap two timestamps that point at the same\n // instant when their offsets differ.\n records.sort(\n (a, b) => Date.parse(b.session.session.started_at) - Date.parse(a.session.session.started_at),\n );\n\n const filtered =\n options.status !== undefined\n ? records.filter((r) => r.session.session.status === options.status)\n : records;\n\n if (filtered.length === 0) {\n printNoSessions(options);\n return;\n }\n\n if (options.json === true) {\n console.log(\n JSON.stringify(\n filtered.map((r) => ({\n ...r.session.session,\n suspect: r.suspect,\n suspect_reason: r.suspectReason,\n })),\n null,\n 2,\n ),\n );\n } else {\n printSessionListText(filtered);\n }\n}\n\n/**\n * Programmatic entry for `basou session show <id>`. See {@link runSessionList}\n * for the split pattern rationale.\n */\nexport async function runSessionShow(\n idInput: string,\n options: SessionShowOptions,\n ctx: SessionContext = {},\n): Promise<void> {\n try {\n await doRunSessionShow(idInput, options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options) });\n process.exitCode = 1;\n }\n}\n\nexport async function doRunSessionShow(\n idInput: string,\n options: SessionShowOptions,\n ctx: SessionContext,\n): Promise<void> {\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForSession(cwd, \"show\");\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n\n const sessionId = await resolveSessionId(paths, idInput);\n\n const sessionDir = join(paths.sessions, sessionId);\n const sessionYamlPath = join(sessionDir, \"session.yaml\");\n let session: Session;\n try {\n const raw = await readYamlFile(sessionYamlPath);\n session = SessionSchema.parse(raw);\n } catch (error: unknown) {\n if (findErrorCode(error, \"ENOENT\")) {\n throw new Error(`Session not found: ${idInput}`);\n }\n throw new Error(\"Failed to read session\", { cause: error });\n }\n\n const events = await readAllEvents(sessionDir, {\n onWarning: (w) => printReplayWarning(w, sessionId),\n });\n\n if (options.json === true) {\n console.log(JSON.stringify({ session: session.session, events }, null, 2));\n return;\n }\n\n printSessionShowText(session, events, options, repositoryRoot);\n}\n\nfunction suspectLabel(reason: string | null): string {\n if (reason === \"events_say_ended_but_yaml_running\") return \" ⚠ ended (yaml stale)\";\n if (reason === \"running_no_end_event\") return \" ⚠ no end event\";\n return \"\";\n}\n\nfunction printSessionListText(records: SessionListRecord[]): void {\n // Grow the SHORT_ID column to the first length where every prefix is\n // unique. Without this an ambiguous prefix would copy-paste from the list\n // and fail `resolveSessionId` with \"Ambiguous session id\".\n const shortLen = computeUniquePrefixLen(records.map((r) => r.sessionId));\n const rows = records.map((r) => {\n const sid = sliceShort(r.sessionId, shortLen);\n const status = `${r.session.session.status}${suspectLabel(r.suspectReason)}`;\n const source = r.session.session.source.kind;\n const startedAt = r.session.session.started_at;\n const fileCount = r.session.session.related_files.length;\n const filesSuffix = fileCount > 0 ? ` (${fileCount} files)` : \"\";\n const label = (r.session.session.label ?? \"\") + filesSuffix;\n return { sid, status, source, startedAt, label };\n });\n\n const widths = {\n sid: maxLen(\n rows.map((r) => r.sid),\n \"SHORT_ID\".length,\n ),\n status: maxLen(\n rows.map((r) => r.status),\n \"STATUS\".length,\n ),\n source: maxLen(\n rows.map((r) => r.source),\n \"SOURCE\".length,\n ),\n startedAt: maxLen(\n rows.map((r) => r.startedAt),\n \"STARTED_AT\".length,\n ),\n };\n\n console.log(\n `${pad(\"SHORT_ID\", widths.sid)} ${pad(\"STATUS\", widths.status)} ${pad(\"SOURCE\", widths.source)} ${pad(\"STARTED_AT\", widths.startedAt)} LABEL`,\n );\n for (const row of rows) {\n console.log(\n `${pad(row.sid, widths.sid)} ${pad(row.status, widths.status)} ${pad(row.source, widths.source)} ${pad(row.startedAt, widths.startedAt)} ${row.label}`,\n );\n }\n}\n\nfunction printSessionShowText(\n session: Session,\n events: Event[],\n options: SessionShowOptions,\n repositoryRoot: string,\n): void {\n const s = session.session;\n console.log(`Session: ${s.id} (status: ${s.status})`);\n console.log(`Source: ${s.source.kind} (v${s.source.version})`);\n console.log(`Workspace: ${s.workspace_id}`);\n console.log(`Started at: ${s.started_at}`);\n if (s.ended_at !== undefined) {\n console.log(`Ended at: ${s.ended_at}`);\n }\n console.log(`Working dir: ${formatWorkingDir(s.working_directory, repositoryRoot, options)}`);\n const invocationArgs = s.invocation.args.length > 0 ? ` ${s.invocation.args.join(\" \")}` : \"\";\n console.log(`Invocation: ${s.invocation.command}${invocationArgs}`);\n if (s.invocation.exit_code !== null) {\n console.log(`Exit code: ${s.invocation.exit_code}`);\n }\n if (s.label !== undefined) {\n console.log(`Label: ${s.label}`);\n }\n console.log(`Related files: ${formatRelatedFiles(s.related_files)}`);\n\n console.log(\"\");\n console.log(`Events: ${events.length} total`);\n const counts = countByType(events);\n for (const [type, n] of counts) {\n console.log(` ${pad(`${type}:`, 24)} ${n}`);\n }\n\n if (events.length === 0) return;\n\n const last = options.last ?? 5;\n const showAll = options.events === true && options.last === undefined;\n const slice = showAll ? events : events.slice(-last);\n const heading = showAll ? \"All events:\" : `Last ${slice.length} events:`;\n console.log(\"\");\n console.log(heading);\n for (const ev of slice) {\n console.log(` ${formatEventLine(ev)}`);\n }\n}\n\nfunction formatWorkingDir(\n workingDir: string,\n repositoryRoot: string,\n options: SessionShowOptions,\n): string {\n if (options.fullPath === true) return workingDir;\n\n // v0.3 sanitized sessions write `working_directory` as a relative form\n // (`~/projects/foo`, `src/sub`, `.`, etc.) rather than the absolute\n // path the older write paths used. path.relative against a relative\n // input would silently resolve it against process.cwd and produce\n // nonsense like `<cwd>/~/projects/foo`, so the relative form must be\n // surfaced verbatim. The one literal we collapse is `.`, which means\n // \"the session ran at the repo root\" — same semantic as an absolute\n // workingDir equal to repositoryRoot.\n if (!isAbsolute(workingDir)) {\n if (workingDir === \".\") return \"<repository_root>\";\n return workingDir;\n }\n\n if (workingDir === repositoryRoot) return \"<repository_root>\";\n const rel = relative(repositoryRoot, workingDir);\n if (rel.length === 0 || rel === \".\") return \"<repository_root>\";\n // Outside-repo working directories surface as a `../...` relative path\n // rather than the absolute path so the default-display contract holds\n // even for sessions recorded from a sibling checkout. `--full-path` is\n // the explicit opt-in for the absolute form.\n if (rel.startsWith(\"..\")) return rel;\n return `./${rel}`;\n}\n\nfunction formatRelatedFiles(files: readonly string[]): string {\n if (files.length === 0) return \"0 paths\";\n const head = files.slice(0, 3).join(\", \");\n const remaining = files.length - 3;\n if (remaining <= 0) return `${files.length} paths (${head})`;\n return `${files.length} paths (${head}, ... +${remaining} more)`;\n}\n\nfunction countByType(events: readonly Event[]): Array<[string, number]> {\n const map = new Map<string, number>();\n for (const ev of events) {\n map.set(ev.type, (map.get(ev.type) ?? 0) + 1);\n }\n return [...map.entries()];\n}\n\nfunction formatEventLine(ev: Event): string {\n return `${ev.occurred_at} [${ev.source}] ${ev.type} ${eventVariantSummary(ev)}`;\n}\n\nfunction eventVariantSummary(ev: Event): string {\n switch (ev.type) {\n case \"command_executed\": {\n const argsPart = ev.args.length > 0 ? ` ${ev.args.join(\" \")}` : \"\";\n const exitPart = ev.exit_code === null ? \"exit=signal\" : `exit=${ev.exit_code}`;\n return `${ev.command}${argsPart} (${exitPart}, ${ev.duration_ms}ms)`;\n }\n case \"git_snapshot\":\n return `branch=${ev.branch} dirty=${ev.dirty}`;\n case \"file_changed\":\n return `${ev.change_type} ${ev.path}`;\n case \"session_status_changed\":\n return `${ev.from} -> ${ev.to}`;\n case \"session_started\":\n return \"(start)\";\n case \"session_ended\":\n return ev.exit_code !== undefined ? `exit_code=${ev.exit_code}` : \"(end)\";\n case \"approval_requested\":\n return `${ev.action.kind} risk=${ev.risk_level}`;\n case \"approval_approved\":\n return ev.resolver !== undefined ? `by ${ev.resolver}` : \"(approved)\";\n case \"approval_rejected\":\n return ev.resolver !== undefined ? `by ${ev.resolver}: ${ev.reason}` : ev.reason;\n case \"approval_expired\":\n return `approval=${ev.approval_id}`;\n case \"decision_recorded\":\n return ev.title;\n case \"task_created\":\n return ev.title;\n case \"task_status_changed\":\n return `${ev.from} -> ${ev.to}`;\n case \"task_reconciled\": {\n const createdPart =\n ev.removed_created_in_session !== null ? \"1 created_in_session\" : \"0 created_in_session\";\n return `task ${shortTaskId(ev.task_id)}: cleared ${ev.removed_linked_sessions.length} linked + ${createdPart}`;\n }\n case \"task_linkage_refreshed\": {\n const added = ev.added_linked_sessions.length;\n const removed = ev.removed_linked_sessions.length;\n const final = ev.final_count !== undefined ? ` final=${ev.final_count}` : \"\";\n return `task ${shortTaskId(ev.task_id)}: +${added} / -${removed} linked${final}`;\n }\n case \"task_deleted\":\n return `task ${shortTaskId(ev.task_id)}: ${ev.title} (deleted)`;\n case \"task_archived\":\n return `task ${shortTaskId(ev.task_id)}: ${ev.title} (archived)`;\n case \"note_added\":\n return ev.body.length > 80 ? `${ev.body.slice(0, 77)}...` : ev.body;\n case \"adapter_output\":\n return `${ev.stream} \"${ev.summary}\" raw_ref=${ev.raw_ref}`;\n }\n}\n\nfunction shortId(id: string): string {\n return sliceShort(id, SHORT_ID_BASE_LEN);\n}\n\nfunction shortTaskId(id: string): string {\n if (id.startsWith(TASK_PREFIX)) {\n return id.slice(TASK_PREFIX.length, TASK_PREFIX.length + SHORT_ID_BASE_LEN);\n }\n return id.slice(0, SHORT_ID_BASE_LEN);\n}\n\nfunction sliceShort(id: string, len: number): string {\n if (id.startsWith(SES_PREFIX)) {\n return id.slice(SES_PREFIX.length, SES_PREFIX.length + len);\n }\n return id.slice(0, len);\n}\n\n/**\n * Find the smallest length where every short_id derived from `sessionIds`\n * is unique. Starts at {@link SHORT_ID_BASE_LEN} and grows by 2 chars at a\n * time (mirroring git's automatic abbreviation behaviour). Caps at the full\n * ULID body length so a pathological collision still terminates.\n */\nfunction computeUniquePrefixLen(sessionIds: readonly string[]): number {\n if (sessionIds.length <= 1) return SHORT_ID_BASE_LEN;\n for (let len = SHORT_ID_BASE_LEN; len <= SHORT_ID_MAX_LEN; len += 2) {\n const seen = new Set<string>();\n let collided = false;\n for (const sid of sessionIds) {\n const key = sliceShort(sid, len);\n if (seen.has(key)) {\n collided = true;\n break;\n }\n seen.add(key);\n }\n if (!collided) return len;\n }\n return SHORT_ID_MAX_LEN;\n}\n\nfunction pad(value: string, width: number): string {\n return value.length >= width ? value : value + \" \".repeat(width - value.length);\n}\n\nfunction maxLen(values: readonly string[], floor: number): number {\n let max = floor;\n for (const v of values) if (v.length > max) max = v.length;\n return max;\n}\n\nasync function resolveRepositoryRootForSession(\n cwd: string,\n subcmd: \"list\" | \"show\" | \"import\" | \"note\",\n): Promise<string> {\n try {\n return await resolveRepositoryRoot(cwd);\n } catch (error: unknown) {\n if (error instanceof Error && error.message === \"Not a git repository\") {\n throw new Error(\n `Not a git repository. Run 'git init' first, then re-run 'basou session ${subcmd}'.`,\n { cause: error },\n );\n }\n throw error;\n }\n}\n\nasync function assertWorkspaceInitialized(basouRoot: string): Promise<void> {\n try {\n await assertBasouRootSafe(basouRoot);\n } catch (error: unknown) {\n if (findErrorCode(error, \"ENOENT\")) {\n throw new Error(\"Workspace not initialized. Run 'basou init' first.\");\n }\n throw error;\n }\n}\n\nfunction parsePositiveInt(raw: string): number {\n const n = Number.parseInt(raw, 10);\n if (!Number.isInteger(n) || n < 1 || raw.trim() !== String(n)) {\n throw new Error(`Invalid number: ${raw}`);\n }\n return n;\n}\n\nfunction parseSessionStatus(raw: string): SessionStatus {\n const result = SessionStatusSchema.safeParse(raw);\n if (!result.success) {\n throw new Error(`Invalid session status: ${raw}. Valid values: ${STATUS_VALUES.join(\", \")}`);\n }\n return result.data;\n}\n\nfunction printNoSessions(options: SessionListOptions): void {\n if (options.json === true) {\n console.log(\"[]\");\n } else {\n console.log(\"No sessions found.\");\n }\n}\n\n// ----------------------------------------------------------------------------\n// session import (Step 15)\n// ----------------------------------------------------------------------------\n\nexport type SessionImportOptions = {\n format: \"json\";\n from: string;\n label?: string;\n task?: string;\n dryRun?: boolean;\n json?: boolean;\n verbose?: boolean;\n};\n\n/**\n * Programmatic entry for `basou session import`. Mirrors the wrapper /\n * pure-runner split used by list / show so tests can target either layer.\n */\nexport async function runSessionImport(\n options: SessionImportOptions,\n ctx: SessionContext = {},\n): Promise<void> {\n try {\n await doRunSessionImport(options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options) });\n process.exitCode = 1;\n }\n}\n\nexport async function doRunSessionImport(\n options: SessionImportOptions,\n ctx: SessionContext,\n): Promise<void> {\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForSession(cwd, \"import\");\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n\n const manifest = await readManifest(paths);\n\n const rawBody = await readInputFile(options.from);\n const json = parseJsonStrict(rawBody);\n\n const parsed = SessionImportPayloadSchema.safeParse(json);\n if (!parsed.success) {\n throw new Error(\"Invalid import payload\", { cause: parsed.error });\n }\n\n if (parsed.data.schema_version !== \"0.1.0\") {\n throw new Error(`Unsupported import schema_version: ${parsed.data.schema_version}`);\n }\n\n const importOptions: ImportSessionOptions = { dryRun: options.dryRun === true };\n if (options.label !== undefined) importOptions.labelOverride = options.label;\n if (options.task !== undefined) {\n importOptions.taskIdOverride = await resolveTaskId(paths, options.task);\n }\n\n const result = await importSessionFromJson(paths, manifest, parsed.data, importOptions);\n\n // Path sanitize visibility: the importer rewrites absolute / homedir\n // prefixes inside related_files[] and working_directory so the operator-\n // private layout does not leak into local state. Surface a single-line\n // warning when anything was actually rewritten — silence on zero so the\n // happy path stays quiet. The warning fires for dry-run too so the\n // operator can preview the rewrite before committing.\n const sanitizeReport = result.pathSanitizeReport;\n if (sanitizeReport.relatedFiles > 0 || sanitizeReport.workingDirectoryRewritten) {\n const wdCount = sanitizeReport.workingDirectoryRewritten ? 1 : 0;\n console.error(\n `Imported session: ${sanitizeReport.relatedFiles + wdCount} path(s) sanitized (related_files: ${sanitizeReport.relatedFiles}, working_directory: ${wdCount})`,\n );\n }\n\n printSessionImportResult(options, result);\n}\n\nasync function readInputFile(path: string): Promise<string> {\n try {\n return await readFile(path, \"utf8\");\n } catch (error: unknown) {\n if (findErrorCode(error, \"ENOENT\")) {\n throw new Error(\"Import source not found\", { cause: error });\n }\n if (findErrorCode(error, \"EISDIR\")) {\n throw new Error(\"Import source is not a file\", { cause: error });\n }\n throw new Error(\"Failed to read import source\", { cause: error });\n }\n}\n\nfunction parseJsonStrict(body: string): unknown {\n try {\n return JSON.parse(body);\n } catch (error: unknown) {\n throw new Error(\"Failed to parse import JSON\", { cause: error });\n }\n}\n\nfunction parseImportFormat(raw: string): \"json\" {\n if (raw !== \"json\") {\n throw new InvalidArgumentError(`Unsupported format: ${raw}. Valid values: json`);\n }\n return \"json\";\n}\n\nfunction parseLabelOverride(raw: string): string {\n if (raw.length === 0) {\n throw new InvalidArgumentError(\"Label must not be empty\");\n }\n return raw;\n}\n\nfunction parseTaskIdOverride(raw: string): string {\n if (raw.length === 0) {\n throw new InvalidArgumentError(\"Task id is empty\");\n }\n return raw;\n}\n\nfunction printSessionImportResult(\n options: SessionImportOptions,\n result: ImportSessionResult,\n): void {\n const isDry = options.dryRun === true;\n const sid = shortId(result.sessionId);\n if (options.json === true) {\n console.log(\n JSON.stringify({\n session_id: result.sessionId,\n event_count: result.eventCount,\n dry_run: isDry,\n source: { kind: result.finalSourceKind, version: \"0.1.0\" },\n status: result.finalStatus,\n }),\n );\n return;\n }\n\n if (isDry) {\n console.log(\n `Dry run: would import ${result.eventCount} events into ${sid} (illustrative ID; not reserved, no files written)`,\n );\n return;\n }\n\n console.log(\n `Imported session ${sid} (${result.eventCount} events) from ${basename(options.from)}`,\n );\n}\n\n// ----------------------------------------------------------------------------\n// session note (Step 16)\n// ----------------------------------------------------------------------------\n\nconst NOTE_BODY_PREVIEW_LIMIT = 80;\nconst NOTE_BODY_PREVIEW_HEAD = 77;\n\nexport type SessionNoteOptions = {\n body?: string;\n fromFile?: string;\n json?: boolean;\n verbose?: boolean;\n};\n\n/**\n * Programmatic entry for `basou session note <session_id>`. Appends a single\n * `note_added` event to an existing attachable session. `session.yaml` is\n * deliberately NOT modified.\n */\nexport async function runSessionNote(\n sessionIdInput: string,\n options: SessionNoteOptions,\n ctx: SessionContext = {},\n): Promise<void> {\n try {\n await doRunSessionNote(sessionIdInput, options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options) });\n process.exitCode = 1;\n }\n}\n\nexport async function doRunSessionNote(\n sessionIdInput: string,\n options: SessionNoteOptions,\n ctx: SessionContext,\n): Promise<void> {\n const hasBody = options.body !== undefined;\n const hasFromFile = options.fromFile !== undefined;\n if (!hasBody && !hasFromFile) {\n throw new Error(\"Provide --body or --from-file\");\n }\n if (hasBody && hasFromFile) {\n throw new Error(\"--body and --from-file are mutually exclusive\");\n }\n // The stdin pipe path is not supported in v0.1. Surface a dedicated\n // pathless error before any disk I/O so the failure mode is obvious.\n if (hasFromFile && options.fromFile === \"-\") {\n throw new Error(\"--from-file - (stdin) is not supported in v0.1\");\n }\n\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForSession(cwd, \"note\");\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n\n const sessionId = await resolveSessionId(paths, sessionIdInput);\n\n const body = hasBody ? (options.body as string) : await readNoteFile(options.fromFile as string);\n if (body.length === 0) {\n throw new Error(\"Note body is empty\");\n }\n\n const occurredAt = new Date().toISOString();\n const sesId = sessionId as `ses_${string}`;\n\n // Per-session lock guards the events.jsonl append + status read window\n // against a concurrent writer (decision record / task attach / another\n // session note on the same id). The lock is the caller's responsibility:\n // appendEventToExistingSession holds no lock so we can compose larger\n // critical sections (e.g. attach-flavoured task commands) under the same\n // lock without re-entrant deadlock.\n const sessionLock = await acquireLock(paths, \"session\", sesId);\n let result: Awaited<ReturnType<typeof appendEventToExistingSession>>;\n try {\n result = await appendEventToExistingSession({\n paths,\n sessionId: sesId,\n eventBuilder: (eventId) =>\n ({\n schema_version: \"0.1.0\",\n id: eventId,\n session_id: sesId,\n occurred_at: occurredAt,\n source: \"local-cli\",\n type: \"note_added\",\n body,\n }) as Event,\n });\n } finally {\n await sessionLock.release();\n }\n\n printSessionNoteResult(options, sessionId, result.eventId, result.sessionStatus, body);\n}\n\nasync function readNoteFile(path: string): Promise<string> {\n try {\n return await readFile(path, \"utf8\");\n } catch (error: unknown) {\n if (findErrorCode(error, \"ENOENT\")) {\n throw new Error(\"Note source not found\", { cause: error });\n }\n if (findErrorCode(error, \"EISDIR\")) {\n throw new Error(\"Note source is not a file\", { cause: error });\n }\n throw new Error(\"Failed to read note source\", { cause: error });\n }\n}\n\nfunction parseNoteBodyOption(raw: string): string {\n if (raw.length === 0) {\n throw new InvalidArgumentError(\"--body must not be empty\");\n }\n return raw;\n}\n\nfunction printSessionNoteResult(\n options: SessionNoteOptions,\n sessionId: string,\n eventId: string,\n sessionStatus: SessionStatus,\n body: string,\n): void {\n const sid = shortId(sessionId);\n if (options.json === true) {\n console.log(\n JSON.stringify({\n event_id: eventId,\n session_id: sessionId,\n session_status: sessionStatus,\n body_length: body.length,\n }),\n );\n return;\n }\n const preview =\n body.length > NOTE_BODY_PREVIEW_LIMIT ? `${body.slice(0, NOTE_BODY_PREVIEW_HEAD)}...` : body;\n console.log(`Added note to session ${sid} (${sessionStatus}): ${preview}`);\n}\n","import {\n type Manifest,\n type StatusSnapshot,\n assertBasouRootSafe,\n basouPaths,\n buildStatusSnapshot,\n findErrorCode,\n readManifest,\n resolveRepositoryRoot,\n writeStatus,\n} from \"@basou/core\";\nimport type { Command } from \"commander\";\nimport { isVerbose, renderCliError } from \"../lib/error-render.js\";\n\nexport type StatusOptions = {\n json?: boolean;\n verbose?: boolean;\n};\n\nexport type StatusContext = {\n /** Defaults to `process.cwd()`. Injectable for tests. */\n cwd?: string;\n};\n\n/**\n * Register `basou status` on a commander program. The command outputs a\n * human-readable summary by default, or a JSON document when `--json` is\n * given. In both modes `.basou/status.json` is rewritten as a side effect.\n */\nexport function registerStatusCommand(program: Command): void {\n program\n .command(\"status\")\n .description(\"Show the current Basou workspace status\")\n .option(\"--json\", \"Output the snapshot as JSON to stdout\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (options: StatusOptions) => {\n await runStatus(options);\n });\n}\n\n/**\n * Programmatic entry that mutates process state (`exitCode`, stderr).\n * Exported for tests, but tests should prefer {@link doRunStatus} when they\n * only need to assert on success behaviour or thrown errors.\n */\nexport async function runStatus(options: StatusOptions, ctx: StatusContext = {}): Promise<void> {\n try {\n await doRunStatus(options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options) });\n process.exitCode = 1;\n }\n}\n\n/**\n * Pure runner: resolves inputs, performs the status snapshot, writes\n * `status.json`, and prints output. On any failure throws an Error whose\n * `message` is pathless; native fs / parse errors are attached as `cause`.\n * Exported for tests so they can assert on thrown errors without touching\n * `process.exitCode`.\n */\nexport async function doRunStatus(options: StatusOptions, ctx: StatusContext): Promise<void> {\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForStatus(cwd);\n const paths = basouPaths(repositoryRoot);\n\n // Pre-condition: refuse to operate on a swapped/non-directory .basou root\n // before we ever touch a file. Treat ENOENT (root absent) the same way as\n // a missing manifest below — both mean \"workspace not initialized\".\n try {\n await assertBasouRootSafe(paths.root);\n } catch (error: unknown) {\n if (findErrorCode(error, \"ENOENT\")) {\n throw new Error(\"Workspace not initialized. Run 'basou init' first.\");\n }\n throw error;\n }\n\n let manifest: Manifest;\n try {\n manifest = await readManifest(paths);\n } catch (error: unknown) {\n if (findErrorCode(error, \"ENOENT\")) {\n throw new Error(\"Workspace not initialized. Run 'basou init' first.\");\n }\n // ZodError's `message` echoes invalid input values verbatim, which can\n // include path-like strings if a user-edited manifest contains them.\n // Wrap in a fixed pathless message and surface only the cause's\n // constructor name in verbose mode via the shared renderCliError helper.\n throw new Error(\"Failed to read workspace manifest\", { cause: error });\n }\n\n const snapshot = await buildStatusSnapshot({ manifest, paths });\n await writeStatus(paths, snapshot);\n\n if (options.json === true) {\n console.log(JSON.stringify(snapshot, null, 2));\n } else {\n renderTextStatus(snapshot);\n }\n}\n\nfunction renderTextStatus(s: StatusSnapshot): void {\n console.log(`Workspace: ${s.workspace.name} (${s.workspace.id})`);\n // The label changed from \"Basou version\" to \"Spec version\" in v0.3.1\n // because the field tracks the workspace data-format spec\n // (`basou_version` literal-locked to \"0.1.0\") and was repeatedly\n // mistaken for the release version returned by `basou --version`. The\n // wire payload field name (= `workspace.basou_version`) stays the same\n // so JSON consumers are unaffected; only the human-readable label\n // moves.\n console.log(`Spec version: ${s.workspace.basou_version}`);\n console.log(`Generated at: ${s.generated_at}`);\n const dp = s.directories_present;\n const total = Object.keys(dp).length;\n const present = Object.values(dp).filter((v) => v === true).length;\n console.log(`Subdirectories present: ${present}/${total}`);\n}\n\n/**\n * Wrap the core git capability so the CLI surfaces the command-specific\n * \"Run 'git init' first, then re-run 'basou status'.\" suffix while the\n * capability layer remains command-agnostic.\n */\nasync function resolveRepositoryRootForStatus(cwd: string): Promise<string> {\n try {\n return await resolveRepositoryRoot(cwd);\n } catch (error: unknown) {\n if (error instanceof Error && error.message === \"Not a git repository\") {\n throw new Error(\"Not a git repository. Run 'git init' first, then re-run 'basou status'.\", {\n cause: error,\n });\n }\n throw error;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n type Event,\n type PrefixedId,\n type ReconcileFailure,\n type ReconcileResult,\n type RefreshLinkageResult,\n type SessionEntry,\n type SessionStatus,\n type TaskDocument,\n type TaskReconciledEvent,\n type TaskStatus,\n TaskStatusSchema,\n TaskWriteAfterEventError,\n archiveTask,\n assertBasouRootSafe,\n basouPaths,\n createTaskWithEvent,\n deleteTask,\n editTask,\n enumerateArchivedTaskIds,\n findErrorCode,\n loadSessionEntries,\n loadTaskEntries,\n prefixedUlid,\n readManifest,\n readTaskFile,\n readTaskFileWithArchiveFallback,\n reconcileAllTasks,\n reconcileTask,\n refreshTaskLinkedSessions,\n replayEvents,\n resolveRepositoryRoot,\n resolveSessionId,\n resolveTaskId,\n updateTaskStatusWithEvent,\n} from \"@basou/core\";\nimport { type Command, InvalidArgumentError } from \"commander\";\nimport {\n type ErrorClassifier,\n failedToFinalizeClassifier,\n isVerbose,\n printReplayWarning,\n printTaskSkip,\n renderCliError,\n shortSessionId,\n shortTaskId,\n} from \"../lib/error-render.js\";\n\nconst STATUS_VALUES = TaskStatusSchema.options;\n\n// ============================================================================\n// Public registration\n// ============================================================================\n\nexport type TaskNewOptions = {\n title: string;\n label?: string;\n status?: TaskStatus;\n /**\n * ISO-8601 timestamp written into `task.md.updated_at` when status is a\n * terminal value (done / cancelled). Lets the operator backdate a\n * retroactively-recorded completed task so `task.md` reflects the\n * actual completion moment while `events.jsonl` keeps recording time.\n * Rejected (exit 1) when supplied with a non-terminal status.\n */\n completedAt?: string;\n session?: string;\n description?: string;\n fromFile?: string;\n json?: boolean;\n verbose?: boolean;\n};\n\nexport type TaskListOptions = {\n status?: TaskStatus;\n includeArchived?: boolean;\n json?: boolean;\n verbose?: boolean;\n};\n\nexport type TaskShowOptions = {\n json?: boolean;\n events?: boolean;\n last?: number;\n verbose?: boolean;\n};\n\nexport type TaskStatusOptions = {\n session?: string;\n json?: boolean;\n verbose?: boolean;\n};\n\nexport type TaskReconcileOptions = {\n task?: string;\n write?: boolean;\n json?: boolean;\n verbose?: boolean;\n};\n\nexport type TaskRefreshLinkageOptions = {\n write?: boolean;\n json?: boolean;\n verbose?: boolean;\n};\n\nexport type TaskEditOptions = {\n title?: string;\n status?: TaskStatus;\n json?: boolean;\n verbose?: boolean;\n};\n\nexport type TaskDeleteOptions = {\n yes?: boolean;\n json?: boolean;\n verbose?: boolean;\n};\n\nexport type TaskArchiveOptions = {\n yes?: boolean;\n json?: boolean;\n verbose?: boolean;\n};\n\nexport type TaskContext = {\n /** Defaults to `process.cwd()`. Injectable for tests. */\n cwd?: string;\n /** Defaults to `() => new Date()`. Injectable for tests. */\n nowProvider?: () => Date;\n};\n\nexport function registerTaskCommand(program: Command): void {\n const task = program\n .command(\"task\")\n .description(\"Manage Basou tasks (purpose units that span sessions)\");\n\n task\n .command(\"new\")\n .description(\"Create a new task and fire a task_created event\")\n .requiredOption(\"--title <text>\", \"Task title\", parseTitle)\n .option(\"--label <text>\", \"Optional label for the task\", parseLabel)\n .option(\n \"--status <status>\",\n `Initial status (one of: ${STATUS_VALUES.join(\", \")}; default planned). For done/cancelled the orchestrator also emits a task_status_changed event so the audit trail records the implicit transition.`,\n parseInitialTaskStatus,\n )\n .option(\n \"--completed-at <iso>\",\n \"ISO-8601 timestamp to record as the task's updated_at when --status is done or cancelled (rejected otherwise)\",\n parseIsoTimestampOption,\n )\n .option(\"--session <session_id>\", \"Attach to existing session; otherwise ad-hoc\")\n .option(\"--description <text>\", \"Task description body (inline)\", parseDescriptionOption)\n .option(\"--from-file <path>\", \"Read description body from a file\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (options: TaskNewOptions) => {\n await runTaskNew(options);\n });\n\n task\n .command(\"list\")\n .description(\"List tasks in the current workspace (newest first)\")\n .option(\n \"--status <status>\",\n `Filter by task status (one of: ${STATUS_VALUES.join(\", \")})`,\n parseTaskStatusFilter,\n )\n .option(\"--include-archived\", \"Also list tasks under .basou/tasks/archive/ (hidden by default)\")\n .option(\"--json\", \"Output the list as a JSON array\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (options: TaskListOptions) => {\n await runTaskList(options);\n });\n\n task\n .command(\"show <task_id>\")\n .description(\"Show a task with its metadata, linked sessions, and events\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--events\", \"Show all related events instead of trailing few\")\n .option(\"--last <n>\", \"Number of trailing events to display (default: 5)\", parsePositiveInt)\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (id: string, options: TaskShowOptions) => {\n await runTaskShow(id, options);\n });\n\n task\n .command(\"status <task_id> <new_status>\")\n .description(\"Change task status and fire a task_status_changed event\")\n .option(\"--session <session_id>\", \"Attach to existing session; otherwise ad-hoc\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (taskIdInput: string, newStatusInput: string, options: TaskStatusOptions) => {\n await runTaskStatus(taskIdInput, newStatusInput, options);\n });\n\n task\n .command(\"reconcile\")\n .description(\n \"Dry-run audit of task session references; use --write to repair broken refs. Forward sync (events -> task.md linked_sessions) is out of scope.\",\n )\n .option(\"--task <task_id>\", \"Limit to a single task (otherwise scan all)\")\n .option(\"--write\", \"Apply repairs (default: dry-run)\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"-v, --verbose\", \"Show error causes and broken session_id values\")\n .action(async (options: TaskReconcileOptions) => {\n await runTaskReconcile(options);\n });\n\n task\n .command(\"refresh-linkage <task_id>\")\n .description(\n \"Re-derive task.md linked_sessions[] from session.yaml.task_id matches across the workspace (forward sync events -> task.md). Dry-run default; use --write to apply.\",\n )\n .option(\"--write\", \"Apply the refresh (default: dry-run)\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (taskIdInput: string, options: TaskRefreshLinkageOptions) => {\n await runTaskRefreshLinkage(taskIdInput, options);\n });\n\n task\n .command(\"edit <task_id>\")\n .description(\n \"Update --title and/or --status on an existing task. Status changes fire a task_status_changed event; title changes update task.md only (no event).\",\n )\n .option(\"--title <text>\", \"New title (must be non-empty)\", parseTitle)\n .option(\n \"--status <status>\",\n `New status (one of: ${STATUS_VALUES.join(\", \")}); routed through STATUS_TRANSITIONS so only valid edges are accepted`,\n parseInitialTaskStatus,\n )\n .option(\"--json\", \"Output as JSON\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (taskIdInput: string, options: TaskEditOptions) => {\n await runTaskEdit(taskIdInput, options);\n });\n\n task\n .command(\"delete <task_id>\")\n .description(\n \"Hard-delete a task.md file and fire a task_deleted event. Requires confirmation by default; use --yes to skip the prompt.\",\n )\n .option(\"--yes\", \"Skip the confirmation prompt (required when stdin is not a TTY)\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (taskIdInput: string, options: TaskDeleteOptions) => {\n await runTaskDelete(taskIdInput, options);\n });\n\n task\n .command(\"archive <task_id>\")\n .description(\n \"Move task.md into .basou/tasks/archive/ and fire a task_archived event. Requires confirmation by default; use --yes to skip the prompt.\",\n )\n .option(\"--yes\", \"Skip the confirmation prompt (required when stdin is not a TTY)\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"-v, --verbose\", \"Show error causes\")\n .action(async (taskIdInput: string, options: TaskArchiveOptions) => {\n await runTaskArchive(taskIdInput, options);\n });\n}\n\n// ============================================================================\n// task new\n// ============================================================================\n\nexport async function runTaskNew(options: TaskNewOptions, ctx: TaskContext = {}): Promise<void> {\n try {\n await doRunTaskNew(options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options), classifiers: TASK_CLASSIFIERS });\n process.exitCode = 1;\n }\n}\n\nexport async function doRunTaskNew(options: TaskNewOptions, ctx: TaskContext): Promise<void> {\n if (options.description !== undefined && options.fromFile !== undefined) {\n throw new Error(\"--description and --from-file are mutually exclusive\");\n }\n if (options.fromFile === \"-\") {\n throw new Error(\"--from-file - (stdin) is not supported in v0.1\");\n }\n\n const initialStatus = options.status ?? \"planned\";\n // `--completed-at` only makes sense paired with a terminal status. Catching\n // the mismatch up front avoids ambiguity about whether the override would\n // still be honored on a planned/in_progress task (= it wouldn't).\n if (options.completedAt !== undefined && !isTerminalStatusForCli(initialStatus)) {\n throw new Error(\"--completed-at requires --status done or cancelled\");\n }\n\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForTask(cwd, \"new\");\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n\n const description =\n options.description !== undefined\n ? options.description\n : options.fromFile !== undefined\n ? await readDescriptionFile(options.fromFile)\n : \"\";\n\n const now = ctx.nowProvider !== undefined ? ctx.nowProvider() : new Date();\n const occurredAt = now.toISOString();\n const taskId = prefixedUlid(\"task\");\n\n if (options.session !== undefined) {\n const sessionId = (await resolveSessionId(paths, options.session)) as PrefixedId<\"ses\">;\n const result = await createTaskWithEvent({\n mode: \"attach\",\n paths,\n occurredAt,\n sessionId,\n taskId,\n title: options.title,\n ...(options.label !== undefined ? { label: options.label } : {}),\n initialStatus,\n description,\n ...(options.completedAt !== undefined ? { completedAt: options.completedAt } : {}),\n });\n printTaskNewResult(options, {\n mode: \"attached\",\n taskId: result.taskId,\n eventId: result.eventId,\n sessionId: result.sessionId,\n sessionStatus: result.sessionStatus,\n title: options.title,\n ...(options.label !== undefined ? { label: options.label } : {}),\n status: initialStatus,\n occurredAt,\n ...(options.completedAt !== undefined ? { completedAt: options.completedAt } : {}),\n descriptionLength: description.length,\n });\n return;\n }\n\n const manifest = await readManifest(paths);\n const result = await createTaskWithEvent({\n mode: \"ad-hoc\",\n paths,\n manifest,\n occurredAt,\n taskId,\n title: options.title,\n ...(options.label !== undefined ? { label: options.label } : {}),\n initialStatus,\n description,\n workingDirectory: repositoryRoot,\n ...(options.completedAt !== undefined ? { completedAt: options.completedAt } : {}),\n });\n printTaskNewResult(options, {\n mode: \"ad-hoc\",\n taskId: result.taskId,\n eventId: result.eventId,\n sessionId: result.sessionId,\n sessionStatus: result.sessionStatus,\n title: options.title,\n ...(options.label !== undefined ? { label: options.label } : {}),\n status: initialStatus,\n occurredAt,\n ...(options.completedAt !== undefined ? { completedAt: options.completedAt } : {}),\n descriptionLength: description.length,\n });\n}\n\nfunction isTerminalStatusForCli(status: TaskStatus): boolean {\n return status === \"done\" || status === \"cancelled\";\n}\n\ntype TaskNewPrint = {\n mode: \"ad-hoc\" | \"attached\";\n taskId: string;\n eventId: string;\n sessionId: string;\n sessionStatus: SessionStatus;\n title: string;\n label?: string;\n status: TaskStatus;\n occurredAt: string;\n completedAt?: string;\n descriptionLength: number;\n};\n\nfunction printTaskNewResult(options: TaskNewOptions, result: TaskNewPrint): void {\n if (options.json === true) {\n console.log(\n JSON.stringify({\n task_id: result.taskId,\n event_id: result.eventId,\n session_id: result.sessionId,\n session_status: result.sessionStatus,\n mode: result.mode,\n title: result.title,\n label: result.label ?? null,\n status: result.status,\n recorded_at: result.occurredAt,\n completed_at: result.completedAt ?? null,\n description_length: result.descriptionLength,\n }),\n );\n return;\n }\n const shortSes = shortSessionId(result.sessionId);\n const created =\n result.mode === \"ad-hoc\"\n ? `Created ${result.taskId} in ad-hoc session ${shortSes}`\n : `Created ${result.taskId} in session ${shortSes} (${result.sessionStatus})`;\n console.log(created);\n console.log(` Title: ${result.title}`);\n // For terminal initial statuses surface both the recording time (= the\n // ad-hoc session timestamp = now) and the supplied completion time so the\n // operator can tell at a glance that the audit trail (events.jsonl)\n // reflects the former while task.md.updated_at reflects the latter.\n if (result.completedAt !== undefined) {\n console.log(\n ` Status: ${result.status} (recorded at ${result.occurredAt}, completed at ${result.completedAt})`,\n );\n } else {\n console.log(` Status: ${result.status}`);\n }\n console.log(` Label: ${result.label ?? \"(none)\"}`);\n}\n\n// ============================================================================\n// task list\n// ============================================================================\n\nexport async function runTaskList(options: TaskListOptions, ctx: TaskContext = {}): Promise<void> {\n try {\n await doRunTaskList(options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options), classifiers: TASK_CLASSIFIERS });\n process.exitCode = 1;\n }\n}\n\nexport async function doRunTaskList(options: TaskListOptions, ctx: TaskContext): Promise<void> {\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForTask(cwd, \"list\");\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n\n const entries = await loadTaskEntries(paths, {\n onSkip: (id, reason) => printTaskSkip(id, reason),\n });\n // Archive entries are read from `<paths.tasks>/archive/` directly (no\n // dedicated loader yet — call sites are rare). Marshalling them through a\n // separate scan keeps the default `task list` path fast (no extra readdir\n // when the operator does not opt in).\n const archivedEntries: { doc: TaskDocument; archived: true }[] = [];\n if (options.includeArchived === true) {\n const archivedIds = await enumerateArchivedTaskIds(paths);\n for (const id of archivedIds) {\n try {\n const { doc } = await readTaskFileWithArchiveFallback(paths, id);\n archivedEntries.push({ doc, archived: true });\n } catch {\n // Skip unreadable archive entries — keep the list output usable\n // when one file is corrupt rather than aborting the run.\n }\n }\n }\n const combined = [...entries, ...archivedEntries.map((a) => a.doc)];\n const archivedIdSet = new Set(archivedEntries.map((a) => a.doc.task.task.id));\n // loadTaskEntries returns asc by created_at; reverse for newest-first display.\n const ordered = [...combined].sort(\n (a, b) => Date.parse(b.task.task.created_at) - Date.parse(a.task.task.created_at),\n );\n const filtered =\n options.status !== undefined\n ? ordered.filter((t) => t.task.task.status === options.status)\n : ordered;\n\n if (filtered.length === 0) {\n if (options.json === true) {\n console.log(\"[]\");\n } else {\n console.log(\"No tasks found.\");\n }\n return;\n }\n\n if (options.json === true) {\n console.log(\n JSON.stringify(\n filtered.map((t) => ({\n task_id: t.task.task.id,\n title: t.task.task.title,\n label: t.task.task.label ?? null,\n status: t.task.task.status,\n created_at: t.task.task.created_at,\n updated_at: t.task.task.updated_at,\n linked_session_count: t.task.task.linked_sessions.length,\n archived: archivedIdSet.has(t.task.task.id),\n })),\n null,\n 2,\n ),\n );\n return;\n }\n printTaskListText(filtered, archivedIdSet);\n}\n\nfunction printTaskListText(\n entries: ReadonlyArray<TaskDocument>,\n archivedIds: ReadonlySet<string>,\n): void {\n const rows = entries.map((t) => ({\n sid: shortTaskId(t.task.task.id),\n status: t.task.task.status,\n createdAt: t.task.task.created_at,\n label: t.task.task.label ?? \"(none)\",\n // Mark archived entries with a leading [archived] tag so the operator\n // can distinguish them from live tasks when --include-archived is on.\n title: archivedIds.has(t.task.task.id) ? `[archived] ${t.task.task.title}` : t.task.task.title,\n linkedCount: String(t.task.task.linked_sessions.length),\n }));\n const widths = {\n sid: maxLen(\n rows.map((r) => r.sid),\n \"SHORT_ID\".length,\n ),\n status: maxLen(\n rows.map((r) => r.status),\n \"STATUS\".length,\n ),\n createdAt: maxLen(\n rows.map((r) => r.createdAt),\n \"CREATED_AT\".length,\n ),\n linkedCount: maxLen(\n rows.map((r) => r.linkedCount),\n \"LINKS\".length,\n ),\n label: maxLen(\n rows.map((r) => r.label),\n \"LABEL\".length,\n ),\n };\n console.log(\n `${pad(\"SHORT_ID\", widths.sid)} ${pad(\"STATUS\", widths.status)} ${pad(\"CREATED_AT\", widths.createdAt)} ${pad(\"LINKS\", widths.linkedCount)} ${pad(\"LABEL\", widths.label)} TITLE`,\n );\n for (const r of rows) {\n console.log(\n `${pad(r.sid, widths.sid)} ${pad(r.status, widths.status)} ${pad(r.createdAt, widths.createdAt)} ${pad(r.linkedCount, widths.linkedCount)} ${pad(r.label, widths.label)} ${r.title}`,\n );\n }\n}\n\n// ============================================================================\n// task show\n// ============================================================================\n\nexport async function runTaskShow(\n idInput: string,\n options: TaskShowOptions,\n ctx: TaskContext = {},\n): Promise<void> {\n try {\n await doRunTaskShow(idInput, options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options), classifiers: TASK_CLASSIFIERS });\n process.exitCode = 1;\n }\n}\n\nexport async function doRunTaskShow(\n idInput: string,\n options: TaskShowOptions,\n ctx: TaskContext,\n): Promise<void> {\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForTask(cwd, \"show\");\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n\n const taskId = await resolveTaskId(paths, idInput, { includeArchived: true });\n const { doc, archived } = await readTaskFileWithArchiveFallback(paths, taskId);\n\n // Collect events related to this task by replaying every session's\n // events.jsonl and filtering by task_id. Could be optimised via an\n // index.json cache later; v0.1 accepts the linear scan.\n const sessions = await loadSessionEntries(paths, { now: new Date() });\n const events: Event[] = [];\n const linkedSessionIds = new Set<string>(doc.task.task.linked_sessions);\n // Replay warnings (malformed JSON / schema violations / partial trailing\n // lines) and unreadable events.jsonl files must reach the operator so\n // silent gaps in the events history don't go unnoticed.\n for (const s of sessions) {\n const sessionDir = join(paths.sessions, s.sessionId);\n try {\n for await (const ev of replayEvents(sessionDir, {\n onWarning: (w) => printReplayWarning(w, s.sessionId),\n })) {\n if (\n (ev.type === \"task_created\" ||\n ev.type === \"task_status_changed\" ||\n ev.type === \"task_reconciled\" ||\n ev.type === \"task_linkage_refreshed\" ||\n ev.type === \"task_deleted\" ||\n ev.type === \"task_archived\") &&\n ev.task_id === taskId\n ) {\n events.push(ev);\n linkedSessionIds.add(s.sessionId);\n }\n }\n } catch (error: unknown) {\n // I/O failure (events.jsonl unreadable). The renderer still works on\n // task.md metadata alone, but the operator must know events from this\n // session are missing from the aggregate.\n const short = shortSessionId(s.sessionId);\n const suffix = error instanceof Error ? `: ${error.message}` : \"\";\n console.error(`Warning: events unavailable for session ${short}${suffix}`);\n }\n }\n events.sort((a, b) => Date.parse(a.occurred_at) - Date.parse(b.occurred_at));\n\n if (options.json === true) {\n console.log(\n JSON.stringify(\n {\n task: doc.task.task,\n body: doc.body,\n linked_sessions: [...linkedSessionIds],\n archived,\n events,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n printTaskShowText(doc, [...linkedSessionIds], events, sessions, options, archived);\n}\n\nfunction printTaskShowText(\n doc: TaskDocument,\n linkedSessions: string[],\n events: ReadonlyArray<Event>,\n sessionEntries: ReadonlyArray<SessionEntry>,\n options: TaskShowOptions,\n archived: boolean,\n): void {\n const t = doc.task.task;\n const archivedTag = archived ? \" [archived]\" : \"\";\n console.log(`Task: ${t.id}${archivedTag}`);\n console.log(` Title: ${t.title}`);\n console.log(` Status: ${t.status}`);\n console.log(` Label: ${t.label ?? \"(none)\"}`);\n console.log(` Created at: ${t.created_at}`);\n console.log(` Updated at: ${t.updated_at}`);\n console.log(` Workspace: ${t.workspace_id}`);\n console.log(\"\");\n console.log(`Linked sessions (${linkedSessions.length}):`);\n const sessionStatusMap = new Map<string, string>(\n sessionEntries.map((s) => [s.sessionId, s.session.session.status]),\n );\n for (const sid of linkedSessions) {\n const status = sessionStatusMap.get(sid) ?? \"unknown\";\n console.log(` ${sid} (${status})`);\n }\n console.log(\"\");\n console.log(\"Description:\");\n if (doc.body.length === 0) {\n console.log(\"(no description)\");\n } else {\n console.log(doc.body);\n }\n console.log(\"\");\n console.log(`Events: ${events.length} total`);\n if (events.length === 0) return;\n const showAll = options.events === true && options.last === undefined;\n const last = options.last ?? 5;\n const slice = showAll ? events : events.slice(-last);\n const heading = showAll ? \"All events:\" : `Last ${slice.length} events:`;\n console.log(\"\");\n console.log(heading);\n const verbose = isVerbose(options);\n for (const ev of slice) {\n console.log(` ${formatTaskEvent(ev)}`);\n if (verbose && ev.type === \"task_reconciled\") {\n for (const line of formatTaskReconciledDetails(ev)) {\n console.log(line);\n }\n }\n }\n}\n\nfunction formatTaskEvent(ev: Event): string {\n if (ev.type === \"task_created\") {\n return `${ev.occurred_at} [${ev.source}] task_created ${ev.title}`;\n }\n if (ev.type === \"task_status_changed\") {\n return `${ev.occurred_at} [${ev.source}] task_status_changed ${ev.from} -> ${ev.to}`;\n }\n if (ev.type === \"task_reconciled\") {\n const removedCount =\n (ev.removed_created_in_session !== null ? 1 : 0) + ev.removed_linked_sessions.length;\n return `${ev.occurred_at} [${ev.source}] task_reconciled ${removedCount} broken ref${removedCount === 1 ? \"\" : \"s\"} (use -v for details)`;\n }\n if (ev.type === \"task_linkage_refreshed\") {\n const added = ev.added_linked_sessions.length;\n const removed = ev.removed_linked_sessions.length;\n const finalPart = ev.final_count !== undefined ? `, final=${ev.final_count}` : \"\";\n return `${ev.occurred_at} [${ev.source}] task_linkage_refreshed +${added} / -${removed}${finalPart}`;\n }\n if (ev.type === \"task_deleted\") {\n return `${ev.occurred_at} [${ev.source}] task_deleted ${ev.title}`;\n }\n if (ev.type === \"task_archived\") {\n return `${ev.occurred_at} [${ev.source}] task_archived ${ev.title}`;\n }\n return `${ev.occurred_at} [${ev.source}] ${ev.type}`;\n}\n\nfunction formatTaskReconciledDetails(ev: TaskReconciledEvent): string[] {\n const lines: string[] = [];\n if (ev.removed_created_in_session !== null) {\n lines.push(` removed_created_in_session: ${ev.removed_created_in_session}`);\n }\n if (ev.created_in_session_replacement !== null) {\n lines.push(` created_in_session_replacement: ${ev.created_in_session_replacement}`);\n }\n if (ev.removed_linked_sessions.length > 0) {\n lines.push(\" removed_linked_sessions:\");\n for (const sid of ev.removed_linked_sessions) {\n lines.push(` - ${sid}`);\n }\n }\n return lines;\n}\n\n// ============================================================================\n// task status\n// ============================================================================\n\nexport async function runTaskStatus(\n taskIdInput: string,\n newStatusInput: string,\n options: TaskStatusOptions,\n ctx: TaskContext = {},\n): Promise<void> {\n try {\n await doRunTaskStatus(taskIdInput, newStatusInput, options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options), classifiers: TASK_CLASSIFIERS });\n process.exitCode = 1;\n }\n}\n\nexport async function doRunTaskStatus(\n taskIdInput: string,\n newStatusInput: string,\n options: TaskStatusOptions,\n ctx: TaskContext,\n): Promise<void> {\n if (taskIdInput.trim().length === 0) {\n throw new Error(\"Task id is empty\");\n }\n const newStatus = parseTaskStatusPositional(newStatusInput);\n\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForTask(cwd, \"status\");\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n\n const taskId = (await resolveTaskId(paths, taskIdInput)) as PrefixedId<\"task\">;\n const now = ctx.nowProvider !== undefined ? ctx.nowProvider() : new Date();\n const occurredAt = now.toISOString();\n\n if (options.session !== undefined) {\n const sessionId = (await resolveSessionId(paths, options.session)) as PrefixedId<\"ses\">;\n const result = await updateTaskStatusWithEvent({\n mode: \"attach\",\n paths,\n occurredAt,\n sessionId,\n taskId,\n newStatus,\n });\n printTaskStatusResult(options, {\n mode: \"attached\",\n taskId: result.taskId,\n eventId: result.eventId,\n sessionId: result.sessionId,\n sessionStatus: result.sessionStatus,\n previousStatus: result.previousStatus,\n newStatus: result.newStatus,\n });\n return;\n }\n\n const manifest = await readManifest(paths);\n const result = await updateTaskStatusWithEvent({\n mode: \"ad-hoc\",\n paths,\n manifest,\n occurredAt,\n taskId,\n newStatus,\n workingDirectory: repositoryRoot,\n });\n printTaskStatusResult(options, {\n mode: \"ad-hoc\",\n taskId: result.taskId,\n eventId: result.eventId,\n sessionId: result.sessionId,\n sessionStatus: result.sessionStatus,\n previousStatus: result.previousStatus,\n newStatus: result.newStatus,\n });\n}\n\ntype TaskStatusPrint = {\n mode: \"ad-hoc\" | \"attached\";\n taskId: string;\n eventId: string;\n sessionId: string;\n sessionStatus: SessionStatus;\n previousStatus: TaskStatus;\n newStatus: TaskStatus;\n};\n\nfunction printTaskStatusResult(options: TaskStatusOptions, result: TaskStatusPrint): void {\n if (options.json === true) {\n console.log(\n JSON.stringify({\n task_id: result.taskId,\n event_id: result.eventId,\n session_id: result.sessionId,\n session_status: result.sessionStatus,\n mode: result.mode,\n previous_status: result.previousStatus,\n new_status: result.newStatus,\n }),\n );\n return;\n }\n const sid = shortSessionId(result.sessionId);\n console.log(\n `Updated ${result.taskId} status: ${result.previousStatus} -> ${result.newStatus} (in session ${sid})`,\n );\n}\n\n// ============================================================================\n// task reconcile (Step 19)\n// ============================================================================\n\nexport async function runTaskReconcile(\n options: TaskReconcileOptions,\n ctx: TaskContext = {},\n): Promise<void> {\n try {\n await doRunTaskReconcile(options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options), classifiers: TASK_CLASSIFIERS });\n process.exitCode = 1;\n }\n}\n\nexport async function doRunTaskReconcile(\n options: TaskReconcileOptions,\n ctx: TaskContext,\n): Promise<void> {\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForTask(cwd, \"reconcile\");\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n const manifest = await readManifest(paths);\n const nowProvider = ctx.nowProvider ?? ((): Date => new Date());\n const write = options.write === true;\n const verbose = isVerbose(options);\n const json = options.json === true;\n\n if (options.task !== undefined) {\n const taskId = (await resolveTaskId(paths, options.task)) as PrefixedId<\"task\">;\n const result = await reconcileTask(paths, manifest, {\n taskId,\n occurredAt: nowProvider().toISOString(),\n workingDirectory: repositoryRoot,\n write,\n scope: \"single\",\n });\n if (json) {\n printReconcileJson({ dryRun: !write, scanned: 1, results: [result], failed: [] });\n } else {\n await printReconcileSingleText(result, paths, { write, verbose });\n }\n return;\n }\n\n const all = await reconcileAllTasks(paths, manifest, {\n occurredAt: () => nowProvider().toISOString(),\n workingDirectory: repositoryRoot,\n write,\n });\n if (json) {\n printReconcileJson({\n dryRun: !write,\n scanned: all.scanned,\n results: all.results,\n failed: all.failed,\n });\n } else {\n printReconcileAllText(all.results, all.failed, all.scanned, { write, verbose });\n }\n if (all.failed.length > 0) {\n process.exitCode = 1;\n }\n}\n\nfunction printReconcileJson(input: {\n dryRun: boolean;\n scanned: number;\n results: ReadonlyArray<ReconcileResult>;\n failed: ReadonlyArray<ReconcileFailure>;\n}): void {\n console.log(\n JSON.stringify(\n {\n dry_run: input.dryRun,\n scanned: input.scanned,\n reconciled: input.results.map((r) => ({\n task_id: r.taskId,\n removed_created_in_session: r.brokenCreatedInSession,\n created_in_session_replacement:\n r.brokenCreatedInSession !== null && r.reconcileSession !== null\n ? r.reconcileSession.sessionId\n : null,\n removed_linked_sessions: r.brokenLinkedSessions,\n reconcile_session_id: r.reconcileSession?.sessionId ?? null,\n event_id: r.reconcileSession?.eventId ?? null,\n })),\n failed: input.failed.map((f) => ({\n task_id: f.taskId,\n error_class: f.errorClass,\n phase: f.phase,\n })),\n },\n null,\n 2,\n ),\n );\n}\n\nasync function printReconcileSingleText(\n result: ReconcileResult,\n paths: ReturnType<typeof basouPaths>,\n options: { write: boolean; verbose: boolean },\n): Promise<void> {\n if (result.clean) {\n // For the --task path with no broken refs we report counts of reachable\n // references so the operator gets a positive audit confirmation rather\n // than a bare \"ok\". Re-read task.md cheaply; the core API already did\n // the integrity work so this is just for the display string.\n let createdCount = 0;\n let linkedCount = 0;\n try {\n const doc = await readTaskFile(paths, result.taskId);\n createdCount = 1;\n linkedCount = doc.task.task.linked_sessions.length;\n } catch {\n // If the file became unreadable between reconcileTask and here just\n // fall back to a less detailed message rather than crashing the run.\n }\n console.log(\n `${result.taskId}: no broken refs (${createdCount} created_in_session + ${linkedCount} linked_sessions, all reachable).`,\n );\n return;\n }\n if (options.write) {\n const sessionPart =\n result.reconcileSession !== null\n ? ` (in session ${shortSessionId(result.reconcileSession.sessionId)})`\n : \"\";\n console.log(`Reconciled ${result.taskId}: ${describeReconcileSummary(result)}${sessionPart}.`);\n return;\n }\n const summary = describeBrokenSummary(result, \"task\", options.verbose);\n console.log(`(dry-run) Would reconcile ${result.taskId}: ${summary}`);\n console.log(\"Note: events -> task.md forward sync is handled by `basou task refresh-linkage`.\");\n console.log(\"Re-run with --write to apply.\");\n}\n\nfunction printReconcileAllText(\n results: ReadonlyArray<ReconcileResult>,\n failed: ReadonlyArray<ReconcileFailure>,\n scanned: number,\n options: { write: boolean; verbose: boolean },\n): void {\n if (results.length === 0 && failed.length === 0) {\n console.log(`Scanned ${scanned} tasks, no broken refs detected.`);\n return;\n }\n\n let totalBrokenRefs = 0;\n for (const r of results) {\n totalBrokenRefs += r.brokenLinkedSessions.length + (r.brokenCreatedInSession !== null ? 1 : 0);\n }\n\n if (options.write) {\n for (const r of results) {\n const sessionPart =\n r.reconcileSession !== null\n ? ` (in session ${shortSessionId(r.reconcileSession.sessionId)})`\n : \"\";\n console.log(`Reconciled ${r.taskId}: ${describeReconcileSummary(r)}${sessionPart}`);\n }\n for (const f of failed) {\n const phase = f.phase ?? \"unknown\";\n console.error(\n `Failed to reconcile ${f.taskId}: ${f.errorClass} (phase: ${phase}); see Caused by with -v`,\n );\n }\n const reconciledCount = results.length;\n const reconciledRefs = totalBrokenRefs;\n const reconciledPart = `reconciled ${reconciledCount} task${reconciledCount === 1 ? \"\" : \"s\"} (${reconciledRefs} broken ref${reconciledRefs === 1 ? \"\" : \"s\"})`;\n const failedPart =\n failed.length === 0 ? \"\" : `, ${failed.length} task${failed.length === 1 ? \"\" : \"s\"} failed`;\n console.log(`Scanned ${scanned} tasks, ${reconciledPart}${failedPart}.`);\n if (failed.length > 0) {\n console.error(\"(exit code 1)\");\n }\n return;\n }\n\n // dry-run with broken refs\n for (const r of results) {\n const summary = describeBrokenSummary(r, \"all\", options.verbose);\n console.log(`(dry-run) Would reconcile ${r.taskId}: ${summary}`);\n }\n console.log(\n `Scanned ${scanned} tasks, would reconcile ${results.length} task${results.length === 1 ? \"\" : \"s\"} (${totalBrokenRefs} broken ref${totalBrokenRefs === 1 ? \"\" : \"s\"}).`,\n );\n console.log(\"Note: events -> task.md forward sync is handled by `basou task refresh-linkage`.\");\n console.log(\"Re-run with --write to apply.\");\n}\n\nfunction describeReconcileSummary(r: ReconcileResult): string {\n const linkedCount = r.brokenLinkedSessions.length;\n const parts: string[] = [];\n if (r.brokenCreatedInSession !== null) {\n parts.push(\"replaced created_in_session\");\n }\n if (linkedCount > 0) {\n parts.push(`removed ${linkedCount} linked_sessions entr${linkedCount === 1 ? \"y\" : \"ies\"}`);\n }\n return parts.join(\" + \");\n}\n\nfunction describeBrokenSummary(\n r: ReconcileResult,\n scope: \"all\" | \"task\",\n verbose: boolean,\n): string {\n const showIds = scope === \"task\" || verbose;\n const parts: string[] = [];\n if (r.brokenCreatedInSession !== null) {\n parts.push(\n showIds\n ? `broken created_in_session ${formatSessionIdForDisplay(r.brokenCreatedInSession, verbose, scope)}`\n : \"broken created_in_session\",\n );\n }\n const linkedCount = r.brokenLinkedSessions.length;\n if (linkedCount > 0) {\n if (showIds) {\n const ids = r.brokenLinkedSessions\n .map((id) => formatSessionIdForDisplay(id, verbose, scope))\n .join(\", \");\n parts.push(`${linkedCount} linked_sessions entr${linkedCount === 1 ? \"y\" : \"ies\"} [${ids}]`);\n } else {\n parts.push(`${linkedCount} linked_sessions entr${linkedCount === 1 ? \"y\" : \"ies\"}`);\n }\n }\n return parts.join(\" + \");\n}\n\nfunction formatSessionIdForDisplay(id: string, verbose: boolean, scope: \"all\" | \"task\"): string {\n if (verbose && scope === \"task\") return id;\n return `ses_${shortSessionId(id)}`;\n}\n\n// ============================================================================\n// task refresh-linkage\n// ============================================================================\n\nexport async function runTaskRefreshLinkage(\n taskIdInput: string,\n options: TaskRefreshLinkageOptions,\n ctx: TaskContext = {},\n): Promise<void> {\n try {\n await doRunTaskRefreshLinkage(taskIdInput, options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options), classifiers: TASK_CLASSIFIERS });\n process.exitCode = 1;\n }\n}\n\nexport async function doRunTaskRefreshLinkage(\n taskIdInput: string,\n options: TaskRefreshLinkageOptions,\n ctx: TaskContext,\n): Promise<void> {\n if (taskIdInput.trim().length === 0) {\n throw new Error(\"Task id is empty\");\n }\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForTask(cwd, \"refresh-linkage\");\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n const manifest = await readManifest(paths);\n const taskId = (await resolveTaskId(paths, taskIdInput)) as PrefixedId<\"task\">;\n const nowProvider = ctx.nowProvider ?? ((): Date => new Date());\n const write = options.write === true;\n\n const result = await refreshTaskLinkedSessions(paths, manifest, {\n taskId,\n occurredAt: nowProvider().toISOString(),\n workingDirectory: repositoryRoot,\n write,\n });\n\n if (options.json === true) {\n printRefreshLinkageJson(result, { dryRun: !write });\n return;\n }\n printRefreshLinkageText(result, { dryRun: !write });\n}\n\nfunction printRefreshLinkageJson(result: RefreshLinkageResult, input: { dryRun: boolean }): void {\n console.log(\n JSON.stringify(\n {\n task_id: result.taskId,\n clean: result.clean,\n dry_run: input.dryRun,\n added_linked_sessions: result.addedLinkedSessions,\n removed_linked_sessions: result.removedLinkedSessions,\n final_count: result.finalCount,\n refresh_session_id: result.refreshSession?.sessionId ?? null,\n event_id: result.refreshSession?.eventId ?? null,\n },\n null,\n 2,\n ),\n );\n}\n\nfunction printRefreshLinkageText(result: RefreshLinkageResult, input: { dryRun: boolean }): void {\n if (result.clean) {\n console.log(\n `${result.taskId}: linked_sessions already fresh (${result.finalCount} entr${result.finalCount === 1 ? \"y\" : \"ies\"}).`,\n );\n return;\n }\n const addedCount = result.addedLinkedSessions.length;\n const removedCount = result.removedLinkedSessions.length;\n const summaryParts: string[] = [];\n if (addedCount > 0) {\n summaryParts.push(`+${addedCount} added`);\n }\n if (removedCount > 0) {\n summaryParts.push(`-${removedCount} removed`);\n }\n const summary = summaryParts.join(\", \");\n if (input.dryRun) {\n console.log(`(dry-run) Would refresh ${result.taskId} linked_sessions: ${summary}.`);\n console.log(\"Re-run with --write to apply.\");\n return;\n }\n const sid =\n result.refreshSession !== null\n ? ` (in session ${shortSessionId(result.refreshSession.sessionId)})`\n : \"\";\n console.log(\n `Refreshed ${result.taskId} linked_sessions: ${summary}${sid}; final count ${result.finalCount}.`,\n );\n}\n\n// ============================================================================\n// task edit / delete / archive\n// ============================================================================\n\nexport async function runTaskEdit(\n taskIdInput: string,\n options: TaskEditOptions,\n ctx: TaskContext = {},\n): Promise<void> {\n try {\n await doRunTaskEdit(taskIdInput, options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options), classifiers: TASK_CLASSIFIERS });\n process.exitCode = 1;\n }\n}\n\nexport async function doRunTaskEdit(\n taskIdInput: string,\n options: TaskEditOptions,\n ctx: TaskContext,\n): Promise<void> {\n if (taskIdInput.trim().length === 0) {\n throw new Error(\"Task id is empty\");\n }\n if (options.title === undefined && options.status === undefined) {\n throw new Error(\"Nothing to edit: provide --title or --status\");\n }\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForTask(cwd, \"edit\");\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n const manifest = await readManifest(paths);\n const taskId = (await resolveTaskId(paths, taskIdInput)) as PrefixedId<\"task\">;\n const now = ctx.nowProvider !== undefined ? ctx.nowProvider() : new Date();\n const occurredAt = now.toISOString();\n\n const result = await editTask({\n paths,\n taskId,\n occurredAt,\n manifest,\n workingDirectory: repositoryRoot,\n ...(options.title !== undefined ? { title: options.title } : {}),\n ...(options.status !== undefined ? { newStatus: options.status } : {}),\n });\n\n if (options.json === true) {\n console.log(\n JSON.stringify({\n task_id: result.taskId,\n title_updated: result.titleUpdated,\n status_updated: result.statusUpdated,\n previous_status: result.previousStatus,\n new_status: result.newStatus,\n status_change_session_id: result.statusChangeSession?.sessionId ?? null,\n status_change_event_id: result.statusChangeSession?.eventId ?? null,\n }),\n );\n return;\n }\n if (result.statusUpdated) {\n const sid =\n result.statusChangeSession !== null\n ? ` (in session ${shortSessionId(result.statusChangeSession.sessionId)})`\n : \"\";\n console.log(\n `Updated ${result.taskId} status: ${result.previousStatus} -> ${result.newStatus}${sid}`,\n );\n }\n if (result.titleUpdated) {\n console.log(`Updated ${result.taskId} title.`);\n }\n if (!result.statusUpdated && !result.titleUpdated) {\n // Both fields were supplied but matched the current values exactly —\n // tell the operator the task was already in the requested state.\n console.log(`No changes for ${result.taskId}.`);\n }\n}\n\nexport async function runTaskDelete(\n taskIdInput: string,\n options: TaskDeleteOptions,\n ctx: TaskContext = {},\n): Promise<void> {\n try {\n await doRunTaskDelete(taskIdInput, options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options), classifiers: TASK_CLASSIFIERS });\n process.exitCode = 1;\n }\n}\n\nexport async function doRunTaskDelete(\n taskIdInput: string,\n options: TaskDeleteOptions,\n ctx: TaskContext,\n): Promise<void> {\n if (taskIdInput.trim().length === 0) {\n throw new Error(\"Task id is empty\");\n }\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForTask(cwd, \"delete\");\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n const manifest = await readManifest(paths);\n const taskId = (await resolveTaskId(paths, taskIdInput)) as PrefixedId<\"task\">;\n\n if (options.yes !== true) {\n await confirmDestructiveAction(\"delete\", taskId);\n }\n\n const now = ctx.nowProvider !== undefined ? ctx.nowProvider() : new Date();\n const occurredAt = now.toISOString();\n const result = await deleteTask({\n paths,\n manifest,\n taskId,\n occurredAt,\n workingDirectory: repositoryRoot,\n });\n\n if (options.json === true) {\n console.log(\n JSON.stringify({\n task_id: result.taskId,\n title: result.title,\n session_id: result.sessionId,\n event_id: result.eventId,\n }),\n );\n return;\n }\n console.log(\n `Deleted ${result.taskId} (\"${result.title}\") in ad-hoc session ${shortSessionId(result.sessionId)}.`,\n );\n}\n\nexport async function runTaskArchive(\n taskIdInput: string,\n options: TaskArchiveOptions,\n ctx: TaskContext = {},\n): Promise<void> {\n try {\n await doRunTaskArchive(taskIdInput, options, ctx);\n } catch (error: unknown) {\n renderCliError(error, { verbose: isVerbose(options), classifiers: TASK_CLASSIFIERS });\n process.exitCode = 1;\n }\n}\n\nexport async function doRunTaskArchive(\n taskIdInput: string,\n options: TaskArchiveOptions,\n ctx: TaskContext,\n): Promise<void> {\n if (taskIdInput.trim().length === 0) {\n throw new Error(\"Task id is empty\");\n }\n const cwd = ctx.cwd ?? process.cwd();\n const repositoryRoot = await resolveRepositoryRootForTask(cwd, \"archive\");\n const paths = basouPaths(repositoryRoot);\n await assertWorkspaceInitialized(paths.root);\n const manifest = await readManifest(paths);\n const taskId = (await resolveTaskId(paths, taskIdInput)) as PrefixedId<\"task\">;\n\n if (options.yes !== true) {\n await confirmDestructiveAction(\"archive\", taskId);\n }\n\n const now = ctx.nowProvider !== undefined ? ctx.nowProvider() : new Date();\n const occurredAt = now.toISOString();\n const result = await archiveTask({\n paths,\n manifest,\n taskId,\n occurredAt,\n workingDirectory: repositoryRoot,\n });\n\n if (options.json === true) {\n console.log(\n JSON.stringify({\n task_id: result.taskId,\n title: result.title,\n session_id: result.sessionId,\n event_id: result.eventId,\n }),\n );\n return;\n }\n console.log(\n `Archived ${result.taskId} (\"${result.title}\") in ad-hoc session ${shortSessionId(result.sessionId)}.`,\n );\n}\n\n/**\n * Read a single y/N answer from stdin when stdin is a TTY. Refuses to wait\n * for input when stdin is not a TTY (operator must pass --yes explicitly),\n * so piping `echo y | basou task delete` cannot accidentally trigger a\n * destructive action.\n */\nasync function confirmDestructiveAction(\n action: \"delete\" | \"archive\",\n taskId: string,\n): Promise<void> {\n if (process.stdin.isTTY !== true) {\n throw new Error(`Refusing to ${action} without TTY; rerun with --yes to skip confirmation.`);\n }\n const verb = action === \"delete\" ? \"Delete\" : \"Archive\";\n process.stdout.write(`${verb} task \\`${taskId}\\`? [y/N] `);\n const answer = await readSingleLineFromStdin();\n const normalized = answer.trim().toLowerCase();\n if (normalized !== \"y\" && normalized !== \"yes\") {\n throw new Error(`${verb} aborted by user.`);\n }\n}\n\nasync function readSingleLineFromStdin(): Promise<string> {\n const { createInterface } = await import(\"node:readline/promises\");\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n const line = await rl.question(\"\");\n return line;\n } finally {\n rl.close();\n }\n}\n\n// ============================================================================\n// option converters\n// ============================================================================\n\nfunction parseTitle(raw: string): string {\n if (raw.length === 0) {\n throw new InvalidArgumentError(\"Title must not be empty\");\n }\n return raw;\n}\n\nfunction parseLabel(raw: string): string {\n if (raw.length === 0) {\n throw new InvalidArgumentError(\"Label must not be empty\");\n }\n return raw;\n}\n\nfunction parseInitialTaskStatus(raw: string): TaskStatus {\n const result = TaskStatusSchema.safeParse(raw);\n if (!result.success) {\n throw new InvalidArgumentError(\n `Initial task status must be one of: ${STATUS_VALUES.join(\", \")}`,\n );\n }\n return result.data;\n}\n\nconst ISO_DATE_RE = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$/;\n\nfunction parseIsoTimestampOption(raw: string): string {\n // Mirror the IsoTimestampSchema accepted form: date + time + explicit\n // zone designator. We rely on Date.parse for content validation and the\n // regex above for shape so misformed inputs are rejected before we hand\n // the string to the orchestrator's downstream parsers.\n if (!ISO_DATE_RE.test(raw) || Number.isNaN(Date.parse(raw))) {\n throw new InvalidArgumentError(\n \"Invalid --completed-at value; expected ISO-8601 timestamp like 2026-05-10T12:34:56+09:00\",\n );\n }\n return raw;\n}\n\nfunction parseTaskStatusFilter(raw: string): TaskStatus {\n const result = TaskStatusSchema.safeParse(raw);\n if (!result.success) {\n throw new InvalidArgumentError(\n `Invalid task status: ${raw}. Valid values: ${STATUS_VALUES.join(\", \")}`,\n );\n }\n return result.data;\n}\n\nfunction parseTaskStatusPositional(raw: string): TaskStatus {\n const result = TaskStatusSchema.safeParse(raw);\n if (!result.success) {\n throw new Error(`Invalid task status: ${raw}. Valid values: ${STATUS_VALUES.join(\", \")}`);\n }\n return result.data;\n}\n\nfunction parseDescriptionOption(raw: string): string {\n if (raw.length === 0) {\n throw new InvalidArgumentError(\"Description must not be empty\");\n }\n return raw;\n}\n\nfunction parsePositiveInt(raw: string): number {\n const n = Number.parseInt(raw, 10);\n if (!Number.isInteger(n) || n < 1 || raw.trim() !== String(n)) {\n throw new InvalidArgumentError(`Invalid number: ${raw}`);\n }\n return n;\n}\n\n// ============================================================================\n// IO helpers\n// ============================================================================\n\nasync function readDescriptionFile(path: string): Promise<string> {\n try {\n return await readFile(path, \"utf8\");\n } catch (error: unknown) {\n if (findErrorCode(error, \"ENOENT\")) {\n throw new Error(\"Description source not found\", { cause: error });\n }\n if (findErrorCode(error, \"EISDIR\")) {\n throw new Error(\"Description source is not a file\", { cause: error });\n }\n throw new Error(\"Failed to read description source\", { cause: error });\n }\n}\n\nasync function resolveRepositoryRootForTask(\n cwd: string,\n subcmd:\n | \"new\"\n | \"list\"\n | \"show\"\n | \"status\"\n | \"reconcile\"\n | \"refresh-linkage\"\n | \"edit\"\n | \"delete\"\n | \"archive\",\n): Promise<string> {\n try {\n return await resolveRepositoryRoot(cwd);\n } catch (error: unknown) {\n if (error instanceof Error && error.message === \"Not a git repository\") {\n throw new Error(\n `Not a git repository. Run 'git init' first, then re-run 'basou task ${subcmd}'.`,\n { cause: error },\n );\n }\n throw error;\n }\n}\n\nasync function assertWorkspaceInitialized(basouRoot: string): Promise<void> {\n try {\n await assertBasouRootSafe(basouRoot);\n } catch (error: unknown) {\n if (findErrorCode(error, \"ENOENT\")) {\n throw new Error(\"Workspace not initialized. Run 'basou init' first.\");\n }\n throw error;\n }\n}\n\n/**\n * Task-specific classifier for {@link TaskWriteAfterEventError}. The\n * generic renderer ({@link renderCliError}) already prints the underlying\n * `error.message`; this classifier appends the two task-specific lines\n * that explain WHICH artefact is in unsafe state and the manual-repair\n * hint. Combined with {@link failedToFinalizeClassifier} from the shared\n * lib so both error classes are surfaced consistently across `task new`,\n * `task status`, `task reconcile`, etc.\n */\nconst taskWriteAfterEventClassifier: ErrorClassifier = {\n match: (error) => error instanceof TaskWriteAfterEventError,\n additionalLines: (error) => {\n const e = error as TaskWriteAfterEventError;\n const sid = shortSessionId(e.sessionId);\n const tid = shortTaskId(e.taskId);\n const unsafeArtefact = describeUnsafeArtefact(e.phase, tid, sid);\n const warning = describeWriteFailureWarning(e.phase);\n const hint =\n e.phase === \"reconcile-concurrent\"\n ? \"re-run `basou task reconcile`\"\n : e.phase === \"linkage-refresh-concurrent\"\n ? \"re-run `basou task refresh-linkage`\"\n : \"manual repair required; see `basou task show -v` for event payload\";\n return [\n `Recorded ${e.eventId} in session ${sid}; ${unsafeArtefact} is in unsafe state; do not rerun`,\n `Warning: ${warning}; events.jsonl is consistent; ${hint}`,\n ];\n },\n};\n\nconst TASK_CLASSIFIERS: readonly ErrorClassifier[] = [\n taskWriteAfterEventClassifier,\n failedToFinalizeClassifier,\n];\n\nfunction describeUnsafeArtefact(\n phase: TaskWriteAfterEventError[\"phase\"],\n tid: string,\n sid: string,\n): string {\n switch (phase) {\n case \"create\":\n return `task ${tid} file`;\n case \"overwrite\":\n return `task ${tid} file`;\n case \"link-session\":\n return \"session-task linkage\";\n case \"reconcile\":\n return `task ${tid} file (reconcile incomplete)`;\n case \"reconcile-finalize\":\n return `reconcile session ${sid} (finalize incomplete)`;\n case \"reconcile-concurrent\":\n return `task ${tid} file (concurrent modification detected)`;\n case \"linkage-refresh\":\n return `task ${tid} file (linkage refresh incomplete)`;\n case \"linkage-refresh-finalize\":\n return `linkage refresh session ${sid} (finalize incomplete)`;\n case \"linkage-refresh-concurrent\":\n return `task ${tid} file (concurrent modification detected)`;\n case \"delete\":\n return `task ${tid} file (delete incomplete; file still on disk)`;\n case \"archive\":\n return `task ${tid} file (archive incomplete; check tasks/ and tasks/archive/)`;\n }\n}\n\nfunction describeWriteFailureWarning(phase: TaskWriteAfterEventError[\"phase\"]): string {\n switch (phase) {\n case \"create\":\n return \"task.md creation failed\";\n case \"overwrite\":\n return \"task.md update failed\";\n case \"link-session\":\n return \"session.yaml task_id update failed\";\n case \"reconcile\":\n return \"task.md reconciliation failed\";\n case \"reconcile-finalize\":\n return \"reconcile session finalize failed (session.yaml status update)\";\n case \"reconcile-concurrent\":\n return \"task.md was modified concurrently; re-run reconcile to retry\";\n case \"linkage-refresh\":\n return \"task.md linkage refresh write failed\";\n case \"linkage-refresh-finalize\":\n return \"linkage refresh session finalize failed (session.yaml status update)\";\n case \"linkage-refresh-concurrent\":\n return \"task.md was modified concurrently; re-run refresh-linkage to retry\";\n case \"delete\":\n return \"task.md unlink failed after task_deleted event committed\";\n case \"archive\":\n return \"task.md move to archive/ failed after task_archived event committed\";\n }\n}\n\nfunction pad(value: string, width: number): string {\n return value.length >= width ? value : value + \" \".repeat(width - value.length);\n}\n\nfunction maxLen(values: readonly string[], floor: number): number {\n let max = floor;\n for (const v of values) if (v.length > max) max = v.length;\n return max;\n}\n"],"mappings":";;;AAAA,SAAS,qBAAqB;AAC9B,SAAS,eAAe;;;ACDxB,SAAS,cAAc;AACvB,SAAS,YAAY;AACrB;AAAA,EAGE;AAAA,EAEA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACtBP;AAAA,EACE;AAAA,OAIK;AAMP,IAAM,aAAa;AACnB,IAAM,cAAc;AACpB,IAAM,eAAe;AAOd,SAAS,eAAe,IAAoB;AACjD,MAAI,GAAG,WAAW,UAAU;AAC1B,WAAO,GAAG,MAAM,WAAW,QAAQ,WAAW,SAAS,YAAY;AACrE,SAAO,GAAG,MAAM,GAAG,YAAY;AACjC;AAKO,SAAS,YAAY,IAAoB;AAC9C,MAAI,GAAG,WAAW,WAAW;AAC3B,WAAO,GAAG,MAAM,YAAY,QAAQ,YAAY,SAAS,YAAY;AACvE,SAAO,GAAG,MAAM,GAAG,YAAY;AACjC;AAWO,SAAS,UAAU,SAAqD;AAC7E,SAAO,SAAS,YAAY,QAAQ,QAAQ,IAAI,gBAAgB;AAClE;AAMA,IAAM,wBAAwB;AAWvB,SAAS,kBAAkB,OAAkC;AAClE,MAAI,UAAmB,MAAM;AAC7B,MAAI;AACJ,WAAS,QAAQ,GAAG,QAAQ,uBAAuB,SAAS,GAAG;AAC7D,QAAI,EAAE,mBAAmB,OAAQ;AACjC,UAAM,OAAQ,QAAuC;AACrD,QAAI,OAAO,SAAS,YAAY,KAAK,SAAS,EAAG,QAAO;AACxD,sBAAkB,QAAQ,YAAY;AACtC,cAAU,QAAQ;AAAA,EACpB;AACA,SAAO;AACT;AAwBO,IAAM,6BAA8C;AAAA,EACzD,OAAO,CAAC,UAAU,iBAAiB;AAAA,EACnC,iBAAiB,CAAC,UAAU;AAC1B,UAAM,IAAI;AACV,UAAM,MAAM,eAAe,EAAE,SAAS;AAOtC,UAAM,SAAS,EAAE,eAAe,CAAC;AACjC,WAAO;AAAA,MACL,YAAY,MAAM,eAAe,GAAG;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AACF;AAmBO,SAAS,eACd,OACA,SACM;AACN,MAAI,EAAE,iBAAiB,QAAQ;AAC7B,YAAQ,MAAM,OAAO,KAAK,CAAC;AAC3B;AAAA,EACF;AACA,UAAQ,MAAM,MAAM,OAAO;AAC3B,aAAW,cAAc,QAAQ,eAAe,CAAC,GAAG;AAClD,QAAI,WAAW,MAAM,KAAK,GAAG;AAC3B,iBAAW,QAAQ,WAAW,gBAAgB,KAAK,EAAG,SAAQ,MAAM,IAAI;AAAA,IAC1E;AAAA,EACF;AACA,MAAI,QAAQ,SAAS;AACnB,UAAM,QAAQ,kBAAkB,KAAK;AACrC,QAAI,UAAU,OAAW,SAAQ,MAAM,cAAc,KAAK,EAAE;AAAA,EAC9D;AACF;AAYO,SAAS,mBAAmB,SAAwB,WAAyB;AAClF,QAAM,QAAQ,eAAe,SAAS;AACtC,UAAQ,QAAQ,MAAM;AAAA,IACpB,KAAK;AACH,cAAQ,MAAM,6CAA6C,KAAK,eAAe;AAC/E;AAAA,IACF,KAAK;AACH,cAAQ;AAAA,QACN,2CAA2C,QAAQ,IAAI,OAAO,KAAK;AAAA,MACrE;AACA;AAAA,IACF,KAAK;AACH,cAAQ;AAAA,QACN,0CAA0C,QAAQ,IAAI,OAAO,KAAK;AAAA,MACpE;AACA;AAAA,EACJ;AACF;AASO,SAAS,iBAAiB,KAAa,QAAiC;AAC7E,QAAM,QAAQ,eAAe,GAAG;AAChC,MAAI,WAAW,2BAA2B;AACxC,YAAQ,MAAM,sCAAsC,KAAK,2BAA2B;AAAA,EACtF,OAAO;AACL,YAAQ,MAAM,WAAW,KAAK,KAAK,MAAM,EAAE;AAAA,EAC7C;AACF;AASO,SAAS,qBAAqB,KAAa,QAAiC;AACjF,QAAM,QAAQ,eAAe,GAAG;AAChC,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,cAAQ,MAAM,WAAW,KAAK,0BAA0B;AACxD;AAAA,IACF,KAAK;AACH,cAAQ,MAAM,WAAW,KAAK,0BAA0B;AACxD;AAAA,IACF,KAAK;AACH,cAAQ,MAAM,sCAAsC,KAAK,2BAA2B;AACpF;AAAA,EACJ;AACF;AAQO,SAAS,cAAc,QAAgB,QAAuC;AACnF,UAAQ,MAAM,WAAW,YAAY,MAAM,CAAC,KAAK,MAAM,EAAE;AAC3D;;;AD3MA,IAAM,cAAc;AACpB,IAAM,oBAAoB;AAC1B,IAAM,mBAAmB;AACzB,IAAM,4BAA4B;AAClC,IAAM,sBAAsB;AAE5B,IAAM,gBAAgB,qBAAqB;AAyCpC,SAAS,wBAAwBA,UAAwB;AAC9D,QAAM,WAAWA,SACd,QAAQ,UAAU,EAClB,YAAY,wDAAwD;AAEvE,WACG,QAAQ,MAAM,EACd,YAAY,2DAA2D,EACvE,OAAO,UAAU,iCAAiC,EAClD;AAAA,IACC;AAAA,IACA,sCAAsC,cAAc,KAAK,IAAI,CAAC;AAAA,IAC9D;AAAA,EACF,EACC,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,YAAiC;AAC9C,UAAM,gBAAgB,OAAO;AAAA,EAC/B,CAAC;AAEH,WACG,QAAQ,WAAW,EACnB,YAAY,gDAAgD,EAC5D,OAAO,UAAU,wCAAwC,EACzD,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,IAAY,YAAiC;AAC1D,UAAM,gBAAgB,IAAI,OAAO;AAAA,EACnC,CAAC;AAEH,WACG,QAAQ,cAAc,EACtB,YAAY,4BAA4B,EACxC,OAAO,iBAAiB,wDAAwD,EAChF,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,IAAY,YAAoC;AAC7D,UAAM,mBAAmB,IAAI,OAAO;AAAA,EACtC,CAAC;AAEH,WACG,QAAQ,aAAa,EACrB,YAAY,2BAA2B,EACvC,eAAe,mBAAmB,iCAAiC,EACnE,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,IAAY,YAAmC;AAC5D,UAAM,kBAAkB,IAAI,OAAO;AAAA,EACrC,CAAC;AACL;AASA,eAAsB,gBACpB,SACA,MAAuB,CAAC,GACT;AACf,MAAI;AACF,UAAM,kBAAkB,SAAS,GAAG;AAAA,EACtC,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,EAAE,CAAC;AACrD,YAAQ,WAAW;AAAA,EACrB;AACF;AAMA,eAAsB,kBACpB,SACA,KACe;AACf,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,iCAAiC,KAAK,MAAM;AACzE,QAAM,QAAQ,WAAW,cAAc;AACvC,QAAM,2BAA2B,MAAM,IAAI;AAE3C,QAAM,MAAM,MAAM,mBAAmB,KAAK;AAI1C,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,UAAgC,CAAC;AAIvC,QAAM,cAAc,IAAI,IAAI,IAAI,QAAQ;AACxC,aAAW,MAAM,IAAI,SAAS;AAC5B,QAAI,YAAY,IAAI,EAAE,GAAG;AACvB,cAAQ,MAAM,oCAAoC,QAAQ,EAAE,CAAC,8BAA8B;AAC3F;AAAA,IACF;AACA,UAAM,MAAM,MAAM,uBAAuB,OAAO,IAAI,WAAW,GAAG;AAClE,QAAI,QAAQ,KAAM,SAAQ,KAAK,GAAG;AAAA,EACpC;AACA,aAAW,MAAM,IAAI,UAAU;AAC7B,UAAM,MAAM,MAAM,uBAAuB,OAAO,IAAI,YAAY,GAAG;AACnE,QAAI,QAAQ,KAAM,SAAQ,KAAK,GAAG;AAAA,EACpC;AAEA,UAAQ,KAAK,CAAC,GAAG,MAAM,KAAK,MAAM,EAAE,SAAS,UAAU,IAAI,KAAK,MAAM,EAAE,SAAS,UAAU,CAAC;AAE5F,QAAM,WACJ,QAAQ,WAAW,SACf,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,WAAW,QAAQ,MAAM,IAC1D;AAEN,MAAI,SAAS,WAAW,GAAG;AACzB,qBAAiB,OAAO;AACxB;AAAA,EACF;AAEA,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ;AAAA,MACN,KAAK;AAAA,QACH,SAAS,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,UAAU,cAAc,EAAE,YAAY,EAAE;AAAA,QACpE;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AACL,0BAAsB,QAAQ;AAAA,EAChC;AACF;AAEA,eAAe,uBACb,OACA,IACA,UACA,KACoC;AACpC,QAAM,WAAW,KAAK,MAAM,UAAU,QAAQ,GAAG,GAAG,EAAE,OAAO;AAC7D,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,aAAa,QAAQ;AAAA,EACnC,SAAS,OAAgB;AACvB,YAAQ,MAAM,WAAW,QAAQ,EAAE,CAAC,KAAK,kBAAkB,KAAK,CAAC,EAAE;AACnE,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,eAAe,UAAU,GAAG;AAC1C,MAAI,CAAC,MAAM,SAAS;AAClB,YAAQ,MAAM,WAAW,QAAQ,EAAE,CAAC,2BAA2B;AAC/D,WAAO;AAAA,EACT;AACA,MAAI,MAAM,KAAK,OAAO,IAAI;AAGxB,YAAQ,MAAM,WAAW,QAAQ,EAAE,CAAC,sCAAsC;AAC1E,WAAO;AAAA,EACT;AACA,QAAM,WAAW,MAAM;AACvB,SAAO,EAAE,UAAU,UAAU,aAAa,cAAc,UAAU,GAAG,EAAE;AACzE;AAIA,eAAsB,gBACpB,SACA,SACA,MAAuB,CAAC,GACT;AACf,MAAI;AACF,UAAM,kBAAkB,SAAS,SAAS,GAAG;AAAA,EAC/C,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,EAAE,CAAC;AACrD,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAsB,kBACpB,SACA,SACA,KACe;AACf,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,iCAAiC,KAAK,MAAM;AACzE,QAAM,QAAQ,WAAW,cAAc;AACvC,QAAM,2BAA2B,MAAM,IAAI;AAE3C,QAAM,EAAE,GAAG,IAAI,MAAM,kBAAkB,OAAO,OAAO;AACrD,QAAM,SAAS,MAAM,aAAa,OAAO,EAAE;AAC3C,MAAI,WAAW,MAAM;AACnB,UAAM,IAAI,MAAM,uBAAuB,OAAO,EAAE;AAAA,EAClD;AAKA,QAAM,aAAa,KAAK,MAAM,UAAU,OAAO,SAAS,UAAU;AAClE,QAAM,gBAAyB,CAAC;AAChC,mBAAiB,MAAM,aAAa,YAAY;AAAA,IAC9C,WAAW,CAAC,MAAM,mBAAmB,GAAG,OAAO,SAAS,UAAU;AAAA,EACpE,CAAC,GAAG;AACF,QAAI,gBAAgB,EAAE,KAAK,GAAG,gBAAgB,IAAI;AAChD,oBAAc,KAAK,EAAE;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,cAAc,cAAc,OAAO,UAAU,GAAG;AAEtD,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ;AAAA,MACN,KAAK;AAAA,QACH;AAAA,UACE,UAAU,EAAE,GAAG,OAAO,UAAU,cAAc,YAAY;AAAA,UAC1D,QAAQ;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA;AAAA,EACF;AAEA,wBAAsB,OAAO,UAAU,OAAO,UAAU,eAAe,WAAW;AACpF;AAIA,eAAsB,mBACpB,SACA,SACA,MAAuB,CAAC,GACT;AACf,MAAI;AACF,UAAM,qBAAqB,SAAS,SAAS,KAAK,SAAS;AAAA,EAC7D,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,EAAE,CAAC;AACrD,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAsB,kBACpB,SACA,SACA,MAAuB,CAAC,GACT;AACf,MAAI;AACF,UAAM,qBAAqB,SAAS,SAAS,KAAK,QAAQ;AAAA,EAC5D,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,EAAE,CAAC;AACrD,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAe,qBACb,SACA,SACA,KACA,UACe;AACf,MAAI,aAAa,UAAU;AACzB,UAAM,SAAU,QAAkC;AAClD,QAAI,OAAO,WAAW,GAAG;AACvB,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AAAA,EACF;AAEA,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,iCAAiC,KAAK,QAAQ;AAC3E,QAAM,QAAQ,WAAW,cAAc;AACvC,QAAM,2BAA2B,MAAM,IAAI;AAG3C,QAAM,EAAE,IAAI,SAAS,IAAI,MAAM,kBAAkB,OAAO,OAAO;AAG/D,MAAI,aAAa,YAAY;AAC3B,UAAM,IAAI,MAAM,8BAA8B,OAAO,EAAE;AAAA,EACzD;AAGA,QAAM,cAAc,KAAK,MAAM,UAAU,SAAS,GAAG,EAAE,OAAO;AAC9D,MAAI;AACJ,MAAI;AACF,iBAAa,MAAM,aAAa,WAAW;AAAA,EAC7C,SAAS,OAAgB;AACvB,QAAI,iBAAiB,SAAS,MAAM,YAAY,uBAAuB;AACrE,YAAM,IAAI,MAAM,uBAAuB,OAAO,EAAE;AAAA,IAClD;AACA,UAAM,IAAI,MAAM,2BAA2B,EAAE,OAAO,MAAM,CAAC;AAAA,EAC7D;AAIA,QAAM,gBAAgB,eAAe,UAAU,UAAU;AACzD,MAAI,CAAC,cAAc,SAAS;AAC1B,UAAM,IAAI,MAAM,2BAA2B,EAAE,OAAO,cAAc,MAAM,CAAC;AAAA,EAC3E;AACA,QAAM,WAAW,cAAc;AAI/B,MAAI,SAAS,OAAO,IAAI;AACtB,UAAM,IAAI,MAAM,2BAA2B;AAAA,MACzC,OAAO,IAAI,MAAM,qCAAqC,EAAE,oBAAoB,SAAS,EAAE,EAAE;AAAA,IAC3F,CAAC;AAAA,EACH;AAIA,MAAI,SAAS,WAAW,WAAW;AACjC,UAAM,IAAI,MAAM,qDAAqD,SAAS,MAAM,EAAE;AAAA,EACxF;AAMA,QAAM,aAAa,KAAK,MAAM,UAAU,SAAS,UAAU;AAC3D,mBAAiB,MAAM,aAAa,YAAY;AAAA,IAC9C,WAAW,CAAC,MAAM,mBAAmB,GAAG,SAAS,UAAU;AAAA,EAC7D,CAAC,GAAG;AACF,QACE,gBAAgB,EAAE,KAClB,GAAG,gBAAgB,SAAS,OAC3B,GAAG,SAAS,uBACX,GAAG,SAAS,uBACZ,GAAG,SAAS,qBACd;AACA,YAAM,IAAI,MAAM,iDAAiD,OAAO,EAAE;AAAA,IAC5E;AAAA,EACF;AAKA,QAAM,MAAM,oBAAI,KAAK;AACrB,MAAI,cAAc,UAAU,GAAG,GAAG;AAChC,UAAM,IAAI,MAAM,6BAA6B,OAAO,EAAE;AAAA,EACxD;AAGA,QAAM,aAAa,IAAI,YAAY;AACnC,QAAM,UAAU,aAAa,KAAK;AAKlC,MAAI,aAAa,WAAW;AAC1B,UAAM,OAAQ,QAAmC,QAAQ;AACzD,UAAM,YAAY,YAAY;AAAA,MAC5B,gBAAgB;AAAA,MAChB,IAAI;AAAA,MACJ,YAAY,SAAS;AAAA,MACrB,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,aAAa,SAAS;AAAA,MACtB,UAAU;AAAA,MACV;AAAA,IACF,CAAC;AAAA,EACH,OAAO;AACL,UAAM,SAAU,QAAkC;AAClD,UAAM,YAAY,YAAY;AAAA,MAC5B,gBAAgB;AAAA,MAChB,IAAI;AAAA,MACJ,YAAY,SAAS;AAAA,MACrB,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,aAAa,SAAS;AAAA,MACtB,UAAU;AAAA,MACV;AAAA,IACF,CAAC;AAAA,EACH;AAGA,QAAM,mBACJ,aAAa,YACT;AAAA,IACE,GAAG;AAAA,IACH,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,aAAa;AAAA,IACb,MAAO,QAAmC,QAAQ;AAAA,EACpD,IACA;AAAA,IACE,GAAG;AAAA,IACH,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,aAAa;AAAA,IACb,kBAAmB,QAAkC;AAAA,EACvD;AAMN,QAAM,eAAe,KAAK,MAAM,UAAU,UAAU,GAAG,EAAE,OAAO;AAChE,MAAI;AACF,UAAM,aAAa,cAAc,gBAAgB;AAAA,EACnD,SAAS,OAAgB;AACvB,UAAM,QAAQ,iBAAiB,QAAQ,MAAM,QAAQ;AACrD,QAAI,iBAAiB,SAAU,MAAqC,SAAS,UAAU;AACrF,YAAM,IAAI,MAAM,8CAA8C,EAAE,MAAM,CAAC;AAAA,IACzE;AACA,UAAM;AAAA,EACR;AAKA,MAAI;AACF,UAAM,OAAO,WAAW;AAAA,EAC1B,QAAQ;AACN,YAAQ;AAAA,MACN,+CAA+C,QAAQ,EAAE,CAAC;AAAA,IAC5D;AAAA,EACF;AAGA,QAAM,OAAO,aAAa,YAAY,aAAa;AACnD,UAAQ,IAAI,GAAG,IAAI,aAAa,QAAQ,EAAE,CAAC,EAAE;AAC/C;AAIA,eAAe,kBACb,OACA,OACqD;AACrD,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,IAAI,MAAM,sBAAsB;AAAA,EACxC;AACA,QAAM,aAAa,QAAQ,WAAW,WAAW,IAAI,UAAU,GAAG,WAAW,GAAG,OAAO;AAGvF,MAAI,WAAW,UAAU,YAAY,QAAQ;AAC3C,UAAM,IAAI,MAAM,uBAAuB,KAAK,EAAE;AAAA,EAChD;AAEA,QAAM,cAAc,MAAM,mBAAmB,KAAK;AAIlD,QAAM,OAAO,oBAAI,IAA8B;AAC/C,aAAWC,OAAM,YAAY,SAAS;AACpC,QAAIA,IAAG,WAAW,UAAU,EAAG,MAAK,IAAIA,KAAI,SAAS;AAAA,EACvD;AACA,aAAWA,OAAM,YAAY,UAAU;AACrC,QAAI,CAACA,IAAG,WAAW,UAAU,EAAG;AAChC,QAAI,KAAK,IAAIA,GAAE,MAAM,WAAW;AAE9B,cAAQ,MAAM,oCAAoC,QAAQA,GAAE,CAAC,8BAA8B;AAAA,IAC7F;AACA,SAAK,IAAIA,KAAI,UAAU;AAAA,EACzB;AAEA,MAAI,KAAK,SAAS,GAAG;AACnB,UAAM,IAAI,MAAM,uBAAuB,KAAK,EAAE;AAAA,EAChD;AACA,MAAI,KAAK,OAAO,GAAG;AACjB,UAAM,IAAI;AAAA,MACR,0BAA0B,KAAK,cAAc,KAAK,IAAI;AAAA,IACxD;AAAA,EACF;AACA,QAAM,QAAQ,KAAK,QAAQ,EAAE,KAAK,EAAE;AACpC,MAAI,UAAU,QAAW;AACvB,UAAM,IAAI,MAAM,uBAAuB,KAAK,EAAE;AAAA,EAChD;AACA,QAAM,CAAC,IAAI,QAAQ,IAAI;AACvB,SAAO,EAAE,IAAI,SAAS;AACxB;AAEA,SAAS,gBAAgB,IAAkD;AACzE,SACE,GAAG,SAAS,wBACZ,GAAG,SAAS,uBACZ,GAAG,SAAS,uBACZ,GAAG,SAAS;AAEhB;AAEA,SAAS,sBAAsB,SAAqC;AAIlE,QAAM,SAAS,QAAQ,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE;AAC/C,QAAM,WAAW,uBAAuB,MAAM;AAC9C,QAAM,OAAO,QAAQ,IAAI,CAAC,MAAM;AAC9B,UAAM,MAAM,WAAW,EAAE,SAAS,IAAI,QAAQ;AAC9C,UAAM,SAAS,EAAE,cAAc,GAAG,EAAE,SAAS,MAAM,eAAe,EAAE,SAAS;AAC7E,UAAM,OAAO,EAAE,SAAS;AACxB,UAAM,SAAS,EAAE,SAAS,OAAO;AACjC,UAAM,YAAY,EAAE,SAAS;AAC7B,UAAM,SAAS,SAAS,EAAE,SAAS,QAAQ,mBAAmB;AAC9D,WAAO,EAAE,KAAK,QAAQ,MAAM,QAAQ,WAAW,OAAO;AAAA,EACxD,CAAC;AAED,QAAM,SAAS;AAAA,IACb,KAAK;AAAA,MACH,KAAK,IAAI,CAAC,MAAM,EAAE,GAAG;AAAA,MACrB,WAAW;AAAA,IACb;AAAA,IACA,QAAQ;AAAA,MACN,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM;AAAA,MACxB,SAAS;AAAA,IACX;AAAA,IACA,MAAM;AAAA,MACJ,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,MACtB,OAAO;AAAA,IACT;AAAA,IACA,QAAQ;AAAA,MACN,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM;AAAA,MACxB,SAAS;AAAA,IACX;AAAA,IACA,WAAW;AAAA,MACT,KAAK,IAAI,CAAC,MAAM,EAAE,SAAS;AAAA,MAC3B,aAAa;AAAA,IACf;AAAA,EACF;AAEA,UAAQ;AAAA,IACN,GAAG,IAAI,YAAY,OAAO,GAAG,CAAC,KAAK,IAAI,UAAU,OAAO,MAAM,CAAC,KAAK,IAAI,QAAQ,OAAO,IAAI,CAAC,KAAK,IAAI,UAAU,OAAO,MAAM,CAAC,KAAK,IAAI,cAAc,OAAO,SAAS,CAAC;AAAA,EACvK;AACA,aAAW,OAAO,MAAM;AACtB,YAAQ;AAAA,MACN,GAAG,IAAI,IAAI,KAAK,OAAO,GAAG,CAAC,KAAK,IAAI,IAAI,QAAQ,OAAO,MAAM,CAAC,KAAK,IAAI,IAAI,MAAM,OAAO,IAAI,CAAC,KAAK,IAAI,IAAI,QAAQ,OAAO,MAAM,CAAC,KAAK,IAAI,IAAI,WAAW,OAAO,SAAS,CAAC,KAAK,IAAI,MAAM;AAAA,IAC1L;AAAA,EACF;AACF;AAEA,SAAS,sBACP,UACA,WACA,QACA,aACM;AACN,UAAQ,IAAI,aAAa,SAAS,EAAE,cAAc,SAAS,MAAM,GAAG;AACpE,UAAQ,IAAI,mBAAmB,SAAS,UAAU,EAAE;AACpD,UAAQ,IAAI,mBAAmB,SAAS,UAAU,EAAE;AACpD,UAAQ,IAAI,mBAAmB,SAAS,UAAU,EAAE;AACpD,UAAQ,IAAI,mBAAmB,iBAAiB,SAAS,MAAM,CAAC,EAAE;AAClE,UAAQ,IAAI,mBAAmB,SAAS,MAAM,EAAE;AAChD,QAAM,eAAe,mBAAmB,SAAS,YAAY,WAAW;AACxE,UAAQ,IAAI,mBAAmB,YAAY,EAAE;AAC7C,UAAQ,IAAI,mBAAmB,SAAS,YAAY,QAAQ,EAAE;AAC9D,UAAQ,IAAI,mBAAmB,SAAS,eAAe,QAAQ,EAAE;AACjE,UAAQ,IAAI,mBAAmB,SAAS,QAAQ,QAAQ,EAAE;AAC1D,UAAQ,IAAI,qBAAqB,SAAS,oBAAoB,QAAQ,EAAE;AAExE,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,mBAAmB,OAAO,MAAM,QAAQ;AACpD,aAAW,MAAM,QAAQ;AACvB,YAAQ,IAAI,KAAK,wBAAwB,EAAE,CAAC,EAAE;AAAA,EAChD;AACF;AAEA,SAAS,iBAAiB,QAA4D;AACpF,QAAM,SAAmB,CAAC;AAC1B,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,QAAQ,OAAQ;AACpB,QAAI,OAAO,UAAU,SAAU;AAC/B,WAAO,KAAK,GAAG,GAAG,KAAK,SAAS,OAAO,yBAAyB,CAAC,GAAG;AACpE,QAAI,OAAO,UAAU,EAAG;AAAA,EAC1B;AACA,SAAO,OAAO,WAAW,IAAI,OAAO,OAAO,GAAG,OAAO,IAAI,KAAK,OAAO,KAAK,IAAI,CAAC;AACjF;AAEA,SAAS,mBAAmB,WAA0B,aAA8B;AAClF,MAAI,cAAc,KAAM,QAAO;AAC/B,SAAO,cAAc,GAAG,SAAS,eAAe;AAClD;AAEA,SAAS,wBAAwB,IAAmB;AAClD,QAAM,UAAU,qBAAqB,EAAE;AACvC,SAAO,GAAG,GAAG,WAAW,KAAK,GAAG,MAAM,MAAM,GAAG,IAAI,KAAK,OAAO;AACjE;AAEA,SAAS,qBAAqB,IAAmB;AAC/C,UAAQ,GAAG,MAAM;AAAA,IACf,KAAK;AACH,aAAO,GAAG,GAAG,OAAO,IAAI,SAAS,GAAG,UAAU;AAAA,IAChD,KAAK;AACH,aAAO,GAAG,aAAa,SAAY,MAAM,GAAG,QAAQ,KAAK;AAAA,IAC3D,KAAK;AACH,aAAO,GAAG,aAAa,SAAY,MAAM,GAAG,QAAQ,KAAK,GAAG,MAAM,KAAK,GAAG;AAAA,IAC5E,KAAK;AACH,aAAO,YAAY,GAAG,WAAW;AAAA,IACnC;AAEE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,QAAQ,IAAoB;AACnC,SAAO,WAAW,IAAI,iBAAiB;AACzC;AAMA,IAAM,oBAAoB,CAAC,SAAS,QAAQ,QAAQ,OAAO,SAAS,WAAW;AAE/E,SAAS,WAAW,IAAY,KAAqB;AACnD,aAAW,UAAU,mBAAmB;AACtC,QAAI,GAAG,WAAW,MAAM,GAAG;AACzB,aAAO,GAAG,MAAM,OAAO,QAAQ,OAAO,SAAS,GAAG;AAAA,IACpD;AAAA,EACF;AACA,SAAO,GAAG,MAAM,GAAG,GAAG;AACxB;AAEA,SAAS,uBAAuB,KAAgC;AAC9D,MAAI,IAAI,UAAU,EAAG,QAAO;AAC5B,WAAS,MAAM,mBAAmB,OAAO,kBAAkB,OAAO,GAAG;AACnE,UAAM,OAAO,oBAAI,IAAY;AAC7B,QAAI,WAAW;AACf,eAAW,MAAM,KAAK;AACpB,YAAM,MAAM,WAAW,IAAI,GAAG;AAC9B,UAAI,KAAK,IAAI,GAAG,GAAG;AACjB,mBAAW;AACX;AAAA,MACF;AACA,WAAK,IAAI,GAAG;AAAA,IACd;AACA,QAAI,CAAC,SAAU,QAAO;AAAA,EACxB;AACA,SAAO;AACT;AAEA,SAAS,IAAI,OAAe,OAAuB;AACjD,SAAO,MAAM,UAAU,QAAQ,QAAQ,QAAQ,IAAI,OAAO,QAAQ,MAAM,MAAM;AAChF;AAEA,SAAS,OAAO,QAA2B,OAAuB;AAChE,MAAI,MAAM;AACV,aAAW,KAAK,OAAQ,KAAI,EAAE,SAAS,IAAK,OAAM,EAAE;AACpD,SAAO;AACT;AAEA,SAAS,SAAS,OAAe,WAA2B;AAC1D,MAAI,MAAM,UAAU,UAAW,QAAO;AACtC,SAAO,GAAG,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC;AACzC;AAEA,eAAe,iCACb,KACA,QACiB;AACjB,MAAI;AACF,WAAO,MAAM,sBAAsB,GAAG;AAAA,EACxC,SAAS,OAAgB;AACvB,QAAI,iBAAiB,SAAS,MAAM,YAAY,wBAAwB;AACtE,YAAM,IAAI;AAAA,QACR,2EAA2E,MAAM;AAAA,QACjF,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAe,2BAA2B,WAAkC;AAC1E,MAAI;AACF,UAAM,oBAAoB,SAAS;AAAA,EACrC,SAAS,OAAgB;AACvB,QAAI,cAAc,OAAO,QAAQ,GAAG;AAClC,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AACA,UAAM;AAAA,EACR;AACF;AAEA,SAAS,kBAAkB,OAAwB;AACjD,MAAI,iBAAiB,OAAO;AAC1B,QAAI,MAAM,YAAY,sBAAuB,QAAO;AACpD,QAAI,MAAM,YAAY,+BAAgC,QAAO;AAC7D,WAAO,MAAM;AAAA,EACf;AACA,SAAO,OAAO,KAAK;AACrB;AAEA,SAAS,oBAAoB,KAA6B;AACxD,QAAM,SAAS,qBAAqB,UAAU,GAAG;AACjD,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,IAAI,MAAM,4BAA4B,GAAG,mBAAmB,cAAc,KAAK,IAAI,CAAC,EAAE;AAAA,EAC9F;AACA,SAAO,OAAO;AAChB;AAEA,SAAS,iBAAiB,SAAoC;AAC5D,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ,IAAI,IAAI;AAAA,EAClB,OAAO;AACL,YAAQ,IAAI,qBAAqB;AAAA,EACnC;AACF;;;AE9vBA;AAAA,EAIE;AAAA,EACA;AAAA,EACA,uBAAAC;AAAA,EACA,cAAAC;AAAA,EACA;AAAA,EACA,iBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA;AAAA,EACA,yBAAAC;AAAA,EACA;AAAA,OACK;AACP,SAAuB,4BAA4B;AAanD,IAAM,kBAAkB;AACxB,IAAM,sBAAsB,kBAAkB;AA0BvC,SAAS,wBAAwBC,UAAwB;AAC9D,QAAM,WAAWA,SACd,QAAQ,UAAU,EAClB,YAAY,2CAA2C;AAE1D,WACG,QAAQ,QAAQ,EAChB,YAAY,kCAAkC,EAC9C,eAAe,kBAAkB,kBAAkB,UAAU,EAC7D,OAAO,sBAAsB,8BAA8B,cAAc,EACzE;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,UAAU,2BAA2B,EAC5C,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,YAAmC;AAChD,UAAM,kBAAkB,OAAO;AAAA,EACjC,CAAC;AACL;AAOA,eAAsB,kBACpB,SACA,MAAuB,CAAC,GACT;AACf,MAAI;AACF,UAAM,oBAAoB,SAAS,GAAG;AAAA,EACxC,SAAS,OAAgB;AACvB,mBAAe,OAAO;AAAA,MACpB,SAAS,UAAU,OAAO;AAAA,MAC1B,aAAa,CAAC,0BAA0B;AAAA,IAC1C,CAAC;AACD,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAsB,oBACpB,SACA,KACe;AACf,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,iCAAiC,GAAG;AACjE,QAAM,QAAQC,YAAW,cAAc;AACvC,QAAMC,4BAA2B,MAAM,IAAI;AAE3C,QAAM,MAAM,IAAI,gBAAgB,SAAY,IAAI,YAAY,IAAI,oBAAI,KAAK;AACzE,QAAM,aAAa,IAAI,YAAY;AACnC,QAAM,aAAaC,cAAa,UAAU;AAE1C,QAAM,OAAO,eAAe,OAAO;AAEnC,MAAI,QAAQ,YAAY,QAAW;AACjC,UAAM,YAAY,MAAM,iBAAiB,OAAO,QAAQ,OAAO;AAC/D,UAAM,QAAQ;AAMd,UAAM,cAAc,MAAM,YAAY,OAAO,WAAW,KAAK;AAC7D,QAAI;AACJ,QAAI;AACF,eAAS,MAAM,6BAA6B;AAAA,QAC1C;AAAA,QACA,WAAW;AAAA,QACX,cAAc,CAAC,YACb,mBAAmB;AAAA,UACjB;AAAA,UACA,WAAW;AAAA,UACX;AAAA,UACA,OAAO,QAAQ;AAAA,UACf;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACL,CAAC;AAAA,IACH,UAAE;AACA,YAAM,YAAY,QAAQ;AAAA,IAC5B;AACA,wBAAoB,SAAS;AAAA,MAC3B,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,SAAS,OAAO;AAAA,MAChB,eAAe,OAAO;AAAA,MACtB,OAAO,QAAQ;AAAA,MACf;AAAA,IACF,CAAC;AACD;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,aAAa,KAAK;AACzC,QAAM,QAAQ,MAAM,4BAA4B;AAAA,IAC9C;AAAA,IACA;AAAA,IACA,OAAO,gBAAgB,QAAQ,KAAK;AAAA,IACpC;AAAA,IACA,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,YAAY;AAAA,MACV,SAAS;AAAA,MACT,MAAM,CAAC,WAAW,QAAQ,KAAK;AAAA,IACjC;AAAA,IACA,qBAAqB;AAAA,MACnB,CAAC,WAAW,YACV,mBAAmB;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,QAAQ;AAAA,QACf;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACL;AAAA,EACF,CAAC;AACD,sBAAoB,SAAS;AAAA,IAC3B,MAAM;AAAA,IACN,WAAW,MAAM;AAAA,IACjB;AAAA,IACA,SAAS,MAAM,eAAe,CAAC;AAAA,IAC/B,eAAe;AAAA,IACf,OAAO,QAAQ;AAAA,IACf;AAAA,EACF,CAAC;AACH;AAUA,SAAS,eAAe,SAAoD;AAC1E,QAAM,MAA0B,CAAC;AACjC,MAAI,QAAQ,cAAc,OAAW,KAAI,YAAY,QAAQ;AAC7D,MAAI,QAAQ,mBAAmB,OAAW,KAAI,kBAAkB,QAAQ;AACxE,MAAI,QAAQ,gBAAgB,UAAa,QAAQ,YAAY,SAAS,GAAG;AACvE,QAAI,eAAe,CAAC,GAAG,QAAQ,WAAW;AAAA,EAC5C;AACA,MAAI,QAAQ,gBAAgB,UAAa,QAAQ,YAAY,SAAS,GAAG;AACvE,QAAI,gBAAgB,CAAC,GAAG,QAAQ,WAAW;AAAA,EAC7C;AACA,MAAI,QAAQ,eAAe,UAAa,QAAQ,WAAW,SAAS,GAAG;AACrE,QAAI,eAAe,CAAC,GAAG,QAAQ,UAAU;AAAA,EAC3C;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,OAOlB;AACR,SAAO;AAAA,IACL,gBAAgB;AAAA,IAChB,IAAI,MAAM;AAAA,IACV,YAAY,MAAM;AAAA,IAClB,aAAa,MAAM;AAAA,IACnB,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,aAAa,MAAM;AAAA,IACnB,OAAO,MAAM;AAAA,IACb,GAAI,MAAM,KAAK,cAAc,SAAY,EAAE,WAAW,MAAM,KAAK,UAAU,IAAI,CAAC;AAAA,IAChF,GAAI,MAAM,KAAK,iBAAiB,SAAY,EAAE,cAAc,MAAM,KAAK,aAAa,IAAI,CAAC;AAAA,IACzF,GAAI,MAAM,KAAK,oBAAoB,SAC/B,EAAE,iBAAiB,MAAM,KAAK,gBAAgB,IAC9C,CAAC;AAAA,IACL,GAAI,MAAM,KAAK,kBAAkB,SAC7B,EAAE,eAAe,MAAM,KAAK,cAAwC,IACpE,CAAC;AAAA,IACL,GAAI,MAAM,KAAK,iBAAiB,SAAY,EAAE,cAAc,MAAM,KAAK,aAAa,IAAI,CAAC;AAAA,EAC3F;AACF;AAEA,SAAS,gBAAgB,OAAuB;AAC9C,QAAM,YACJ,MAAM,SAAS,kBAAkB,GAAG,MAAM,MAAM,GAAG,mBAAmB,CAAC,QAAQ;AACjF,SAAO,oBAAoB,SAAS;AACtC;AAEA,SAAS,WAAW,KAAqB;AACvC,MAAI,IAAI,WAAW,GAAG;AACpB,UAAM,IAAI,qBAAqB,yBAAyB;AAAA,EAC1D;AACA,SAAO;AACT;AAEA,SAAS,eAAe,KAAqB;AAC3C,MAAI,IAAI,WAAW,GAAG;AACpB,UAAM,IAAI,qBAAqB,6BAA6B;AAAA,EAC9D;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,KAAqB;AAChD,MAAI,IAAI,WAAW,GAAG;AACpB,UAAM,IAAI,qBAAqB,mCAAmC;AAAA,EACpE;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,OAAe,MAA0B;AACnE,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,IAAI,qBAAqB,+BAA+B;AAAA,EAChE;AACA,SAAO,KAAK,OAAO,KAAK;AAC1B;AAEA,IAAM,cAAc;AAEpB,SAAS,mBAAmB,OAAe,MAA0B;AACnE,MAAI,CAAC,YAAY,KAAK,KAAK,GAAG;AAC5B,UAAM,IAAI,qBAAqB,+CAA+C,KAAK,GAAG;AAAA,EACxF;AACA,SAAO,KAAK,OAAO,KAAK;AAC1B;AAEA,SAAS,kBAAkB,OAAe,MAA0B;AAClE,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,IAAI,qBAAqB,oCAAoC;AAAA,EACrE;AACA,MAAI,MAAM,SAAS,MAAM;AACvB,UAAM,IAAI,qBAAqB,qCAAqC;AAAA,EACtE;AACA,SAAO,KAAK,OAAO,KAAK;AAC1B;AAYA,SAAS,oBAAoB,SAAgC,QAAkC;AAC7F,QAAM,MAAM,eAAe,OAAO,SAAS;AAC3C,MAAI,QAAQ,SAAS,MAAM;AACzB,UAAM,UAAmC;AAAA,MACvC,aAAa,OAAO;AAAA,MACpB,UAAU,OAAO;AAAA,MACjB,YAAY,OAAO;AAAA,MACnB,gBAAgB,OAAO;AAAA,MACvB,MAAM,OAAO;AAAA,MACb,OAAO,OAAO;AAAA,IAChB;AAIA,QAAI,OAAO,KAAK,cAAc,OAAW,SAAQ,YAAY,OAAO,KAAK;AACzE,QAAI,OAAO,KAAK,iBAAiB,OAAW,SAAQ,eAAe,OAAO,KAAK;AAC/E,QAAI,OAAO,KAAK,oBAAoB,QAAW;AAC7C,cAAQ,kBAAkB,OAAO,KAAK;AAAA,IACxC;AACA,QAAI,OAAO,KAAK,kBAAkB,OAAW,SAAQ,gBAAgB,OAAO,KAAK;AACjF,QAAI,OAAO,KAAK,iBAAiB,OAAW,SAAQ,eAAe,OAAO,KAAK;AAC/E,YAAQ,IAAI,KAAK,UAAU,OAAO,CAAC;AACnC;AAAA,EACF;AACA,QAAM,kBACJ,OAAO,KAAK,cAAc,SAAY,gBAAgB,OAAO,KAAK,SAAS,MAAM;AACnF,MAAI,OAAO,SAAS,UAAU;AAC5B,YAAQ,IAAI,YAAY,OAAO,UAAU,sBAAsB,GAAG,GAAG,eAAe,EAAE;AAAA,EACxF,OAAO;AACL,YAAQ;AAAA,MACN,YAAY,OAAO,UAAU,eAAe,GAAG,KAAK,OAAO,aAAa,IAAI,eAAe;AAAA,IAC7F;AAAA,EACF;AACF;AAEA,eAAe,iCAAiC,KAA8B;AAC5E,MAAI;AACF,WAAO,MAAMC,uBAAsB,GAAG;AAAA,EACxC,SAAS,OAAgB;AACvB,QAAI,iBAAiB,SAAS,MAAM,YAAY,wBAAwB;AACtE,YAAM,IAAI;AAAA,QACR;AAAA,QACA,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAeF,4BAA2B,WAAkC;AAC1E,MAAI;AACF,UAAMG,qBAAoB,SAAS;AAAA,EACrC,SAAS,OAAgB;AACvB,QAAIC,eAAc,OAAO,QAAQ,GAAG;AAClC,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AACA,UAAM;AAAA,EACR;AACF;;;AC9XA;AAAA,EACE,uBAAAC;AAAA,EACA,cAAAC;AAAA,EACA,iBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,yBAAAC;AAAA,EACA;AAAA,OACK;AAiBA,SAAS,yBAAyBC,UAAwB;AAC/D,QAAM,YAAYA,SACf,QAAQ,WAAW,EACnB,YAAY,yCAAyC;AAExD,YACG,QAAQ,UAAU,EAClB,YAAY,8DAA8D,EAC1E,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,SAAmC;AAChD,UAAM,qBAAqB,IAAI;AAAA,EACjC,CAAC;AACL;AAEA,eAAsB,qBACpB,SACA,MAAwB,CAAC,GACV;AACf,MAAI;AACF,UAAM,uBAAuB,SAAS,GAAG;AAAA,EAC3C,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,EAAE,CAAC;AACrD,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAsB,uBACpB,SACA,KACe;AACf,OAAK;AACL,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,kCAAkC,GAAG;AAClE,QAAM,QAAQC,YAAW,cAAc;AACvC,QAAMC,4BAA2B,MAAM,IAAI;AAE3C,QAAM,UAAU,IAAI,cAAc,KAAK,oBAAI,KAAK,GAAG,YAAY;AAC/D,QAAM,SAAS,MAAM,gBAAgB;AAAA,IACnC;AAAA,IACA;AAAA,IACA,WAAW,CAAC,GAAG,QAAQ,mBAAmB,GAAG,GAAG;AAAA,IAChD,eAAe,CAAC,KAAK,WAAW,iBAAiB,KAAK,MAAM;AAAA,EAC9D,CAAC;AAED,QAAM,WAAW,MAAM,iBAAiB,MAAM,MAAM,SAAS;AAC7D,QAAM,YAAY,kBAAkB,UAAU,OAAO,MAAM,cAAc;AACzE,QAAM,kBAAkB,MAAM,MAAM,WAAW,SAAS;AAExD,UAAQ,IAAI,6CAA6C,OAAO,aAAa,GAAG;AAClF;AAEA,eAAe,kCAAkC,KAA8B;AAC7E,MAAI;AACF,WAAO,MAAMC,uBAAsB,GAAG;AAAA,EACxC,SAAS,OAAgB;AACvB,QAAI,iBAAiB,SAAS,MAAM,YAAY,wBAAwB;AACtE,YAAM,IAAI;AAAA,QACR;AAAA,QACA,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAeD,4BAA2B,WAAkC;AAC1E,MAAI;AACF,UAAME,qBAAoB,SAAS;AAAA,EACrC,SAAS,OAAgB;AACvB,QAAIC,eAAc,OAAO,QAAQ,GAAG;AAClC,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AACA,UAAM;AAAA,EACR;AACF;;;ACnGA,SAAS,aAAa;AACtB,SAAS,eAAe;AACxB,SAAS,QAAAC,aAAY;AAErB;AAAA,EACE;AAAA,EAKA;AAAA,EACA,uBAAAC;AAAA,EACA,cAAAC;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,yBAAAC;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAqCA,SAAS,oBAAoBC,UAAwB;AAC1D,EAAAA,SACG,QAAQ,0BAA0B,EAClC,YAAY,oDAAoD,EAKhE,mBAAmB,EACnB,OAAO,wBAAwB,uDAAuD,EACtF,OAAO,iBAAiB,4CAA4C,EACpE,OAAO,gBAAgB,gDAAgD,EACvE,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,SAAiB,MAAgB,YAAyB;AACvE,QAAI;AACF,YAAM,WAAW,MAAM,QAAQ,SAAS,MAAM,OAAO;AACrD,cAAQ,KAAK,QAAQ;AAAA,IACvB,SAAS,OAAgB;AACvB,qBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,EAAE,CAAC;AACrD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;AAEA,eAAsB,QACpB,SACA,MACA,SACA,MAAmB,CAAC,GACH;AACjB,QAAM,SAAS,IAAI,UAAU,IAAI,mBAAmB;AACpD,QAAM,MAAM,IAAI,QAAQ,MAAM,oBAAI,KAAK;AACvC,QAAMC,eAA6B,IAAI,eAAe;AACtD,QAAM,MAAM,QAAQ,OAAO,QAAQ,IAAI;AAGvC,QAAM,aAAa,QAAQ,YAAY,SAAY,cAAc,QAAQ,OAAO,IAAI;AAIpF,QAAM,WAAW,MAAM,6BAA6B,GAAG;AACvD,QAAM,QAAQC,YAAW,QAAQ;AAGjC,QAAMC,qBAAoB,MAAM,IAAI;AAGpC,QAAM,WAAW,MAAMC,cAAa,KAAK;AAGzC,QAAM,YAAYC,cAAa,KAAK;AACpC,QAAM,aAAaC,MAAK,MAAM,UAAU,SAAS;AACjD,QAAM,MAAM,YAAY,EAAE,WAAW,KAAK,CAAC;AAE3C,QAAM,YAAY,IAAI,EAAE,YAAY;AACpC,QAAM,kBAAkBA,MAAK,YAAY,cAAc;AACvD,QAAM,UAAU,oBAAoB;AAAA,IAClC,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,SAAS,UAAU;AAAA,IAChC;AAAA,EACF,CAAC;AACD,QAAM,cAAc,iBAAiB,OAAO;AAG5C,QAAML,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAII,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,QAAQ;AAAA,EACV,CAAC;AAGD,MAAI,QAAQ,aAAa,OAAO;AAC9B,UAAM,qBAAqB,YAAY,WAAW,UAAU,KAAKJ,YAAW;AAAA,EAC9E;AAGA,QAAM,YAAY,IAAI,EAAE,YAAY;AACpC,QAAMA,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAII,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,IAAI;AAAA,EACN,CAAC;AACD,QAAM,kBAAkB,iBAAiB,CAAC,MAAM;AAC9C,MAAE,QAAQ,SAAS;AAAA,EACrB,CAAC;AAID,QAAM,aAAa,IAAI,gBAAgB;AACvC,MAAI,iBAAwC;AAC5C,MAAI,cAAmC;AACvC,QAAM,gBAAgB,CAAC,QAAwB;AAC7C,QAAI,mBAAmB,KAAM;AAC7B,qBAAiB;AACjB,eAAW,MAAM;AAAA,EACnB;AACA,QAAM,cAAc,MAAM;AACxB,QAAI,gBAAgB,MAAM;AACxB,UAAI;AACF,oBAAY,KAAK,SAAS;AAAA,MAC5B,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAGA,QAAM,WAAW,MAAM,cAAc,QAAQ;AAC7C,QAAM,YAAY,MAAM,cAAc,SAAS;AAC/C,UAAQ,GAAG,UAAU,QAAQ;AAC7B,UAAQ,GAAG,WAAW,SAAS;AAC/B,UAAQ,GAAG,QAAQ,WAAW;AAG9B,MAAI,sBAAsB,WAAW;AAErC,MAAI;AACJ,MAAI;AACF,QAAI;AACF,eAAS,MAAM,OAAO,IAAI,SAAS,MAAM;AAAA,QACvC;AAAA,QACA,SAAS;AAAA,QACT,GAAI,eAAe,SAAY,EAAE,WAAW,IAAI,CAAC;AAAA,QACjD,QAAQ,WAAW;AAAA,QACnB,SAAS,CAAC,UAAU;AAClB,wBAAc;AAAA,QAChB;AAAA,MACF,CAAC;AAAA,IACH,SAAS,YAAqB;AAI5B,YAAM,wBAAwB,YAAY,iBAAiB,WAAWJ,cAAa;AAAA,QACjF;AAAA,QACA;AAAA,QACA;AAAA,QACA,YAAY,IAAI,EAAE,YAAY;AAAA,QAC9B;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF,UAAE;AACA,YAAQ,IAAI,UAAU,QAAQ;AAC9B,YAAQ,IAAI,WAAW,SAAS;AAChC,YAAQ,IAAI,QAAQ,WAAW;AAC/B,kBAAc;AAAA,EAChB;AAEA,QAAM,UAAU,IAAI,EAAE,YAAY;AAGlC,QAAMA,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAII,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,OAAO;AAAA,IAClB,GAAI,OAAO,WAAW,OAAO,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;AAAA,IAC1D,GAAI,mBAAmB,OAAO,EAAE,iBAAiB,eAAe,IAAI,CAAC;AAAA,IACrE,aAAa,OAAO;AAAA,EACtB,CAAC;AAID,MAAI,QAAQ,aAAa,OAAO;AAC9B,UAAM,qBAAqB,YAAY,WAAW,UAAU,KAAKJ,YAAW;AAAA,EAC9E;AAEA,QAAM,cAAc,kBAAkB,QAAQ,cAAc;AAG5D,QAAMA,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAII,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,IAAI;AAAA,EACN,CAAC;AAGD,QAAMJ,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAII,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,GAAI,OAAO,cAAc,OAAO,EAAE,WAAW,OAAO,UAAU,IAAI,CAAC;AAAA,EACrE,CAAC;AAGD,QAAM,kBAAkB,iBAAiB,CAAC,MAAM;AAC9C,MAAE,QAAQ,SAAS;AACnB,MAAE,QAAQ,WAAW;AACrB,MAAE,QAAQ,WAAW,YAAY,OAAO;AAAA,EAC1C,CAAC;AAED,MAAI,OAAO,cAAc,MAAM;AAC7B,WAAO,OAAO;AAAA,EAChB;AACA,SAAO,iBAAiB,kBAAkB,OAAO,MAAM;AACzD;AAEA,SAAS,kBACP,QACA,gBACwC;AACxC,MAAI,mBAAmB,YAAY,mBAAmB,UAAW,QAAO;AACxE,MAAI,OAAO,WAAW,YAAY,OAAO,WAAW,aAAa,OAAO,WAAW,WAAW;AAC5F,WAAO;AAAA,EACT;AACA,MAAI,OAAO,cAAc,EAAG,QAAO;AACnC,SAAO;AACT;AAEA,IAAM,aAAqC;AAAA,EACzC,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AACX;AAEA,SAAS,iBAAiB,KAAoC;AAC5D,MAAI,QAAQ,KAAM,QAAO;AACzB,QAAM,MAAM,WAAW,GAAG,KAAK;AAC/B,SAAO,MAAM;AACf;AAEA,eAAe,qBACb,YACA,WACA,UACA,KACAJ,cACe;AAKf,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,YAAY,QAAQ;AAAA,EACvC,SAAS,OAAgB;AACvB,YAAQ,KAAK,gCAAgC,KAAK,CAAC;AACnD;AAAA,EACF;AAOA,QAAMA,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAII,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa,IAAI,EAAE,YAAY;AAAA,IAC/B,QAAQ;AAAA,IACR,GAAG;AAAA,EACL,CAAC;AACH;AAEA,SAAS,gCAAgC,OAAwB;AAC/D,MAAI,EAAE,iBAAiB,QAAQ;AAC7B,WAAO,yBAAyB,OAAO,KAAK,CAAC;AAAA,EAC/C;AACA,QAAM,MAAM,MAAM;AAClB,MAAI,QAAQ,wBAAwB;AAClC,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,wDAAwD;AAClE,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,4BAA4B;AACtC,WAAO;AAAA,EACT;AACA,SAAO,yBAAyB,GAAG;AACrC;AAEA,SAAS,oBAAoB,OAOjB;AACV,QAAM,UAAU,CAAC,MAAM,SAAS,GAAG,MAAM,IAAI,EAAE,KAAK,GAAG;AACvD,SAAO;AAAA,IACL,gBAAgB;AAAA,IAChB,SAAS;AAAA,MACP,IAAI,MAAM;AAAA,MACV,OAAO,cAAc,OAAO,KAAK,MAAM,SAAS;AAAA,MAChD,SAAS;AAAA,MACT,cAAc,MAAM;AAAA,MACpB,QAAQ,EAAE,MAAM,YAAY,SAAS,QAAQ;AAAA,MAC7C,YAAY,MAAM;AAAA,MAClB,QAAQ;AAAA,MACR,mBAAmB,yBAAyB,MAAM,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;AAAA,MAC7E,YAAY;AAAA,QACV,SAAS,MAAM;AAAA,QACf,MAAM,CAAC,GAAG,MAAM,IAAI;AAAA,QACpB,WAAW;AAAA,MACb;AAAA,MACA,eAAe,CAAC;AAAA,MAChB,YAAY;AAAA,IACd;AAAA,EACF;AACF;AAEA,eAAe,kBACb,UACA,SACe;AACf,QAAM,MAAM,MAAME,cAAa,QAAQ;AACvC,QAAM,SAAS,cAAc,MAAM,GAAG;AACtC,UAAQ,MAAM;AAEd,QAAM,YAAY,cAAc,MAAM,MAAM;AAC5C,QAAM,kBAAkB,UAAU,SAAS;AAC7C;AAEA,eAAe,wBACb,YACA,iBACA,WACAN,cACA,KAOe;AACf,QAAMA,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAII,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa,IAAI;AAAA,IACjB,QAAQ;AAAA,IACR,SAAS,IAAI;AAAA,IACb,MAAM,IAAI;AAAA,IACV,KAAK,IAAI;AAAA,IACT,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,GAAI,IAAI,mBAAmB,OAAO,EAAE,iBAAiB,IAAI,eAAe,IAAI,CAAC;AAAA,IAC7E,aAAa;AAAA,EACf,CAAC;AACD,QAAMJ,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAII,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa,IAAI;AAAA,IACjB,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,IAAI;AAAA,EACN,CAAC;AACD,QAAMJ,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAII,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa,IAAI;AAAA,IACjB,QAAQ;AAAA,EACV,CAAC;AACD,QAAM,kBAAkB,iBAAiB,CAAC,MAAM;AAC9C,MAAE,QAAQ,SAAS;AACnB,MAAE,QAAQ,WAAW,IAAI;AACzB,MAAE,QAAQ,WAAW,YAAY;AAAA,EACnC,CAAC;AACH;AAEA,eAAe,6BAA6B,KAA8B;AACxE,MAAI;AACF,WAAO,MAAMG,uBAAsB,GAAG;AAAA,EACxC,SAAS,OAAgB;AACvB,QAAI,iBAAiB,SAAS,MAAM,YAAY,wBAAwB;AACtE,YAAM,IAAI,MAAM,yEAAyE;AAAA,QACvF,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AACA,UAAM;AAAA,EACR;AACF;;;ACpdA;AAAA,EACE,uBAAAC;AAAA,EACA,cAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,oBAAAC;AAAA,EACA;AAAA,EACA,qBAAAC;AAAA,EACA,yBAAAC;AAAA,EACA,qBAAAC;AAAA,OACK;AAwBA,SAAS,uBAAuBC,UAAwB;AAC7D,QAAM,UAAUA,SAAQ,QAAQ,SAAS,EAAE,YAAY,uCAAuC;AAE9F,UACG,QAAQ,UAAU,EAClB,YAAY,yDAAyD,EACrE,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,SAAiC;AAC9C,UAAM,mBAAmB,IAAI;AAAA,EAC/B,CAAC;AACL;AAMA,eAAsB,mBACpB,SACA,MAAsB,CAAC,GACR;AACf,MAAI;AACF,UAAM,qBAAqB,SAAS,GAAG;AAAA,EACzC,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,EAAE,CAAC;AACrD,YAAQ,WAAW;AAAA,EACrB;AACF;AAMA,eAAsB,qBACpB,SACA,KACe;AACf,OAAK;AACL,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,gCAAgC,GAAG;AAChE,QAAM,QAAQC,YAAW,cAAc;AACvC,QAAMC,4BAA2B,MAAM,IAAI;AAE3C,QAAM,UAAU,IAAI,cAAc,KAAK,oBAAI,KAAK,GAAG,YAAY;AAC/D,QAAM,SAAS,MAAM,cAAc;AAAA,IACjC;AAAA,IACA;AAAA,IACA,WAAW,CAAC,GAAG,QAAQ,mBAAmB,GAAG,GAAG;AAAA,IAChD,eAAe,CAAC,KAAK,WAAW,iBAAiB,KAAK,MAAM;AAAA,IAC5D,YAAY,CAAC,QAAQ,WAAW,cAAc,QAAQ,MAAM;AAAA,EAC9D,CAAC;AAED,QAAM,WAAW,MAAMC,kBAAiB,MAAM,MAAM,OAAO;AAC3D,QAAM,YAAYC,mBAAkB,UAAU,OAAO,MAAM,YAAY;AACvE,QAAMC,mBAAkB,MAAM,MAAM,SAAS,SAAS;AAEtD,UAAQ;AAAA,IACN,0CAA0C,OAAO,YAAY,YAAY,OAAO,SAAS,gBAAgB,OAAO,aAAa,wBAAwB,OAAO,qBAAqB;AAAA,EACnL;AACF;AAEA,eAAe,gCAAgC,KAA8B;AAC3E,MAAI;AACF,WAAO,MAAMC,uBAAsB,GAAG;AAAA,EACxC,SAAS,OAAgB;AACvB,QAAI,iBAAiB,SAAS,MAAM,YAAY,wBAAwB;AACtE,YAAM,IAAI;AAAA,QACR;AAAA,QACA,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAeJ,4BAA2B,WAAkC;AAC1E,MAAI;AACF,UAAMK,qBAAoB,SAAS;AAAA,EACrC,SAAS,OAAgB;AACvB,QAAIC,eAAc,OAAO,QAAQ,GAAG;AAClC,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AACA,UAAM;AAAA,EACR;AACF;;;ACpHA,SAAS,gBAAgB;AACzB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA,yBAAAC;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAwBA,SAAS,oBAAoBC,UAAwB;AAC1D,EAAAA,SACG,QAAQ,MAAM,EACd,YAAY,iEAAiE,EAC7E,OAAO,iBAAiB,4DAA4D,EACpF,OAAO,yBAAyB,sBAAsB,EACtD,OAAO,uCAAuC,qBAAqB,EACnE;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,eAAe,gCAAgC,EACtD,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,YAAyB;AACtC,UAAM,QAAQ,OAAO;AAAA,EACvB,CAAC;AACL;AAOA,eAAsB,QAAQ,SAAsB,MAAmB,CAAC,GAAkB;AACxF,MAAI;AACF,UAAM,UAAU,SAAS,GAAG;AAAA,EAC9B,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,EAAE,CAAC;AACrD,YAAQ,WAAW;AAAA,EACrB;AACF;AAQA,eAAsB,UAAU,SAAsB,KAAiC;AACrF,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,6BAA6B,GAAG;AAC7D,QAAM,gBAAgB,QAAQ,QAAQ,SAAS,cAAc;AAI7D,MAAI;AACJ,MAAI,QAAQ,YAAY,QAAW;AACjC,oBAAgB,QAAQ,YAAY,KAAK,OAAO,QAAQ;AAAA,EAC1D,OAAO;AACL,oBAAgB,MAAM,aAAa,cAAc;AAAA,EACnD;AAEA,QAAM,QAAQ,MAAM,qBAAqB,cAAc;AACvD,QAAM,WAAW,eAAe;AAAA,IAC9B;AAAA,IACA,GAAI,QAAQ,gBAAgB,SAAY,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,IAChF,GAAI,QAAQ,uBAAuB,SAC/B,EAAE,oBAAoB,QAAQ,mBAAmB,IACjD,CAAC;AAAA,IACL,GAAI,kBAAkB,SAAY,EAAE,cAAc,IAAI,CAAC;AAAA,EACzD,CAAC;AAED,QAAM,cAAc,OAAO,UAAU,EAAE,OAAO,QAAQ,UAAU,KAAK,CAAC;AAMtE,MAAI;AACF,UAAM,qBAAqB,cAAc;AAAA,EAC3C,SAAS,OAAgB;AACvB,2BAAuB,OAAO,UAAU,OAAO,CAAC;AAAA,EAClD;AAEA,UAAQ,IAAI,gCAAgC,SAAS,UAAU,EAAE,EAAE;AACrE;AAQA,SAAS,uBAAuB,OAAgB,SAAwB;AACtE,QAAM,cAAc,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAIzE,UAAQ;AAAA,IACN,yCAAyC,WAAW;AAAA,EACtD;AACA,MAAI,WAAW,iBAAiB,OAAO;AACrC,UAAM,QAAQ,kBAAkB,KAAK;AACrC,QAAI,UAAU,OAAW,SAAQ,MAAM,cAAc,KAAK,EAAE;AAAA,EAC9D;AACF;AAOA,eAAe,6BAA6B,KAA8B;AACxE,MAAI;AACF,WAAO,MAAMC,uBAAsB,GAAG;AAAA,EACxC,SAAS,OAAgB;AACvB,QAAI,iBAAiB,SAAS,MAAM,YAAY,wBAAwB;AACtE,YAAM,IAAI,MAAM,yEAAyE;AAAA,QACvF,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AACA,UAAM;AAAA,EACR;AACF;;;AChJA,SAAS,SAAAC,cAAa;AACtB,SAAS,WAAAC,gBAAe;AACxB,SAAS,QAAAC,aAAY;AAErB;AAAA,EACE,sBAAAC;AAAA,EAOA,iBAAAC;AAAA,EACA,uBAAAC;AAAA,EACA,cAAAC;AAAA,EACA;AAAA,EACA,eAAeC;AAAA,EACf;AAAA,EACA,eAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA;AAAA,EACA,yBAAAC;AAAA,EACA;AAAA,EACA,4BAAAC;AAAA,EACA,iBAAAC;AAAA,OACK;AAsDA,SAAS,mBAAmBC,UAAkB,MAAkB,CAAC,GAAS;AAC/E,QAAM,aAAaA,SAChB,QAAQ,KAAK,EACb,YAAY,0DAA0D,EAItE,wBAAwB,EACxB,OAAO,iBAAiB,4CAA4C,EACpE,OAAO,gBAAgB,gDAAgD,EACvE,OAAO,iBAAiB,mBAAmB;AAE9C,aACG,QAAQ,uBAAuB,EAC/B,YAAY,gDAAgD,EAG5D,OAAO,iBAAiB,4CAA4C,EACpE,OAAO,gBAAgB,gDAAgD,EACvE,OAAO,iBAAiB,mBAAmB,EAC3C,mBAAmB,EACnB,OAAO,OAAO,MAAgB,SAAqB,YAAqB;AACvE,UAAM,gBAAiB,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAKlD,UAAM,aAAa,cAAc,aAAa,SAAS,QAAQ,aAAa;AAC5E,UAAM,SAAqB;AAAA,MACzB,GAAG;AAAA,MACH,GAAG;AAAA,MACH,UAAU;AAAA,IACZ;AACA,QAAI;AACF,YAAM,WAAW,MAAM,cAAc,MAAM,QAAQ,GAAG;AACtD,cAAQ,KAAK,QAAQ;AAAA,IACvB,SAAS,OAAgB;AACvB,qBAAe,OAAO,EAAE,SAAS,UAAU,MAAM,EAAE,CAAC;AACpD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;AAEA,eAAsB,cACpB,MACA,SACA,MAAkB,CAAC,GACF;AACjB,QAAM,SAAS,IAAI,UAAU,IAAIC,oBAAmB;AACpD,QAAM,MAAM,IAAI,QAAQ,MAAM,oBAAI,KAAK;AACvC,QAAMC,eAA6B,IAAI,eAAeC;AACtD,QAAM,iBAAmC,IAAI,kBAAkB;AAC/D,QAAM,YAAuB,IAAI,WAAW;AAK5C,QAAM,EAAE,QAAQ,IAAI,MAAM,eAAe;AAEzC,QAAM,MAAM,QAAQ,OAAO,QAAQ,IAAI;AAGvC,QAAM,WAAW,MAAM,4BAA4B,GAAG;AACtD,QAAM,QAAQC,YAAW,QAAQ;AAGjC,QAAMC,qBAAoB,MAAM,IAAI;AAGpC,QAAM,WAAW,MAAMC,cAAa,KAAK;AAGzC,QAAM,YAAYC,cAAa,KAAK;AACpC,QAAM,aAAaC,MAAK,MAAM,UAAU,SAAS;AACjD,QAAMC,OAAM,YAAY,EAAE,WAAW,KAAK,CAAC;AAE3C,QAAM,YAAY,IAAI,EAAE,YAAY;AACpC,QAAM,kBAAkBD,MAAK,YAAY,cAAc;AACvD,QAAM,UAAUE,qBAAoB;AAAA,IAClC,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA,KAAK;AAAA,IACL,aAAa,SAAS,UAAU;AAAA,IAChC;AAAA,EACF,CAAC;AACD,QAAMC,eAAc,iBAAiB,OAAO;AAG5C,QAAMT,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAIK,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,QAAQ,0BAA0B;AAAA,EACpC,CAAC;AAGD,MAAI,cAAkC;AACtC,MAAI,QAAQ,aAAa,OAAO;AAC9B,kBAAc,MAAMK,sBAAqB,YAAY,WAAW,UAAU,KAAKV,YAAW;AAAA,EAC5F;AAGA,QAAM,YAAY,IAAI,EAAE,YAAY;AACpC,QAAMA,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAIK,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,QAAQ,0BAA0B;AAAA,IAClC,MAAM;AAAA,IACN,IAAI;AAAA,EACN,CAAC;AACD,QAAMM,mBAAkB,iBAAiB,CAAC,MAAM;AAC9C,MAAE,QAAQ,SAAS;AAAA,EACrB,CAAC;AAID,QAAM,aAAa,IAAI,gBAAgB;AACvC,MAAI,iBAAwC;AAC5C,MAAI,cAAmC;AACvC,QAAM,gBAAgB,CAAC,QAAwB;AAC7C,QAAI,mBAAmB,KAAM;AAC7B,qBAAiB;AACjB,eAAW,MAAM;AAAA,EACnB;AACA,QAAM,cAAc,MAAM;AACxB,QAAI,gBAAgB,MAAM;AACxB,UAAI;AACF,oBAAY,KAAK,SAAS;AAAA,MAC5B,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACA,QAAM,WAAW,MAAM,cAAc,QAAQ;AAC7C,QAAM,YAAY,MAAM,cAAc,SAAS;AAC/C,UAAQ,GAAG,UAAU,QAAQ;AAC7B,UAAQ,GAAG,WAAW,SAAS;AAC/B,UAAQ,GAAG,QAAQ,WAAW;AAC9B,MAAI,sBAAsB,WAAW;AAKrC,MAAI;AACJ,MAAI;AACF,QAAI;AACF,eAAS,MAAM,OAAO,IAAI,SAAS,MAAM;AAAA,QACvC,KAAK;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,WAAW;AAAA,QACnB,SAAS,CAAC,UAAU;AAClB,wBAAc;AAAA,QAChB;AAAA,MACF,CAAC;AAAA,IACH,SAAS,YAAqB;AAC5B,YAAMC,yBAAwB,YAAY,iBAAiB,WAAWZ,cAAa;AAAA,QACjF;AAAA,QACA;AAAA,QACA,KAAK;AAAA,QACL,YAAY,IAAI,EAAE,YAAY;AAAA,QAC9B;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF,UAAE;AACA,YAAQ,IAAI,UAAU,QAAQ;AAC9B,YAAQ,IAAI,WAAW,SAAS;AAChC,YAAQ,IAAI,QAAQ,WAAW;AAC/B,kBAAc;AAAA,EAChB;AAEA,QAAM,UAAU,IAAI,EAAE,YAAY;AAGlC,QAAMA,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAIK,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,KAAK;AAAA,IACL,WAAW,OAAO;AAAA,IAClB,GAAI,OAAO,WAAW,OAAO,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;AAAA,IAC1D,GAAI,mBAAmB,OAAO,EAAE,iBAAiB,eAAe,IAAI,CAAC;AAAA,IACrE,aAAa,OAAO;AAAA,EACtB,CAAC;AAGD,MAAI,eAAmC;AACvC,MAAI,QAAQ,aAAa,OAAO;AAC9B,mBAAe,MAAMK,sBAAqB,YAAY,WAAW,UAAU,KAAKV,YAAW;AAAA,EAC7F;AAKA,MAAI,OAA0B;AAC9B,MAAI,gBAAgB,QAAQ,iBAAiB,MAAM;AACjD,WAAO,MAAM;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,IAAI,EAAE,YAAY;AAAA,MAClBA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAQA,QAAM,aAAa,oBAAoB,aAAa,cAAc,IAAI;AACtE,QAAM,eAAe,qBAAqB,YAAY;AAAA,IACpD,kBAAkB;AAAA,IAClB,SAASa,SAAQ;AAAA,EACnB,CAAC,EAAE;AAEH,QAAM,cAAcC,mBAAkB,QAAQ,cAAc;AAG5D,QAAMd,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAIK,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,QAAQ,0BAA0B;AAAA,IAClC,MAAM;AAAA,IACN,IAAI;AAAA,EACN,CAAC;AAGD,QAAML,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAIK,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,QAAQ,0BAA0B;AAAA,IAClC,GAAI,OAAO,cAAc,OAAO,EAAE,WAAW,OAAO,UAAU,IAAI,CAAC;AAAA,EACrE,CAAC;AAID,QAAMM,mBAAkB,iBAAiB,CAAC,MAAM;AAC9C,MAAE,QAAQ,SAAS;AACnB,MAAE,QAAQ,WAAW;AACrB,MAAE,QAAQ,WAAW,YAAY,OAAO;AACxC,MAAE,QAAQ,gBAAgB;AAAA,EAC5B,CAAC;AAED,MAAI,OAAO,cAAc,KAAM,QAAO,OAAO;AAC7C,SAAOI,kBAAiB,kBAAkB,OAAO,MAAM;AACzD;AAEA,SAASD,mBACP,QACA,gBACwC;AACxC,MAAI,mBAAmB,YAAY,mBAAmB,UAAW,QAAO;AACxE,MAAI,OAAO,WAAW,YAAY,OAAO,WAAW,aAAa,OAAO,WAAW,WAAW;AAC5F,WAAO;AAAA,EACT;AACA,MAAI,OAAO,cAAc,EAAG,QAAO;AACnC,SAAO;AACT;AAEA,IAAME,cAAqC;AAAA,EACzC,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AACX;AAEA,SAASD,kBAAiB,KAAoC;AAC5D,MAAI,QAAQ,KAAM,QAAO;AACzB,QAAM,MAAMC,YAAW,GAAG,KAAK;AAC/B,SAAO,MAAM;AACf;AAEA,eAAeN,sBACb,YACA,WACA,UACA,KACAV,cAC6B;AAI7B,MAAI;AACJ,MAAI;AACF,eAAW,MAAMiB,aAAY,QAAQ;AAAA,EACvC,SAAS,OAAgB;AACvB,YAAQ,KAAKC,iCAAgC,KAAK,CAAC;AACnD,WAAO;AAAA,EACT;AAKA,QAAMlB,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAIK,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa,IAAI,EAAE,YAAY;AAAA,IAC/B,QAAQ;AAAA,IACR,GAAG;AAAA,EACL,CAAC;AACD,SAAO;AACT;AAEA,eAAe,2BACb,YACA,WACA,UACA,SACA,SACA,YACAL,cACA,WAC4B;AAG5B,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,UAAU,UAAU,SAAS,OAAO;AAAA,EACnD,SAAS,OAAgB;AACvB,YAAQ,KAAK,gCAAgC,KAAK,CAAC;AACnD,WAAO;AAAA,EACT;AAGA,aAAW,UAAU,KAAK,eAAe;AACvC,UAAMA,aAAY,YAAY;AAAA,MAC5B,gBAAgB;AAAA,MAChB,MAAM;AAAA,MACN,IAAIK,cAAa,KAAK;AAAA,MACtB,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,MAAM,OAAO;AAAA,MACb,aAAa,OAAO;AAAA,MACpB,GAAI,OAAO,aAAa,SAAY,EAAE,UAAU,OAAO,SAAS,IAAI,CAAC;AAAA,IACvE,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,oBACP,aACA,cACA,MACU;AACV,QAAM,MAAM,oBAAI,IAAY;AAC5B,aAAW,QAAQ,CAAC,aAAa,YAAY,GAAG;AAC9C,QAAI,SAAS,KAAM;AACnB,eAAW,KAAK,KAAK,OAAQ,KAAI,IAAI,CAAC;AACtC,eAAW,KAAK,KAAK,SAAU,KAAI,IAAI,CAAC;AACxC,eAAW,KAAK,KAAK,UAAW,KAAI,IAAI,CAAC;AAAA,EAC3C;AACA,MAAI,SAAS,MAAM;AACjB,eAAW,UAAU,KAAK,cAAe,KAAI,IAAI,OAAO,IAAI;AAAA,EAC9D;AACA,SAAO,CAAC,GAAG,GAAG,EAAE,KAAK;AACvB;AAEA,SAASa,iCAAgC,OAAwB;AAC/D,MAAI,EAAE,iBAAiB,QAAQ;AAC7B,WAAO,yBAAyB,OAAO,KAAK,CAAC;AAAA,EAC/C;AACA,QAAM,MAAM,MAAM;AAClB,MAAI,QAAQ,uBAAwB,QAAO;AAC3C,MAAI,QAAQ,wDAAwD;AAClE,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,2BAA4B,QAAO;AAC/C,SAAO,yBAAyB,GAAG;AACrC;AAEA,SAAS,gCAAgC,OAAwB;AAC/D,MAAI,EAAE,iBAAiB,QAAQ;AAC7B,WAAO,yBAAyB,OAAO,KAAK,CAAC;AAAA,EAC/C;AACA,QAAM,MAAM,MAAM;AAClB,MAAI,QAAQ,uBAAwB,QAAO;AAC3C,MAAI,QAAQ,wDAAwD;AAClE,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,cAAe,QAAO;AAClC,MAAI,QAAQ;AACV,WAAO;AACT,SAAO,yBAAyB,GAAG;AACrC;AAEA,SAASV,qBAAoB,OAOjB;AACV,QAAM,UAAU,CAAC,MAAM,SAAS,GAAG,MAAM,IAAI,EAAE,KAAK,GAAG;AACvD,SAAO;AAAA,IACL,gBAAgB;AAAA,IAChB,SAAS;AAAA,MACP,IAAI,MAAM;AAAA,MACV,OAAO,aAAa,OAAO,KAAK,MAAM,SAAS;AAAA,MAC/C,SAAS;AAAA,MACT,cAAc,MAAM;AAAA,MACpB,QAAQ,EAAE,GAAG,0BAA0B;AAAA,MACvC,YAAY,MAAM;AAAA,MAClB,QAAQ;AAAA,MACR,mBAAmBW,0BAAyB,MAAM,KAAK,EAAE,SAASN,SAAQ,EAAE,CAAC;AAAA,MAC7E,YAAY;AAAA,QACV,SAAS,MAAM;AAAA,QACf,MAAM,CAAC,GAAG,MAAM,IAAI;AAAA,QACpB,WAAW;AAAA,MACb;AAAA,MACA,eAAe,CAAC;AAAA,MAChB,YAAY;AAAA,IACd;AAAA,EACF;AACF;AAEA,eAAeF,mBACb,UACA,SACe;AACf,QAAM,MAAM,MAAMS,cAAa,QAAQ;AACvC,QAAM,SAASC,eAAc,MAAM,GAAG;AACtC,UAAQ,MAAM;AACd,QAAM,YAAYA,eAAc,MAAM,MAAM;AAC5C,QAAMC,mBAAkB,UAAU,SAAS;AAC7C;AAEA,eAAeV,yBACb,YACA,iBACA,WACAZ,cACA,KAOe;AACf,QAAMA,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAIK,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa,IAAI;AAAA,IACjB,QAAQ;AAAA,IACR,SAAS,IAAI;AAAA,IACb,MAAM,IAAI;AAAA,IACV,KAAK,IAAI;AAAA,IACT,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,GAAI,IAAI,mBAAmB,OAAO,EAAE,iBAAiB,IAAI,eAAe,IAAI,CAAC;AAAA,IAC7E,aAAa;AAAA,EACf,CAAC;AACD,QAAML,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAIK,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa,IAAI;AAAA,IACjB,QAAQ,0BAA0B;AAAA,IAClC,MAAM;AAAA,IACN,IAAI;AAAA,EACN,CAAC;AACD,QAAML,aAAY,YAAY;AAAA,IAC5B,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,IAAIK,cAAa,KAAK;AAAA,IACtB,YAAY;AAAA,IACZ,aAAa,IAAI;AAAA,IACjB,QAAQ,0BAA0B;AAAA,EACpC,CAAC;AACD,QAAMM,mBAAkB,iBAAiB,CAAC,MAAM;AAC9C,MAAE,QAAQ,SAAS;AACnB,MAAE,QAAQ,WAAW,IAAI;AACzB,MAAE,QAAQ,WAAW,YAAY;AAAA,EACnC,CAAC;AACH;AAEA,eAAe,4BAA4B,KAA8B;AACvE,MAAI;AACF,WAAO,MAAMY,uBAAsB,GAAG;AAAA,EACxC,SAAS,OAAgB;AACvB,QAAI,iBAAiB,SAAS,MAAM,YAAY,wBAAwB;AACtE,YAAM,IAAI,MAAM,wEAAwE;AAAA,QACtF,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AACA,UAAM;AAAA,EACR;AACF;;;ACxlBA,SAAS,gBAAgB;AACzB,SAAS,YAAAC,WAAU,YAAY,QAAAC,OAAM,gBAAgB;AACrD;AAAA,EAKE;AAAA,EACA,iBAAAC;AAAA,EAEA;AAAA,EACA,eAAAC;AAAA,EACA,gCAAAC;AAAA,EACA,uBAAAC;AAAA,EACA,cAAAC;AAAA,EACA,iBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,yBAAAC;AAAA,EACA,oBAAAC;AAAA,EACA;AAAA,OACK;AACP,SAAuB,wBAAAC,6BAA4B;AAQnD,IAAMC,cAAa;AACnB,IAAMC,eAAc;AACpB,IAAMC,qBAAoB;AAC1B,IAAMC,oBAAmB;AAEzB,IAAMC,iBAAgB,oBAAoB;AAmCnC,SAAS,uBAAuBC,UAAwB;AAC7D,QAAM,UAAUA,SACb,QAAQ,SAAS,EACjB,YAAY,sDAAsD;AAErE,UACG,QAAQ,MAAM,EACd,YAAY,uDAAuD,EACnE,OAAO,UAAU,iCAAiC,EAClD;AAAA,IACC;AAAA,IACA,qCAAqCD,eAAc,KAAK,IAAI,CAAC;AAAA,IAC7D;AAAA,EACF,EACC,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,YAAgC;AAC7C,UAAM,eAAe,OAAO;AAAA,EAC9B,CAAC;AAEH,UACG,QAAQ,WAAW,EACnB,YAAY,6CAA6C,EACzD,OAAO,UAAU,uCAAuC,EACxD,OAAO,YAAY,kDAAkD,EACrE,OAAO,cAAc,qDAAqD,gBAAgB,EAC1F;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,IAAY,YAAgC;AACzD,UAAM,eAAe,IAAI,OAAO;AAAA,EAClC,CAAC;AAEH,UACG,QAAQ,QAAQ,EAChB,YAAY,mCAAmC,EAC/C,eAAe,qBAAqB,wCAAwC,iBAAiB,EAC7F,eAAe,iBAAiB,6BAA6B,EAC7D,OAAO,kBAAkB,8BAA8B,kBAAkB,EACzE,OAAO,oBAAoB,gCAAgC,mBAAmB,EAC9E,OAAO,aAAa,2CAA2C,EAC/D,OAAO,UAAU,2BAA2B,EAC5C,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,YAAkC;AAC/C,UAAM,iBAAiB,OAAO;AAAA,EAChC,CAAC;AAEH,UACG,QAAQ,mBAAmB,EAC3B,YAAY,kDAAkD,EAC9D,OAAO,iBAAiB,sBAAsB,mBAAmB,EACjE,OAAO,sBAAsB,4BAA4B,EACzD,OAAO,UAAU,2BAA2B,EAC5C,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,gBAAwB,YAAgC;AACrE,UAAM,eAAe,gBAAgB,OAAO;AAAA,EAC9C,CAAC;AACL;AAOA,eAAsB,eACpB,SACA,MAAsB,CAAC,GACR;AACf,MAAI;AACF,UAAM,iBAAiB,SAAS,GAAG;AAAA,EACrC,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,EAAE,CAAC;AACrD,YAAQ,WAAW;AAAA,EACrB;AACF;AAMA,eAAsB,iBACpB,SACA,KACe;AACf,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,gCAAgC,KAAK,MAAM;AACxE,QAAM,QAAQE,YAAW,cAAc;AACvC,QAAMC,4BAA2B,MAAM,IAAI;AAM3C,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,WACJ,MAAM,mBAAmB,OAAO;AAAA,IAC9B;AAAA,IACA,WAAW,CAAC,GAAG,QAAQ,mBAAmB,GAAG,GAAG;AAAA,IAChD,QAAQ,CAAC,KAAK,WAAW,qBAAqB,KAAK,MAAM;AAAA,EAC3D,CAAC,GACD,IAAI,CAAC,WAAW;AAAA,IAChB,WAAW,MAAM;AAAA,IACjB,SAAS,MAAM;AAAA,IACf,SAAS,MAAM;AAAA,IACf,eAAe,MAAM;AAAA,EACvB,EAAE;AAEF,MAAI,QAAQ,WAAW,GAAG;AACxB,oBAAgB,OAAO;AACvB;AAAA,EACF;AAKA,UAAQ;AAAA,IACN,CAAC,GAAG,MAAM,KAAK,MAAM,EAAE,QAAQ,QAAQ,UAAU,IAAI,KAAK,MAAM,EAAE,QAAQ,QAAQ,UAAU;AAAA,EAC9F;AAEA,QAAM,WACJ,QAAQ,WAAW,SACf,QAAQ,OAAO,CAAC,MAAM,EAAE,QAAQ,QAAQ,WAAW,QAAQ,MAAM,IACjE;AAEN,MAAI,SAAS,WAAW,GAAG;AACzB,oBAAgB,OAAO;AACvB;AAAA,EACF;AAEA,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ;AAAA,MACN,KAAK;AAAA,QACH,SAAS,IAAI,CAAC,OAAO;AAAA,UACnB,GAAG,EAAE,QAAQ;AAAA,UACb,SAAS,EAAE;AAAA,UACX,gBAAgB,EAAE;AAAA,QACpB,EAAE;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AACL,yBAAqB,QAAQ;AAAA,EAC/B;AACF;AAMA,eAAsB,eACpB,SACA,SACA,MAAsB,CAAC,GACR;AACf,MAAI;AACF,UAAM,iBAAiB,SAAS,SAAS,GAAG;AAAA,EAC9C,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,EAAE,CAAC;AACrD,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAsB,iBACpB,SACA,SACA,KACe;AACf,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,gCAAgC,KAAK,MAAM;AACxE,QAAM,QAAQD,YAAW,cAAc;AACvC,QAAMC,4BAA2B,MAAM,IAAI;AAE3C,QAAM,YAAY,MAAMC,kBAAiB,OAAO,OAAO;AAEvD,QAAM,aAAaC,MAAK,MAAM,UAAU,SAAS;AACjD,QAAM,kBAAkBA,MAAK,YAAY,cAAc;AACvD,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAMC,cAAa,eAAe;AAC9C,cAAUC,eAAc,MAAM,GAAG;AAAA,EACnC,SAAS,OAAgB;AACvB,QAAIC,eAAc,OAAO,QAAQ,GAAG;AAClC,YAAM,IAAI,MAAM,sBAAsB,OAAO,EAAE;AAAA,IACjD;AACA,UAAM,IAAI,MAAM,0BAA0B,EAAE,OAAO,MAAM,CAAC;AAAA,EAC5D;AAEA,QAAM,SAAS,MAAM,cAAc,YAAY;AAAA,IAC7C,WAAW,CAAC,MAAM,mBAAmB,GAAG,SAAS;AAAA,EACnD,CAAC;AAED,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,QAAQ,SAAS,OAAO,GAAG,MAAM,CAAC,CAAC;AACzE;AAAA,EACF;AAEA,uBAAqB,SAAS,QAAQ,SAAS,cAAc;AAC/D;AAEA,SAAS,aAAa,QAA+B;AACnD,MAAI,WAAW,oCAAqC,QAAO;AAC3D,MAAI,WAAW,uBAAwB,QAAO;AAC9C,SAAO;AACT;AAEA,SAAS,qBAAqB,SAAoC;AAIhE,QAAM,WAAWC,wBAAuB,QAAQ,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC;AACvE,QAAM,OAAO,QAAQ,IAAI,CAAC,MAAM;AAC9B,UAAM,MAAMC,YAAW,EAAE,WAAW,QAAQ;AAC5C,UAAM,SAAS,GAAG,EAAE,QAAQ,QAAQ,MAAM,GAAG,aAAa,EAAE,aAAa,CAAC;AAC1E,UAAM,SAAS,EAAE,QAAQ,QAAQ,OAAO;AACxC,UAAM,YAAY,EAAE,QAAQ,QAAQ;AACpC,UAAM,YAAY,EAAE,QAAQ,QAAQ,cAAc;AAClD,UAAM,cAAc,YAAY,IAAI,KAAK,SAAS,YAAY;AAC9D,UAAM,SAAS,EAAE,QAAQ,QAAQ,SAAS,MAAM;AAChD,WAAO,EAAE,KAAK,QAAQ,QAAQ,WAAW,MAAM;AAAA,EACjD,CAAC;AAED,QAAM,SAAS;AAAA,IACb,KAAKC;AAAA,MACH,KAAK,IAAI,CAAC,MAAM,EAAE,GAAG;AAAA,MACrB,WAAW;AAAA,IACb;AAAA,IACA,QAAQA;AAAA,MACN,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM;AAAA,MACxB,SAAS;AAAA,IACX;AAAA,IACA,QAAQA;AAAA,MACN,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM;AAAA,MACxB,SAAS;AAAA,IACX;AAAA,IACA,WAAWA;AAAA,MACT,KAAK,IAAI,CAAC,MAAM,EAAE,SAAS;AAAA,MAC3B,aAAa;AAAA,IACf;AAAA,EACF;AAEA,UAAQ;AAAA,IACN,GAAGC,KAAI,YAAY,OAAO,GAAG,CAAC,KAAKA,KAAI,UAAU,OAAO,MAAM,CAAC,KAAKA,KAAI,UAAU,OAAO,MAAM,CAAC,KAAKA,KAAI,cAAc,OAAO,SAAS,CAAC;AAAA,EAC1I;AACA,aAAW,OAAO,MAAM;AACtB,YAAQ;AAAA,MACN,GAAGA,KAAI,IAAI,KAAK,OAAO,GAAG,CAAC,KAAKA,KAAI,IAAI,QAAQ,OAAO,MAAM,CAAC,KAAKA,KAAI,IAAI,QAAQ,OAAO,MAAM,CAAC,KAAKA,KAAI,IAAI,WAAW,OAAO,SAAS,CAAC,KAAK,IAAI,KAAK;AAAA,IAC1J;AAAA,EACF;AACF;AAEA,SAAS,qBACP,SACA,QACA,SACA,gBACM;AACN,QAAM,IAAI,QAAQ;AAClB,UAAQ,IAAI,YAAY,EAAE,EAAE,cAAc,EAAE,MAAM,GAAG;AACrD,UAAQ,IAAI,kBAAkB,EAAE,OAAO,IAAI,MAAM,EAAE,OAAO,OAAO,GAAG;AACpE,UAAQ,IAAI,kBAAkB,EAAE,YAAY,EAAE;AAC9C,UAAQ,IAAI,kBAAkB,EAAE,UAAU,EAAE;AAC5C,MAAI,EAAE,aAAa,QAAW;AAC5B,YAAQ,IAAI,kBAAkB,EAAE,QAAQ,EAAE;AAAA,EAC5C;AACA,UAAQ,IAAI,kBAAkB,iBAAiB,EAAE,mBAAmB,gBAAgB,OAAO,CAAC,EAAE;AAC9F,QAAM,iBAAiB,EAAE,WAAW,KAAK,SAAS,IAAI,IAAI,EAAE,WAAW,KAAK,KAAK,GAAG,CAAC,KAAK;AAC1F,UAAQ,IAAI,kBAAkB,EAAE,WAAW,OAAO,GAAG,cAAc,EAAE;AACrE,MAAI,EAAE,WAAW,cAAc,MAAM;AACnC,YAAQ,IAAI,kBAAkB,EAAE,WAAW,SAAS,EAAE;AAAA,EACxD;AACA,MAAI,EAAE,UAAU,QAAW;AACzB,YAAQ,IAAI,kBAAkB,EAAE,KAAK,EAAE;AAAA,EACzC;AACA,UAAQ,IAAI,kBAAkB,mBAAmB,EAAE,aAAa,CAAC,EAAE;AAEnE,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,WAAW,OAAO,MAAM,QAAQ;AAC5C,QAAM,SAAS,YAAY,MAAM;AACjC,aAAW,CAAC,MAAM,CAAC,KAAK,QAAQ;AAC9B,YAAQ,IAAI,KAAKA,KAAI,GAAG,IAAI,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE;AAAA,EAC7C;AAEA,MAAI,OAAO,WAAW,EAAG;AAEzB,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,UAAU,QAAQ,WAAW,QAAQ,QAAQ,SAAS;AAC5D,QAAM,QAAQ,UAAU,SAAS,OAAO,MAAM,CAAC,IAAI;AACnD,QAAM,UAAU,UAAU,gBAAgB,QAAQ,MAAM,MAAM;AAC9D,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAO;AACnB,aAAW,MAAM,OAAO;AACtB,YAAQ,IAAI,KAAK,gBAAgB,EAAE,CAAC,EAAE;AAAA,EACxC;AACF;AAEA,SAAS,iBACP,YACA,gBACA,SACQ;AACR,MAAI,QAAQ,aAAa,KAAM,QAAO;AAUtC,MAAI,CAAC,WAAW,UAAU,GAAG;AAC3B,QAAI,eAAe,IAAK,QAAO;AAC/B,WAAO;AAAA,EACT;AAEA,MAAI,eAAe,eAAgB,QAAO;AAC1C,QAAM,MAAM,SAAS,gBAAgB,UAAU;AAC/C,MAAI,IAAI,WAAW,KAAK,QAAQ,IAAK,QAAO;AAK5C,MAAI,IAAI,WAAW,IAAI,EAAG,QAAO;AACjC,SAAO,KAAK,GAAG;AACjB;AAEA,SAAS,mBAAmB,OAAkC;AAC5D,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAM,OAAO,MAAM,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI;AACxC,QAAM,YAAY,MAAM,SAAS;AACjC,MAAI,aAAa,EAAG,QAAO,GAAG,MAAM,MAAM,WAAW,IAAI;AACzD,SAAO,GAAG,MAAM,MAAM,WAAW,IAAI,UAAU,SAAS;AAC1D;AAEA,SAAS,YAAY,QAAmD;AACtE,QAAM,MAAM,oBAAI,IAAoB;AACpC,aAAW,MAAM,QAAQ;AACvB,QAAI,IAAI,GAAG,OAAO,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK,CAAC;AAAA,EAC9C;AACA,SAAO,CAAC,GAAG,IAAI,QAAQ,CAAC;AAC1B;AAEA,SAAS,gBAAgB,IAAmB;AAC1C,SAAO,GAAG,GAAG,WAAW,KAAK,GAAG,MAAM,MAAM,GAAG,IAAI,KAAK,oBAAoB,EAAE,CAAC;AACjF;AAEA,SAAS,oBAAoB,IAAmB;AAC9C,UAAQ,GAAG,MAAM;AAAA,IACf,KAAK,oBAAoB;AACvB,YAAM,WAAW,GAAG,KAAK,SAAS,IAAI,IAAI,GAAG,KAAK,KAAK,GAAG,CAAC,KAAK;AAChE,YAAM,WAAW,GAAG,cAAc,OAAO,gBAAgB,QAAQ,GAAG,SAAS;AAC7E,aAAO,GAAG,GAAG,OAAO,GAAG,QAAQ,KAAK,QAAQ,KAAK,GAAG,WAAW;AAAA,IACjE;AAAA,IACA,KAAK;AACH,aAAO,UAAU,GAAG,MAAM,UAAU,GAAG,KAAK;AAAA,IAC9C,KAAK;AACH,aAAO,GAAG,GAAG,WAAW,IAAI,GAAG,IAAI;AAAA,IACrC,KAAK;AACH,aAAO,GAAG,GAAG,IAAI,OAAO,GAAG,EAAE;AAAA,IAC/B,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,GAAG,cAAc,SAAY,aAAa,GAAG,SAAS,KAAK;AAAA,IACpE,KAAK;AACH,aAAO,GAAG,GAAG,OAAO,IAAI,SAAS,GAAG,UAAU;AAAA,IAChD,KAAK;AACH,aAAO,GAAG,aAAa,SAAY,MAAM,GAAG,QAAQ,KAAK;AAAA,IAC3D,KAAK;AACH,aAAO,GAAG,aAAa,SAAY,MAAM,GAAG,QAAQ,KAAK,GAAG,MAAM,KAAK,GAAG;AAAA,IAC5E,KAAK;AACH,aAAO,YAAY,GAAG,WAAW;AAAA,IACnC,KAAK;AACH,aAAO,GAAG;AAAA,IACZ,KAAK;AACH,aAAO,GAAG;AAAA,IACZ,KAAK;AACH,aAAO,GAAG,GAAG,IAAI,OAAO,GAAG,EAAE;AAAA,IAC/B,KAAK,mBAAmB;AACtB,YAAM,cACJ,GAAG,+BAA+B,OAAO,yBAAyB;AACpE,aAAO,QAAQC,aAAY,GAAG,OAAO,CAAC,aAAa,GAAG,wBAAwB,MAAM,aAAa,WAAW;AAAA,IAC9G;AAAA,IACA,KAAK,0BAA0B;AAC7B,YAAM,QAAQ,GAAG,sBAAsB;AACvC,YAAM,UAAU,GAAG,wBAAwB;AAC3C,YAAM,QAAQ,GAAG,gBAAgB,SAAY,UAAU,GAAG,WAAW,KAAK;AAC1E,aAAO,QAAQA,aAAY,GAAG,OAAO,CAAC,MAAM,KAAK,OAAO,OAAO,UAAU,KAAK;AAAA,IAChF;AAAA,IACA,KAAK;AACH,aAAO,QAAQA,aAAY,GAAG,OAAO,CAAC,KAAK,GAAG,KAAK;AAAA,IACrD,KAAK;AACH,aAAO,QAAQA,aAAY,GAAG,OAAO,CAAC,KAAK,GAAG,KAAK;AAAA,IACrD,KAAK;AACH,aAAO,GAAG,KAAK,SAAS,KAAK,GAAG,GAAG,KAAK,MAAM,GAAG,EAAE,CAAC,QAAQ,GAAG;AAAA,IACjE,KAAK;AACH,aAAO,GAAG,GAAG,MAAM,KAAK,GAAG,OAAO,aAAa,GAAG,OAAO;AAAA,EAC7D;AACF;AAEA,SAASC,SAAQ,IAAoB;AACnC,SAAOJ,YAAW,IAAIZ,kBAAiB;AACzC;AAEA,SAASe,aAAY,IAAoB;AACvC,MAAI,GAAG,WAAWhB,YAAW,GAAG;AAC9B,WAAO,GAAG,MAAMA,aAAY,QAAQA,aAAY,SAASC,kBAAiB;AAAA,EAC5E;AACA,SAAO,GAAG,MAAM,GAAGA,kBAAiB;AACtC;AAEA,SAASY,YAAW,IAAY,KAAqB;AACnD,MAAI,GAAG,WAAWd,WAAU,GAAG;AAC7B,WAAO,GAAG,MAAMA,YAAW,QAAQA,YAAW,SAAS,GAAG;AAAA,EAC5D;AACA,SAAO,GAAG,MAAM,GAAG,GAAG;AACxB;AAQA,SAASa,wBAAuB,YAAuC;AACrE,MAAI,WAAW,UAAU,EAAG,QAAOX;AACnC,WAAS,MAAMA,oBAAmB,OAAOC,mBAAkB,OAAO,GAAG;AACnE,UAAM,OAAO,oBAAI,IAAY;AAC7B,QAAI,WAAW;AACf,eAAW,OAAO,YAAY;AAC5B,YAAM,MAAMW,YAAW,KAAK,GAAG;AAC/B,UAAI,KAAK,IAAI,GAAG,GAAG;AACjB,mBAAW;AACX;AAAA,MACF;AACA,WAAK,IAAI,GAAG;AAAA,IACd;AACA,QAAI,CAAC,SAAU,QAAO;AAAA,EACxB;AACA,SAAOX;AACT;AAEA,SAASa,KAAI,OAAe,OAAuB;AACjD,SAAO,MAAM,UAAU,QAAQ,QAAQ,QAAQ,IAAI,OAAO,QAAQ,MAAM,MAAM;AAChF;AAEA,SAASD,QAAO,QAA2B,OAAuB;AAChE,MAAI,MAAM;AACV,aAAW,KAAK,OAAQ,KAAI,EAAE,SAAS,IAAK,OAAM,EAAE;AACpD,SAAO;AACT;AAEA,eAAe,gCACb,KACA,QACiB;AACjB,MAAI;AACF,WAAO,MAAMI,uBAAsB,GAAG;AAAA,EACxC,SAAS,OAAgB;AACvB,QAAI,iBAAiB,SAAS,MAAM,YAAY,wBAAwB;AACtE,YAAM,IAAI;AAAA,QACR,0EAA0E,MAAM;AAAA,QAChF,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAeZ,4BAA2B,WAAkC;AAC1E,MAAI;AACF,UAAMa,qBAAoB,SAAS;AAAA,EACrC,SAAS,OAAgB;AACvB,QAAIR,eAAc,OAAO,QAAQ,GAAG;AAClC,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AACA,UAAM;AAAA,EACR;AACF;AAEA,SAAS,iBAAiB,KAAqB;AAC7C,QAAM,IAAI,OAAO,SAAS,KAAK,EAAE;AACjC,MAAI,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,KAAK,IAAI,KAAK,MAAM,OAAO,CAAC,GAAG;AAC7D,UAAM,IAAI,MAAM,mBAAmB,GAAG,EAAE;AAAA,EAC1C;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,KAA4B;AACtD,QAAM,SAAS,oBAAoB,UAAU,GAAG;AAChD,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,IAAI,MAAM,2BAA2B,GAAG,mBAAmBR,eAAc,KAAK,IAAI,CAAC,EAAE;AAAA,EAC7F;AACA,SAAO,OAAO;AAChB;AAEA,SAAS,gBAAgB,SAAmC;AAC1D,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ,IAAI,IAAI;AAAA,EAClB,OAAO;AACL,YAAQ,IAAI,oBAAoB;AAAA,EAClC;AACF;AAoBA,eAAsB,iBACpB,SACA,MAAsB,CAAC,GACR;AACf,MAAI;AACF,UAAM,mBAAmB,SAAS,GAAG;AAAA,EACvC,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,EAAE,CAAC;AACrD,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAsB,mBACpB,SACA,KACe;AACf,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,gCAAgC,KAAK,QAAQ;AAC1E,QAAM,QAAQE,YAAW,cAAc;AACvC,QAAMC,4BAA2B,MAAM,IAAI;AAE3C,QAAM,WAAW,MAAMc,cAAa,KAAK;AAEzC,QAAM,UAAU,MAAM,cAAc,QAAQ,IAAI;AAChD,QAAM,OAAO,gBAAgB,OAAO;AAEpC,QAAM,SAAS,2BAA2B,UAAU,IAAI;AACxD,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,IAAI,MAAM,0BAA0B,EAAE,OAAO,OAAO,MAAM,CAAC;AAAA,EACnE;AAEA,MAAI,OAAO,KAAK,mBAAmB,SAAS;AAC1C,UAAM,IAAI,MAAM,sCAAsC,OAAO,KAAK,cAAc,EAAE;AAAA,EACpF;AAEA,QAAM,gBAAsC,EAAE,QAAQ,QAAQ,WAAW,KAAK;AAC9E,MAAI,QAAQ,UAAU,OAAW,eAAc,gBAAgB,QAAQ;AACvE,MAAI,QAAQ,SAAS,QAAW;AAC9B,kBAAc,iBAAiB,MAAM,cAAc,OAAO,QAAQ,IAAI;AAAA,EACxE;AAEA,QAAM,SAAS,MAAM,sBAAsB,OAAO,UAAU,OAAO,MAAM,aAAa;AAQtF,QAAM,iBAAiB,OAAO;AAC9B,MAAI,eAAe,eAAe,KAAK,eAAe,2BAA2B;AAC/E,UAAM,UAAU,eAAe,4BAA4B,IAAI;AAC/D,YAAQ;AAAA,MACN,qBAAqB,eAAe,eAAe,OAAO,sCAAsC,eAAe,YAAY,wBAAwB,OAAO;AAAA,IAC5J;AAAA,EACF;AAEA,2BAAyB,SAAS,MAAM;AAC1C;AAEA,eAAe,cAAc,MAA+B;AAC1D,MAAI;AACF,WAAO,MAAM,SAAS,MAAM,MAAM;AAAA,EACpC,SAAS,OAAgB;AACvB,QAAIT,eAAc,OAAO,QAAQ,GAAG;AAClC,YAAM,IAAI,MAAM,2BAA2B,EAAE,OAAO,MAAM,CAAC;AAAA,IAC7D;AACA,QAAIA,eAAc,OAAO,QAAQ,GAAG;AAClC,YAAM,IAAI,MAAM,+BAA+B,EAAE,OAAO,MAAM,CAAC;AAAA,IACjE;AACA,UAAM,IAAI,MAAM,gCAAgC,EAAE,OAAO,MAAM,CAAC;AAAA,EAClE;AACF;AAEA,SAAS,gBAAgB,MAAuB;AAC9C,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,SAAS,OAAgB;AACvB,UAAM,IAAI,MAAM,+BAA+B,EAAE,OAAO,MAAM,CAAC;AAAA,EACjE;AACF;AAEA,SAAS,kBAAkB,KAAqB;AAC9C,MAAI,QAAQ,QAAQ;AAClB,UAAM,IAAIU,sBAAqB,uBAAuB,GAAG,sBAAsB;AAAA,EACjF;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,KAAqB;AAC/C,MAAI,IAAI,WAAW,GAAG;AACpB,UAAM,IAAIA,sBAAqB,yBAAyB;AAAA,EAC1D;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,KAAqB;AAChD,MAAI,IAAI,WAAW,GAAG;AACpB,UAAM,IAAIA,sBAAqB,kBAAkB;AAAA,EACnD;AACA,SAAO;AACT;AAEA,SAAS,yBACP,SACA,QACM;AACN,QAAM,QAAQ,QAAQ,WAAW;AACjC,QAAM,MAAMJ,SAAQ,OAAO,SAAS;AACpC,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ;AAAA,MACN,KAAK,UAAU;AAAA,QACb,YAAY,OAAO;AAAA,QACnB,aAAa,OAAO;AAAA,QACpB,SAAS;AAAA,QACT,QAAQ,EAAE,MAAM,OAAO,iBAAiB,SAAS,QAAQ;AAAA,QACzD,QAAQ,OAAO;AAAA,MACjB,CAAC;AAAA,IACH;AACA;AAAA,EACF;AAEA,MAAI,OAAO;AACT,YAAQ;AAAA,MACN,yBAAyB,OAAO,UAAU,gBAAgB,GAAG;AAAA,IAC/D;AACA;AAAA,EACF;AAEA,UAAQ;AAAA,IACN,oBAAoB,GAAG,KAAK,OAAO,UAAU,iBAAiBK,UAAS,QAAQ,IAAI,CAAC;AAAA,EACtF;AACF;AAMA,IAAM,0BAA0B;AAChC,IAAM,yBAAyB;AAc/B,eAAsB,eACpB,gBACA,SACA,MAAsB,CAAC,GACR;AACf,MAAI;AACF,UAAM,iBAAiB,gBAAgB,SAAS,GAAG;AAAA,EACrD,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,EAAE,CAAC;AACrD,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAsB,iBACpB,gBACA,SACA,KACe;AACf,QAAM,UAAU,QAAQ,SAAS;AACjC,QAAM,cAAc,QAAQ,aAAa;AACzC,MAAI,CAAC,WAAW,CAAC,aAAa;AAC5B,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AACA,MAAI,WAAW,aAAa;AAC1B,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AAGA,MAAI,eAAe,QAAQ,aAAa,KAAK;AAC3C,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AAEA,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,gCAAgC,KAAK,MAAM;AACxE,QAAM,QAAQjB,YAAW,cAAc;AACvC,QAAMC,4BAA2B,MAAM,IAAI;AAE3C,QAAM,YAAY,MAAMC,kBAAiB,OAAO,cAAc;AAE9D,QAAM,OAAO,UAAW,QAAQ,OAAkB,MAAM,aAAa,QAAQ,QAAkB;AAC/F,MAAI,KAAK,WAAW,GAAG;AACrB,UAAM,IAAI,MAAM,oBAAoB;AAAA,EACtC;AAEA,QAAM,cAAa,oBAAI,KAAK,GAAE,YAAY;AAC1C,QAAM,QAAQ;AAQd,QAAM,cAAc,MAAMgB,aAAY,OAAO,WAAW,KAAK;AAC7D,MAAI;AACJ,MAAI;AACF,aAAS,MAAMC,8BAA6B;AAAA,MAC1C;AAAA,MACA,WAAW;AAAA,MACX,cAAc,CAAC,aACZ;AAAA,QACC,gBAAgB;AAAA,QAChB,IAAI;AAAA,QACJ,YAAY;AAAA,QACZ,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,MAAM;AAAA,QACN;AAAA,MACF;AAAA,IACJ,CAAC;AAAA,EACH,UAAE;AACA,UAAM,YAAY,QAAQ;AAAA,EAC5B;AAEA,yBAAuB,SAAS,WAAW,OAAO,SAAS,OAAO,eAAe,IAAI;AACvF;AAEA,eAAe,aAAa,MAA+B;AACzD,MAAI;AACF,WAAO,MAAM,SAAS,MAAM,MAAM;AAAA,EACpC,SAAS,OAAgB;AACvB,QAAIb,eAAc,OAAO,QAAQ,GAAG;AAClC,YAAM,IAAI,MAAM,yBAAyB,EAAE,OAAO,MAAM,CAAC;AAAA,IAC3D;AACA,QAAIA,eAAc,OAAO,QAAQ,GAAG;AAClC,YAAM,IAAI,MAAM,6BAA6B,EAAE,OAAO,MAAM,CAAC;AAAA,IAC/D;AACA,UAAM,IAAI,MAAM,8BAA8B,EAAE,OAAO,MAAM,CAAC;AAAA,EAChE;AACF;AAEA,SAAS,oBAAoB,KAAqB;AAChD,MAAI,IAAI,WAAW,GAAG;AACpB,UAAM,IAAIU,sBAAqB,0BAA0B;AAAA,EAC3D;AACA,SAAO;AACT;AAEA,SAAS,uBACP,SACA,WACA,SACA,eACA,MACM;AACN,QAAM,MAAMJ,SAAQ,SAAS;AAC7B,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ;AAAA,MACN,KAAK,UAAU;AAAA,QACb,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,aAAa,KAAK;AAAA,MACpB,CAAC;AAAA,IACH;AACA;AAAA,EACF;AACA,QAAM,UACJ,KAAK,SAAS,0BAA0B,GAAG,KAAK,MAAM,GAAG,sBAAsB,CAAC,QAAQ;AAC1F,UAAQ,IAAI,yBAAyB,GAAG,KAAK,aAAa,MAAM,OAAO,EAAE;AAC3E;;;ACr2BA;AAAA,EAGE,uBAAAQ;AAAA,EACA,cAAAC;AAAA,EACA;AAAA,EACA,iBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,yBAAAC;AAAA,EACA;AAAA,OACK;AAmBA,SAAS,sBAAsBC,UAAwB;AAC5D,EAAAA,SACG,QAAQ,QAAQ,EAChB,YAAY,yCAAyC,EACrD,OAAO,UAAU,uCAAuC,EACxD,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,YAA2B;AACxC,UAAM,UAAU,OAAO;AAAA,EACzB,CAAC;AACL;AAOA,eAAsB,UAAU,SAAwB,MAAqB,CAAC,GAAkB;AAC9F,MAAI;AACF,UAAM,YAAY,SAAS,GAAG;AAAA,EAChC,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,EAAE,CAAC;AACrD,YAAQ,WAAW;AAAA,EACrB;AACF;AASA,eAAsB,YAAY,SAAwB,KAAmC;AAC3F,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,+BAA+B,GAAG;AAC/D,QAAM,QAAQC,YAAW,cAAc;AAKvC,MAAI;AACF,UAAMC,qBAAoB,MAAM,IAAI;AAAA,EACtC,SAAS,OAAgB;AACvB,QAAIC,eAAc,OAAO,QAAQ,GAAG;AAClC,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AACA,UAAM;AAAA,EACR;AAEA,MAAI;AACJ,MAAI;AACF,eAAW,MAAMC,cAAa,KAAK;AAAA,EACrC,SAAS,OAAgB;AACvB,QAAID,eAAc,OAAO,QAAQ,GAAG;AAClC,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AAKA,UAAM,IAAI,MAAM,qCAAqC,EAAE,OAAO,MAAM,CAAC;AAAA,EACvE;AAEA,QAAM,WAAW,MAAM,oBAAoB,EAAE,UAAU,MAAM,CAAC;AAC9D,QAAM,YAAY,OAAO,QAAQ;AAEjC,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ,IAAI,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,EAC/C,OAAO;AACL,qBAAiB,QAAQ;AAAA,EAC3B;AACF;AAEA,SAAS,iBAAiB,GAAyB;AACjD,UAAQ,IAAI,cAAc,EAAE,UAAU,IAAI,KAAK,EAAE,UAAU,EAAE,GAAG;AAQhE,UAAQ,IAAI,kBAAkB,EAAE,UAAU,aAAa,EAAE;AACzD,UAAQ,IAAI,kBAAkB,EAAE,YAAY,EAAE;AAC9C,QAAM,KAAK,EAAE;AACb,QAAM,QAAQ,OAAO,KAAK,EAAE,EAAE;AAC9B,QAAM,UAAU,OAAO,OAAO,EAAE,EAAE,OAAO,CAAC,MAAM,MAAM,IAAI,EAAE;AAC5D,UAAQ,IAAI,2BAA2B,OAAO,IAAI,KAAK,EAAE;AAC3D;AAOA,eAAe,+BAA+B,KAA8B;AAC1E,MAAI;AACF,WAAO,MAAME,uBAAsB,GAAG;AAAA,EACxC,SAAS,OAAgB;AACvB,QAAI,iBAAiB,SAAS,MAAM,YAAY,wBAAwB;AACtE,YAAM,IAAI,MAAM,2EAA2E;AAAA,QACzF,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AACA,UAAM;AAAA,EACR;AACF;;;ACvIA,SAAS,YAAAC,iBAAgB;AACzB,SAAS,QAAAC,aAAY;AACrB;AAAA,EAWE;AAAA,EACA;AAAA,EACA;AAAA,EACA,uBAAAC;AAAA,EACA,cAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAAC;AAAA,EACA,sBAAAC;AAAA,EACA;AAAA,EACA,gBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAAC;AAAA,EACA,yBAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA;AAAA,OACK;AACP,SAAuB,wBAAAC,6BAA4B;AAYnD,IAAMC,iBAAgB,iBAAiB;AAoFhC,SAAS,oBAAoBC,UAAwB;AAC1D,QAAM,OAAOA,SACV,QAAQ,MAAM,EACd,YAAY,uDAAuD;AAEtE,OACG,QAAQ,KAAK,EACb,YAAY,iDAAiD,EAC7D,eAAe,kBAAkB,cAAcC,WAAU,EACzD,OAAO,kBAAkB,+BAA+B,UAAU,EAClE;AAAA,IACC;AAAA,IACA,2BAA2BF,eAAc,KAAK,IAAI,CAAC;AAAA,IACnD;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,EACF,EACC,OAAO,0BAA0B,8CAA8C,EAC/E,OAAO,wBAAwB,kCAAkC,sBAAsB,EACvF,OAAO,sBAAsB,mCAAmC,EAChE,OAAO,UAAU,gBAAgB,EACjC,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,YAA4B;AACzC,UAAM,WAAW,OAAO;AAAA,EAC1B,CAAC;AAEH,OACG,QAAQ,MAAM,EACd,YAAY,oDAAoD,EAChE;AAAA,IACC;AAAA,IACA,kCAAkCA,eAAc,KAAK,IAAI,CAAC;AAAA,IAC1D;AAAA,EACF,EACC,OAAO,sBAAsB,iEAAiE,EAC9F,OAAO,UAAU,iCAAiC,EAClD,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,YAA6B;AAC1C,UAAM,YAAY,OAAO;AAAA,EAC3B,CAAC;AAEH,OACG,QAAQ,gBAAgB,EACxB,YAAY,4DAA4D,EACxE,OAAO,UAAU,gBAAgB,EACjC,OAAO,YAAY,iDAAiD,EACpE,OAAO,cAAc,qDAAqDG,iBAAgB,EAC1F,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,IAAY,YAA6B;AACtD,UAAM,YAAY,IAAI,OAAO;AAAA,EAC/B,CAAC;AAEH,OACG,QAAQ,+BAA+B,EACvC,YAAY,yDAAyD,EACrE,OAAO,0BAA0B,8CAA8C,EAC/E,OAAO,UAAU,gBAAgB,EACjC,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,aAAqB,gBAAwB,YAA+B;AACzF,UAAM,cAAc,aAAa,gBAAgB,OAAO;AAAA,EAC1D,CAAC;AAEH,OACG,QAAQ,WAAW,EACnB;AAAA,IACC;AAAA,EACF,EACC,OAAO,oBAAoB,6CAA6C,EACxE,OAAO,WAAW,kCAAkC,EACpD,OAAO,UAAU,gBAAgB,EACjC,OAAO,iBAAiB,gDAAgD,EACxE,OAAO,OAAO,YAAkC;AAC/C,UAAM,iBAAiB,OAAO;AAAA,EAChC,CAAC;AAEH,OACG,QAAQ,2BAA2B,EACnC;AAAA,IACC;AAAA,EACF,EACC,OAAO,WAAW,sCAAsC,EACxD,OAAO,UAAU,gBAAgB,EACjC,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,aAAqB,YAAuC;AACzE,UAAM,sBAAsB,aAAa,OAAO;AAAA,EAClD,CAAC;AAEH,OACG,QAAQ,gBAAgB,EACxB;AAAA,IACC;AAAA,EACF,EACC,OAAO,kBAAkB,iCAAiCD,WAAU,EACpE;AAAA,IACC;AAAA,IACA,uBAAuBF,eAAc,KAAK,IAAI,CAAC;AAAA,IAC/C;AAAA,EACF,EACC,OAAO,UAAU,gBAAgB,EACjC,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,aAAqB,YAA6B;AAC/D,UAAM,YAAY,aAAa,OAAO;AAAA,EACxC,CAAC;AAEH,OACG,QAAQ,kBAAkB,EAC1B;AAAA,IACC;AAAA,EACF,EACC,OAAO,SAAS,iEAAiE,EACjF,OAAO,UAAU,gBAAgB,EACjC,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,aAAqB,YAA+B;AACjE,UAAM,cAAc,aAAa,OAAO;AAAA,EAC1C,CAAC;AAEH,OACG,QAAQ,mBAAmB,EAC3B;AAAA,IACC;AAAA,EACF,EACC,OAAO,SAAS,iEAAiE,EACjF,OAAO,UAAU,gBAAgB,EACjC,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,OAAO,aAAqB,YAAgC;AAClE,UAAM,eAAe,aAAa,OAAO;AAAA,EAC3C,CAAC;AACL;AAMA,eAAsB,WAAW,SAAyB,MAAmB,CAAC,GAAkB;AAC9F,MAAI;AACF,UAAM,aAAa,SAAS,GAAG;AAAA,EACjC,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,GAAG,aAAa,iBAAiB,CAAC;AACpF,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAsB,aAAa,SAAyB,KAAiC;AAC3F,MAAI,QAAQ,gBAAgB,UAAa,QAAQ,aAAa,QAAW;AACvE,UAAM,IAAI,MAAM,sDAAsD;AAAA,EACxE;AACA,MAAI,QAAQ,aAAa,KAAK;AAC5B,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AAEA,QAAM,gBAAgB,QAAQ,UAAU;AAIxC,MAAI,QAAQ,gBAAgB,UAAa,CAAC,uBAAuB,aAAa,GAAG;AAC/E,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AAEA,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,6BAA6B,KAAK,KAAK;AACpE,QAAM,QAAQI,YAAW,cAAc;AACvC,QAAMC,4BAA2B,MAAM,IAAI;AAE3C,QAAM,cACJ,QAAQ,gBAAgB,SACpB,QAAQ,cACR,QAAQ,aAAa,SACnB,MAAM,oBAAoB,QAAQ,QAAQ,IAC1C;AAER,QAAM,MAAM,IAAI,gBAAgB,SAAY,IAAI,YAAY,IAAI,oBAAI,KAAK;AACzE,QAAM,aAAa,IAAI,YAAY;AACnC,QAAM,SAASC,cAAa,MAAM;AAElC,MAAI,QAAQ,YAAY,QAAW;AACjC,UAAM,YAAa,MAAMC,kBAAiB,OAAO,QAAQ,OAAO;AAChE,UAAMC,UAAS,MAAM,oBAAoB;AAAA,MACvC,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO,QAAQ;AAAA,MACf,GAAI,QAAQ,UAAU,SAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,MAC9D;AAAA,MACA;AAAA,MACA,GAAI,QAAQ,gBAAgB,SAAY,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,IAClF,CAAC;AACD,uBAAmB,SAAS;AAAA,MAC1B,MAAM;AAAA,MACN,QAAQA,QAAO;AAAA,MACf,SAASA,QAAO;AAAA,MAChB,WAAWA,QAAO;AAAA,MAClB,eAAeA,QAAO;AAAA,MACtB,OAAO,QAAQ;AAAA,MACf,GAAI,QAAQ,UAAU,SAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,MAC9D,QAAQ;AAAA,MACR;AAAA,MACA,GAAI,QAAQ,gBAAgB,SAAY,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,MAChF,mBAAmB,YAAY;AAAA,IACjC,CAAC;AACD;AAAA,EACF;AAEA,QAAM,WAAW,MAAMC,cAAa,KAAK;AACzC,QAAM,SAAS,MAAM,oBAAoB;AAAA,IACvC,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,QAAQ;AAAA,IACf,GAAI,QAAQ,UAAU,SAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,IAC9D;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,IAClB,GAAI,QAAQ,gBAAgB,SAAY,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,EAClF,CAAC;AACD,qBAAmB,SAAS;AAAA,IAC1B,MAAM;AAAA,IACN,QAAQ,OAAO;AAAA,IACf,SAAS,OAAO;AAAA,IAChB,WAAW,OAAO;AAAA,IAClB,eAAe,OAAO;AAAA,IACtB,OAAO,QAAQ;AAAA,IACf,GAAI,QAAQ,UAAU,SAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,IAC9D,QAAQ;AAAA,IACR;AAAA,IACA,GAAI,QAAQ,gBAAgB,SAAY,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,IAChF,mBAAmB,YAAY;AAAA,EACjC,CAAC;AACH;AAEA,SAAS,uBAAuB,QAA6B;AAC3D,SAAO,WAAW,UAAU,WAAW;AACzC;AAgBA,SAAS,mBAAmB,SAAyB,QAA4B;AAC/E,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ;AAAA,MACN,KAAK,UAAU;AAAA,QACb,SAAS,OAAO;AAAA,QAChB,UAAU,OAAO;AAAA,QACjB,YAAY,OAAO;AAAA,QACnB,gBAAgB,OAAO;AAAA,QACvB,MAAM,OAAO;AAAA,QACb,OAAO,OAAO;AAAA,QACd,OAAO,OAAO,SAAS;AAAA,QACvB,QAAQ,OAAO;AAAA,QACf,aAAa,OAAO;AAAA,QACpB,cAAc,OAAO,eAAe;AAAA,QACpC,oBAAoB,OAAO;AAAA,MAC7B,CAAC;AAAA,IACH;AACA;AAAA,EACF;AACA,QAAM,WAAW,eAAe,OAAO,SAAS;AAChD,QAAM,UACJ,OAAO,SAAS,WACZ,WAAW,OAAO,MAAM,sBAAsB,QAAQ,KACtD,WAAW,OAAO,MAAM,eAAe,QAAQ,KAAK,OAAO,aAAa;AAC9E,UAAQ,IAAI,OAAO;AACnB,UAAQ,IAAI,aAAa,OAAO,KAAK,EAAE;AAKvC,MAAI,OAAO,gBAAgB,QAAW;AACpC,YAAQ;AAAA,MACN,aAAa,OAAO,MAAM,iBAAiB,OAAO,UAAU,kBAAkB,OAAO,WAAW;AAAA,IAClG;AAAA,EACF,OAAO;AACL,YAAQ,IAAI,aAAa,OAAO,MAAM,EAAE;AAAA,EAC1C;AACA,UAAQ,IAAI,aAAa,OAAO,SAAS,QAAQ,EAAE;AACrD;AAMA,eAAsB,YAAY,SAA0B,MAAmB,CAAC,GAAkB;AAChG,MAAI;AACF,UAAM,cAAc,SAAS,GAAG;AAAA,EAClC,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,GAAG,aAAa,iBAAiB,CAAC;AACpF,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAsB,cAAc,SAA0B,KAAiC;AAC7F,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,6BAA6B,KAAK,MAAM;AACrE,QAAM,QAAQL,YAAW,cAAc;AACvC,QAAMC,4BAA2B,MAAM,IAAI;AAE3C,QAAM,UAAU,MAAM,gBAAgB,OAAO;AAAA,IAC3C,QAAQ,CAAC,IAAI,WAAW,cAAc,IAAI,MAAM;AAAA,EAClD,CAAC;AAKD,QAAM,kBAA2D,CAAC;AAClE,MAAI,QAAQ,oBAAoB,MAAM;AACpC,UAAM,cAAc,MAAM,yBAAyB,KAAK;AACxD,eAAW,MAAM,aAAa;AAC5B,UAAI;AACF,cAAM,EAAE,IAAI,IAAI,MAAM,gCAAgC,OAAO,EAAE;AAC/D,wBAAgB,KAAK,EAAE,KAAK,UAAU,KAAK,CAAC;AAAA,MAC9C,QAAQ;AAAA,MAGR;AAAA,IACF;AAAA,EACF;AACA,QAAM,WAAW,CAAC,GAAG,SAAS,GAAG,gBAAgB,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;AAClE,QAAM,gBAAgB,IAAI,IAAI,gBAAgB,IAAI,CAAC,MAAM,EAAE,IAAI,KAAK,KAAK,EAAE,CAAC;AAE5E,QAAM,UAAU,CAAC,GAAG,QAAQ,EAAE;AAAA,IAC5B,CAAC,GAAG,MAAM,KAAK,MAAM,EAAE,KAAK,KAAK,UAAU,IAAI,KAAK,MAAM,EAAE,KAAK,KAAK,UAAU;AAAA,EAClF;AACA,QAAM,WACJ,QAAQ,WAAW,SACf,QAAQ,OAAO,CAAC,MAAM,EAAE,KAAK,KAAK,WAAW,QAAQ,MAAM,IAC3D;AAEN,MAAI,SAAS,WAAW,GAAG;AACzB,QAAI,QAAQ,SAAS,MAAM;AACzB,cAAQ,IAAI,IAAI;AAAA,IAClB,OAAO;AACL,cAAQ,IAAI,iBAAiB;AAAA,IAC/B;AACA;AAAA,EACF;AAEA,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ;AAAA,MACN,KAAK;AAAA,QACH,SAAS,IAAI,CAAC,OAAO;AAAA,UACnB,SAAS,EAAE,KAAK,KAAK;AAAA,UACrB,OAAO,EAAE,KAAK,KAAK;AAAA,UACnB,OAAO,EAAE,KAAK,KAAK,SAAS;AAAA,UAC5B,QAAQ,EAAE,KAAK,KAAK;AAAA,UACpB,YAAY,EAAE,KAAK,KAAK;AAAA,UACxB,YAAY,EAAE,KAAK,KAAK;AAAA,UACxB,sBAAsB,EAAE,KAAK,KAAK,gBAAgB;AAAA,UAClD,UAAU,cAAc,IAAI,EAAE,KAAK,KAAK,EAAE;AAAA,QAC5C,EAAE;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA;AAAA,EACF;AACA,oBAAkB,UAAU,aAAa;AAC3C;AAEA,SAAS,kBACP,SACA,aACM;AACN,QAAM,OAAO,QAAQ,IAAI,CAAC,OAAO;AAAA,IAC/B,KAAK,YAAY,EAAE,KAAK,KAAK,EAAE;AAAA,IAC/B,QAAQ,EAAE,KAAK,KAAK;AAAA,IACpB,WAAW,EAAE,KAAK,KAAK;AAAA,IACvB,OAAO,EAAE,KAAK,KAAK,SAAS;AAAA;AAAA;AAAA,IAG5B,OAAO,YAAY,IAAI,EAAE,KAAK,KAAK,EAAE,IAAI,cAAc,EAAE,KAAK,KAAK,KAAK,KAAK,EAAE,KAAK,KAAK;AAAA,IACzF,aAAa,OAAO,EAAE,KAAK,KAAK,gBAAgB,MAAM;AAAA,EACxD,EAAE;AACF,QAAM,SAAS;AAAA,IACb,KAAKK;AAAA,MACH,KAAK,IAAI,CAAC,MAAM,EAAE,GAAG;AAAA,MACrB,WAAW;AAAA,IACb;AAAA,IACA,QAAQA;AAAA,MACN,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM;AAAA,MACxB,SAAS;AAAA,IACX;AAAA,IACA,WAAWA;AAAA,MACT,KAAK,IAAI,CAAC,MAAM,EAAE,SAAS;AAAA,MAC3B,aAAa;AAAA,IACf;AAAA,IACA,aAAaA;AAAA,MACX,KAAK,IAAI,CAAC,MAAM,EAAE,WAAW;AAAA,MAC7B,QAAQ;AAAA,IACV;AAAA,IACA,OAAOA;AAAA,MACL,KAAK,IAAI,CAAC,MAAM,EAAE,KAAK;AAAA,MACvB,QAAQ;AAAA,IACV;AAAA,EACF;AACA,UAAQ;AAAA,IACN,GAAGC,KAAI,YAAY,OAAO,GAAG,CAAC,KAAKA,KAAI,UAAU,OAAO,MAAM,CAAC,KAAKA,KAAI,cAAc,OAAO,SAAS,CAAC,KAAKA,KAAI,SAAS,OAAO,WAAW,CAAC,KAAKA,KAAI,SAAS,OAAO,KAAK,CAAC;AAAA,EAC7K;AACA,aAAW,KAAK,MAAM;AACpB,YAAQ;AAAA,MACN,GAAGA,KAAI,EAAE,KAAK,OAAO,GAAG,CAAC,KAAKA,KAAI,EAAE,QAAQ,OAAO,MAAM,CAAC,KAAKA,KAAI,EAAE,WAAW,OAAO,SAAS,CAAC,KAAKA,KAAI,EAAE,aAAa,OAAO,WAAW,CAAC,KAAKA,KAAI,EAAE,OAAO,OAAO,KAAK,CAAC,KAAK,EAAE,KAAK;AAAA,IACzL;AAAA,EACF;AACF;AAMA,eAAsB,YACpB,SACA,SACA,MAAmB,CAAC,GACL;AACf,MAAI;AACF,UAAM,cAAc,SAAS,SAAS,GAAG;AAAA,EAC3C,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,GAAG,aAAa,iBAAiB,CAAC;AACpF,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAsB,cACpB,SACA,SACA,KACe;AACf,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,6BAA6B,KAAK,MAAM;AACrE,QAAM,QAAQP,YAAW,cAAc;AACvC,QAAMC,4BAA2B,MAAM,IAAI;AAE3C,QAAM,SAAS,MAAMO,eAAc,OAAO,SAAS,EAAE,iBAAiB,KAAK,CAAC;AAC5E,QAAM,EAAE,KAAK,SAAS,IAAI,MAAM,gCAAgC,OAAO,MAAM;AAK7E,QAAM,WAAW,MAAMC,oBAAmB,OAAO,EAAE,KAAK,oBAAI,KAAK,EAAE,CAAC;AACpE,QAAM,SAAkB,CAAC;AACzB,QAAM,mBAAmB,IAAI,IAAY,IAAI,KAAK,KAAK,eAAe;AAItE,aAAW,KAAK,UAAU;AACxB,UAAM,aAAaC,MAAK,MAAM,UAAU,EAAE,SAAS;AACnD,QAAI;AACF,uBAAiB,MAAMC,cAAa,YAAY;AAAA,QAC9C,WAAW,CAAC,MAAM,mBAAmB,GAAG,EAAE,SAAS;AAAA,MACrD,CAAC,GAAG;AACF,aACG,GAAG,SAAS,kBACX,GAAG,SAAS,yBACZ,GAAG,SAAS,qBACZ,GAAG,SAAS,4BACZ,GAAG,SAAS,kBACZ,GAAG,SAAS,oBACd,GAAG,YAAY,QACf;AACA,iBAAO,KAAK,EAAE;AACd,2BAAiB,IAAI,EAAE,SAAS;AAAA,QAClC;AAAA,MACF;AAAA,IACF,SAAS,OAAgB;AAIvB,YAAM,QAAQ,eAAe,EAAE,SAAS;AACxC,YAAM,SAAS,iBAAiB,QAAQ,KAAK,MAAM,OAAO,KAAK;AAC/D,cAAQ,MAAM,2CAA2C,KAAK,GAAG,MAAM,EAAE;AAAA,IAC3E;AAAA,EACF;AACA,SAAO,KAAK,CAAC,GAAG,MAAM,KAAK,MAAM,EAAE,WAAW,IAAI,KAAK,MAAM,EAAE,WAAW,CAAC;AAE3E,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ;AAAA,MACN,KAAK;AAAA,QACH;AAAA,UACE,MAAM,IAAI,KAAK;AAAA,UACf,MAAM,IAAI;AAAA,UACV,iBAAiB,CAAC,GAAG,gBAAgB;AAAA,UACrC;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA;AAAA,EACF;AAEA,oBAAkB,KAAK,CAAC,GAAG,gBAAgB,GAAG,QAAQ,UAAU,SAAS,QAAQ;AACnF;AAEA,SAAS,kBACP,KACA,gBACA,QACA,gBACA,SACA,UACM;AACN,QAAM,IAAI,IAAI,KAAK;AACnB,QAAM,cAAc,WAAW,gBAAgB;AAC/C,UAAQ,IAAI,SAAS,EAAE,EAAE,GAAG,WAAW,EAAE;AACzC,UAAQ,IAAI,kBAAkB,EAAE,KAAK,EAAE;AACvC,UAAQ,IAAI,kBAAkB,EAAE,MAAM,EAAE;AACxC,UAAQ,IAAI,kBAAkB,EAAE,SAAS,QAAQ,EAAE;AACnD,UAAQ,IAAI,kBAAkB,EAAE,UAAU,EAAE;AAC5C,UAAQ,IAAI,kBAAkB,EAAE,UAAU,EAAE;AAC5C,UAAQ,IAAI,kBAAkB,EAAE,YAAY,EAAE;AAC9C,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,oBAAoB,eAAe,MAAM,IAAI;AACzD,QAAM,mBAAmB,IAAI;AAAA,IAC3B,eAAe,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,QAAQ,MAAM,CAAC;AAAA,EACnE;AACA,aAAW,OAAO,gBAAgB;AAChC,UAAM,SAAS,iBAAiB,IAAI,GAAG,KAAK;AAC5C,YAAQ,IAAI,KAAK,GAAG,MAAM,MAAM,GAAG;AAAA,EACrC;AACA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,cAAc;AAC1B,MAAI,IAAI,KAAK,WAAW,GAAG;AACzB,YAAQ,IAAI,kBAAkB;AAAA,EAChC,OAAO;AACL,YAAQ,IAAI,IAAI,IAAI;AAAA,EACtB;AACA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,WAAW,OAAO,MAAM,QAAQ;AAC5C,MAAI,OAAO,WAAW,EAAG;AACzB,QAAM,UAAU,QAAQ,WAAW,QAAQ,QAAQ,SAAS;AAC5D,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,QAAQ,UAAU,SAAS,OAAO,MAAM,CAAC,IAAI;AACnD,QAAM,UAAU,UAAU,gBAAgB,QAAQ,MAAM,MAAM;AAC9D,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAO;AACnB,QAAM,UAAU,UAAU,OAAO;AACjC,aAAW,MAAM,OAAO;AACtB,YAAQ,IAAI,KAAK,gBAAgB,EAAE,CAAC,EAAE;AACtC,QAAI,WAAW,GAAG,SAAS,mBAAmB;AAC5C,iBAAW,QAAQ,4BAA4B,EAAE,GAAG;AAClD,gBAAQ,IAAI,IAAI;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,IAAmB;AAC1C,MAAI,GAAG,SAAS,gBAAgB;AAC9B,WAAO,GAAG,GAAG,WAAW,KAAK,GAAG,MAAM,+BAA+B,GAAG,KAAK;AAAA,EAC/E;AACA,MAAI,GAAG,SAAS,uBAAuB;AACrC,WAAO,GAAG,GAAG,WAAW,KAAK,GAAG,MAAM,+BAA+B,GAAG,IAAI,OAAO,GAAG,EAAE;AAAA,EAC1F;AACA,MAAI,GAAG,SAAS,mBAAmB;AACjC,UAAM,gBACH,GAAG,+BAA+B,OAAO,IAAI,KAAK,GAAG,wBAAwB;AAChF,WAAO,GAAG,GAAG,WAAW,KAAK,GAAG,MAAM,+BAA+B,YAAY,cAAc,iBAAiB,IAAI,KAAK,GAAG;AAAA,EAC9H;AACA,MAAI,GAAG,SAAS,0BAA0B;AACxC,UAAM,QAAQ,GAAG,sBAAsB;AACvC,UAAM,UAAU,GAAG,wBAAwB;AAC3C,UAAM,YAAY,GAAG,gBAAgB,SAAY,WAAW,GAAG,WAAW,KAAK;AAC/E,WAAO,GAAG,GAAG,WAAW,KAAK,GAAG,MAAM,gCAAgC,KAAK,OAAO,OAAO,GAAG,SAAS;AAAA,EACvG;AACA,MAAI,GAAG,SAAS,gBAAgB;AAC9B,WAAO,GAAG,GAAG,WAAW,KAAK,GAAG,MAAM,+BAA+B,GAAG,KAAK;AAAA,EAC/E;AACA,MAAI,GAAG,SAAS,iBAAiB;AAC/B,WAAO,GAAG,GAAG,WAAW,KAAK,GAAG,MAAM,+BAA+B,GAAG,KAAK;AAAA,EAC/E;AACA,SAAO,GAAG,GAAG,WAAW,KAAK,GAAG,MAAM,MAAM,GAAG,IAAI;AACrD;AAEA,SAAS,4BAA4B,IAAmC;AACtE,QAAM,QAAkB,CAAC;AACzB,MAAI,GAAG,+BAA+B,MAAM;AAC1C,UAAM,KAAK,wCAAwC,GAAG,0BAA0B,EAAE;AAAA,EACpF;AACA,MAAI,GAAG,mCAAmC,MAAM;AAC9C,UAAM,KAAK,yCAAyC,GAAG,8BAA8B,EAAE;AAAA,EACzF;AACA,MAAI,GAAG,wBAAwB,SAAS,GAAG;AACzC,UAAM,KAAK,gCAAgC;AAC3C,eAAW,OAAO,GAAG,yBAAyB;AAC5C,YAAM,KAAK,aAAa,GAAG,EAAE;AAAA,IAC/B;AAAA,EACF;AACA,SAAO;AACT;AAMA,eAAsB,cACpB,aACA,gBACA,SACA,MAAmB,CAAC,GACL;AACf,MAAI;AACF,UAAM,gBAAgB,aAAa,gBAAgB,SAAS,GAAG;AAAA,EACjE,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,GAAG,aAAa,iBAAiB,CAAC;AACpF,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAsB,gBACpB,aACA,gBACA,SACA,KACe;AACf,MAAI,YAAY,KAAK,EAAE,WAAW,GAAG;AACnC,UAAM,IAAI,MAAM,kBAAkB;AAAA,EACpC;AACA,QAAM,YAAY,0BAA0B,cAAc;AAE1D,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,6BAA6B,KAAK,QAAQ;AACvE,QAAM,QAAQX,YAAW,cAAc;AACvC,QAAMC,4BAA2B,MAAM,IAAI;AAE3C,QAAM,SAAU,MAAMO,eAAc,OAAO,WAAW;AACtD,QAAM,MAAM,IAAI,gBAAgB,SAAY,IAAI,YAAY,IAAI,oBAAI,KAAK;AACzE,QAAM,aAAa,IAAI,YAAY;AAEnC,MAAI,QAAQ,YAAY,QAAW;AACjC,UAAM,YAAa,MAAML,kBAAiB,OAAO,QAAQ,OAAO;AAChE,UAAMC,UAAS,MAAM,0BAA0B;AAAA,MAC7C,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,0BAAsB,SAAS;AAAA,MAC7B,MAAM;AAAA,MACN,QAAQA,QAAO;AAAA,MACf,SAASA,QAAO;AAAA,MAChB,WAAWA,QAAO;AAAA,MAClB,eAAeA,QAAO;AAAA,MACtB,gBAAgBA,QAAO;AAAA,MACvB,WAAWA,QAAO;AAAA,IACpB,CAAC;AACD;AAAA,EACF;AAEA,QAAM,WAAW,MAAMC,cAAa,KAAK;AACzC,QAAM,SAAS,MAAM,0BAA0B;AAAA,IAC7C,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,EACpB,CAAC;AACD,wBAAsB,SAAS;AAAA,IAC7B,MAAM;AAAA,IACN,QAAQ,OAAO;AAAA,IACf,SAAS,OAAO;AAAA,IAChB,WAAW,OAAO;AAAA,IAClB,eAAe,OAAO;AAAA,IACtB,gBAAgB,OAAO;AAAA,IACvB,WAAW,OAAO;AAAA,EACpB,CAAC;AACH;AAYA,SAAS,sBAAsB,SAA4B,QAA+B;AACxF,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ;AAAA,MACN,KAAK,UAAU;AAAA,QACb,SAAS,OAAO;AAAA,QAChB,UAAU,OAAO;AAAA,QACjB,YAAY,OAAO;AAAA,QACnB,gBAAgB,OAAO;AAAA,QACvB,MAAM,OAAO;AAAA,QACb,iBAAiB,OAAO;AAAA,QACxB,YAAY,OAAO;AAAA,MACrB,CAAC;AAAA,IACH;AACA;AAAA,EACF;AACA,QAAM,MAAM,eAAe,OAAO,SAAS;AAC3C,UAAQ;AAAA,IACN,WAAW,OAAO,MAAM,YAAY,OAAO,cAAc,OAAO,OAAO,SAAS,gBAAgB,GAAG;AAAA,EACrG;AACF;AAMA,eAAsB,iBACpB,SACA,MAAmB,CAAC,GACL;AACf,MAAI;AACF,UAAM,mBAAmB,SAAS,GAAG;AAAA,EACvC,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,GAAG,aAAa,iBAAiB,CAAC;AACpF,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAsB,mBACpB,SACA,KACe;AACf,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,6BAA6B,KAAK,WAAW;AAC1E,QAAM,QAAQL,YAAW,cAAc;AACvC,QAAMC,4BAA2B,MAAM,IAAI;AAC3C,QAAM,WAAW,MAAMI,cAAa,KAAK;AACzC,QAAM,cAAc,IAAI,gBAAgB,MAAY,oBAAI,KAAK;AAC7D,QAAM,QAAQ,QAAQ,UAAU;AAChC,QAAM,UAAU,UAAU,OAAO;AACjC,QAAM,OAAO,QAAQ,SAAS;AAE9B,MAAI,QAAQ,SAAS,QAAW;AAC9B,UAAM,SAAU,MAAMG,eAAc,OAAO,QAAQ,IAAI;AACvD,UAAM,SAAS,MAAM,cAAc,OAAO,UAAU;AAAA,MAClD;AAAA,MACA,YAAY,YAAY,EAAE,YAAY;AAAA,MACtC,kBAAkB;AAAA,MAClB;AAAA,MACA,OAAO;AAAA,IACT,CAAC;AACD,QAAI,MAAM;AACR,yBAAmB,EAAE,QAAQ,CAAC,OAAO,SAAS,GAAG,SAAS,CAAC,MAAM,GAAG,QAAQ,CAAC,EAAE,CAAC;AAAA,IAClF,OAAO;AACL,YAAM,yBAAyB,QAAQ,OAAO,EAAE,OAAO,QAAQ,CAAC;AAAA,IAClE;AACA;AAAA,EACF;AAEA,QAAM,MAAM,MAAM,kBAAkB,OAAO,UAAU;AAAA,IACnD,YAAY,MAAM,YAAY,EAAE,YAAY;AAAA,IAC5C,kBAAkB;AAAA,IAClB;AAAA,EACF,CAAC;AACD,MAAI,MAAM;AACR,uBAAmB;AAAA,MACjB,QAAQ,CAAC;AAAA,MACT,SAAS,IAAI;AAAA,MACb,SAAS,IAAI;AAAA,MACb,QAAQ,IAAI;AAAA,IACd,CAAC;AAAA,EACH,OAAO;AACL,0BAAsB,IAAI,SAAS,IAAI,QAAQ,IAAI,SAAS,EAAE,OAAO,QAAQ,CAAC;AAAA,EAChF;AACA,MAAI,IAAI,OAAO,SAAS,GAAG;AACzB,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,SAAS,mBAAmB,OAKnB;AACP,UAAQ;AAAA,IACN,KAAK;AAAA,MACH;AAAA,QACE,SAAS,MAAM;AAAA,QACf,SAAS,MAAM;AAAA,QACf,YAAY,MAAM,QAAQ,IAAI,CAAC,OAAO;AAAA,UACpC,SAAS,EAAE;AAAA,UACX,4BAA4B,EAAE;AAAA,UAC9B,gCACE,EAAE,2BAA2B,QAAQ,EAAE,qBAAqB,OACxD,EAAE,iBAAiB,YACnB;AAAA,UACN,yBAAyB,EAAE;AAAA,UAC3B,sBAAsB,EAAE,kBAAkB,aAAa;AAAA,UACvD,UAAU,EAAE,kBAAkB,WAAW;AAAA,QAC3C,EAAE;AAAA,QACF,QAAQ,MAAM,OAAO,IAAI,CAAC,OAAO;AAAA,UAC/B,SAAS,EAAE;AAAA,UACX,aAAa,EAAE;AAAA,UACf,OAAO,EAAE;AAAA,QACX,EAAE;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,yBACb,QACA,OACA,SACe;AACf,MAAI,OAAO,OAAO;AAKhB,QAAI,eAAe;AACnB,QAAI,cAAc;AAClB,QAAI;AACF,YAAM,MAAM,MAAM,aAAa,OAAO,OAAO,MAAM;AACnD,qBAAe;AACf,oBAAc,IAAI,KAAK,KAAK,gBAAgB;AAAA,IAC9C,QAAQ;AAAA,IAGR;AACA,YAAQ;AAAA,MACN,GAAG,OAAO,MAAM,qBAAqB,YAAY,yBAAyB,WAAW;AAAA,IACvF;AACA;AAAA,EACF;AACA,MAAI,QAAQ,OAAO;AACjB,UAAM,cACJ,OAAO,qBAAqB,OACxB,gBAAgB,eAAe,OAAO,iBAAiB,SAAS,CAAC,MACjE;AACN,YAAQ,IAAI,cAAc,OAAO,MAAM,KAAK,yBAAyB,MAAM,CAAC,GAAG,WAAW,GAAG;AAC7F;AAAA,EACF;AACA,QAAM,UAAU,sBAAsB,QAAQ,QAAQ,QAAQ,OAAO;AACrE,UAAQ,IAAI,6BAA6B,OAAO,MAAM,KAAK,OAAO,EAAE;AACpE,UAAQ,IAAI,kFAAkF;AAC9F,UAAQ,IAAI,+BAA+B;AAC7C;AAEA,SAAS,sBACP,SACA,QACA,SACA,SACM;AACN,MAAI,QAAQ,WAAW,KAAK,OAAO,WAAW,GAAG;AAC/C,YAAQ,IAAI,WAAW,OAAO,kCAAkC;AAChE;AAAA,EACF;AAEA,MAAI,kBAAkB;AACtB,aAAW,KAAK,SAAS;AACvB,uBAAmB,EAAE,qBAAqB,UAAU,EAAE,2BAA2B,OAAO,IAAI;AAAA,EAC9F;AAEA,MAAI,QAAQ,OAAO;AACjB,eAAW,KAAK,SAAS;AACvB,YAAM,cACJ,EAAE,qBAAqB,OACnB,gBAAgB,eAAe,EAAE,iBAAiB,SAAS,CAAC,MAC5D;AACN,cAAQ,IAAI,cAAc,EAAE,MAAM,KAAK,yBAAyB,CAAC,CAAC,GAAG,WAAW,EAAE;AAAA,IACpF;AACA,eAAW,KAAK,QAAQ;AACtB,YAAM,QAAQ,EAAE,SAAS;AACzB,cAAQ;AAAA,QACN,uBAAuB,EAAE,MAAM,KAAK,EAAE,UAAU,YAAY,KAAK;AAAA,MACnE;AAAA,IACF;AACA,UAAM,kBAAkB,QAAQ;AAChC,UAAM,iBAAiB;AACvB,UAAM,iBAAiB,cAAc,eAAe,QAAQ,oBAAoB,IAAI,KAAK,GAAG,KAAK,cAAc,cAAc,mBAAmB,IAAI,KAAK,GAAG;AAC5J,UAAM,aACJ,OAAO,WAAW,IAAI,KAAK,KAAK,OAAO,MAAM,QAAQ,OAAO,WAAW,IAAI,KAAK,GAAG;AACrF,YAAQ,IAAI,WAAW,OAAO,WAAW,cAAc,GAAG,UAAU,GAAG;AACvE,QAAI,OAAO,SAAS,GAAG;AACrB,cAAQ,MAAM,eAAe;AAAA,IAC/B;AACA;AAAA,EACF;AAGA,aAAW,KAAK,SAAS;AACvB,UAAM,UAAU,sBAAsB,GAAG,OAAO,QAAQ,OAAO;AAC/D,YAAQ,IAAI,6BAA6B,EAAE,MAAM,KAAK,OAAO,EAAE;AAAA,EACjE;AACA,UAAQ;AAAA,IACN,WAAW,OAAO,2BAA2B,QAAQ,MAAM,QAAQ,QAAQ,WAAW,IAAI,KAAK,GAAG,KAAK,eAAe,cAAc,oBAAoB,IAAI,KAAK,GAAG;AAAA,EACtK;AACA,UAAQ,IAAI,kFAAkF;AAC9F,UAAQ,IAAI,+BAA+B;AAC7C;AAEA,SAAS,yBAAyB,GAA4B;AAC5D,QAAM,cAAc,EAAE,qBAAqB;AAC3C,QAAM,QAAkB,CAAC;AACzB,MAAI,EAAE,2BAA2B,MAAM;AACrC,UAAM,KAAK,6BAA6B;AAAA,EAC1C;AACA,MAAI,cAAc,GAAG;AACnB,UAAM,KAAK,WAAW,WAAW,wBAAwB,gBAAgB,IAAI,MAAM,KAAK,EAAE;AAAA,EAC5F;AACA,SAAO,MAAM,KAAK,KAAK;AACzB;AAEA,SAAS,sBACP,GACA,OACA,SACQ;AACR,QAAM,UAAU,UAAU,UAAU;AACpC,QAAM,QAAkB,CAAC;AACzB,MAAI,EAAE,2BAA2B,MAAM;AACrC,UAAM;AAAA,MACJ,UACI,6BAA6B,0BAA0B,EAAE,wBAAwB,SAAS,KAAK,CAAC,KAChG;AAAA,IACN;AAAA,EACF;AACA,QAAM,cAAc,EAAE,qBAAqB;AAC3C,MAAI,cAAc,GAAG;AACnB,QAAI,SAAS;AACX,YAAM,MAAM,EAAE,qBACX,IAAI,CAAC,OAAO,0BAA0B,IAAI,SAAS,KAAK,CAAC,EACzD,KAAK,IAAI;AACZ,YAAM,KAAK,GAAG,WAAW,wBAAwB,gBAAgB,IAAI,MAAM,KAAK,KAAK,GAAG,GAAG;AAAA,IAC7F,OAAO;AACL,YAAM,KAAK,GAAG,WAAW,wBAAwB,gBAAgB,IAAI,MAAM,KAAK,EAAE;AAAA,IACpF;AAAA,EACF;AACA,SAAO,MAAM,KAAK,KAAK;AACzB;AAEA,SAAS,0BAA0B,IAAY,SAAkB,OAA+B;AAC9F,MAAI,WAAW,UAAU,OAAQ,QAAO;AACxC,SAAO,OAAO,eAAe,EAAE,CAAC;AAClC;AAMA,eAAsB,sBACpB,aACA,SACA,MAAmB,CAAC,GACL;AACf,MAAI;AACF,UAAM,wBAAwB,aAAa,SAAS,GAAG;AAAA,EACzD,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,GAAG,aAAa,iBAAiB,CAAC;AACpF,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAsB,wBACpB,aACA,SACA,KACe;AACf,MAAI,YAAY,KAAK,EAAE,WAAW,GAAG;AACnC,UAAM,IAAI,MAAM,kBAAkB;AAAA,EACpC;AACA,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,6BAA6B,KAAK,iBAAiB;AAChF,QAAM,QAAQR,YAAW,cAAc;AACvC,QAAMC,4BAA2B,MAAM,IAAI;AAC3C,QAAM,WAAW,MAAMI,cAAa,KAAK;AACzC,QAAM,SAAU,MAAMG,eAAc,OAAO,WAAW;AACtD,QAAM,cAAc,IAAI,gBAAgB,MAAY,oBAAI,KAAK;AAC7D,QAAM,QAAQ,QAAQ,UAAU;AAEhC,QAAM,SAAS,MAAM,0BAA0B,OAAO,UAAU;AAAA,IAC9D;AAAA,IACA,YAAY,YAAY,EAAE,YAAY;AAAA,IACtC,kBAAkB;AAAA,IAClB;AAAA,EACF,CAAC;AAED,MAAI,QAAQ,SAAS,MAAM;AACzB,4BAAwB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC;AAClD;AAAA,EACF;AACA,0BAAwB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC;AACpD;AAEA,SAAS,wBAAwB,QAA8B,OAAkC;AAC/F,UAAQ;AAAA,IACN,KAAK;AAAA,MACH;AAAA,QACE,SAAS,OAAO;AAAA,QAChB,OAAO,OAAO;AAAA,QACd,SAAS,MAAM;AAAA,QACf,uBAAuB,OAAO;AAAA,QAC9B,yBAAyB,OAAO;AAAA,QAChC,aAAa,OAAO;AAAA,QACpB,oBAAoB,OAAO,gBAAgB,aAAa;AAAA,QACxD,UAAU,OAAO,gBAAgB,WAAW;AAAA,MAC9C;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,wBAAwB,QAA8B,OAAkC;AAC/F,MAAI,OAAO,OAAO;AAChB,YAAQ;AAAA,MACN,GAAG,OAAO,MAAM,oCAAoC,OAAO,UAAU,QAAQ,OAAO,eAAe,IAAI,MAAM,KAAK;AAAA,IACpH;AACA;AAAA,EACF;AACA,QAAM,aAAa,OAAO,oBAAoB;AAC9C,QAAM,eAAe,OAAO,sBAAsB;AAClD,QAAM,eAAyB,CAAC;AAChC,MAAI,aAAa,GAAG;AAClB,iBAAa,KAAK,IAAI,UAAU,QAAQ;AAAA,EAC1C;AACA,MAAI,eAAe,GAAG;AACpB,iBAAa,KAAK,IAAI,YAAY,UAAU;AAAA,EAC9C;AACA,QAAM,UAAU,aAAa,KAAK,IAAI;AACtC,MAAI,MAAM,QAAQ;AAChB,YAAQ,IAAI,2BAA2B,OAAO,MAAM,qBAAqB,OAAO,GAAG;AACnF,YAAQ,IAAI,+BAA+B;AAC3C;AAAA,EACF;AACA,QAAM,MACJ,OAAO,mBAAmB,OACtB,gBAAgB,eAAe,OAAO,eAAe,SAAS,CAAC,MAC/D;AACN,UAAQ;AAAA,IACN,aAAa,OAAO,MAAM,qBAAqB,OAAO,GAAG,GAAG,iBAAiB,OAAO,UAAU;AAAA,EAChG;AACF;AAMA,eAAsB,YACpB,aACA,SACA,MAAmB,CAAC,GACL;AACf,MAAI;AACF,UAAM,cAAc,aAAa,SAAS,GAAG;AAAA,EAC/C,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,GAAG,aAAa,iBAAiB,CAAC;AACpF,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAsB,cACpB,aACA,SACA,KACe;AACf,MAAI,YAAY,KAAK,EAAE,WAAW,GAAG;AACnC,UAAM,IAAI,MAAM,kBAAkB;AAAA,EACpC;AACA,MAAI,QAAQ,UAAU,UAAa,QAAQ,WAAW,QAAW;AAC/D,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AACA,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,6BAA6B,KAAK,MAAM;AACrE,QAAM,QAAQR,YAAW,cAAc;AACvC,QAAMC,4BAA2B,MAAM,IAAI;AAC3C,QAAM,WAAW,MAAMI,cAAa,KAAK;AACzC,QAAM,SAAU,MAAMG,eAAc,OAAO,WAAW;AACtD,QAAM,MAAM,IAAI,gBAAgB,SAAY,IAAI,YAAY,IAAI,oBAAI,KAAK;AACzE,QAAM,aAAa,IAAI,YAAY;AAEnC,QAAM,SAAS,MAAM,SAAS;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,IAClB,GAAI,QAAQ,UAAU,SAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,IAC9D,GAAI,QAAQ,WAAW,SAAY,EAAE,WAAW,QAAQ,OAAO,IAAI,CAAC;AAAA,EACtE,CAAC;AAED,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ;AAAA,MACN,KAAK,UAAU;AAAA,QACb,SAAS,OAAO;AAAA,QAChB,eAAe,OAAO;AAAA,QACtB,gBAAgB,OAAO;AAAA,QACvB,iBAAiB,OAAO;AAAA,QACxB,YAAY,OAAO;AAAA,QACnB,0BAA0B,OAAO,qBAAqB,aAAa;AAAA,QACnE,wBAAwB,OAAO,qBAAqB,WAAW;AAAA,MACjE,CAAC;AAAA,IACH;AACA;AAAA,EACF;AACA,MAAI,OAAO,eAAe;AACxB,UAAM,MACJ,OAAO,wBAAwB,OAC3B,gBAAgB,eAAe,OAAO,oBAAoB,SAAS,CAAC,MACpE;AACN,YAAQ;AAAA,MACN,WAAW,OAAO,MAAM,YAAY,OAAO,cAAc,OAAO,OAAO,SAAS,GAAG,GAAG;AAAA,IACxF;AAAA,EACF;AACA,MAAI,OAAO,cAAc;AACvB,YAAQ,IAAI,WAAW,OAAO,MAAM,SAAS;AAAA,EAC/C;AACA,MAAI,CAAC,OAAO,iBAAiB,CAAC,OAAO,cAAc;AAGjD,YAAQ,IAAI,kBAAkB,OAAO,MAAM,GAAG;AAAA,EAChD;AACF;AAEA,eAAsB,cACpB,aACA,SACA,MAAmB,CAAC,GACL;AACf,MAAI;AACF,UAAM,gBAAgB,aAAa,SAAS,GAAG;AAAA,EACjD,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,GAAG,aAAa,iBAAiB,CAAC;AACpF,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAsB,gBACpB,aACA,SACA,KACe;AACf,MAAI,YAAY,KAAK,EAAE,WAAW,GAAG;AACnC,UAAM,IAAI,MAAM,kBAAkB;AAAA,EACpC;AACA,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,6BAA6B,KAAK,QAAQ;AACvE,QAAM,QAAQR,YAAW,cAAc;AACvC,QAAMC,4BAA2B,MAAM,IAAI;AAC3C,QAAM,WAAW,MAAMI,cAAa,KAAK;AACzC,QAAM,SAAU,MAAMG,eAAc,OAAO,WAAW;AAEtD,MAAI,QAAQ,QAAQ,MAAM;AACxB,UAAM,yBAAyB,UAAU,MAAM;AAAA,EACjD;AAEA,QAAM,MAAM,IAAI,gBAAgB,SAAY,IAAI,YAAY,IAAI,oBAAI,KAAK;AACzE,QAAM,aAAa,IAAI,YAAY;AACnC,QAAM,SAAS,MAAM,WAAW;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,EACpB,CAAC;AAED,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ;AAAA,MACN,KAAK,UAAU;AAAA,QACb,SAAS,OAAO;AAAA,QAChB,OAAO,OAAO;AAAA,QACd,YAAY,OAAO;AAAA,QACnB,UAAU,OAAO;AAAA,MACnB,CAAC;AAAA,IACH;AACA;AAAA,EACF;AACA,UAAQ;AAAA,IACN,WAAW,OAAO,MAAM,MAAM,OAAO,KAAK,wBAAwB,eAAe,OAAO,SAAS,CAAC;AAAA,EACpG;AACF;AAEA,eAAsB,eACpB,aACA,SACA,MAAmB,CAAC,GACL;AACf,MAAI;AACF,UAAM,iBAAiB,aAAa,SAAS,GAAG;AAAA,EAClD,SAAS,OAAgB;AACvB,mBAAe,OAAO,EAAE,SAAS,UAAU,OAAO,GAAG,aAAa,iBAAiB,CAAC;AACpF,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAsB,iBACpB,aACA,SACA,KACe;AACf,MAAI,YAAY,KAAK,EAAE,WAAW,GAAG;AACnC,UAAM,IAAI,MAAM,kBAAkB;AAAA,EACpC;AACA,QAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;AACnC,QAAM,iBAAiB,MAAM,6BAA6B,KAAK,SAAS;AACxE,QAAM,QAAQR,YAAW,cAAc;AACvC,QAAMC,4BAA2B,MAAM,IAAI;AAC3C,QAAM,WAAW,MAAMI,cAAa,KAAK;AACzC,QAAM,SAAU,MAAMG,eAAc,OAAO,WAAW;AAEtD,MAAI,QAAQ,QAAQ,MAAM;AACxB,UAAM,yBAAyB,WAAW,MAAM;AAAA,EAClD;AAEA,QAAM,MAAM,IAAI,gBAAgB,SAAY,IAAI,YAAY,IAAI,oBAAI,KAAK;AACzE,QAAM,aAAa,IAAI,YAAY;AACnC,QAAM,SAAS,MAAM,YAAY;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,EACpB,CAAC;AAED,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ;AAAA,MACN,KAAK,UAAU;AAAA,QACb,SAAS,OAAO;AAAA,QAChB,OAAO,OAAO;AAAA,QACd,YAAY,OAAO;AAAA,QACnB,UAAU,OAAO;AAAA,MACnB,CAAC;AAAA,IACH;AACA;AAAA,EACF;AACA,UAAQ;AAAA,IACN,YAAY,OAAO,MAAM,MAAM,OAAO,KAAK,wBAAwB,eAAe,OAAO,SAAS,CAAC;AAAA,EACrG;AACF;AAQA,eAAe,yBACb,QACA,QACe;AACf,MAAI,QAAQ,MAAM,UAAU,MAAM;AAChC,UAAM,IAAI,MAAM,eAAe,MAAM,sDAAsD;AAAA,EAC7F;AACA,QAAM,OAAO,WAAW,WAAW,WAAW;AAC9C,UAAQ,OAAO,MAAM,GAAG,IAAI,WAAW,MAAM,YAAY;AACzD,QAAM,SAAS,MAAM,wBAAwB;AAC7C,QAAM,aAAa,OAAO,KAAK,EAAE,YAAY;AAC7C,MAAI,eAAe,OAAO,eAAe,OAAO;AAC9C,UAAM,IAAI,MAAM,GAAG,IAAI,mBAAmB;AAAA,EAC5C;AACF;AAEA,eAAe,0BAA2C;AACxD,QAAM,EAAE,gBAAgB,IAAI,MAAM,OAAO,mBAAwB;AACjE,QAAM,KAAK,gBAAgB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,OAAO,CAAC;AAC3E,MAAI;AACF,UAAM,OAAO,MAAM,GAAG,SAAS,EAAE;AACjC,WAAO;AAAA,EACT,UAAE;AACA,OAAG,MAAM;AAAA,EACX;AACF;AAMA,SAASV,YAAW,KAAqB;AACvC,MAAI,IAAI,WAAW,GAAG;AACpB,UAAM,IAAIc,sBAAqB,yBAAyB;AAAA,EAC1D;AACA,SAAO;AACT;AAEA,SAAS,WAAW,KAAqB;AACvC,MAAI,IAAI,WAAW,GAAG;AACpB,UAAM,IAAIA,sBAAqB,yBAAyB;AAAA,EAC1D;AACA,SAAO;AACT;AAEA,SAAS,uBAAuB,KAAyB;AACvD,QAAM,SAAS,iBAAiB,UAAU,GAAG;AAC7C,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,IAAIA;AAAA,MACR,uCAAuChB,eAAc,KAAK,IAAI,CAAC;AAAA,IACjE;AAAA,EACF;AACA,SAAO,OAAO;AAChB;AAEA,IAAM,cAAc;AAEpB,SAAS,wBAAwB,KAAqB;AAKpD,MAAI,CAAC,YAAY,KAAK,GAAG,KAAK,OAAO,MAAM,KAAK,MAAM,GAAG,CAAC,GAAG;AAC3D,UAAM,IAAIgB;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,sBAAsB,KAAyB;AACtD,QAAM,SAAS,iBAAiB,UAAU,GAAG;AAC7C,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,IAAIA;AAAA,MACR,wBAAwB,GAAG,mBAAmBhB,eAAc,KAAK,IAAI,CAAC;AAAA,IACxE;AAAA,EACF;AACA,SAAO,OAAO;AAChB;AAEA,SAAS,0BAA0B,KAAyB;AAC1D,QAAM,SAAS,iBAAiB,UAAU,GAAG;AAC7C,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,IAAI,MAAM,wBAAwB,GAAG,mBAAmBA,eAAc,KAAK,IAAI,CAAC,EAAE;AAAA,EAC1F;AACA,SAAO,OAAO;AAChB;AAEA,SAAS,uBAAuB,KAAqB;AACnD,MAAI,IAAI,WAAW,GAAG;AACpB,UAAM,IAAIgB,sBAAqB,+BAA+B;AAAA,EAChE;AACA,SAAO;AACT;AAEA,SAASb,kBAAiB,KAAqB;AAC7C,QAAM,IAAI,OAAO,SAAS,KAAK,EAAE;AACjC,MAAI,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,KAAK,IAAI,KAAK,MAAM,OAAO,CAAC,GAAG;AAC7D,UAAM,IAAIa,sBAAqB,mBAAmB,GAAG,EAAE;AAAA,EACzD;AACA,SAAO;AACT;AAMA,eAAe,oBAAoB,MAA+B;AAChE,MAAI;AACF,WAAO,MAAMC,UAAS,MAAM,MAAM;AAAA,EACpC,SAAS,OAAgB;AACvB,QAAIC,eAAc,OAAO,QAAQ,GAAG;AAClC,YAAM,IAAI,MAAM,gCAAgC,EAAE,OAAO,MAAM,CAAC;AAAA,IAClE;AACA,QAAIA,eAAc,OAAO,QAAQ,GAAG;AAClC,YAAM,IAAI,MAAM,oCAAoC,EAAE,OAAO,MAAM,CAAC;AAAA,IACtE;AACA,UAAM,IAAI,MAAM,qCAAqC,EAAE,OAAO,MAAM,CAAC;AAAA,EACvE;AACF;AAEA,eAAe,6BACb,KACA,QAUiB;AACjB,MAAI;AACF,WAAO,MAAMC,wBAAsB,GAAG;AAAA,EACxC,SAAS,OAAgB;AACvB,QAAI,iBAAiB,SAAS,MAAM,YAAY,wBAAwB;AACtE,YAAM,IAAI;AAAA,QACR,uEAAuE,MAAM;AAAA,QAC7E,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAed,4BAA2B,WAAkC;AAC1E,MAAI;AACF,UAAMe,qBAAoB,SAAS;AAAA,EACrC,SAAS,OAAgB;AACvB,QAAIF,eAAc,OAAO,QAAQ,GAAG;AAClC,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AACA,UAAM;AAAA,EACR;AACF;AAWA,IAAM,gCAAiD;AAAA,EACrD,OAAO,CAAC,UAAU,iBAAiB;AAAA,EACnC,iBAAiB,CAAC,UAAU;AAC1B,UAAM,IAAI;AACV,UAAM,MAAM,eAAe,EAAE,SAAS;AACtC,UAAM,MAAM,YAAY,EAAE,MAAM;AAChC,UAAM,iBAAiB,uBAAuB,EAAE,OAAO,KAAK,GAAG;AAC/D,UAAM,UAAU,4BAA4B,EAAE,KAAK;AACnD,UAAM,OACJ,EAAE,UAAU,yBACR,kCACA,EAAE,UAAU,+BACV,wCACA;AACR,WAAO;AAAA,MACL,YAAY,EAAE,OAAO,eAAe,GAAG,KAAK,cAAc;AAAA,MAC1D,YAAY,OAAO,iCAAiC,IAAI;AAAA,IAC1D;AAAA,EACF;AACF;AAEA,IAAM,mBAA+C;AAAA,EACnD;AAAA,EACA;AACF;AAEA,SAAS,uBACP,OACA,KACA,KACQ;AACR,UAAQ,OAAO;AAAA,IACb,KAAK;AACH,aAAO,QAAQ,GAAG;AAAA,IACpB,KAAK;AACH,aAAO,QAAQ,GAAG;AAAA,IACpB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,QAAQ,GAAG;AAAA,IACpB,KAAK;AACH,aAAO,qBAAqB,GAAG;AAAA,IACjC,KAAK;AACH,aAAO,QAAQ,GAAG;AAAA,IACpB,KAAK;AACH,aAAO,QAAQ,GAAG;AAAA,IACpB,KAAK;AACH,aAAO,2BAA2B,GAAG;AAAA,IACvC,KAAK;AACH,aAAO,QAAQ,GAAG;AAAA,IACpB,KAAK;AACH,aAAO,QAAQ,GAAG;AAAA,IACpB,KAAK;AACH,aAAO,QAAQ,GAAG;AAAA,EACtB;AACF;AAEA,SAAS,4BAA4B,OAAkD;AACrF,UAAQ,OAAO;AAAA,IACb,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAEA,SAASP,KAAI,OAAe,OAAuB;AACjD,SAAO,MAAM,UAAU,QAAQ,QAAQ,QAAQ,IAAI,OAAO,QAAQ,MAAM,MAAM;AAChF;AAEA,SAASD,QAAO,QAA2B,OAAuB;AAChE,MAAI,MAAM;AACV,aAAW,KAAK,OAAQ,KAAI,EAAE,SAAS,IAAK,OAAM,EAAE;AACpD,SAAO;AACT;;;AX/lDA,IAAMW,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,MAAMA,SAAQ,iBAAiB;AACrC,IAAM,oBAAoB,IAAI;AAE9B,IAAM,UAAU,IAAI,QAAQ;AAC5B,QACG,KAAK,OAAO,EACZ,YAAY,qCAAqC,EACjD,QAAQ,iBAAiB,EAGzB,wBAAwB;AAE3B,oBAAoB,OAAO;AAC3B,sBAAsB,OAAO;AAC7B,oBAAoB,OAAO;AAC3B,mBAAmB,OAAO;AAC1B,uBAAuB,OAAO;AAC9B,wBAAwB,OAAO;AAC/B,wBAAwB,OAAO;AAC/B,oBAAoB,OAAO;AAC3B,uBAAuB,OAAO;AAC9B,yBAAyB,OAAO;AAEhC,QAAQ,WAAW,QAAQ,IAAI,EAAE,MAAM,CAAC,QAAiB;AAMvD,iBAAe,KAAK,EAAE,SAAS,UAAU,MAAS,EAAE,CAAC;AACrD,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["program","id","assertBasouRootSafe","basouPaths","findErrorCode","prefixedUlid","resolveRepositoryRoot","program","basouPaths","assertWorkspaceInitialized","prefixedUlid","resolveRepositoryRoot","assertBasouRootSafe","findErrorCode","assertBasouRootSafe","basouPaths","findErrorCode","resolveRepositoryRoot","program","basouPaths","assertWorkspaceInitialized","resolveRepositoryRoot","assertBasouRootSafe","findErrorCode","join","assertBasouRootSafe","basouPaths","prefixedUlid","readManifest","readYamlFile","resolveRepositoryRoot","program","appendEvent","basouPaths","assertBasouRootSafe","readManifest","prefixedUlid","join","readYamlFile","resolveRepositoryRoot","assertBasouRootSafe","basouPaths","findErrorCode","readMarkdownFile","renderWithMarkers","resolveRepositoryRoot","writeMarkdownFile","program","basouPaths","assertWorkspaceInitialized","readMarkdownFile","renderWithMarkers","writeMarkdownFile","resolveRepositoryRoot","assertBasouRootSafe","findErrorCode","resolveRepositoryRoot","program","resolveRepositoryRoot","mkdir","homedir","join","ChildProcessRunner","SessionSchema","assertBasouRootSafe","basouPaths","coreAppendEvent","getSnapshot","overwriteYamlFile","prefixedUlid","readManifest","readYamlFile","resolveRepositoryRoot","sanitizeWorkingDirectory","writeYamlFile","program","ChildProcessRunner","appendEvent","coreAppendEvent","basouPaths","assertBasouRootSafe","readManifest","prefixedUlid","join","mkdir","buildInitialSession","writeYamlFile","tryAppendGitSnapshot","mutateSessionYaml","finalizeSessionAsFailed","homedir","decideFinalStatus","signalToExitCode","SIGNUM_MAP","getSnapshot","normalizeGitSnapshotSkipMessage","sanitizeWorkingDirectory","readYamlFile","SessionSchema","overwriteYamlFile","resolveRepositoryRoot","basename","join","SessionSchema","acquireLock","appendEventToExistingSession","assertBasouRootSafe","basouPaths","findErrorCode","readManifest","readYamlFile","resolveRepositoryRoot","resolveSessionId","InvalidArgumentError","SES_PREFIX","TASK_PREFIX","SHORT_ID_BASE_LEN","SHORT_ID_MAX_LEN","STATUS_VALUES","program","basouPaths","assertWorkspaceInitialized","resolveSessionId","join","readYamlFile","SessionSchema","findErrorCode","computeUniquePrefixLen","sliceShort","maxLen","pad","shortTaskId","shortId","resolveRepositoryRoot","assertBasouRootSafe","readManifest","InvalidArgumentError","basename","acquireLock","appendEventToExistingSession","assertBasouRootSafe","basouPaths","findErrorCode","readManifest","resolveRepositoryRoot","program","basouPaths","assertBasouRootSafe","findErrorCode","readManifest","resolveRepositoryRoot","readFile","join","assertBasouRootSafe","basouPaths","findErrorCode","loadSessionEntries","prefixedUlid","readManifest","replayEvents","resolveRepositoryRoot","resolveSessionId","resolveTaskId","InvalidArgumentError","STATUS_VALUES","program","parseTitle","parsePositiveInt","basouPaths","assertWorkspaceInitialized","prefixedUlid","resolveSessionId","result","readManifest","maxLen","pad","resolveTaskId","loadSessionEntries","join","replayEvents","InvalidArgumentError","readFile","findErrorCode","resolveRepositoryRoot","assertBasouRootSafe","require"]}
|