@mu-crew/mu 4.1.1 → 4.2.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/dist/{chunk-L7I3BLXP.js → chunk-4ZWBLTZK.js} +1512 -411
- package/dist/chunk-4ZWBLTZK.js.map +1 -0
- package/dist/{chunk-DEYBQDTO.js → chunk-FVRIKUBR.js} +2 -2
- package/dist/{chunk-B74N2EAS.js → chunk-RJQNDFBU.js} +8 -4
- package/dist/chunk-RJQNDFBU.js.map +1 -0
- package/dist/{chunk-LBBZAG5C.js → chunk-U2QLTREB.js} +26 -23
- package/dist/chunk-U2QLTREB.js.map +1 -0
- package/dist/{cli-H2PWJAJN.js → cli-H3VVCP7M.js} +146 -31
- package/dist/cli-H3VVCP7M.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/{errors-G5IVXSMY.js → errors-MDQZHB42.js} +8 -2
- package/dist/extension/mu-pi.js +20 -3
- package/dist/extension/mu-pi.js.map +1 -1
- package/dist/index.d.ts +2574 -2288
- package/dist/index.js +58 -4
- package/dist/index.js.map +1 -1
- package/dist/{tui-EN2CDP6G.js → tui-5ZARE7RS.js} +14 -15
- package/dist/tui-5ZARE7RS.js.map +1 -0
- package/docs/ARCHITECTURE.md +15 -8
- package/docs/VOCABULARY.md +14 -6
- package/docs/guide/remote.md +113 -4
- package/docs/guide/sql.md +1 -1
- package/docs/reference/env.md +1 -0
- package/package.json +1 -1
- package/skills/mu/recipes/remote-workers.md +7 -6
- package/dist/chunk-B74N2EAS.js.map +0 -1
- package/dist/chunk-L7I3BLXP.js.map +0 -1
- package/dist/chunk-LBBZAG5C.js.map +0 -1
- package/dist/cli-H2PWJAJN.js.map +0 -1
- package/dist/tui-EN2CDP6G.js.map +0 -1
- /package/dist/{chunk-DEYBQDTO.js.map → chunk-FVRIKUBR.js.map} +0 -0
- /package/dist/{errors-G5IVXSMY.js.map → errors-MDQZHB42.js.map} +0 -0
package/dist/tui-EN2CDP6G.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/tui/index.ts","../src/cli/tui/app.tsx","../node_modules/ansi-regex/index.js","../node_modules/strip-ansi/index.js","../node_modules/get-east-asian-width/lookup-data.js","../node_modules/get-east-asian-width/utilities.js","../node_modules/get-east-asian-width/lookup.js","../node_modules/get-east-asian-width/index.js","../node_modules/string-width/index.js","../src/cli/tui/commands.ts","../src/cli/tui/drill.tsx","../src/cli/tui/frame.tsx","../src/cli/tui/text.ts","../src/cli/tui/theme.ts","../src/cli/tui/nav.ts","../src/cli/tui/overview.tsx","../src/cli/tui/grid.ts","../src/cli/tui/columns.ts","../src/cli/tui/rows.ts","../src/cli/tui/use-snapshot.ts","../src/cli/tui/runtime.ts"],"sourcesContent":["// The dashboard entry. Loaded ONLY by `src/cli/dashboard-launch.ts` through a\n// dynamic import: ink and react stay out of every other verb and out of the SDK\n// index. Never import `../../cli.js` from here (import-cycle trap).\n\nimport { type Instance, render } from \"ink\";\nimport { createElement } from \"react\";\nimport { spawnerFromEnv } from \"../../agents/spawn.js\";\nimport type { Db } from \"../../db.js\";\nimport { resolveMuxSessionWorkstreamName } from \"../../workstream.js\";\nimport type { Shutdown } from \"../dashboard-shutdown.js\";\nimport { App } from \"./app.js\";\nimport { createRuntime } from \"./runtime.js\";\n\nexport interface RunDashboardOptions {\n dbPath: string;\n /** The writable connection ambient sync runs on (see runtime.ts). */\n syncDb: Db;\n /** The launcher's teardown; this registers render and runtime steps on it. */\n shutdown: Shutdown;\n /** `-w`; else the mux session's workstream; else the most recently active one. */\n initialWorkstream?: string;\n /** The fast tick in ms (default 1000; `+`/`-` change it live). */\n pollMs?: number;\n}\n\n/**\n * Run the dashboard until q/Esc/Ctrl-C. Teardown is the launcher's `shutdown`\n * (signals, errors and this return all end in it); this only registers steps.\n */\nexport async function runDashboard(opts: RunDashboardOptions): Promise<void> {\n const runtime = createRuntime({\n dbPath: opts.dbPath,\n syncDb: opts.syncDb,\n caller: spawnerFromEnv(),\n });\n let app: Instance | undefined;\n // Steps run in order: restore the terminal first, then drain and close.\n opts.shutdown.add(() => app?.unmount());\n opts.shutdown.add(() => runtime.close());\n app = render(\n createElement(App, {\n runtime,\n initialWorkstream:\n opts.initialWorkstream ?? (await resolveMuxSessionWorkstreamName()) ?? undefined,\n pollMs: opts.pollMs ?? 1000,\n }),\n { alternateScreen: true, interactive: true },\n );\n await app.waitUntilExit();\n}\n","// The dashboard: a workstream row, five tabs (Overview, Tasks, DAG, Agents, Log), an\n// attention strip (every view, drills too), a framed list that fills the screen, and Next plus a hint/error\n// line pinned to the last row. Overview (the first screen) is a grid of framed cards\n// (overview.tsx). Enter drills into a row, `a` attaches to an agent, `y` copies its command.\n// Plain text only: every line is\n// cleaned and cut/padded by visual width (text.ts), never ANSI inside <Text>; colour is\n// theme roles (theme.ts) passed as ink props.\n\nimport { Box, Text, useApp, useInput, useStdin, useStdout, useWindowSize } from \"ink\";\nimport { useEffect, useRef, useState } from \"react\";\nimport stringWidth from \"string-width\";\nimport type { DashboardSnapshot } from \"../../dashboard-data.js\";\nimport {\n type AttachResult,\n attachKeyHint,\n planAttach,\n runAttach,\n type StepRunner,\n spawnStep,\n} from \"./commands.js\";\nimport { Drill, useYank } from \"./drill.js\";\nimport { FRAME_CHROME, FRAME_SIDES, Frame, Segs } from \"./frame.js\";\nimport { NAV_HINT, navKey } from \"./nav.js\";\nimport { Overview, overviewCards } from \"./overview.js\";\nimport {\n attentionStrip,\n cursorIndex,\n type DrillTarget,\n type Filter,\n moveCursor,\n NO_FILTER,\n nextLine,\n nextSortLabel,\n nextStatusLabel,\n pickWorkstream,\n type Row,\n SORT_ARROWS,\n scopeKey,\n statusesOf,\n TABS,\n type TabId,\n tabRows,\n workstreamLabel,\n} from \"./rows.js\";\nimport type { DashboardQuery, DashboardRuntime } from \"./runtime.js\";\nimport { cell, clean, fitLine, type Line, scrollTop } from \"./text.js\";\nimport { type Seg, style } from \"./theme.js\";\nimport { fasterTick, slowerTick, useSnapshot } from \"./use-snapshot.js\";\n\nexport interface AppProps {\n runtime: DashboardRuntime;\n /** The workstream to start on (the mux session's, or `-w`); else the most recently active. */\n initialWorkstream?: string;\n /** The fast tick in ms (`+`/`-` change it live); null loads once. */\n pollMs: number | null;\n /** The slow tier's gap (agent state, scrollback); default SLOW_TICK_MS. A test seam. */\n slowMs?: number;\n /** The tab to open on (default: Overview). */\n initialTab?: TabId;\n /** Clock seam for elapsed times. */\n now?: () => number;\n /** Runs one attach step with the terminal handed over (a test seam; default spawns). */\n runStep?: StepRunner;\n}\n\n// Every screen line is one row tall (cut by width), so the layout is exactly `rows`\n// lines at any size. A short terminal drops lines in this order of importance: the\n// workstream row and tab row always stay, then ONE data line, then the pinned\n// footer, the attention strip, the filter line and Next last.\nconst FIXED_BY_PRIORITY = [\"footer\", \"strip\", \"filter\", \"next\"] as const;\ntype FixedLine = (typeof FIXED_BY_PRIORITY)[number];\nconst TOP_LINES = 2;\n\n/**\n * Which of `lines` fit in `rows` screen lines, and how many lines remain for the\n * data area (a frame, or bare rows when too short to frame).\n */\nexport function layout(\n rows: number,\n lines: readonly FixedLine[] = FIXED_BY_PRIORITY,\n): { shown: ReadonlySet<FixedLine>; height: number } {\n const spare = Math.max(0, rows - TOP_LINES - 1); // one line kept for data\n const shown = new Set(lines.slice(0, spare));\n return { shown, height: Math.max(0, rows - TOP_LINES - shown.size) };\n}\n\n// `q quit` comes right after the tab keys: a narrow terminal cuts the hint from the right.\nconst HINT_HEAD = `←/→ tab q quit [/] workstream ${NAV_HINT} move`;\nconst HINT_OVERVIEW = `${HINT_HEAD} Enter open y copy +/- rate`;\nconst HINT = `${HINT_HEAD} Enter open / filter c clear y copy +/- rate`;\nconst HINT_TASKS = `${HINT_HEAD} Enter open s sort o status / filter c clear y copy +/- rate`;\nconst hintAgents = (attachKey: string): string =>\n `${HINT_HEAD} Enter scrollback ${attachKey} / filter c clear y copy +/- rate`;\n\n/**\n * The workstream labels as one line of `width` columns in roles (the selected one bold\n * cyan, the others dim: the 3.x tab strip), scrolled so the selected one shows whole.\n */\nfunction workstreamSegs(labels: readonly string[], selected: number, width: number): Seg[] {\n const cell = (i: number): string => (i === selected ? `[${labels[i]}]` : ` ${labels[i]} `);\n let first = 0;\n // The columns from `first` on, with the 1-column \"…\" a scrolled line starts with.\n const total = (from: number): number =>\n (from > 0 ? 1 : 0) +\n labels.slice(from).reduce((n, _, k) => n + stringWidth(clean(cell(from + k))), 0);\n while (first < selected && total(first) > width) first++;\n return [\n ...(first > 0 ? [{ text: \"…\", role: \"muted\" as const }] : []),\n ...labels.flatMap((_, i): Seg[] =>\n i >= first ? [{ text: cell(i), role: i === selected ? \"title\" : \"muted\" }] : [],\n ),\n ];\n}\n\ninterface View {\n filter: Filter;\n /** Key of the row under the cursor; null = the tab's default row. */\n cursor: string | null;\n}\n\n/** An open drill, and what to say above it (an attach that fell back to it). */\ninterface Open {\n target: DrillTarget;\n notice: readonly string[];\n}\ntype ScrollTarget = Extract<DrillTarget, { kind: \"scrollback\" }>;\n\nexport function App({\n runtime,\n initialWorkstream,\n initialTab = \"overview\",\n pollMs,\n slowMs,\n now = Date.now,\n runStep = spawnStep,\n}: AppProps) {\n const { exit, suspendTerminal } = useApp();\n const { stdin } = useStdin();\n const { stdout } = useStdout();\n const yank = useYank();\n const [drill, setDrill] = useState<Open | null>(null);\n // A ref, not state or `isActive`: deactivating useInput would drop Ink's raw-mode count,\n // and Ink could not restore raw mode on resume (a key right after the repaint would\n // arrive line-buffered and be lost). The hooks stay active; the handlers just return.\n const busy = useRef(false);\n const [flash, setFlash] = useState<string | null>(null);\n const [attachKey, setAttachKey] = useState(\"a attach\");\n useEffect(() => {\n void attachKeyHint().then(setAttachKey);\n }, []);\n const { columns, rows: screenRows } = useWindowSize();\n const [tab, setTab] = useState<TabId>(initialTab);\n const [chosen, setChosen] = useState<string | null>(null);\n const [views, setViews] = useState<Record<string, View>>({});\n const [editing, setEditing] = useState<{ before: string } | null>(null);\n const tops = useRef<Record<string, number>>({});\n // The cursor's last index per scope: a row that leaves the list hands the cursor to its neighbour.\n const lastSel = useRef<Record<string, number>>({});\n const [tick, setTick] = useState(pollMs);\n\n const viewOf = (t: TabId, w: string | null): View =>\n views[scopeKey(t, w)] ?? { filter: NO_FILTER, cursor: null };\n // The workstream shown: the chosen one while it is live, else the pick (the hint, or\n // the most recent). The query needs it BEFORE this render's snapshot exists, so it\n // resolves against the workstreams the previous snapshot named; until there is one,\n // the hint, so the first read already scopes to it (never every workstream's tasks).\n const known = useRef<DashboardSnapshot[\"workstreams\"] | null>(null);\n const pickShown = (list: DashboardSnapshot[\"workstreams\"] | null): string | null =>\n list === null\n ? (chosen ?? initialWorkstream ?? null)\n : chosen !== null && list.some((w) => w.name === chosen)\n ? chosen\n : pickWorkstream(list, initialWorkstream);\n const queryWs = pickShown(known.current);\n // The query is the shown workstream's: its tasks and DAG (every other tab's rows and\n // the Overview cards are cut from them client-side), its Log tail (a quiet workstream\n // must not vanish behind a busy one's 100 ops). CLOSED tasks ride along only while the\n // Tasks tab asks for them; its status and text filters are applied client-side, so\n // the Overview and the attention drills never see a filtered snapshot.\n const wantsClosed =\n tab === \"tasks\" && statusesOf(viewOf(\"tasks\", queryWs).filter.status).includes(\"CLOSED\");\n const query: DashboardQuery = {\n scopeWorkstream: queryWs,\n ...(wantsClosed ? { status: [...statusesOf(\"all\")] } : {}),\n ...(queryWs !== null ? { logWorkstream: queryWs } : {}),\n };\n const state = useSnapshot(runtime, query, tick, slowMs);\n const snap: DashboardSnapshot | null = state.snapshot;\n const names = snap?.workstreams ?? [];\n known.current = snap?.workstreams ?? known.current;\n const ws = snap ? pickShown(names) : queryWs;\n // Lock the pick, the fallback after a teardown included: later polls must not move you\n // to whatever is newest, and the state must name what the row shows.\n useEffect(() => {\n if (ws !== null && ws !== chosen) setChosen(ws);\n }, [ws, chosen]);\n\n const view = viewOf(tab, ws);\n const all: Row[] = snap ? tabRows(tab, snap, ws, view.filter, now()) : [];\n const overview = tab === \"overview\";\n const { shown, height: area } = layout(\n screenRows,\n // The Overview has no filter; the strip shows on every view, next to the Attention card.\n FIXED_BY_PRIORITY.filter((l) => !(overview && l === \"filter\")),\n );\n // The data area is framed when it has room for a border and a row; else bare rows.\n const framed = !overview && area > FRAME_CHROME && columns > FRAME_SIDES + 2;\n const height = framed ? area - FRAME_CHROME : area;\n const scope = scopeKey(tab, ws);\n const sel = cursorIndex(all, view.cursor, tab, lastSel.current[scope]);\n lastSel.current[scope] = sel;\n const top = scrollTop(tops.current[scope] ?? 0, sel, all.length, height);\n tops.current[scope] = top;\n\n const patch = (change: Partial<View>, t: TabId = tab): void =>\n setViews((v) => {\n const k = scopeKey(t, ws);\n return { ...v, [k]: { filter: NO_FILTER, cursor: null, ...v[k], ...change } };\n });\n const setFilter = (change: Partial<Filter>): void =>\n patch({ filter: { ...view.filter, ...change }, cursor: null });\n const move = (delta: number): void =>\n patch({ cursor: moveCursor(all, view.cursor, tab, delta, lastSel.current[scope]) });\n // Pin the default row: with no cursor yet (first view, or a filter just reset it) the\n // cursor is index 0 of whatever is listed NOW, and a later poll that reorders by\n // activity must not carry it to another task. Log keeps null: its default is the\n // newest row, so it follows the tail until you move. A stale snapshot (a status\n // filter just changed) is not pinned: its rows are about to be replaced.\n useEffect(() => {\n const key = all[sel]?.key;\n if (view.cursor === null && tab !== \"log\" && !state.stale && key !== undefined)\n setViews((v) => {\n const k = scopeKey(tab, ws);\n // Only if nothing (a key press) set a cursor since this render.\n if (v[k]?.cursor != null) return v;\n return { ...v, [k]: { filter: NO_FILTER, ...v[k], cursor: key } };\n });\n });\n const cycle = (list: readonly string[], cur: string | null, d: number): string | null =>\n list.length === 0\n ? null\n : (list[(Math.max(0, list.indexOf(cur ?? \"\")) + d + list.length) % list.length] ?? null);\n\n // Attach runs ONLY from an explicit `a`. The backend's ordered steps get the real\n // terminal (Ink suspends: alternate screen and raw mode off, restored after). If no\n // client can open (no server, no workspace, a required step fails) the user lands on\n // that agent's scrollback with the reason and the line for a shell outside.\n const attach = async (t: ScrollTarget): Promise<void> => {\n if (busy.current) return;\n busy.current = true;\n setFlash(null);\n let outcome: AttachResult;\n const plan = await planAttach(t);\n if (!plan.ok) outcome = { ok: false, reason: plan.reason, warnings: [] };\n else {\n outcome = { ok: false, reason: \"terminal unavailable\", warnings: [] };\n try {\n await suspendTerminal(async () => {\n // The suspended terminal keeps this line: where the user went, and how to get back.\n stdout.write(`${plan.notice}\\n`);\n outcome = await runAttach(plan.steps, runStep);\n // Still suspended: Ink has not resumed input, so nothing reads stdin yet.\n // Drop what is buffered (typeahead must not replay into the next screen);\n // Ink then restores raw mode for the hooks that own it, before it repaints.\n await new Promise<void>((r) => setImmediate(r));\n while (stdin.read() !== null) {}\n busy.current = false;\n });\n } catch (e) {\n outcome = { ok: false, reason: e instanceof Error ? e.message : String(e), warnings: [] };\n }\n }\n busy.current = false;\n if (!outcome.ok)\n setDrill({\n target: t,\n notice: [\n `could not attach: ${outcome.reason}`,\n ...(plan.line === null ? [] : [`from a shell outside the mux: ${plan.line}`]),\n ],\n });\n else if (outcome.warnings.length > 0) setFlash(`attach: ${outcome.warnings.join(\"; \")}`);\n };\n\n useInput(\n (input, key) => {\n if (busy.current) return;\n setFlash(null);\n if (editing !== null) {\n if (key.return) setEditing(null);\n else if (key.escape) {\n setFilter({ text: editing.before });\n setEditing(null);\n } else if (key.backspace || key.delete) setFilter({ text: view.filter.text.slice(0, -1) });\n else if (input !== \"\" && !key.ctrl && !key.meta)\n setFilter({ text: view.filter.text + clean(input) });\n return;\n }\n if (input === \"q\" || key.escape) return exit();\n // The Overview's cursor is the Attention card's; its page is the screen's data area.\n const nav = navKey(input, key, height);\n const ids = TABS.map((t) => t.id);\n if (key.tab || key.rightArrow || key.leftArrow) {\n const back = key.leftArrow || (key.tab && key.shift);\n setTab((cycle(ids, tab, back ? -1 : 1) ?? tab) as TabId);\n state.refresh(); // 3.x: a tab switch fetches eagerly, agent states included\n } else if (input === \"[\" || input === \"]\") {\n const next = cycle(\n names.map((w) => w.name),\n ws,\n input === \"]\" ? 1 : -1,\n );\n if (next !== null) setChosen(next);\n } else if (nav !== null)\n move(\"by\" in nav ? nav.by : nav.to === \"top\" ? -all.length : all.length);\n else if (input === \"s\" && tab === \"tasks\")\n setFilter({ sort: nextSortLabel(view.filter.sort) });\n else if (input === \"o\" && tab === \"tasks\")\n setFilter({ status: nextStatusLabel(view.filter.status) });\n else if (input === \"/\" && !overview) setEditing({ before: view.filter.text });\n else if (input === \"c\" && !overview)\n setFilter({\n text: \"\",\n ...(tab === \"tasks\" ? { status: \"active\" as const, sort: \"activity\" as const } : {}),\n });\n else if (input === \"r\") state.refresh();\n else if ((input === \"+\" || input === \"=\" || input === \"-\") && tick !== null) {\n const next = input === \"-\" ? slowerTick(tick) : fasterTick(tick);\n setTick(next);\n setFlash(`refresh every ${next >= 1000 ? `${next / 1000}s` : `${next}ms`}`);\n } else if (key.return) {\n const target = all[sel]?.drill;\n if (target !== undefined) setDrill({ target, notice: [] });\n } else if (input === \"a\" && tab === \"agents\") {\n const target = all[sel]?.drill;\n if (target?.kind === \"scrollback\") void attach(target);\n } else if (input === \"y\") {\n const target = all[sel]?.drill;\n if (target !== undefined) void yank(target).then(setFlash);\n }\n },\n // A drill owns the keys while it is open: App reads none.\n { isActive: drill === null },\n );\n\n const text = (s: string) => cell(s, columns);\n const attention = snap?.attention ?? [];\n const lineOf = (r: Row, i: number): Line => [{ text: i === sel ? \"> \" : \" \" }, ...r.line];\n const visible = all.slice(top, top + height);\n const f = view.filter;\n const filterLine = [\n tab === \"tasks\" ? `status: ${f.status}` : \"\",\n tab === \"tasks\" ? `sort: ${f.sort} ${SORT_ARROWS[f.sort]}` : \"\",\n `filter: ${f.text}${editing ? \"_\" : \"\"}`,\n snap ? `${all.length} row${all.length === 1 ? \"\" : \"s\"}` : \"\",\n state.stale || (state.loading && !snap) ? \"loading…\" : \"\",\n ]\n .filter((p) => p !== \"\")\n .join(\" \");\n const tabIndex = TABS.findIndex((t) => t.id === tab);\n const tabsFit = TABS.reduce((n, t) => n + t.label.length + 2, 0) <= columns;\n const wsLabels = names.map(workstreamLabel);\n const wsIndex = Math.max(\n 0,\n names.findIndex((w) => w.name === ws),\n );\n const strip = attentionStrip(attention, ws);\n const empty =\n snap === null\n ? state.error\n ? \"\"\n : \"loading…\"\n : all.length === 0\n ? f.text !== \"\"\n ? \"no rows match the filter\"\n : \"nothing here\"\n : \"\";\n const footer = flash\n ? { text: flash, role: \"text\" as const }\n : state.error\n ? { text: `error: ${state.error}`, role: \"bad\" as const }\n : {\n text: editing\n ? \"type to filter Enter keep Esc cancel\"\n : overview\n ? HINT_OVERVIEW\n : tab === \"agents\"\n ? hintAgents(attachKey)\n : tab === \"tasks\"\n ? HINT_TASKS\n : HINT,\n role: \"muted\" as const,\n };\n\n if (drill !== null)\n return (\n <Drill\n target={drill.target}\n notice={drill.notice}\n strip={strip}\n runtime={runtime}\n busy={busy}\n nonce={state.nonce}\n slowNonce={state.slowNonce}\n onClose={() => setDrill(null)}\n onAttach={(t) => void attach(t)}\n />\n );\n\n const bodyLines: Line[] = [\n ...visible.map((r, i) => lineOf(r, top + i)),\n ...(empty ? [[{ text: ` ${empty}`, role: \"muted\" as const }]] : []),\n ];\n const tabLabel = TABS[tabIndex]?.label ?? \"\";\n\n return (\n <Box flexDirection=\"column\" height={screenRows}>\n <Text wrap=\"truncate\">\n <Segs\n line={fitLine(\n wsLabels.length > 0\n ? workstreamSegs(wsLabels, wsIndex, columns)\n : [{ text: \"no workstreams\", role: \"muted\" }],\n columns,\n )}\n />\n </Text>\n {tabsFit ? (\n <Box>\n {TABS.map((t) => (\n <Text key={t.id} inverse={t.id === tab} {...style(t.id === tab ? \"title\" : \"muted\")}>\n {` ${t.label} `}\n </Text>\n ))}\n </Box>\n ) : (\n // Too narrow for the labels (they would wrap onto a second row): show the\n // active one and its place.\n <Text wrap=\"truncate\" inverse {...style(\"title\")}>\n {cell(` ${tabLabel} ${tabIndex + 1}/${TABS.length}`, columns)}\n </Text>\n )}\n {shown.has(\"strip\") ? (\n <Text wrap=\"truncate\">\n <Segs line={fitLine(strip, columns)} />\n </Text>\n ) : null}\n {shown.has(\"filter\") ? (\n <Text wrap=\"truncate\" {...style(\"muted\")}>\n {text(filterLine)}\n </Text>\n ) : null}\n {overview ? (\n <Overview\n cards={snap ? overviewCards(snap, ws, now()) : []}\n sel={sel}\n width={columns}\n height={area}\n />\n ) : framed ? (\n <Frame\n width={columns}\n height={area}\n title={tabLabel}\n subtitle={snap ? String(all.length) : \"\"}\n bottom={all.length > height ? `${sel + 1}/${all.length}` : \"\"}\n body={bodyLines}\n selected={sel - top}\n />\n ) : (\n bodyLines.map((l, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: positional rows of a fixed-height viewport\n <Text key={i} wrap=\"truncate\">\n {i === sel - top ? (\n <Text inverse>{text(l.map((s) => s.text).join(\"\"))}</Text>\n ) : (\n <Segs line={fitLine(l, columns)} />\n )}\n </Text>\n ))\n )}\n <Box flexGrow={1} />\n {shown.has(\"next\") ? (\n <Text wrap=\"truncate\" {...style(\"muted\")}>\n {text(snap ? nextLine(snap) : \"next: unavailable\")}\n </Text>\n ) : null}\n {shown.has(\"footer\") ? (\n <Text wrap=\"truncate\" {...style(footer.role)}>\n {text(footer.text)}\n </Text>\n ) : null}\n </Box>\n );\n}\n","export default function ansiRegex({onlyFirst = false} = {}) {\n\t// Valid string terminator sequences are BEL, ESC\\, and 0x9c\n\tconst ST = '(?:\\\\u0007|\\\\u001B\\\\u005C|\\\\u009C)';\n\n\t// OSC sequences only: ESC ] ... ST\n\t// The payload stops at the first terminator character rather than scanning ahead for one, so an unterminated `ESC ]` cannot rescan the rest of the input. Terminals likewise abort a control string on an unexpected ESC.\n\tconst osc = `(?:\\\\u001B\\\\][^\\\\u0007\\\\u001B\\\\u009C]*${ST})`;\n\n\t// CSI and related: ESC/C1, optional intermediates, optional params (supports ; and :) then final byte\n\tconst csi = '[\\\\u001B\\\\u009B][[\\\\]()#;?]*(?:\\\\d{1,4}(?:[;:]\\\\d{0,4})*)?[\\\\dA-PR-TZcf-nq-uy=><~]';\n\n\tconst pattern = `${osc}|${csi}`;\n\n\treturn new RegExp(pattern, onlyFirst ? undefined : 'g');\n}\n","import ansiRegex from 'ansi-regex';\n\nconst regex = ansiRegex();\n\nexport default function stripAnsi(string) {\n\tif (typeof string !== 'string') {\n\t\tthrow new TypeError(`Expected a \\`string\\`, got \\`${typeof string}\\``);\n\t}\n\n\t// Fast path: ANSI codes require ESC (7-bit) or CSI (8-bit) introducer\n\tif (!string.includes('\\u001B') && !string.includes('\\u009B')) {\n\t\treturn string;\n\t}\n\n\t// Even though the regex is global, we don't need to reset the `.lastIndex`\n\t// because unlike `.exec()` and `.test()`, `.replace()` does it automatically\n\t// and doing it manually has a performance penalty.\n\treturn string.replace(regex, '');\n}\n","// Generated by scripts/build.js\n\nexport const ambiguousMinimalCodePoint = 161;\nexport const ambiguousMaximumCodePoint = 1114109;\nexport const ambiguousRanges = [161, 161, 164, 164, 167, 168, 170, 170, 173, 174, 176, 180, 182, 186, 188, 191, 198, 198, 208, 208, 215, 216, 222, 225, 230, 230, 232, 234, 236, 237, 240, 240, 242, 243, 247, 250, 252, 252, 254, 254, 257, 257, 273, 273, 275, 275, 283, 283, 294, 295, 299, 299, 305, 307, 312, 312, 319, 322, 324, 324, 328, 331, 333, 333, 338, 339, 358, 359, 363, 363, 462, 462, 464, 464, 466, 466, 468, 468, 470, 470, 472, 472, 474, 474, 476, 476, 593, 593, 609, 609, 708, 708, 711, 711, 713, 715, 717, 717, 720, 720, 728, 731, 733, 733, 735, 735, 768, 879, 913, 929, 931, 937, 945, 961, 963, 969, 1025, 1025, 1040, 1103, 1105, 1105, 8208, 8208, 8211, 8214, 8216, 8217, 8220, 8221, 8224, 8226, 8228, 8231, 8240, 8240, 8242, 8243, 8245, 8245, 8251, 8251, 8254, 8254, 8308, 8308, 8319, 8319, 8321, 8324, 8364, 8364, 8451, 8451, 8453, 8453, 8457, 8457, 8467, 8467, 8470, 8470, 8481, 8482, 8486, 8486, 8491, 8491, 8531, 8532, 8539, 8542, 8544, 8555, 8560, 8569, 8585, 8585, 8592, 8601, 8632, 8633, 8658, 8658, 8660, 8660, 8679, 8679, 8704, 8704, 8706, 8707, 8711, 8712, 8715, 8715, 8719, 8719, 8721, 8721, 8725, 8725, 8730, 8730, 8733, 8736, 8739, 8739, 8741, 8741, 8743, 8748, 8750, 8750, 8756, 8759, 8764, 8765, 8776, 8776, 8780, 8780, 8786, 8786, 8800, 8801, 8804, 8807, 8810, 8811, 8814, 8815, 8834, 8835, 8838, 8839, 8853, 8853, 8857, 8857, 8869, 8869, 8895, 8895, 8978, 8978, 9312, 9449, 9451, 9547, 9552, 9587, 9600, 9615, 9618, 9621, 9632, 9633, 9635, 9641, 9650, 9651, 9654, 9655, 9660, 9661, 9664, 9665, 9670, 9672, 9675, 9675, 9678, 9681, 9698, 9701, 9711, 9711, 9733, 9734, 9737, 9737, 9742, 9743, 9756, 9756, 9758, 9758, 9792, 9792, 9794, 9794, 9824, 9825, 9827, 9829, 9831, 9834, 9836, 9837, 9839, 9839, 9886, 9887, 9919, 9919, 9926, 9933, 9935, 9939, 9941, 9953, 9955, 9955, 9960, 9961, 9963, 9969, 9972, 9972, 9974, 9977, 9979, 9980, 9982, 9983, 10045, 10045, 10102, 10111, 11094, 11097, 12872, 12879, 57344, 63743, 65024, 65039, 65533, 65533, 127232, 127242, 127248, 127277, 127280, 127337, 127344, 127373, 127375, 127376, 127387, 127404, 917760, 917999, 983040, 1048573, 1048576, 1114109];\n\nexport const fullwidthMinimalCodePoint = 12288;\nexport const fullwidthMaximumCodePoint = 65510;\nexport const fullwidthRanges = [12288, 12288, 65281, 65376, 65504, 65510];\n\nexport const halfwidthMinimalCodePoint = 8361;\nexport const halfwidthMaximumCodePoint = 65518;\nexport const halfwidthRanges = [8361, 8361, 65377, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65512, 65518];\n\nexport const narrowMinimalCodePoint = 32;\nexport const narrowMaximumCodePoint = 10630;\nexport const narrowRanges = [32, 126, 162, 163, 165, 166, 172, 172, 175, 175, 10214, 10221, 10629, 10630];\n\nexport const wideMinimalCodePoint = 4352;\nexport const wideMaximumCodePoint = 262141;\nexport const wideRanges = [4352, 4447, 8986, 8987, 9001, 9002, 9193, 9196, 9200, 9200, 9203, 9203, 9725, 9726, 9748, 9749, 9776, 9783, 9800, 9811, 9855, 9855, 9866, 9871, 9875, 9875, 9889, 9889, 9898, 9899, 9917, 9918, 9924, 9925, 9934, 9934, 9940, 9940, 9962, 9962, 9970, 9971, 9973, 9973, 9978, 9978, 9981, 9981, 9989, 9989, 9994, 9995, 10024, 10024, 10060, 10060, 10062, 10062, 10067, 10069, 10071, 10071, 10133, 10135, 10160, 10160, 10175, 10175, 11035, 11036, 11088, 11088, 11093, 11093, 11904, 11929, 11931, 12019, 12032, 12245, 12272, 12287, 12289, 12350, 12353, 12438, 12441, 12543, 12549, 12591, 12593, 12686, 12688, 12773, 12783, 12830, 12832, 12871, 12880, 42124, 42128, 42182, 43360, 43388, 44032, 55203, 63744, 64255, 65040, 65049, 65072, 65106, 65108, 65126, 65128, 65131, 94176, 94180, 94192, 94198, 94208, 101594, 101631, 101664, 101760, 101874, 101888, 102801, 102816, 102866, 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110888, 110898, 110898, 110928, 110930, 110933, 110933, 110948, 110952, 110960, 111355, 119552, 119638, 119648, 119670, 126980, 126980, 127183, 127183, 127374, 127374, 127377, 127386, 127406, 127406, 127488, 127490, 127504, 127547, 127552, 127560, 127568, 127569, 127584, 127589, 127744, 127776, 127789, 127797, 127799, 127868, 127870, 127891, 127904, 127946, 127951, 127955, 127968, 127984, 127988, 127988, 127992, 128062, 128064, 128064, 128066, 128252, 128255, 128317, 128331, 128334, 128336, 128359, 128378, 128378, 128405, 128406, 128420, 128420, 128507, 128591, 128640, 128709, 128716, 128716, 128720, 128722, 128725, 128729, 128732, 128735, 128747, 128748, 128756, 128764, 128986, 128986, 128992, 129003, 129008, 129008, 129292, 129338, 129340, 129349, 129351, 129535, 129648, 129660, 129664, 129734, 129736, 129736, 129740, 129757, 129759, 129771, 129775, 129786, 131072, 196605, 196608, 262141];\n","/**\nBinary search on a sorted flat array of [start, end] pairs.\n\n@param {number[]} ranges - Flat array of inclusive [start, end] range pairs, e.g. [0, 5, 10, 20].\n@param {number} codePoint - The value to search for.\n@returns {boolean} Whether the value falls within any of the ranges.\n*/\nexport const isInRange = (ranges, codePoint) => {\n\tlet low = 0;\n\tlet high = Math.floor(ranges.length / 2) - 1;\n\twhile (low <= high) {\n\t\tconst mid = Math.floor((low + high) / 2);\n\t\tconst i = mid * 2;\n\t\tif (codePoint < ranges[i]) {\n\t\t\thigh = mid - 1;\n\t\t} else if (codePoint > ranges[i + 1]) {\n\t\t\tlow = mid + 1;\n\t\t} else {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n};\n","import {\n\tambiguousMinimalCodePoint,\n\tambiguousMaximumCodePoint,\n\tambiguousRanges,\n\n\tfullwidthMinimalCodePoint,\n\tfullwidthMaximumCodePoint,\n\tfullwidthRanges,\n\n\thalfwidthMinimalCodePoint,\n\thalfwidthMaximumCodePoint,\n\thalfwidthRanges,\n\n\tnarrowMinimalCodePoint,\n\tnarrowMaximumCodePoint,\n\tnarrowRanges,\n\n\twideMinimalCodePoint,\n\twideMaximumCodePoint,\n\twideRanges,\n} from './lookup-data.js';\nimport {isInRange} from './utilities.js';\n\nconst commonCjkCodePoint = 0x4E_00;\nconst [wideFastPathStart, wideFastPathEnd] = /* #__PURE__ */ findWideFastPathRange(wideRanges);\n\n// Use a hot-path range so common `isWide` calls can skip binary search.\n// The range containing U+4E00 covers common CJK ideographs;\n// fallback to the largest range for resilience to Unicode table changes.\nfunction findWideFastPathRange(ranges) {\n\tlet fastPathStart = ranges[0];\n\tlet fastPathEnd = ranges[1];\n\n\tfor (let index = 0; index < ranges.length; index += 2) {\n\t\tconst start = ranges[index];\n\t\tconst end = ranges[index + 1];\n\n\t\tif (\n\t\t\tcommonCjkCodePoint >= start\n\t\t\t&& commonCjkCodePoint <= end\n\t\t) {\n\t\t\treturn [start, end];\n\t\t}\n\n\t\tif ((end - start) > (fastPathEnd - fastPathStart)) {\n\t\t\tfastPathStart = start;\n\t\t\tfastPathEnd = end;\n\t\t}\n\t}\n\n\treturn [fastPathStart, fastPathEnd];\n}\n\nexport const isAmbiguous = codePoint => {\n\tif (\n\t\tcodePoint < ambiguousMinimalCodePoint\n\t\t|| codePoint > ambiguousMaximumCodePoint\n\t) {\n\t\treturn false;\n\t}\n\n\treturn isInRange(ambiguousRanges, codePoint);\n};\n\nexport const isFullwidth = codePoint => {\n\tif (\n\t\tcodePoint < fullwidthMinimalCodePoint\n\t\t|| codePoint > fullwidthMaximumCodePoint\n\t) {\n\t\treturn false;\n\t}\n\n\treturn isInRange(fullwidthRanges, codePoint);\n};\n\nconst isHalfwidth = codePoint => {\n\tif (\n\t\tcodePoint < halfwidthMinimalCodePoint\n\t\t|| codePoint > halfwidthMaximumCodePoint\n\t) {\n\t\treturn false;\n\t}\n\n\treturn isInRange(halfwidthRanges, codePoint);\n};\n\nconst isNarrow = codePoint => {\n\tif (\n\t\tcodePoint < narrowMinimalCodePoint\n\t\t|| codePoint > narrowMaximumCodePoint\n\t) {\n\t\treturn false;\n\t}\n\n\treturn isInRange(narrowRanges, codePoint);\n};\n\nexport const isWide = codePoint => {\n\tif (\n\t\tcodePoint >= wideFastPathStart\n\t\t&& codePoint <= wideFastPathEnd\n\t) {\n\t\treturn true;\n\t}\n\n\tif (\n\t\tcodePoint < wideMinimalCodePoint\n\t\t|| codePoint > wideMaximumCodePoint\n\t) {\n\t\treturn false;\n\t}\n\n\treturn isInRange(wideRanges, codePoint);\n};\n\nexport function getCategory(codePoint) {\n\tif (isAmbiguous(codePoint)) {\n\t\treturn 'ambiguous';\n\t}\n\n\tif (isFullwidth(codePoint)) {\n\t\treturn 'fullwidth';\n\t}\n\n\tif (isHalfwidth(codePoint)) {\n\t\treturn 'halfwidth';\n\t}\n\n\tif (isNarrow(codePoint)) {\n\t\treturn 'narrow';\n\t}\n\n\tif (isWide(codePoint)) {\n\t\treturn 'wide';\n\t}\n\n\treturn 'neutral';\n}\n","import {getCategory, isAmbiguous, isFullwidth, isWide} from './lookup.js';\n\nfunction validate(codePoint) {\n\tif (!Number.isSafeInteger(codePoint)) {\n\t\tthrow new TypeError(`Expected a code point, got \\`${typeof codePoint}\\`.`);\n\t}\n}\n\nexport function eastAsianWidthType(codePoint) {\n\tvalidate(codePoint);\n\n\treturn getCategory(codePoint);\n}\n\nexport function eastAsianWidth(codePoint, {ambiguousAsWide = false} = {}) {\n\tvalidate(codePoint);\n\n\tif (\n\t\tisFullwidth(codePoint)\n\t\t|| isWide(codePoint)\n\t\t|| (ambiguousAsWide && isAmbiguous(codePoint))\n\t) {\n\t\treturn 2;\n\t}\n\n\treturn 1;\n}\n\n// Private exports for https://github.com/sindresorhus/is-fullwidth-code-point\nexport {\n\tisFullwidth as _isFullwidth,\n\t// TODO: Remove this in the next major version.\n\tisFullwidth as _isFullWidth,\n\tisWide as _isWide,\n} from './lookup.js';\n","import stripAnsi from 'strip-ansi';\nimport {eastAsianWidth} from 'get-east-asian-width';\n\n/**\nLogic:\n- Segment graphemes to match how terminals render clusters.\n- Width rules:\n\t1. Skip non-printing clusters (Default_Ignorable, Control, pure nonspacing/enclosing Mark, lone Surrogates). Tabs are ignored by design.\n\t2. RGI emoji clusters (\\p{RGI_Emoji}) are double-width.\n\t3. Minimally-qualified/unqualified emoji clusters (ZWJ sequences with 2+ Extended_Pictographic, or keycap sequences) are double-width.\n\t4. Hangul jamo collapse each standard modern Hangul L+V or L+V+T syllable piece to width 2.\n\t Unmatched repeated leading/vowel/trailing jamo stay additive because that matches how the terminals we target render them.\n\t5. Otherwise use East Asian Width of the cluster's first visible code point, and add widths for trailing spacing marks and Halfwidth/Fullwidth Forms within the same cluster (e.g., dakuten/handakuten/prolonged sound mark).\n*/\n\nconst segmenter = new Intl.Segmenter();\n\n// Matches a visible (printing) character. Used to find the base scalar of a cluster (skipping leading Prepend/Format/Marks) and to detect whole-cluster zero-width.\n// Intentionally a single negated class without a quantifier: a repeated pattern like `^(?:…|…)+$` backtracks exponentially on overlapping properties, and even `^[…]+$` overflows V8's backtrack stack (RangeError) on clusters with millions of marks.\nconst visibleCharacterRegex = /[^\\p{Default_Ignorable_Code_Point}\\p{Control}\\p{Format}\\p{Nonspacing_Mark}\\p{Enclosing_Mark}\\p{Surrogate}]/v;\nconst spacingMarkRegex = /\\p{Spacing_Mark}/v;\n\n// RGI emoji sequences\nconst rgiEmojiRegex = /^\\p{RGI_Emoji}$/v;\n\n// Detect minimally-qualified/unqualified emoji sequences (missing VS16 but still render as double-width)\nconst unqualifiedKeycapRegex = /^[\\d#*]\\u20E3$/;\nconst extendedPictographicRegex = /\\p{Extended_Pictographic}/gu;\n\nfunction isDoubleWidthNonRgiEmojiSequence(segment) {\n\t// Real emoji clusters are < 30 chars; guard against pathological input\n\tif (segment.length > 50) {\n\t\treturn false;\n\t}\n\n\tif (unqualifiedKeycapRegex.test(segment)) {\n\t\treturn true;\n\t}\n\n\t// ZWJ sequences with 2+ Extended_Pictographic\n\tif (segment.includes('\\u200D')) {\n\t\tconst pictographics = segment.match(extendedPictographicRegex);\n\t\treturn pictographics !== null && pictographics.length >= 2;\n\t}\n\n\treturn false;\n}\n\n// Returns the cluster starting at its first visible character, or `undefined` if the whole cluster is zero-width.\nfunction baseVisible(segment) {\n\tconst index = segment.search(visibleCharacterRegex);\n\treturn index === -1 ? undefined : segment.slice(index);\n}\n\nfunction isHangulLeadingJamo(codePoint) {\n\treturn (codePoint >= 0x11_00 && codePoint <= 0x11_5F)\n\t\t|| (codePoint >= 0xA9_60 && codePoint <= 0xA9_7C);\n}\n\nfunction isHangulVowelJamo(codePoint) {\n\treturn (codePoint >= 0x11_60 && codePoint <= 0x11_A7)\n\t\t|| (codePoint >= 0xD7_B0 && codePoint <= 0xD7_C6);\n}\n\nfunction isHangulTrailingJamo(codePoint) {\n\treturn (codePoint >= 0x11_A8 && codePoint <= 0x11_FF)\n\t\t|| (codePoint >= 0xD7_CB && codePoint <= 0xD7_FB);\n}\n\nfunction isHangulJamo(codePoint) {\n\treturn isHangulLeadingJamo(codePoint)\n\t\t|| isHangulVowelJamo(codePoint)\n\t\t|| isHangulTrailingJamo(codePoint);\n}\n\nfunction hangulClusterWidth(visibleSegment, eastAsianWidthOptions) {\n\tconst codePoints = [];\n\n\tfor (const character of visibleSegment) {\n\t\tif (!visibleCharacterRegex.test(character)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tcodePoints.push(character.codePointAt(0));\n\t}\n\n\tif (codePoints.length === 0) {\n\t\treturn undefined;\n\t}\n\n\tlet width = 0;\n\n\tfor (let index = 0; index < codePoints.length; index++) {\n\t\tconst codePoint = codePoints[index];\n\t\tif (!isHangulJamo(codePoint)) {\n\t\t\tif (width === 0) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\t// Mixed cluster (e.g., L + precomposed syllable): use EAW for non-jamo remainder\n\t\t\tfor (let remaining = index; remaining < codePoints.length; remaining++) {\n\t\t\t\twidth += eastAsianWidth(codePoints[remaining], eastAsianWidthOptions);\n\t\t\t}\n\n\t\t\treturn width;\n\t\t}\n\n\t\t// Modern Hangul L+V(+T) shapes as one syllable block. Unmatched jamo stay additive:\n\t\t// U+1100 U+1100 U+1161 => U+1100 + (U+1100 U+1161) => 2 + 2.\n\t\tif (\n\t\t\tisHangulLeadingJamo(codePoint)\n\t\t\t&& isHangulVowelJamo(codePoints[index + 1])\n\t\t) {\n\t\t\twidth += 2;\n\t\t\tindex += isHangulTrailingJamo(codePoints[index + 2]) ? 2 : 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\twidth += eastAsianWidth(codePoint, eastAsianWidthOptions);\n\t}\n\n\treturn width;\n}\n\nfunction trailingWidth(visibleSegment, eastAsianWidthOptions) {\n\tlet extra = 0;\n\tlet first = true;\n\n\tfor (const character of visibleSegment) {\n\t\tif (first) {\n\t\t\tfirst = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (\n\t\t\tspacingMarkRegex.test(character)\n\t\t\t|| (character >= '\\uFF00' && character <= '\\uFFEF')\n\t\t) {\n\t\t\textra += eastAsianWidth(character.codePointAt(0), eastAsianWidthOptions);\n\t\t}\n\t}\n\n\treturn extra;\n}\n\nexport default function stringWidth(input, options = {}) {\n\tif (typeof input !== 'string' || input.length === 0) {\n\t\treturn 0;\n\t}\n\n\tconst {\n\t\tambiguousIsNarrow = true,\n\t\tcountAnsiEscapeCodes = false,\n\t} = options;\n\n\tlet string = input;\n\n\t// Avoid calling stripAnsi when there are no ANSI escape sequences (ESC = 0x1B, CSI = 0x9B)\n\tif (!countAnsiEscapeCodes && (string.includes('\\u001B') || string.includes('\\u009B'))) {\n\t\tstring = stripAnsi(string);\n\t}\n\n\tif (string.length === 0) {\n\t\treturn 0;\n\t}\n\n\t// Fast path: printable ASCII (0x20–0x7E) needs no segmenter, regex, or EAW lookup — width equals length.\n\tif (/^[\\u0020-\\u007E]*$/.test(string)) {\n\t\treturn string.length;\n\t}\n\n\tlet width = 0;\n\tconst eastAsianWidthOptions = {ambiguousAsWide: !ambiguousIsNarrow};\n\n\tfor (const {segment} of segmenter.segment(string)) {\n\t\t// Zero-width / non-printing clusters\n\t\tconst visibleSegment = baseVisible(segment);\n\t\tif (visibleSegment === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Emoji width logic\n\t\tif (rgiEmojiRegex.test(segment) || isDoubleWidthNonRgiEmojiSequence(segment)) {\n\t\t\twidth += 2;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst hangulWidth = hangulClusterWidth(visibleSegment, eastAsianWidthOptions);\n\t\tif (hangulWidth !== undefined) {\n\t\t\twidth += hangulWidth;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Everything else: EAW of the cluster’s first visible scalar\n\t\tconst codePoint = visibleSegment.codePointAt(0);\n\t\twidth += eastAsianWidth(codePoint, eastAsianWidthOptions);\n\n\t\t// Add width for trailing spacing marks and Halfwidth/Fullwidth Forms (e.g., ゙, ゚, ー)\n\t\twidth += trailingWidth(visibleSegment, eastAsianWidthOptions);\n\t}\n\n\treturn width;\n}\n","// What the dashboard may RUN or COPY, and nothing else. Pure of React.\n//\n// - attach: `mux.attachCommands` gives ordered argv steps, not a launcher. They run\n// only on an explicit `a` (never on Enter, never on a poll), in order, with the\n// socket/session routing the backend put in the argv. A required step that fails\n// stops the rest; an optional one is reported and skipped. Any failure is a\n// REASON the caller shows next to the scrollback it falls back to.\n// - yank: the exact command, as an OSC 52 clipboard sequence (no clipboard\n// dependency). The command is also printed on screen, so a terminal that ignores\n// OSC 52 loses nothing. Control characters are refused: a pasted newline runs.\n\nimport { spawn } from \"node:child_process\";\nimport { activeMux, attachShellLine, type MuxCommand, tmuxAttachMode } from \"../../mux.js\";\nimport { shellWord } from \"../../shell-quote.js\";\nimport type { DrillTarget } from \"./rows.js\";\n\n/** Which agent to attach to: its workstream, name and tab (window), as `mu agent spawn` reports them. */\nexport interface AttachSubject {\n workstream: string;\n name: string;\n tab: string | null;\n}\n\nexport type AttachPlan =\n | {\n ok: true;\n /** Run these, in order (inside a client of the mux: the switch, else the blocking attach). */\n steps: readonly MuxCommand[];\n /** The line for a shell OUTSIDE any client; what `y` copies. */\n line: string;\n /** One line for the terminal before it is handed over: where to, and how to get back. */\n notice: string;\n }\n | { ok: false; reason: string; line: null };\n\nconst message = (e: unknown): string => (e instanceof Error ? e.message : String(e));\n\n/** Inside a client of the mux? `$TMUX` set (herdr decides itself). Whether that client is on\n * mu's own server is the backend's call (`tmux.ts` `attachCommands`: switch or nest). */\nexport const insideClient = (): boolean => Boolean(process.env.TMUX);\n\n/** How to get back from an attach, by backend and where the caller runs. */\nfunction backHint(backend: string): { short: string; text: string } {\n if (backend !== \"tmux\") return { short: \"\", text: \"\" };\n switch (tmuxAttachMode()) {\n case \"switch\":\n return { short: \"back: C-b L\", text: \"back: C-b L\" };\n case \"nested\":\n return { short: \"detach: C-b C-b d\", text: \"detach: C-b d (nested: C-b C-b d)\" };\n case \"plain\":\n return { short: \"detach: C-b d\", text: \"detach: C-b d (nested: C-b C-b d)\" };\n }\n}\n\n/** The Agents footer's attach key, with how to come back. */\nexport async function attachKeyHint(): Promise<string> {\n try {\n const { short } = backHint((await activeMux()).name);\n return short === \"\" ? \"a attach\" : `a attach (${short})`;\n } catch {\n return \"a attach\";\n }\n}\n\n/** Ask the active backend for the attach steps; a backend that cannot (no mux, no workspace) is a reason. */\nexport async function planAttach(t: AttachSubject): Promise<AttachPlan> {\n try {\n const mux = await activeMux();\n const target = { session: `mu-${t.workstream}`, window: t.tab ?? t.name };\n const inside = insideClient();\n const steps = await mux.attachCommands({ ...target, inside });\n // The copied line is for a shell outside any client, whatever this one is inside of.\n const outside = await mux.attachCommands({ ...target, inside: false, outside: true });\n const { text } = backHint(mux.name);\n const notice = `attaching ${target.session}:${target.window}${text === \"\" ? \"\" : ` · ${text}`}`;\n return { ok: true, steps, line: attachShellLine(outside), notice };\n } catch (e) {\n return { ok: false, reason: message(e), line: null };\n }\n}\n\nexport interface StepResult {\n /** Exit status; null when it never ran or died on a signal. */\n code: number | null;\n /** Why it never ran (spawn error, e.g. ENOENT). */\n error?: string;\n /** The tail of its stderr. */\n stderr: string;\n}\n\n/** Runs one argv with the terminal handed over (stdin/stdout inherited, stderr kept for the reason). */\nexport type StepRunner = (step: MuxCommand) => Promise<StepResult>;\n\nexport const spawnStep: StepRunner = (step) =>\n new Promise((resolve) => {\n let stderr = \"\";\n // A nested client is deliberate: tmux refuses an attach while `$TMUX` is set.\n const env = { ...process.env };\n if (step.nested === true) delete env.TMUX;\n const child = spawn(step.command, [...step.args], {\n stdio: [\"inherit\", \"inherit\", \"pipe\"],\n env,\n });\n child.stderr.on(\"data\", (d: Buffer) => {\n stderr = (stderr + d.toString()).slice(-400);\n });\n child.on(\"error\", (e) => resolve({ code: null, error: e.message, stderr }));\n child.on(\"close\", (code) => resolve({ code, stderr }));\n });\n\nexport interface AttachResult {\n ok: boolean;\n /** Set when `!ok`: which step failed and why. */\n reason?: string;\n /** Optional steps that failed (their own `reason` when they have one). */\n warnings: string[];\n}\n\nconst wordsOf = (step: MuxCommand): string => [step.command, ...step.args].map(shellWord).join(\" \");\n\n/** The steps in order, with `attachShellLine`'s semantics: a required failure stops, an optional one does not. */\nexport async function runAttach(\n steps: readonly MuxCommand[],\n run: StepRunner,\n): Promise<AttachResult> {\n const warnings: string[] = [];\n for (const step of steps) {\n let r: StepResult;\n try {\n r = await run(step);\n } catch (e) {\n r = { code: null, error: message(e), stderr: \"\" };\n }\n if (r.code === 0) continue;\n const why =\n r.error ?? `exit ${r.code ?? \"?\"}${r.stderr.trim() === \"\" ? \"\" : `: ${r.stderr.trim()}`}`;\n if (step.optional === true) {\n warnings.push(`${step.reason ?? wordsOf(step)} (${why})`);\n continue;\n }\n return { ok: false, reason: `${wordsOf(step)} failed (${why})`, warnings };\n }\n return { ok: true, warnings };\n}\n\n/** OSC 52 payloads past this are refused: terminals cap them, and a huge \"command\" is not one. */\nexport const YANK_MAX_BYTES = 1024;\n\n// biome-ignore lint/suspicious/noControlCharactersInRegex: this IS the control-character guard\nconst CONTROL = /[\\u0000-\\u001f\\u007f-\\u009f]/;\n\n/** The OSC 52 sequence that copies `command`, or why it will not be copied. */\nexport function yankSequence(\n command: string,\n): { ok: true; sequence: string } | { ok: false; why: string } {\n if (CONTROL.test(command)) return { ok: false, why: \"it has control characters\" };\n if (Buffer.byteLength(command) > YANK_MAX_BYTES) return { ok: false, why: \"it is too long\" };\n return { ok: true, sequence: `\\u001b]52;c;${Buffer.from(command).toString(\"base64\")}\\u0007` };\n}\n\n/** The `mu` command a drill's copy key yields (the exact line shown beside it). */\nexport function copyCommand(\n t: DrillTarget,\n opts: { all?: boolean; attachLine?: string | null } = {},\n): string {\n switch (t.kind) {\n case \"notes\":\n return `mu task show ${shellWord(t.id)} -w ${shellWord(t.workstream)}${opts.all === true ? \" --all\" : \"\"}`;\n case \"scrollback\":\n return opts.attachLine ?? `mu agent read ${shellWord(t.name)} -w ${shellWord(t.workstream)}`;\n case \"log\":\n return `mu log --all --since ${Math.max(0, t.item.seq - 1)} -n 1`;\n }\n}\n","// The drills: one full-screen, read-only, scrollable body per Enter.\n// notes a task's notes (the CLI's default selection; `A` = all), whole\n// scrollback an agent's pane tail (captured through the active mux)\n// log one op of the canonical log, every field\n// Keys are this component's alone while it is mounted (App's input is off), so a\n// press is consumed once and Esc returns to the tab with its filters untouched.\n// Plain text only: bodies are cleaned, then wrapped by visual width (never ANSI in <Text>);\n// colour comes from theme roles as ink props (a note's header rule, its kind, a verdict line).\n// A load is guarded: a result that lands after Esc (or for an older `r`) is dropped.\n// Live, on the dashboard's one poll loop (3.x task-detail tickNonce): notes and the log\n// entry's task context re-read whenever the snapshot changed (`nonce`), scrollback\n// re-captures on every slow tick (`slowNonce`). A refresh keeps the previous body on screen\n// (no \"loading…\" flash) and the scroll position of the same entity; a body scrolled to its\n// end follows new lines, like `tail -f`.\n\nimport { Box, Text, useInput, useStdout, useWindowSize } from \"ink\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport stringWidth from \"string-width\";\nimport { verdictLineLabel } from \"../../delegate-verdict.js\";\nimport { parseOpKey } from \"../../log-render.js\";\nimport { activeMux } from \"../../mux.js\";\nimport { formatPair } from \"../../tasks/status.js\";\nimport type { SelectedNotes, TaskRow } from \"../../tasks.js\";\nimport { copyCommand, planAttach, yankSequence } from \"./commands.js\";\nimport { Segs } from \"./frame.js\";\nimport { NAV_HINT, navKey } from \"./nav.js\";\nimport type { DrillTarget } from \"./rows.js\";\nimport type { DashboardRuntime } from \"./runtime.js\";\nimport { cell, clean, fitLine, type Line } from \"./text.js\";\nimport { noteKindRole, type Role, type Seg, style } from \"./theme.js\";\n\n/** Lines of scrollback a drill captures (the tail; the pane has more). */\nexport const SCROLLBACK_LINES = 2000;\nconst END = Number.MAX_SAFE_INTEGER;\n\nconst segmenter = new Intl.Segmenter();\n\n/**\n * `text` as screen lines of at most `width` columns: split on newlines, cleaned of\n * escapes and control characters, broken at the last space that fits (else\n * mid-word, by grapheme). Plain text out, so no line is ever re-measured with ANSI in it.\n */\nexport function wrap(text: string, width: number): string[] {\n const max = Math.max(1, width);\n const out: string[] = [];\n for (const raw of text.split(/\\r\\n|\\n|\\r/)) {\n let cur = \"\";\n let curW = 0;\n let breakAt = -1; // index in `cur` just after the last space that follows content\n let broke = false;\n for (const { segment } of segmenter.segment(clean(raw.replace(/\\t/g, \" \")))) {\n const sw = stringWidth(segment);\n if (curW + sw > max) {\n if (segment === \" \") {\n // The space itself overflows: the line ends cleanly here.\n out.push(cur.trimEnd());\n cur = \"\";\n curW = 0;\n breakAt = -1;\n broke = true;\n continue;\n }\n if (breakAt > 0) {\n out.push(cur.slice(0, breakAt).trimEnd());\n cur = cur.slice(breakAt);\n } else {\n if (cur !== \"\") out.push(cur);\n cur = \"\";\n }\n curW = stringWidth(cur);\n breakAt = -1;\n broke = true;\n }\n if (broke && cur === \"\" && segment === \" \") continue; // no space opens a continuation\n cur += segment;\n curW += sw;\n if (segment === \" \" && cur.trim() !== \"\") breakAt = cur.length;\n }\n out.push(cur.trimEnd());\n }\n return out;\n}\n\n/** The first visible line of a scrolled body: `top` held inside `[0, count - height]`. */\nexport const clampTop = (top: number, count: number, height: number): number =>\n Math.max(0, Math.min(top, count - Math.max(1, height)));\n\n/** Columns a note's content is indented under its header rule. */\nconst NOTE_INDENT = 2;\n\n/** `2026-10-28T07:41:50.123Z` as `2026-10-28 07:41:50` (UTC, like the log); anything else as is. */\nconst noteTime = (iso: string): string =>\n /^(\\d{4}-\\d\\d-\\d\\d)T(\\d\\d:\\d\\d:\\d\\d)/.exec(iso)?.slice(1, 3).join(\" \") ?? iso;\n\n/** A verdict line's role by its label (as `parseVerdict` reads it): CONFIRMED good, REFUTED bad, else warn. */\nconst verdictRole = (label: string | undefined): Role =>\n label === \"CONFIRMED\" ? \"good\" : label === \"REFUTED\" ? \"bad\" : \"warn\";\n\n/**\n * The notes as styled screen lines, `width` wide: per note a header rule\n * (`── #n kind pinned · author · time ───`, the kind in its colour), then the whole\n * content wrapped and indented under it, then a blank line. The first `VERDICT:`\n * line takes its label's colour.\n */\nexport function notesLines(sel: SelectedNotes, width: number): Line[] {\n const out: Line[] = [];\n for (const n of sel.notes) {\n const head: Seg[] = [\n { text: \"── \", role: \"border\" },\n { text: `#${n.n} `, role: \"muted\" },\n { text: n.kind, role: noteKindRole(n.kind) },\n ...(sel.pinned.includes(n.n) ? [{ text: \" pinned\", role: \"muted\" as const }] : []),\n { text: \" · \", role: \"border\" },\n { text: n.author ?? \"-\", role: \"id\" },\n { text: \" · \", role: \"border\" },\n { text: noteTime(n.createdAt), role: \"muted\" },\n { text: \" \", role: \"border\" },\n ];\n const used = stringWidth(head.map((x) => x.text).join(\"\"));\n // A narrow screen cuts the header (ending \"…\") rather than wrap it.\n out.push(\n used > width\n ? fitLine(head, width)\n : [...head, { text: \"─\".repeat(width - used), role: \"border\" }],\n );\n const pad = \" \".repeat(NOTE_INDENT);\n // Only the note's FIRST verdict line is its verdict; a later one is quoted evidence.\n let verdictSeen = false;\n for (const raw of n.content.replace(/\\s+$/, \"\").split(/\\r\\n|\\n|\\r/)) {\n const label = verdictSeen ? null : verdictLineLabel(raw);\n if (label !== null) verdictSeen = true;\n const role = label === null ? \"text\" : verdictRole(label);\n for (const l of wrap(raw, width - NOTE_INDENT)) out.push([{ text: pad + l, role }]);\n }\n out.push([]);\n }\n return out;\n}\n\nexport function titleOf(t: DrillTarget): string {\n switch (t.kind) {\n case \"notes\":\n return `Notes ${t.workstream}/${t.id} ${t.title}`;\n case \"scrollback\":\n return `Scrollback ${t.workstream}/${t.name} ${t.paneId} (last ${SCROLLBACK_LINES} lines)`;\n case \"log\":\n return `Log #${t.item.seq}`;\n }\n}\n\nfunction logText(t: Extract<DrillTarget, { kind: \"log\" }>): string {\n const i = t.item;\n return [\n t.item.rendered,\n \"\",\n `seq: ${i.seq}`,\n `time: ${i.created_at}`,\n `scope: ${t.item.scope ?? \"-\"}`,\n `actor: ${i.actor}`,\n `intent: ${i.intent ?? \"-\"}`,\n `op: ${i.op}`,\n `entity: ${i.entity}`,\n `key: ${i.key === \"\" ? \"-\" : i.key}`,\n `payload: ${i.payload}`,\n ...(i.cut !== undefined && i.cut > 0 ? [`(${i.cut} characters cut from this item)`] : []),\n ].join(\"\\n\");\n}\n\ntype Load =\n | { state: \"loading\" }\n | { state: \"error\"; message: string }\n | {\n state: \"ready\";\n text: string;\n notices: string[];\n header?: string;\n /** A notes drill's notes: drawn as styled lines instead of `text`. */\n notes?: SelectedNotes;\n };\n\n/** A task's live line for the notes drill and a log entry's context: status, owner, title. */\nexport function taskLine(t: TaskRow | undefined): string {\n if (t === undefined) return \"task: gone\";\n return `${formatPair(t)} ${t.ownerName === null ? \"unowned\" : `@${t.ownerName}`} ${t.title}`;\n}\n\n/**\n * Copy a target's command with OSC 52 and say what happened: the command is always\n * in the message. A scrollback copies the attach line for a shell OUTSIDE any client\n * (its absence is said, then `mu agent read` is copied instead).\n */\nexport function useYank(): (target: DrillTarget, all?: boolean) => Promise<string> {\n const { stdout } = useStdout();\n return async (target, all = false) => {\n const plan = target.kind === \"scrollback\" ? await planAttach(target) : null;\n const command = copyCommand(target, { all, attachLine: plan?.line ?? null });\n const y = yankSequence(command);\n const why = plan !== null && !plan.ok ? ` (attach unavailable: ${plan.reason})` : \"\";\n if (!y.ok) return `not copied (${y.why}): ${command}${why}`;\n stdout.write(y.sequence);\n return `copied: ${command}${why}`;\n };\n}\n\nexport interface DrillProps {\n target: DrillTarget;\n runtime: DashboardRuntime;\n /** Lines pinned under the title, outside the scrolled body (an attach failure and the outside-client line). */\n notice: readonly string[];\n /** The dashboard's attention strip, shown under the title (null: none). */\n strip?: Line | null;\n /** True while the terminal belongs to an attach: a key is ignored (the hook stays active). */\n busy: { readonly current: boolean };\n /** The poll loop's change counter: notes and log context re-read when it moves. */\n nonce?: number;\n /** The slow tier's counter: scrollback re-captures when it moves. */\n slowNonce?: number;\n onClose(): void;\n onAttach(target: Extract<DrillTarget, { kind: \"scrollback\" }>): void;\n}\n\nexport function Drill({\n target,\n runtime,\n notice,\n strip = null,\n busy,\n onClose,\n onAttach,\n nonce = 0,\n slowNonce = 0,\n}: DrillProps) {\n const { columns, rows } = useWindowSize();\n const yank = useYank();\n const [all, setAll] = useState(false);\n const [reload, setReload] = useState(0);\n const [load, setLoad] = useState<Load>({ state: \"loading\" });\n const [flash, setFlash] = useState<string | null>(null);\n const [top, setTop] = useState(target.kind === \"scrollback\" ? END : 0);\n const topSeen = useRef(0);\n const entityAll = useRef(false);\n\n // What a refresh re-reads on: notes and log follow the snapshot, scrollback the slow tick.\n const tick = target.kind === \"scrollback\" ? slowNonce : nonce;\n // The entity on screen: a change of it (or of `all`) is a new body, so it shows\n // \"loading…\"; a tick of the same one keeps the old body until the new one lands.\n const entity = useRef<unknown>(null);\n\n // One guarded load per (target, all, reload, tick): the cleanup drops a late result.\n // biome-ignore lint/correctness/useExhaustiveDependencies: `reload` and `tick` only re-run the effect\n useEffect(() => {\n let live = true;\n if (entity.current !== target || all !== entityAll.current) {\n entity.current = target;\n entityAll.current = all;\n setLoad({ state: \"loading\" });\n }\n const done = (l: Load): void => {\n if (live)\n // A byte-equal result keeps the old object: no re-render.\n setLoad((prev) => (JSON.stringify(prev) === JSON.stringify(l) ? prev : l));\n };\n try {\n if (target.kind === \"notes\") {\n const sel = runtime.notes(target.workstream, target.id, all);\n done({\n state: \"ready\",\n text: \"(no notes)\",\n ...(sel.notes.length > 0 ? { notes: sel } : {}),\n notices:\n sel.more > 0\n ? [`${sel.more} of ${sel.total} notes not shown: A shows them all (oldest first)`]\n : [],\n header: taskLine(runtime.task(target.workstream, target.id)),\n });\n } else if (target.kind === \"log\") {\n // The op is immutable; the task it is about is live.\n const { workstream, local } = parseOpKey(target.item.key === \"\" ? null : target.item.key);\n const ctx =\n workstream !== undefined && local !== undefined && local !== \"\"\n ? `\\n\\ntask now: ${taskLine(runtime.task(workstream, local))}`\n : \"\";\n done({ state: \"ready\", text: `${logText(target)}${ctx}`, notices: [] });\n } else {\n void (async () => {\n try {\n const mux = await activeMux();\n const text = await mux.capture(target.paneId, { lines: SCROLLBACK_LINES });\n done({ state: \"ready\", text: text.replace(/\\s+$/, \"\"), notices: [] });\n } catch (e) {\n done({ state: \"error\", message: e instanceof Error ? e.message : String(e) });\n }\n })();\n }\n } catch (e) {\n done({ state: \"error\", message: e instanceof Error ? e.message : String(e) });\n }\n return () => {\n live = false;\n };\n }, [target, runtime, all, reload, tick]);\n\n const lines = useMemo(() => {\n const above = [...notice, ...(flash === null ? [] : [flash])];\n const ready = load.state === \"ready\" ? load : null;\n const head = [\n ...(ready?.header !== undefined ? [ready.header] : []),\n ...(ready?.notices ?? []),\n ...above,\n ].flatMap((l) => wrap(l, columns));\n const plain = (t: string, role: Role = \"text\"): Line[] =>\n wrap(t, columns).map((l) => [{ text: l, role }]);\n const body: Line[] =\n load.state === \"loading\"\n ? plain(\"loading…\")\n : load.state === \"error\"\n ? plain(`error: ${load.message}`, \"bad\")\n : load.notes !== undefined\n ? notesLines(load.notes, columns)\n : plain(load.text);\n return { head, body };\n }, [load, notice, flash, columns]);\n\n // The head (notices, attach failure, yank confirmation) is pinned under the title, never part of\n // the scrolled body: a long scrollback opens at its END and must not push the reason out of view.\n // It takes at most half of the room, so the body always keeps some rows.\n // The strip (title + strip + hint + one body row) needs 4 rows; shorter screens drop it.\n const showStrip = strip !== null && rows >= 4;\n const room = Math.max(0, rows - 1 - (rows >= 3 ? 1 : 0) - (showStrip ? 1 : 0));\n const pinned = lines.head.slice(0, Math.floor(room / 2));\n const height = room - pinned.length;\n const first = clampTop(top, lines.body.length, height);\n topSeen.current = first;\n const hint =\n target.kind === \"notes\"\n ? `${NAV_HINT} scroll A all notes r reload y copy cmd Esc back`\n : target.kind === \"scrollback\"\n ? `${NAV_HINT} scroll r reload a attach y copy cmd Esc back`\n : `${NAV_HINT} scroll y copy cmd Esc back`;\n\n useInput((input, key) => {\n if (busy.current) return;\n setFlash(null);\n const at = topSeen.current;\n if (key.escape || input === \"q\") return onClose();\n const nav = navKey(input, key, height, true);\n // Reaching the end pins the view to it (END), so lines that arrive later are followed.\n const end = Math.max(0, lines.body.length - Math.max(1, height));\n if (nav !== null)\n setTop(\n \"by\" in nav\n ? at + nav.by >= end\n ? END\n : Math.max(0, at + nav.by)\n : nav.to === \"top\"\n ? 0\n : END,\n );\n else if (input === \"r\") setReload((n) => n + 1);\n else if (input === \"A\" && target.kind === \"notes\") setAll((a) => !a);\n else if (input === \"a\" && target.kind === \"scrollback\") onAttach(target);\n else if (input === \"y\") void yank(target, all).then(setFlash);\n });\n\n const visible = lines.body.slice(first, first + height);\n const where =\n lines.body.length === 0\n ? \"\"\n : `${first + 1}-${Math.min(lines.body.length, first + height)}/${lines.body.length} `;\n return (\n // Exactly `rows` lines: a short body is followed by the spacer, so the hint stays on the last row.\n <Box flexDirection=\"column\" height={rows}>\n <Text wrap=\"truncate\" {...style(\"heading\")}>\n {cell(titleOf(target), columns)}\n </Text>\n {showStrip ? (\n <Text wrap=\"truncate\">\n <Segs line={fitLine(strip, columns)} />\n </Text>\n ) : null}\n {pinned.map((l, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: lines have no identity; the index IS the position\n <Text key={`p${i}`} wrap=\"truncate\" {...style(\"strong\")}>\n {cell(l, columns)}\n </Text>\n ))}\n {visible.map((l, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: lines have no identity; the index IS the position\n <Text key={first + i} wrap=\"truncate\">\n <Segs line={fitLine(l, columns)} />\n </Text>\n ))}\n <Box flexGrow={1} />\n {rows >= 3 ? (\n <Text wrap=\"truncate\" {...style(\"muted\")}>\n {cell(`${where}${hint}`, columns)}\n </Text>\n ) : null}\n </Box>\n );\n}\n","// A rounded frame with its title and count in the top border and an overflow\n// note in the bottom border (3.x titled-box, without ink's border machinery):\n//\n// ╭─ Agents · 3 ───────────╮\n// │ worker-1 busy │\n// ╰─ +2 more ──────────────╯\n//\n// `<Frame>` draws it in theme roles (gray border, bold cyan title, dim subtitle and\n// bottom note; the cursor row solid inverse). Always `height` lines tall.\n\nimport { Box, Text } from \"ink\";\nimport type { ReactElement } from \"react\";\nimport stringWidth from \"string-width\";\nimport { cell, clean, fitLine, type Line } from \"./text.js\";\nimport { type Seg, style } from \"./theme.js\";\n\n/** Border rows a frame adds around its body (top + bottom). */\nexport const FRAME_CHROME = 2;\n/** Columns it adds on each row (border + one space of padding, both sides). */\nexport const FRAME_SIDES = 4;\n\nexport interface FrameSpec {\n /** Outer width in columns. */\n width: number;\n /** Outer height in lines: body rows are `height - FRAME_CHROME`. */\n height: number;\n title: string;\n /** Dim text after the title, e.g. a count. */\n subtitle?: string;\n /** Inside the bottom border, e.g. `+N more` or `12/197`. */\n bottom?: string;\n}\n\n/** A border line split around its label: `╭─ ` + label + ` ───╮`, the label cut to fit and a dash always kept. */\nexport function borderParts(\n width: number,\n left: string,\n right: string,\n label: string,\n): { head: string; shown: string; tail: string } {\n if (width < 2) return { head: \"─\".repeat(Math.max(0, width)), shown: \"\", tail: \"\" };\n const inner = width - 2;\n const text = clean(label);\n if (text === \"\") return { head: left + \"─\".repeat(inner) + right, shown: \"\", tail: \"\" };\n const room = Math.max(0, inner - 4); // \"─ \" + label + \" \" + at least one dash\n const shown = stringWidth(text) <= room ? text : cell(text, room).trimEnd();\n const fill = \"─\".repeat(Math.max(1, inner - 3 - stringWidth(shown)));\n return { head: `${left}─ `, shown, tail: ` ${fill}${right}` };\n}\n\nexport interface FrameProps extends FrameSpec {\n /** One entry per body row: plain text, or a line in theme roles. */\n body: ReadonlyArray<string | Line>;\n /** Body row drawn solid inverse (the cursor), its roles dropped as in 3.x. */\n selected?: number;\n}\n\n/** Runs of one line as ink <Text>s, each in its role. */\nexport function Segs({ line }: { line: ReadonlyArray<Seg> }): ReactElement {\n return (\n <>\n {line.map((seg, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: runs of one line are positional\n <Text key={i} {...style(seg.role)}>\n {seg.text}\n </Text>\n ))}\n </>\n );\n}\n\n/** A border line in roles: the title bold cyan, ` · ` border, the rest (count, `+N more`) dim. */\nfunction borderSegs(\n width: number,\n left: string,\n right: string,\n title: string,\n rest: string,\n): Seg[] {\n const label = title !== \"\" && rest !== \"\" ? `${title} · ${rest}` : title || rest;\n const { head, shown, tail } = borderParts(width, left, right, label);\n const t = title === \"\" ? 0 : Math.min(shown.length, clean(title).length);\n const sep = title !== \"\" && rest !== \"\" ? shown.slice(t, t + 3) : \"\";\n const parts: Seg[] = [\n { text: head, role: \"border\" },\n { text: shown.slice(0, t), role: \"title\" },\n { text: sep, role: \"border\" },\n { text: shown.slice(t + sep.length), role: \"muted\" },\n { text: tail, role: \"border\" },\n ];\n return parts.filter((p) => p.text !== \"\");\n}\n\nexport function Frame({ body, selected, ...spec }: FrameProps): ReactElement | null {\n if (spec.height < FRAME_CHROME || spec.width < FRAME_SIDES) return null;\n const rows = Math.max(0, spec.height - FRAME_CHROME);\n const room = Math.max(0, spec.width - FRAME_SIDES);\n const lineOf = (b: string | Line | undefined): Line =>\n typeof b === \"string\" ? [{ text: b }] : (b ?? []);\n return (\n <Box flexDirection=\"column\" width={spec.width} height={spec.height} flexShrink={0}>\n <Text wrap=\"truncate\">\n <Segs line={borderSegs(spec.width, \"╭\", \"╮\", spec.title, spec.subtitle ?? \"\")} />\n </Text>\n {Array.from({ length: rows }, (_, i) => {\n const fitted = fitLine(lineOf(body[i]), room);\n return (\n // biome-ignore lint/suspicious/noArrayIndexKey: fixed-height frame, rows are positional\n <Text key={i} wrap=\"truncate\">\n <Text {...style(\"border\")}>│ </Text>\n {i === selected ? (\n <Text inverse>{fitted.map((s) => s.text).join(\"\")}</Text>\n ) : (\n <Segs line={fitted} />\n )}\n <Text {...style(\"border\")}> │</Text>\n </Text>\n );\n })}\n <Text wrap=\"truncate\">\n <Segs line={borderSegs(spec.width, \"╰\", \"╯\", \"\", spec.bottom ?? \"\")} />\n </Text>\n </Box>\n );\n}\n","// Plain-text helpers for the dashboard. Ink's <Text> never receives ANSI: wrap\n// and padding maths would break on it. Everything is cleaned, then cut and\n// padded by VISUAL width (wide glyphs count 2), then handed over as plain text.\n\nimport stringWidth from \"string-width\";\nimport type { Seg } from \"./theme.js\";\n\n// CSI and OSC sequences, then any other control character (tabs and newlines\n// become one space so a title can never add a line to a row).\n// biome-ignore lint/suspicious/noControlCharactersInRegex: this IS the control-character filter\nconst ESCAPES = /\\u001b\\[[0-?]*[ -/]*[@-~]|\\u001b\\][^\\u0007\\u001b]*(?:\\u0007|\\u001b\\\\)?|\\u001b./g;\n// biome-ignore lint/suspicious/noControlCharactersInRegex: same\nconst CONTROL = /[\\u0000-\\u001f\\u007f-\\u009f]/g;\n\n/** Strip escape sequences and control characters; the result is safe for `<Text>`. */\nexport function clean(s: string): string {\n return s.replace(ESCAPES, \"\").replace(CONTROL, \" \");\n}\n\nconst segmenter = new Intl.Segmenter();\n\n/** `s` cleaned, cut to `width` columns (a cut ends in \"…\") and padded to exactly `width`. */\nexport function cell(s: string, width: number): string {\n if (width <= 0) return \"\";\n const text = clean(s);\n const w = stringWidth(text);\n if (w <= width) return text + \" \".repeat(width - w);\n let out = \"\";\n let used = 0;\n for (const { segment } of segmenter.segment(text)) {\n const sw = stringWidth(segment);\n if (used + sw > width - 1) break;\n out += segment;\n used += sw;\n }\n return `${out}…${\" \".repeat(width - used - 1)}`;\n}\n\n/**\n * The first visible row of a viewport: keep `top` while `selected` is inside the\n * window, else move it the least that shows `selected`; never past the end.\n */\nexport function scrollTop(top: number, selected: number, count: number, height: number): number {\n const h = Math.max(1, height);\n let next = top;\n if (selected < next) next = selected;\n else if (selected >= next + h) next = selected - h + 1;\n return Math.max(0, Math.min(next, count - h));\n}\n\n/** A styled line: runs of text, each in one theme role. */\nexport type Line = readonly Seg[];\n\n/** The plain text of a line. */\nexport const lineText = (line: Line): string => line.map((s) => s.text).join(\"\");\n\n/** `line` cleaned, cut to `width` columns (a cut ends in \"…\", in the cut run's role) and padded to exactly `width`. */\nexport function fitLine(line: Line, width: number): Seg[] {\n if (width <= 0) return [];\n const runs = line.map((s) => ({ ...s, text: clean(s.text) }));\n const total = stringWidth(runs.map((s) => s.text).join(\"\"));\n if (total <= width) return [...runs, { text: \" \".repeat(width - total) }];\n const out: Seg[] = [];\n let used = 0;\n for (const run of runs) {\n let text = \"\";\n for (const { segment } of segmenter.segment(run.text)) {\n const sw = stringWidth(segment);\n if (used + sw > width - 1) {\n out.push({ ...run, text: `${text}…` });\n return [...out, { text: \" \".repeat(width - used - 1) }];\n }\n text += segment;\n used += sw;\n }\n out.push({ ...run, text });\n }\n return out;\n}\n","// The dashboard's one palette: named roles -> ink <Text> props, taken from the 3.x\n// TUI (v3.13.3: titled-box, list-row, inkColorForPair, format.ts STATUS_COLORS,\n// log card, tab strip, drill). Views name a ROLE, never a colour: a re-colour is\n// one line here.\n//\n// NO_COLOR (https://no-color.org/, any defined value, as src/output.ts reads it)\n// drops every colour. Ink's chalk does not read it (only FORCE_COLOR and the TTY),\n// so the check lives here. Bold, dim and inverse stay: they are not colour, and the\n// cursor row and the selected tab must still show.\n//\n// No state glyphs: 3.x drew Nerd Font codepoints with no ASCII fallback\n// (src/glyphs.ts \"Requires a Nerd Font\"), and Nerd Fonts are not universal.\n\nimport { DEFAULT_SUBSTATE, isTaskStatus } from \"../../tasks/status.js\";\n\nexport interface TextStyle {\n color?: string;\n bold?: boolean;\n dimColor?: boolean;\n}\n\nconst STYLES = {\n /** Plain text (titles in lists, prose). */\n text: {},\n /** Frame borders (rounded, gray). */\n border: { color: \"gray\" },\n /** A frame's title, the selected tab and workstream. */\n title: { color: \"cyan\", bold: true },\n /** Secondary text: subtitles, `+N more`, owners, times, hosts, hint, filter, next. */\n muted: { dimColor: true },\n /** A row's id or name. */\n id: { bold: true },\n /** Emphasis without colour: a drill's pinned notice (an attach failure). */\n strong: { bold: true },\n /** A log line's verb. */\n verb: { color: \"cyan\" },\n /** A drill's title line. */\n heading: { color: \"magenta\", bold: true },\n /** Task OPEN (ready). */\n open: { color: \"cyan\" },\n /** Task OPEN/parked and OPEN/triage: out of the ready set. */\n parked: { color: \"gray\" },\n /** Task IN_PROGRESS. */\n progress: { color: \"yellow\" },\n /** Task CLOSED/done. */\n done: { color: \"green\" },\n /** Task CLOSED as anything but done (wontfix, duplicate, superseded). */\n undone: { color: \"red\" },\n /** Agent busy. */\n busy: { color: \"cyan\" },\n /** Agent waiting on a permission dialog. */\n permission: { color: \"magenta\" },\n /** \"all quiet\". */\n good: { color: \"green\" },\n /** Needs a look: an attention item, a stalled tool, a sync warning. */\n warn: { color: \"yellow\" },\n /** Broken: a dead agent, an error. */\n bad: { color: \"red\" },\n} as const satisfies Record<string, TextStyle>;\n\nexport type Role = keyof typeof STYLES;\n\n/** A run of text drawn in one role; a line is a list of them. */\nexport interface Seg {\n text: string;\n role?: Role;\n}\n\n/** Colour is on unless NO_COLOR is set (read per call so a test can flip it). */\nconst colorOn = (): boolean => process.env.NO_COLOR === undefined;\n\n/** The ink props for `role`, without colour under NO_COLOR. */\nexport function style(role: Role = \"text\"): TextStyle {\n const s: TextStyle = STYLES[role];\n if (colorOn() || s.color === undefined) return s;\n const { color: _, ...rest } = s;\n return rest;\n}\n\n/** A task's (status, substate) pair, as 3.x's inkColorForPair. */\nexport function statusRole(status: string, substate: string): Role {\n if (status === \"OPEN\") return substate === \"parked\" || substate === \"triage\" ? \"parked\" : \"open\";\n if (status === \"IN_PROGRESS\") return \"progress\";\n if (status === \"CLOSED\") {\n const dflt = isTaskStatus(status) ? DEFAULT_SUBSTATE[status] : \"done\";\n return substate === \"\" || substate === dflt ? \"done\" : \"undone\";\n }\n return \"text\";\n}\n\n/** An agent's state (a `RuntimeState`), as 3.x's STATUS_COLORS: idle and unknown are muted. */\nexport function agentStateRole(state: string | null | undefined): Role {\n if (state === \"busy\") return \"busy\";\n if (state === \"needs_permission\") return \"permission\";\n return \"muted\";\n}\n\n/** A note's kind (`NOTE_KINDS`): the brief and the report stand out, a verdict needs a look. */\nexport function noteKindRole(kind: string): Role {\n if (kind === \"brief\") return \"title\";\n if (kind === \"report\" || kind === \"close\") return \"good\";\n if (kind === \"verdict\") return \"warn\";\n return \"id\";\n}\n","// The one list-navigation key map, shared by every list (tabs, the Overview's\n// Attention cursor) and every drill body (notes, scrollback, log entry), so a\n// key moves the same way everywhere. Pure: the caller applies the result to a\n// cursor (lists) or a scroll offset (drills).\n//\n// j / ↓ k / ↑ one row\n// Ctrl-d Ctrl-u half a page\n// PgDn PgUp a page (drills: space too)\n// g g g Home top (`gg` is two tops, so vim hands work)\n// G End bottom\n\nimport type { Key } from \"ink\";\n\nexport type NavMove = { to: \"top\" } | { to: \"bottom\" } | { by: number };\n\n/** What `input`/`key` does in a list or body showing `page` rows; null = not a navigation key. */\nexport function navKey(input: string, key: Key, page: number, space = false): NavMove | null {\n const full = Math.max(1, page);\n const half = Math.max(1, Math.floor(full / 2));\n if (key.ctrl && input === \"d\") return { by: half };\n if (key.ctrl && input === \"u\") return { by: -half };\n if (key.ctrl || key.meta) return null;\n if (key.downArrow || input === \"j\") return { by: 1 };\n if (key.upArrow || input === \"k\") return { by: -1 };\n if (key.pageDown || (space && input === \" \")) return { by: full };\n if (key.pageUp) return { by: -full };\n if (input === \"g\" || key.home) return { to: \"top\" };\n if (input === \"G\" || key.end) return { to: \"bottom\" };\n return null;\n}\n\n/** The hint text for these keys. */\nexport const NAV_HINT = \"j/k ^d/^u g/G\";\n","// The Overview tab: framed cards over the selected workstream (Attention, Agents,\n// In progress, Open by ROI, Log) in 1/2/3 columns by width (grid.ts). The card\n// contents are the other tabs' own rows, so a line reads the same everywhere.\n// Attention is the cursor's list; the rest are read-only glances.\n\nimport { Box } from \"ink\";\nimport type { ReactElement } from \"react\";\nimport type { DashboardSnapshot } from \"../../dashboard-data.js\";\nimport { Frame } from \"./frame.js\";\nimport { COLUMN_GAP, columnCount, fitColumn, gridWidths, placeCards } from \"./grid.js\";\nimport { NO_FILTER, tabRows, taskRows, waveRows } from \"./rows.js\";\nimport { type Line, scrollTop } from \"./text.js\";\nimport type { Role } from \"./theme.js\";\n\nexport interface Card {\n id: string;\n title: string;\n lines: Line[];\n /** Shown when there are no lines. */\n empty: string;\n /** The empty line's role (Attention's `✓ all quiet` is good news; the rest are muted). */\n emptyRole?: Role;\n /** Body rows it takes before spare rows are shared out. */\n max: number;\n /** Show the newest lines (the log), not the first. */\n tail?: boolean;\n}\n\n/** The cards of workstream `ws`, in order: five, plus Waves when it has delegate waves. */\nexport function overviewCards(snap: DashboardSnapshot, ws: string | null, now: number): Card[] {\n const lines = (tab: \"overview\" | \"agents\" | \"log\"): Line[] =>\n tabRows(tab, snap, ws, NO_FILTER, now).map((r) => r.line);\n const tasks = (f: typeof NO_FILTER): Line[] =>\n taskRows(snap, ws, f, { call: false }).map((r) => r.line);\n const waves = waveRows(snap, ws).map((r) => r.line);\n return [\n {\n id: \"attention\",\n title: \"Attention\",\n lines: lines(\"overview\"),\n empty: \"✓ all quiet\",\n emptyRole: \"good\",\n max: 6,\n },\n { id: \"agents\", title: \"Agents\", lines: lines(\"agents\"), empty: \"no agents\", max: 6 },\n {\n id: \"progress\",\n title: \"In progress\",\n lines: tasks({ ...NO_FILTER, status: \"in_progress\" }),\n empty: \"nothing in progress\",\n max: 8,\n },\n {\n id: \"open\",\n title: \"Open · by ROI\",\n lines: tasks({ ...NO_FILTER, status: \"open\", sort: \"roi\" }),\n empty: \"nothing open\",\n max: 12,\n },\n ...(waves.length > 0\n ? [{ id: \"waves\", title: \"Waves\", lines: waves, empty: \"no waves\", max: 5 }]\n : []),\n { id: \"log\", title: \"Log\", lines: lines(\"log\"), empty: \"no activity\", max: 10, tail: true },\n ];\n}\n\n/** The cards laid out in `width` x `height`; `sel` is the Attention cursor. */\nexport function Overview(p: {\n cards: readonly Card[];\n sel: number;\n width: number;\n height: number;\n}): ReactElement {\n const columns = placeCards(\n p.cards.map((c) => c.id),\n columnCount(p.width),\n );\n const widths = gridWidths(p.width, columns.length);\n return (\n <Box height={p.height} width={p.width} columnGap={COLUMN_GAP}>\n {columns.map((ids, ci) => {\n const cards = ids.flatMap((id) => p.cards.find((c) => c.id === id) ?? []);\n const placed = fitColumn(\n p.height,\n cards.map((c) => ({\n id: c.id,\n // Attention keeps up to 3 rows even on a short screen: it is why you look.\n min: c.id === \"attention\" ? Math.max(1, Math.min(3, c.lines.length)) : 1,\n max: c.max,\n count: c.lines.length,\n })),\n );\n return (\n <Box key={ids.join()} flexDirection=\"column\" width={widths[ci]} flexShrink={0}>\n {placed.map((pl) => {\n const card = cards.find((c) => c.id === pl.id);\n if (card === undefined) return null;\n const attention = card.id === \"attention\";\n const from = card.tail\n ? Math.max(0, card.lines.length - pl.rows)\n : attention\n ? scrollTop(0, p.sel, card.lines.length, pl.rows)\n : 0;\n const body = card.lines\n .slice(from, from + pl.rows)\n .map(\n (l, i): Line =>\n attention ? [{ text: from + i === p.sel ? \"> \" : \" \" }, ...l] : l,\n );\n return (\n <Frame\n key={card.id}\n width={widths[ci] ?? 0}\n height={pl.height}\n title={card.title}\n subtitle={card.lines.length > 0 ? String(card.lines.length) : \"\"}\n bottom={pl.hidden > 0 ? `+${pl.hidden} ${card.tail ? \"older\" : \"more\"}` : \"\"}\n body={\n card.lines.length === 0\n ? [[{ text: card.empty, role: card.emptyRole ?? \"muted\" }]]\n : body\n }\n {...(attention && card.lines.length > 0 ? { selected: p.sel - from } : {})}\n />\n );\n })}\n </Box>\n );\n })}\n </Box>\n );\n}\n","// Overview card geometry (ported from 3.x layout.ts, rewritten over a small\n// CardSpec): how many columns, how wide, which card goes where, and how many\n// body rows each card gets. Pure and plain-text; no ink.\n//\n// Rules: 1 column below 120 cols, 2 from 120, 3 from 180. Each card has min and\n// max body rows. The allocator hands rows out up to max first so a noisy list\n// cannot crowd its siblings, then gives spare rows to the cards still hiding\n// data, in proportion to what each hides: a column with hidden data fills its\n// height, a short list is not padded.\n\nimport { FRAME_CHROME } from \"./frame.js\";\n\nexport interface CardSpec {\n id: string;\n /** Body rows reserved even when empty. */\n min: number;\n /** First-pass cap on body rows; spare rows may go past it while data is hidden. */\n max: number;\n /** How many rows the card has to show. */\n count: number;\n}\n\n/** Space between two columns. */\nexport const COLUMN_GAP = 1;\n\nexport function columnCount(cols: number): 1 | 2 | 3 {\n if (cols >= 180) return 3;\n if (cols >= 120) return 2;\n return 1;\n}\n\n/** Outer widths of `n` columns across `total` cols, leaving a gap between each; the leftmost take the remainder. */\nexport function gridWidths(total: number, n: number): number[] {\n if (n <= 0) return [];\n const usable = Math.max(n, total - COLUMN_GAP * (n - 1));\n const base = Math.floor(usable / n);\n const extra = usable - base * n;\n return Array.from({ length: n }, (_, i) => base + (i < extra ? 1 : 0));\n}\n\n/**\n * Which column each Overview card sits in, per column count. A fixed table, so a\n * list growing by one row never moves a card. Attention first, Log last.\n */\nconst PLACEMENT: Readonly<Record<1 | 2 | 3, Readonly<Record<string, number>>>> = {\n 1: {},\n 2: { attention: 0, agents: 0, progress: 1, open: 1, waves: 1, log: 0 },\n 3: { attention: 0, agents: 0, progress: 1, open: 1, waves: 1, log: 2 },\n};\n\n/**\n * `ids` (in card order) split into columns by `PLACEMENT[n]`. An id the table\n * does not name goes in the last column. Empty columns are dropped.\n */\nexport function placeCards(ids: readonly string[], n: 1 | 2 | 3): string[][] {\n const table = PLACEMENT[n];\n const cols: string[][] = Array.from({ length: n }, () => []);\n for (const id of ids) cols[Math.min(n - 1, table[id] ?? n - 1)]?.push(id);\n return cols.filter((c) => c.length > 0);\n}\n\nconst clamp = (v: number, lo: number, hi: number): number => Math.max(lo, Math.min(hi, v));\n\n/**\n * Body rows per card for one column of `availableRows` lines (chrome included).\n * The result is keyed by card id, in `cards` order. When even the minimums do\n * not fit, the minimums come back and `fitColumn` clips them.\n */\nexport function allocateRowBudgets(\n availableRows: number,\n cards: readonly CardSpec[],\n): Map<string, number> {\n const out = new Map<string, number>();\n const entries = cards.map((c) => {\n const min = Math.max(0, c.min);\n const max = Math.max(min, c.max);\n const count = Math.max(0, Math.floor(c.count));\n return { id: c.id, min, max, count, natural: clamp(count, min, max) };\n });\n if (entries.length === 0) return out;\n\n const body = Math.max(0, availableRows - FRAME_CHROME * entries.length);\n const set = (id: string, n: number): void => void out.set(id, n);\n\n const naturalTotal = entries.reduce((n, e) => n + e.natural, 0);\n if (naturalTotal <= body) {\n for (const e of entries) set(e.id, e.natural);\n return fillHidden(out, entries, body);\n }\n const minTotal = entries.reduce((n, e) => n + e.min, 0);\n for (const e of entries) set(e.id, e.min);\n if (body <= minTotal) return out;\n\n // Share what is left above the minimums, weighted by each card's natural size.\n const left = body - minTotal;\n const weight = entries.reduce((n, e) => n + e.natural, 0);\n const shares = entries.map((e, index) => {\n const raw = weight === 0 ? left / entries.length : (left * e.natural) / weight;\n return { e, index, raw, add: Math.min(e.max - e.min, Math.floor(raw)) };\n });\n let remaining = left;\n for (const s of shares) {\n set(s.e.id, s.e.min + s.add);\n remaining -= s.add;\n }\n const byRemainder = [...shares].sort(\n (a, b) => b.raw - Math.floor(b.raw) - (a.raw - Math.floor(a.raw)) || a.index - b.index,\n );\n while (remaining > 0) {\n let changed = false;\n for (const s of byRemainder) {\n if (remaining <= 0) break;\n const have = out.get(s.e.id) ?? 0;\n if (have >= s.e.max) continue;\n set(s.e.id, have + 1);\n remaining -= 1;\n changed = true;\n }\n if (!changed) break;\n }\n return fillHidden(out, entries, body);\n}\n\n/**\n * Spare rows go to the cards that still hide data, in proportion to how many each\n * hides (largest remainder, ties by card order), never past a card's own count.\n */\nfunction fillHidden(\n out: Map<string, number>,\n entries: ReadonlyArray<{ id: string; count: number }>,\n body: number,\n): Map<string, number> {\n let spare = body - entries.reduce((n, e) => n + (out.get(e.id) ?? 0), 0);\n while (spare > 0) {\n const hidden = entries\n .map((e, index) => ({ id: e.id, index, rows: Math.max(0, e.count - (out.get(e.id) ?? 0)) }))\n .filter((h) => h.rows > 0);\n const total = hidden.reduce((n, h) => n + h.rows, 0);\n if (total === 0) break;\n const pool = Math.min(spare, total);\n const shares = hidden.map((h) => {\n const raw = (pool * h.rows) / total;\n return { ...h, add: Math.floor(raw), rem: raw - Math.floor(raw) };\n });\n let given = 0;\n for (const s of shares) {\n out.set(s.id, (out.get(s.id) ?? 0) + s.add);\n given += s.add;\n }\n shares.sort((a, b) => b.rem - a.rem || a.index - b.index);\n for (const s of shares) {\n if (given >= pool) break;\n const count = entries[s.index]?.count ?? 0;\n if ((out.get(s.id) ?? 0) >= count) continue;\n out.set(s.id, (out.get(s.id) ?? 0) + 1);\n given += 1;\n }\n if (given === 0) break;\n spare -= given;\n }\n return out;\n}\n\nexport interface PlacedCard {\n id: string;\n /** Outer height, frame included. */\n height: number;\n /** Body rows the card shows. */\n rows: number;\n /** Rows of data it cannot show (`+N more`). */\n hidden: number;\n}\n\n/**\n * One column laid out in `availableRows` lines: budgets from `allocateRowBudgets`,\n * clipped top-down so the stack never passes `availableRows`. A card left with no\n * body row is dropped rather than drawn as an empty frame, but the first card\n * always stays. Total height is at most `availableRows`.\n */\nexport function fitColumn(availableRows: number, cards: readonly CardSpec[]): PlacedCard[] {\n const budgets = allocateRowBudgets(availableRows, cards);\n const out: PlacedCard[] = [];\n let left = Math.max(0, Math.floor(availableRows));\n for (const c of cards) {\n const rows = Math.min(budgets.get(c.id) ?? 0, Math.max(0, left - FRAME_CHROME));\n if (rows === 0 && c.min > 0 && out.length > 0) continue;\n if (left < FRAME_CHROME) break;\n out.push({ id: c.id, height: FRAME_CHROME + rows, rows, hidden: Math.max(0, c.count - rows) });\n left -= FRAME_CHROME + rows;\n }\n return out;\n}\n","// Column alignment for dashboard rows (ported from 3.x columns.ts, plain text).\n//\n// A column is PROTECTED (ids, statuses, owners, times: never cut, the user\n// copies them verbatim) or CLIP (titles, rendered text: cut to what is left and\n// ending in \"…\" when the view cuts the line). Rows keep one clip column, last. Widths come from the rows the\n// CALLER passes: pass every row of the snapshot, not the filtered or scrolled\n// window, so a filter or a poll never moves a column.\n\nimport stringWidth from \"string-width\";\nimport { cell, clean } from \"./text.js\";\n\nexport interface ColumnSpec {\n kind: \"protect\" | \"clip\";\n /** \"right\" pads on the left (numbers). Default \"left\". */\n align?: \"left\" | \"right\";\n /** Floor for the natural width. A fixed column is min === max. */\n min?: number;\n /** Cap for the natural width, so one rogue row cannot balloon the column. */\n max?: number;\n}\n\n/** Space between two columns. */\nexport const GUTTER = 2;\n\n/** The widest cell per column over `rows`, by visual width. */\nexport function naturalWidths(rows: ReadonlyArray<ReadonlyArray<string>>, ncols: number): number[] {\n const widths = new Array<number>(ncols).fill(0);\n for (const row of rows) {\n for (let i = 0; i < ncols; i++) {\n const w = stringWidth(clean(row[i] ?? \"\"));\n if (w > (widths[i] ?? 0)) widths[i] = w;\n }\n }\n return widths;\n}\n\n/**\n * The width of every column: the natural width of its widest cell, inside min/max. The\n * clip column is NOT sized here: its text goes out whole and the view cuts the line to\n * the screen width (`fitLine`, ending in \"…\").\n */\nexport function columnWidths(\n rows: ReadonlyArray<ReadonlyArray<string>>,\n specs: ReadonlyArray<ColumnSpec>,\n): number[] {\n const natural = naturalWidths(rows, specs.length);\n return specs.map((s, i) => {\n let w = natural[i] ?? 0;\n if (s.min !== undefined) w = Math.max(w, s.min);\n if (s.max !== undefined) w = Math.min(w, s.max);\n return w;\n });\n}\n\n/** One cell cut (end \"…\") or padded to exactly `width`; \"right\" pads on the left. */\nexport function fitCell(s: string, width: number, align: \"left\" | \"right\" = \"left\"): string {\n const text = clean(s);\n const w = stringWidth(text);\n if (align === \"right\" && w < width) return \" \".repeat(width - w) + text;\n return cell(text, width);\n}\n\n/** The cells of one row, each exactly its column width (zero-width columns vanish). */\nexport function renderCells(\n cells: ReadonlyArray<string>,\n widths: ReadonlyArray<number>,\n specs: ReadonlyArray<ColumnSpec>,\n): string[] {\n return specs.map((s, i) => fitCell(cells[i] ?? \"\", widths[i] ?? 0, s.align));\n}\n","// The dashboard's pure model: which workstream to start on, what each tab's\n// rows are, how filters apply, how the cursor moves. No React, no I/O, no\n// clock (callers pass `now`), so every rule here is a plain unit test.\n//\n// Row text is plain and unpadded; the view cuts and pads it by visual width.\n// Every row has a STABLE key: the cursor follows the key across polls, so a\n// reorder by activity never moves it onto another task.\n\nimport type {\n DashboardAgent,\n DashboardAttention,\n DashboardEdge,\n DashboardLogItem,\n DashboardSnapshot,\n DashboardTask,\n DashboardWave,\n} from \"../../dashboard-data.js\";\nimport { formatElapsed, matches } from \"../../dashboard-data.js\";\nimport { KNOWN_VERBS } from \"../../log-render.js\";\nimport {\n formatPair,\n TASK_STATUSES,\n TASK_SUBSTATES,\n type TaskPair,\n type TaskStatus,\n} from \"../../tasks/status.js\";\nimport { type ColumnSpec, columnWidths, GUTTER, renderCells } from \"./columns.js\";\nimport { clean, type Line, lineText } from \"./text.js\";\nimport { agentStateRole, type Role, type Seg, statusRole } from \"./theme.js\";\n\nexport type TabId = \"overview\" | \"tasks\" | \"dag\" | \"agents\" | \"log\";\nexport const TABS: readonly { id: TabId; label: string }[] = [\n { id: \"overview\", label: \"Overview\" },\n { id: \"tasks\", label: \"Tasks\" },\n { id: \"dag\", label: \"DAG\" },\n { id: \"agents\", label: \"Agents\" },\n { id: \"log\", label: \"Log\" },\n];\n\n/** What Enter opens on a row (a tagged union). */\nexport type DrillTarget =\n | { kind: \"notes\"; workstream: string; id: string; title: string }\n | { kind: \"scrollback\"; workstream: string; name: string; paneId: string; tab: string | null }\n | { kind: \"log\"; item: DashboardLogItem };\n\nexport interface Row {\n key: string;\n /** The plain line (filters, tests, copy); `line` is the same text in theme roles. */\n text: string;\n line: Line;\n /** Enter opens this; absent = nothing to open. */\n drill?: DrillTarget;\n}\n\n/** Task status filter, cycled with `o`. `active` is the dashboard default (CLOSED hidden). */\nconst STATUS_LABELS = [\"active\", \"open\", \"in_progress\", \"closed\", \"all\"] as const;\nexport type StatusLabel = (typeof STATUS_LABELS)[number];\n\n/** Task order, cycled with `s` (Tasks tab only): newest activity (default), ROI, oldest first, id. */\nconst SORT_LABELS = [\"activity\", \"roi\", \"age\", \"id\"] as const;\nexport type SortLabel = (typeof SORT_LABELS)[number];\n\n/** The filter line's name for a sort: the arrow points at what comes first. */\nexport const SORT_ARROWS: Record<SortLabel, string> = {\n activity: \"↓\", // newest first\n roi: \"↓\", // highest first\n age: \"↑\", // oldest first\n id: \"↑\",\n};\n\nexport interface Filter {\n status: StatusLabel;\n text: string;\n sort: SortLabel;\n}\nexport const NO_FILTER: Filter = { status: \"active\", text: \"\", sort: \"activity\" };\n\nconst STATUS_SETS: Record<StatusLabel, readonly TaskStatus[]> = {\n active: [\"OPEN\", \"IN_PROGRESS\"],\n open: [\"OPEN\"],\n in_progress: [\"IN_PROGRESS\"],\n closed: [\"CLOSED\"],\n all: [\"OPEN\", \"IN_PROGRESS\", \"CLOSED\"],\n};\n\nexport const statusesOf = (label: StatusLabel): readonly TaskStatus[] => STATUS_SETS[label];\n\nexport function nextStatusLabel(label: StatusLabel): StatusLabel {\n const i = STATUS_LABELS.indexOf(label);\n return STATUS_LABELS[(i + 1) % STATUS_LABELS.length] ?? \"active\";\n}\n\nexport function nextSortLabel(label: SortLabel): SortLabel {\n const i = SORT_LABELS.indexOf(label);\n return SORT_LABELS[(i + 1) % SORT_LABELS.length] ?? \"activity\";\n}\n\n/** Filters (and cursors) persist per tab and workstream: every tab shows the selected one. */\nexport const scopeKey = (tab: TabId, workstream: string | null): string =>\n `${tab}\\u0000${workstream ?? \"\"}`;\n\n/**\n * The workstream to start on: the hint (the mux session's, or `-w`) when it is\n * live, else the one with the MOST RECENT activity (`latest_seq`; ties by name).\n * Never `workstreams[0]`: the list is alphabetical, which says nothing.\n */\nexport function pickWorkstream(\n workstreams: DashboardSnapshot[\"workstreams\"],\n hint?: string,\n): string | null {\n if (hint !== undefined && workstreams.some((w) => w.name === hint)) return hint;\n let best: DashboardSnapshot[\"workstreams\"][number] | undefined;\n for (const w of workstreams) {\n if (best === undefined || w.latest_seq > best.latest_seq) best = w;\n }\n return best?.name ?? null;\n}\n\n/** `scratch` carries a `*`: the picker is the only place that says it is ephemeral. */\nexport const workstreamLabel = (w: { name: string; scratch: boolean }): string =>\n w.scratch ? `${w.name}*` : w.name;\n\n/** The Next line. Unavailable is NOT \"no authorised work\": only a computed null says that. */\nexport function nextLine(snap: DashboardSnapshot): string {\n if (snap.next_source !== \"computed\") return \"next: unavailable\";\n if (snap.next === null) return \"next: no authorised work\";\n return `next (${snap.next.mode}): ${snap.next.commands.join(\" ; \")}`;\n}\n\n/** `OPEN`, `OPEN/parked`: the CLI's `formatPair` over the snapshot's string columns. */\nexport const statusText = (status: string, substate: string): string =>\n substate === \"\" ? status : formatPair({ status, substate } as TaskPair);\n\nconst scrollbackOf = (a: DashboardAgent): DrillTarget => ({\n kind: \"scrollback\",\n workstream: a.workstream,\n name: a.name,\n paneId: a.pane_id,\n tab: a.tab,\n});\n\n// Column widths come from the SNAPSHOT (every row of the workstream), never from the\n// filtered or scrolled rows, so typing a filter or a poll never moves a column. A\n// status label is fixed at the longest legal one (`CLOSED/superseded`); the one clip\n// column (title, rendered text, tool) is last.\nconst STATUS_WIDTH = Math.max(\n ...TASK_STATUSES.flatMap((st) => TASK_SUBSTATES[st].map((sub) => statusText(st, sub).length)),\n);\nconst STATE_WIDTH = \"needs_permission\".length;\nconst HOST_WIDTH = 6;\nconst LOCAL = \"local\";\nconst TIME_WIDTH = 8;\n\nconst protect = (min = 0, max?: number): ColumnSpec => ({\n kind: \"protect\",\n min,\n ...(max !== undefined ? { max } : {}),\n});\nconst fixed = (n: number): ColumnSpec => ({ kind: \"protect\", min: n, max: n });\nconst CLIP: ColumnSpec = { kind: \"clip\" };\n\n/**\n * Lay rows out in columns sized over `basis` (every row of the snapshot, protected\n * columns only). The LAST spec is the one clip column: its text goes out whole and\n * the view cuts the line to its width, ending in \"…\". Zero-width columns vanish.\n */\nfunction layoutRows(\n basis: ReadonlyArray<ReadonlyArray<string>>,\n specs: readonly ColumnSpec[],\n): (cells: readonly string[], roles: readonly (Role | undefined)[]) => Line {\n const widths = columnWidths(basis, specs);\n const last = specs.length - 1;\n return (cells, roles) => {\n const fitted = renderCells(cells, widths, specs);\n const shown = specs.flatMap((_, i) =>\n i === last\n ? [{ text: clean(cells[last] ?? \"\"), role: roles[last] }]\n : (widths[i] ?? 0) > 0\n ? [{ text: fitted[i] ?? \"\", role: roles[i] }]\n : [],\n );\n const out: Seg[] = shown.flatMap((seg, i) => [\n ...(i > 0 ? [{ text: \" \".repeat(GUTTER) }] : []),\n seg.role === undefined ? { text: seg.text } : { text: seg.text, role: seg.role },\n ]);\n // The line ends at its last non-blank character, as the plain text always did.\n while (out.length > 0) {\n const tail = out[out.length - 1] as Seg;\n const trimmed = tail.text.trimEnd();\n if (trimmed !== \"\") {\n out[out.length - 1] = { ...tail, text: trimmed };\n break;\n }\n out.pop();\n }\n return out;\n };\n}\n\n/** A row from its styled line (the plain text is derived, so the two never differ). */\nconst rowOf = (key: string, line: Line, rest: Omit<Row, \"key\" | \"text\" | \"line\"> = {}): Row => ({\n key,\n text: lineText(line),\n line,\n ...rest,\n});\n\n/** `@name`, with the owner's workstream when it is not the task's own. */\nconst ownerLabel = (t: DashboardTask): string =>\n t.owner === null\n ? \"\"\n : `@${t.owner_workstream !== null && t.owner_workstream !== t.workstream ? `${t.owner_workstream}/` : \"\"}${t.owner}`;\n\n/** Order of a task list: activity is the snapshot's own order (newest first); ties keep it. */\nfunction sortTasks(tasks: DashboardTask[], sort: SortLabel): DashboardTask[] {\n const roi = (t: DashboardTask): number => t.impact / Math.max(t.effort_days, 1e-9);\n const out = [...tasks];\n if (sort === \"roi\") out.sort((a, b) => roi(b) - roi(a) || a.effort_days - b.effort_days);\n else if (sort === \"age\")\n out.sort((a, b) => (a.created_at < b.created_at ? -1 : a.created_at > b.created_at ? 1 : 0));\n else if (sort === \"id\") out.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));\n return out;\n}\n\n/** A delegate task's call: `running`, `done REFUTED`, `refused`, then `> <judged task>`. Empty for other tasks. */\nexport function callText(t: DashboardTask): string {\n const c = t.call;\n if (c === undefined) return \"\";\n const judged = c.judges === null ? \"\" : ` > ${c.judges}`;\n return `${c.state}${c.verdict === null ? \"\" : ` ${c.verdict}`}${judged}`;\n}\n\n/** A call that needs you is coloured as its attention item would be. */\nconst callRole = (t: DashboardTask): Role =>\n t.call?.state === \"failed\" ? \"bad\" : t.call?.state === \"refused\" ? \"warn\" : \"muted\";\n\n/**\n * The Tasks tab's rows. `call: false` drops the delegate call column: the Overview\n * cards are a third of the screen, and the column would crowd every title out.\n */\nexport function taskRows(\n snap: DashboardSnapshot,\n ws: string | null,\n f: Filter,\n opts: { call?: boolean } = {},\n): Row[] {\n const callOf = opts.call === false ? () => \"\" : callText;\n const statuses: readonly string[] = statusesOf(f.status);\n const inWs = snap.tasks.filter((t) => t.workstream === ws);\n const tasks = sortTasks(\n inWs.filter(\n (t) =>\n statuses.includes(t.status) &&\n matches(f.text, t.key, t.title, t.owner, t.substate, callOf(t)),\n ),\n f.sort,\n );\n // The call column is zero wide (gone) in a workstream with no delegate tasks.\n const specs = [protect(0, 24), fixed(STATUS_WIDTH), protect(0, 24), protect(0, 48), CLIP];\n // The owner sits BEFORE the title, so a long title can never clip it away. Its width\n // covers the workstream's agents too: a task claimed later does not shift the title.\n const agentNames = snap.agents.filter((a) => a.workstream === ws).map((a) => `@${a.name}`);\n const line = layoutRows(\n [\n ...inWs.map((t) => [t.id, \"\", ownerLabel(t), callOf(t)]),\n ...agentNames.map((n) => [\"\", \"\", n, \"\"]),\n ],\n specs,\n );\n return tasks.map((t) =>\n rowOf(\n t.key,\n line(\n [t.id, statusText(t.status, t.substate), ownerLabel(t), callOf(t), t.title],\n [\"id\", statusRole(t.status, t.substate), \"muted\", callRole(t), undefined],\n ),\n { drill: { kind: \"notes\", workstream: t.workstream, id: t.id, title: t.title } },\n ),\n );\n}\n\nfunction edgeNotes(e: DashboardEdge): string {\n const notes = [\n e.again ? \"again, listed above\" : \"\",\n e.kids > 0 ? `+${e.kids} open` : \"\",\n e.closed > 0 ? `${e.closed} closed` : \"\",\n e.cap_cut > 0 ? `${e.cap_cut} cut by cap` : \"\",\n ].filter((n) => n !== \"\");\n return notes.length > 0 ? ` (${notes.join(\", \")})` : \"\";\n}\n\n/** A cut notice: a row in the warning role that `dagRows` never filters out. */\nconst notice = (key: string, text: string): Row => rowOf(key, [{ text, role: \"warn\" }]);\n\n/** The id cell carries the tree indent: the protected column that shows the shape. */\nconst edgeId = (e: DashboardEdge): string => `${\" \".repeat(e.depth)}${e.id}`;\n\n/**\n * The open DAG of one workstream, preorder. The text filter hides entry lines\n * (an entry's parent may vanish: the line keeps its indent); the status filter\n * does not apply (the DAG is the OPEN work and its frontier by definition). Cuts\n * are ALWAYS listed, per-entry ones included (a hidden entry leaves a notice): a\n * filter must not hide that open work was left out.\n */\nfunction dagRows(snap: DashboardSnapshot, ws: string | null, f: Filter): Row[] {\n const rows: Row[] = [];\n const mine = snap.edges.filter((e) => e.workstream === ws);\n const specs = [protect(0, 40), fixed(STATUS_WIDTH), CLIP];\n const line = layoutRows(\n mine.map((e) => [edgeId(e), \"\", \"\"]),\n specs,\n );\n for (const e of mine) {\n if (matches(f.text, e.key, e.title, e.substate)) {\n rows.push(\n rowOf(\n `${e.parent ?? \"\"}>${e.key}`,\n [\n ...line(\n [edgeId(e), statusText(e.status, e.substate), e.title],\n [\"id\", statusRole(e.status, e.substate), undefined],\n ),\n ...(edgeNotes(e) === \"\" ? [] : [{ text: edgeNotes(e), role: \"muted\" as const }]),\n ],\n { drill: { kind: \"notes\", workstream: e.workstream, id: e.id, title: e.title } },\n ),\n );\n } else if (e.cap_cut > 0) {\n // Its line is filtered out, and the line is the only place its cap cut was\n // said: keep the warning as a notice naming the entry.\n rows.push(\n notice(\n `cut:cap:${e.key}`,\n `… ${e.cap_cut} open task${e.cap_cut === 1 ? \"\" : \"s\"} under ${e.id} left out by the node cap`,\n ),\n );\n }\n }\n const cut = snap.frontier.find((c) => c.workstream === ws);\n if (cut !== undefined && cut.roots_cut > 0) {\n rows.push(\n notice(\n \"cut:roots\",\n `… ${cut.roots_cut} open start task${cut.roots_cut === 1 ? \"\" : \"s\"} left out by the node cap`,\n ),\n );\n }\n if (cut !== undefined && cut.again_cut > 0) {\n rows.push(\n notice(\n \"cut:again\",\n `… ${cut.again_cut} repeat line${cut.again_cut === 1 ? \"\" : \"s\"} left out by the node cap`,\n ),\n );\n }\n return rows;\n}\n\n/** Running tool + elapsed; `-` = none running; an agent whose tool is not reported is `?` (unknown), never \"none\". */\nfunction toolText(a: DashboardAgent, now: number): string {\n if (a.tool === undefined) return \"tool ?\";\n if (a.tool === null) return \"tool -\";\n const ms = a.tool.elapsed_ms ?? now - a.tool.since;\n return `${a.tool.name} ${formatElapsed(ms)}`;\n}\n\nfunction agentRows(snap: DashboardSnapshot, ws: string | null, f: Filter, now: number): Row[] {\n const mine = snap.agents.filter((a) => a.workstream === ws);\n const agents = mine.filter((a) => matches(f.text, a.key, a.state, a.tool?.name, ...a.tasks));\n // The tab shows one workstream: a bare name, the host in its own column (`local` =\n // none), and a task of another workstream keeps its qualifier.\n const taskOf = (a: DashboardAgent): string =>\n a.task === null\n ? \"-\"\n : a.task.startsWith(`${a.workstream}/`)\n ? a.task.slice(a.workstream.length + 1)\n : a.task;\n const specs = [protect(0, 32), fixed(HOST_WIDTH), fixed(STATE_WIDTH), protect(0, 32), CLIP];\n const line = layoutRows(\n // The task column is as wide as the workstream's task ids, not just the tasks owned\n // right now: an agent claiming or finishing a task must not move the tool column.\n [\n ...mine.map((a) => [a.name, \"\", \"\", taskOf(a)]),\n ...snap.tasks.filter((t) => t.workstream === ws).map((t) => [\"\", \"\", \"\", t.id]),\n ],\n specs,\n );\n // Trouble is coloured from the attention list, the one place that decides what is dead or stalled.\n const flagged = (kind: string, key: string): boolean =>\n snap.attention.some((x) => x.kind === kind && x.target === key);\n return agents.map((a) =>\n rowOf(\n a.key,\n line(\n [a.name, a.host ?? LOCAL, a.state ?? \"?\", taskOf(a), toolText(a, now)],\n [\n \"id\",\n \"muted\",\n flagged(\"dead\", a.key) ? \"bad\" : agentStateRole(a.state),\n \"muted\",\n flagged(\"stalled\", a.key) ? \"warn\" : \"muted\",\n ],\n ),\n { drill: scrollbackOf(a) },\n ),\n );\n}\n\nconst timeOf = (iso: string): string => /T(\\d\\d:\\d\\d:\\d\\d)/.exec(iso)?.[1] ?? iso;\n\n/** The log is one workstream's (the data layer reads it so), so there is no scope column. */\nfunction logRows(snap: DashboardSnapshot, ws: string | null, f: Filter): Row[] {\n const mine = snap.log.filter((l) => l.scope === ws);\n const specs: ColumnSpec[] = [{ kind: \"protect\", align: \"right\" }, fixed(TIME_WIDTH), CLIP];\n const line = layoutRows(\n mine.map((l) => [String(l.seq), \"\", \"\"]),\n specs,\n );\n return mine\n .filter((l) => matches(f.text, l.rendered, l.actor, l.scope))\n .map((l) => {\n const head = line([String(l.seq), timeOf(l.created_at), \"\"], [\"muted\", \"muted\", undefined]);\n return rowOf(String(l.seq), [...head, { text: \" \".repeat(GUTTER) }, ...logProse(l)], {\n drill: { kind: \"log\", item: l },\n });\n });\n}\n\n/** Every verb `renderOpLine` can start a line with, longest first (a prefix never shadows a longer verb). */\nconst LOG_VERBS = [...KNOWN_VERBS, \"task status\", \"op put\", \"op del\", \"op\"].sort(\n (a, b) => b.length - a.length,\n);\n\n/** A log line's prose with its verb in the verb role (3.x log card); operator prose (no intent) stays plain. */\nfunction logProse(l: DashboardLogItem): Seg[] {\n const text = clean(l.rendered);\n const verb = l.intent ? LOG_VERBS.find((v) => text === v || text.startsWith(`${v} `)) : undefined;\n if (verb === undefined) return [{ text }];\n return [\n { text: verb, role: \"verb\" },\n ...(text.length > verb.length ? [{ text: text.slice(verb.length) }] : []),\n ];\n}\n\n/** One attention item as a line: another workstream's is qualified, bare names otherwise. */\nfunction attentionLabel(a: DashboardAttention, ws: string | null): string {\n const where = a.workstream !== null && a.workstream !== ws ? `${a.workstream}/` : \"\";\n return `${where}${a.kind === \"human\" ? `human: ${a.text}` : a.text}`;\n}\n\n/** The attention strip (every view): `✓ all quiet` green, else the count and each item in its role. */\nexport function attentionStrip(attention: readonly DashboardAttention[], ws: string | null): Line {\n if (attention.length === 0) return [{ text: \"✓ all quiet\", role: \"good\" }];\n return [\n { text: `⚠ ${attention.length} need you: `, role: \"warn\" },\n ...attention.flatMap((a, i): Seg[] => [\n ...(i > 0 ? [{ text: \" · \", role: \"muted\" as const }] : []),\n { text: attentionLabel(a, ws), role: attentionRole(a) },\n ]),\n ];\n}\n\n/** 3.x attention colours: a dead agent (or a failed delegate call) red, everything else that needs you yellow. */\nconst attentionRole = (a: DashboardAttention): Role =>\n a.kind === \"dead\" || (a.kind === \"delegate\" && a.text.startsWith(\"delegate failed\"))\n ? \"bad\"\n : \"warn\";\n\n/** The Overview's cursor stops: every attention item (all workstreams), Enter opens its agent or task. */\nfunction attentionRows(snap: DashboardSnapshot, ws: string | null): Row[] {\n return snap.attention.map((a) => {\n const agent = snap.agents.find((x) => x.key === a.target);\n // A task item's task comes from the item itself: snap.tasks is the shown workstream's only.\n const id =\n a.kind === \"human\" || a.kind === \"delegate\"\n ? a.target?.slice((a.workstream?.length ?? 0) + 1)\n : undefined;\n const drill: DrillTarget | undefined = agent\n ? scrollbackOf(agent)\n : a.workstream !== null && id\n ? { kind: \"notes\", workstream: a.workstream, id, title: a.text }\n : undefined;\n return rowOf(\n a.key,\n [{ text: attentionLabel(a, ws), role: attentionRole(a) }],\n drill ? { drill } : {},\n );\n });\n}\n\n/** `refute-ws 5 calls 2 CONFIRMED 1 REFUTED 2 pending (1 refused)`: zero counts left out. */\nexport function waveText(w: DashboardWave): string {\n const parts = [\n `${w.calls} call${w.calls === 1 ? \"\" : \"s\"}`,\n w.confirmed > 0 ? `${w.confirmed} CONFIRMED` : \"\",\n w.refuted > 0 ? `${w.refuted} REFUTED` : \"\",\n w.unverified > 0 ? `${w.unverified} UNVERIFIED` : \"\",\n w.pending > 0 ? `${w.pending} pending${w.refused > 0 ? ` (${w.refused} refused)` : \"\"}` : \"\",\n ].filter((p) => p !== \"\");\n return parts.join(\" \");\n}\n\n/** The shown workstream's recent waves (Overview's Waves card), newest first; read-only. */\nexport function waveRows(snap: DashboardSnapshot, ws: string | null): Row[] {\n const mine = snap.waves.filter((w) => w.workstream === ws);\n const line = layoutRows(\n mine.map((w) => [w.wave, \"\"]),\n [protect(0, 32), CLIP],\n );\n return mine.map((w) =>\n rowOf(\n w.key,\n line(\n [w.wave, waveText(w)],\n [\"id\", w.refused > 0 ? \"warn\" : w.pending > 0 ? \"progress\" : \"muted\"],\n ),\n ),\n );\n}\n\n/** Every tab shows the selected workstream only (scratch included, like any other). */\nexport function tabRows(\n tab: TabId,\n snap: DashboardSnapshot,\n ws: string | null,\n f: Filter,\n now: number,\n): Row[] {\n switch (tab) {\n case \"overview\":\n return attentionRows(snap, ws);\n case \"tasks\":\n return taskRows(snap, ws, f);\n case \"dag\":\n return dagRows(snap, ws, f);\n case \"agents\":\n return agentRows(snap, ws, f, now);\n case \"log\":\n return logRows(snap, ws, f);\n }\n}\n\n/**\n * Index of the cursor: its key when still listed. A key that left the list (closed,\n * deleted, filtered) lands on its neighbour: `was`, the index it last had, clamped.\n * No key: the tab default (Log: the newest row).\n */\nexport function cursorIndex(\n rows: readonly Row[],\n key: string | null,\n tab: TabId,\n was?: number,\n): number {\n const i = key === null ? -1 : rows.findIndex((r) => r.key === key);\n if (i >= 0) return i;\n if (key !== null && was !== undefined) return Math.max(0, Math.min(was, rows.length - 1));\n return tab === \"log\" ? Math.max(0, rows.length - 1) : 0;\n}\n\n/** The key `delta` rows from the cursor (clamped); null for no rows. */\nexport function moveCursor(\n rows: readonly Row[],\n key: string | null,\n tab: TabId,\n delta: number,\n was?: number,\n): string | null {\n if (rows.length === 0) return null;\n const i = Math.max(0, Math.min(rows.length - 1, cursorIndex(rows, key, tab, was) + delta));\n return rows[i]?.key ?? null;\n}\n","// The dashboard's ONE poll loop (3.x `useDashboardSnapshot`, v3.13.3 state.ts), owned\n// by <App> and kept running while a drill is open so every view shares its cadence:\n//\n// FAST tier every `tickMs` (default 1 s, +/- live: 100 ms .. 10 s): SQL only, agent\n// states from the slow tier's cache (runtime.ts).\n// SLOW tier every SLOW_TICK_MS (10 s): the same read, re-probing every agent's state\n// (control socket, gate pane). `refresh()` (r / F5) runs it now.\n//\n// Flicker guard, as 3.x:\n// (A) a snapshot whose key (its visible content, `snapshotKey`) equals the published\n// one is dropped: no setState, the same data reference, no re-render;\n// (B) `nonce` moves ONLY when that key changes: drills depend on it to re-read;\n// `slowNonce` moves after every slow read (pane captures ride on it);\n// (C) nothing else is preloaded on the fast tick.\n//\n// Ticks never overlap: the next one is scheduled after the previous settled (the\n// runtime is single-flight too). `pollMs: null` loads once (tests, a static render).\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { DashboardSnapshot } from \"../../dashboard-data.js\";\nimport type { DashboardQuery, DashboardRuntime } from \"./runtime.js\";\n\n/** The slow tier's gap (3.x SLOW_TICK_MS). */\nexport const SLOW_TICK_MS = 10_000;\nexport const TICK_FLOOR_MS = 100;\nexport const TICK_CEILING_MS = 10_000;\n\n/** A tick inside [floor, ceiling]. */\nexport const clampTick = (ms: number): number =>\n Math.max(TICK_FLOOR_MS, Math.min(TICK_CEILING_MS, ms));\n/** `+`: halve the fast tick (floor 100 ms). */\nexport const fasterTick = (ms: number): number => clampTick(Math.floor(ms / 2));\n/** `-`: double it (ceiling 10 s). */\nexport const slowerTick = (ms: number): number => clampTick(ms * 2);\n\n/**\n * What a snapshot shows, as one string: two snapshots with the same key render the\n * same frame. A running tool's elapsed time counts in whole seconds, the unit shown.\n */\nexport const snapshotKey = (s: DashboardSnapshot): string =>\n JSON.stringify(s, (k, v: unknown) =>\n k === \"elapsed_ms\" && typeof v === \"number\" ? Math.floor(v / 1000) : v,\n );\n\nexport interface SnapshotState {\n loading: boolean;\n /** The last refresh's failure; a later success clears it. */\n error: string | null;\n /** The last good snapshot, kept across a failed refresh. */\n snapshot: DashboardSnapshot | null;\n /** The snapshot was read for an older query than the current one (a filter just changed). */\n stale: boolean;\n /** Moves only when the published snapshot's key changes (flicker guard B). */\n nonce: number;\n /** Moves after every slow-tier read (agent state re-probed): pane captures follow it. */\n slowNonce: number;\n /** Run the slow tier now (r / F5; a tab switch). Never stacks a second read. */\n refresh(): void;\n}\n\ninterface Published {\n loading: boolean;\n error: string | null;\n snapshot: DashboardSnapshot | null;\n /** The query the snapshot was read for. */\n key: string;\n nonce: number;\n slowNonce: number;\n}\n\nexport function useSnapshot(\n runtime: DashboardRuntime,\n query: DashboardQuery,\n pollMs: number | null,\n slowMs: number = SLOW_TICK_MS,\n): SnapshotState {\n const [state, setState] = useState<Published>({\n loading: true,\n error: null,\n snapshot: null,\n key: \"\",\n nonce: 0,\n slowNonce: 0,\n });\n // The query is a value, not an identity: re-run only when its content changes.\n const queryKey = JSON.stringify(query);\n const wake = useRef<(() => void) | null>(null);\n const forceSlow = useRef(false);\n const published = useRef(\"\");\n // Survives a query change (a filter, the first workstream pick): only the clock or r runs the slow tier.\n const lastSlow = useRef(Number.NEGATIVE_INFINITY);\n\n useEffect(() => {\n let cancelled = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const q = JSON.parse(queryKey) as DashboardQuery;\n const loop = async (): Promise<void> => {\n while (!cancelled) {\n const slow = forceSlow.current || Date.now() - lastSlow.current >= slowMs;\n forceSlow.current = false;\n if (slow) lastSlow.current = Date.now();\n try {\n const r = await runtime.refresh(q, { slow });\n if (cancelled) return;\n const key = `${queryKey}\\u0000${snapshotKey(r.snapshot)}`;\n const changed = key !== published.current;\n published.current = key;\n if (changed || slow)\n setState((s) => {\n const next = {\n ...s,\n loading: false,\n error: null,\n key: queryKey,\n slowNonce: slow ? s.slowNonce + 1 : s.slowNonce,\n };\n if (!changed && s.error === null && !s.loading)\n return { ...next, snapshot: s.snapshot };\n return { ...next, snapshot: r.snapshot, nonce: s.nonce + 1 };\n });\n else\n setState((s) =>\n // Byte-equal and nothing to clear: the same state object, no re-render.\n s.error === null && !s.loading ? s : { ...s, loading: false, error: null },\n );\n } catch (err) {\n if (cancelled) return;\n const error = err instanceof Error ? err.message : String(err);\n setState((s) => (s.error === error && !s.loading ? s : { ...s, loading: false, error }));\n }\n if (pollMs === null) return;\n await new Promise<void>((resolve) => {\n timer = setTimeout(resolve, pollMs);\n wake.current = resolve;\n });\n wake.current = null;\n }\n };\n void loop();\n return () => {\n cancelled = true;\n if (timer !== undefined) clearTimeout(timer);\n wake.current?.();\n };\n }, [runtime, queryKey, pollMs, slowMs]);\n\n const refresh = useCallback(() => {\n forceSlow.current = true;\n wake.current?.();\n }, []);\n const { key, ...rest } = state;\n return { ...rest, stale: state.snapshot !== null && key !== queryKey, refresh };\n}\n","// Dashboard lifecycle, outside render. TWO connections, by design:\n//\n// - `ro`: a `readonly: true` connection. Every projection (`loadDashboard`)\n// runs here, so the UI can never write.\n// - `syncDb`: a WRITABLE connection owned by the caller (the launcher's\n// `handle()`, which also ran the DB-inside-MU_SYNC_DIR / sync/v1 refusals).\n// A read-only connection cannot ingest peer ops (\"attempt to write a\n// readonly database\"), so ambient sync runs here and only here.\n//\n// Sync is bounded: at most one refresh in flight (callers share its promise),\n// ingest at most every `syncEveryMs` (never on each repaint), always `quiet`\n// (a stderr write would paint over the alternate screen; warnings come back in\n// the result), no reconcile, no reap. `close()` waits for the in-flight\n// refresh and closes `ro`. The final flush is not here: the launcher's single\n// idempotent shutdown (`src/cli/dashboard-shutdown.ts`) runs it after every\n// step, on q/Esc, signals and boot errors alike.\n\nimport type { StateReading } from \"../../agent-state.js\";\nimport {\n type DashboardOptions,\n type DashboardSnapshot,\n loadDashboard,\n} from \"../../dashboard-data.js\";\nimport { type Db, openDb } from \"../../db.js\";\nimport { ambientIngest, syncEnabled } from \"../../sync.js\";\nimport { getTask, type SelectedNotes, selectTaskNotes, type TaskRow } from \"../../tasks.js\";\nimport { currentCallers } from \"../../wait-callers.js\";\n\n/** One refresh: the projection plus whatever sync said while producing it. */\nexport interface RefreshResult {\n snapshot: DashboardSnapshot;\n /** The latest ingest's non-fatal sync problems (kept until the next ingest replaces them). */\n warnings: readonly string[];\n}\n\nexport type DashboardQuery = Omit<DashboardOptions, \"caller\">;\n\nexport interface RefreshOptions {\n /**\n * The slow tier: re-probe every agent's state (control socket, gate pane). Without it\n * the read is SQL only, agent states coming from the last slow read (an agent never\n * probed yet is probed once). 3.x's fast/slow tiers, merged by this cache.\n */\n slow?: boolean;\n}\n\nexport interface DashboardRuntime {\n /** Ingest if due, then project. Concurrent calls with the same query and tier share one run. */\n refresh(query?: DashboardQuery, opts?: RefreshOptions): Promise<RefreshResult>;\n /** A task's notes (the CLI's default selection, or all of them), read on `ro`. */\n notes(workstream: string, id: string, all: boolean): SelectedNotes;\n /** A task's row (the notes drill's live header), read on `ro`; undefined when gone. */\n task(workstream: string, id: string): TaskRow | undefined;\n /** Drain the in-flight refresh, close `ro`. Idempotent. */\n close(): Promise<void>;\n}\n\nexport interface RuntimeOptions {\n dbPath: string;\n /** The caller's writable connection; used for sync only, never closed here. */\n syncDb: Db;\n /** `spawnerFromEnv()`; null for a human shell. */\n caller: string | null;\n /** Who `next` is computed for; default `currentCallers()`. */\n callers?: readonly string[];\n /** Minimum gap between ingests (default 10 s). */\n syncEveryMs?: number;\n /** Clock seam for tests. */\n now?: () => number;\n}\n\nconst DEFAULT_SYNC_EVERY_MS = 10_000;\n\nexport function createRuntime(opts: RuntimeOptions): DashboardRuntime {\n const ro = openDb({ path: opts.dbPath, readonly: true });\n const now = opts.now ?? Date.now;\n const every = opts.syncEveryMs ?? DEFAULT_SYNC_EVERY_MS;\n let inflight: Promise<RefreshResult> | null = null;\n let inflightQuery = \"\";\n let lastSync = Number.NEGATIVE_INFINITY;\n // The last ingest's warnings: replaced when an ingest runs, never cleared by a read,\n // so the `sync` attention item stays while the problem does.\n let warnings: readonly string[] = [];\n // `latest_seq` costs one log scan per workstream and only ranks the starting pick, so it\n // is read when the set of live workstreams changed (the first read, a teardown), not per tick.\n let seenNames = \"\";\n let closed = false;\n // The slow tier's agent readings, merged into every fast read.\n const agentStates = new Map<string, StateReading>();\n\n async function run(query: DashboardQuery, slow: boolean): Promise<RefreshResult> {\n if (syncEnabled() && now() - lastSync >= every) {\n lastSync = now();\n warnings = (await ambientIngest(opts.syncDb, { quiet: true })).warnings;\n }\n const names = (\n ro.prepare(\"SELECT name FROM workstreams WHERE torn_down_at IS NULL ORDER BY name\").all() as {\n name: string;\n }[]\n )\n .map((w) => w.name)\n .join(\"\\n\");\n const activity = names !== seenNames;\n seenNames = names;\n const snapshot = await loadDashboard(ro, {\n ...query,\n activity,\n caller: opts.caller,\n callers: opts.callers ?? currentCallers(),\n syncWarnings: warnings,\n agentStates: { cache: agentStates, probe: slow },\n });\n return { snapshot, warnings };\n }\n\n return {\n refresh(query = {}, { slow = false } = {}) {\n if (closed) return Promise.reject(new Error(\"dashboard runtime is closed\"));\n const key = `${slow ? \"slow\" : \"fast\"}:${JSON.stringify(query)}`;\n // Same query: share the run. A different one (the user changed a filter)\n // waits for the in-flight run, then runs: never two at once, never a\n // result for the wrong query.\n if (inflight !== null && inflightQuery === key) return inflight;\n const prior = inflight?.catch(() => undefined) ?? Promise.resolve();\n inflightQuery = key;\n const mine: Promise<RefreshResult> = prior\n .then(() => run(query, slow))\n .finally(() => {\n if (inflight === mine) inflight = null;\n });\n inflight = mine;\n return mine;\n },\n notes(workstream, id, all) {\n if (closed) throw new Error(\"dashboard runtime is closed\");\n return selectTaskNotes(ro, id, { workstream, all });\n },\n task(workstream, id) {\n if (closed) throw new Error(\"dashboard runtime is closed\");\n return getTask(ro, id, workstream);\n },\n async close() {\n if (closed) return;\n closed = true;\n try {\n await inflight?.catch(() => undefined);\n } finally {\n ro.close();\n }\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,SAAwB,cAAc;AACtC,SAAS,qBAAqB;;;ACG9B,SAAS,OAAAA,MAAK,QAAAC,OAAM,QAAQ,YAAAC,WAAU,UAAU,aAAAC,YAAW,iBAAAC,sBAAqB;AAChF,SAAS,aAAAC,YAAW,UAAAC,SAAQ,YAAAC,iBAAgB;;;ACT7B,SAAR,UAA2B,EAAC,YAAY,MAAK,IAAI,CAAC,GAAG;AAE3D,QAAM,KAAK;AAIX,QAAM,MAAM,yCAAyC,EAAE;AAGvD,QAAM,MAAM;AAEZ,QAAM,UAAU,GAAG,GAAG,IAAI,GAAG;AAE7B,SAAO,IAAI,OAAO,SAAS,YAAY,SAAY,GAAG;AACvD;;;ACZA,IAAM,QAAQ,UAAU;AAET,SAAR,UAA2B,QAAQ;AACzC,MAAI,OAAO,WAAW,UAAU;AAC/B,UAAM,IAAI,UAAU,gCAAgC,OAAO,MAAM,IAAI;AAAA,EACtE;AAGA,MAAI,CAAC,OAAO,SAAS,MAAQ,KAAK,CAAC,OAAO,SAAS,MAAQ,GAAG;AAC7D,WAAO;AAAA,EACR;AAKA,SAAO,OAAO,QAAQ,OAAO,EAAE;AAChC;;;AChBO,IAAM,4BAA4B;AAClC,IAAM,4BAA4B;AAClC,IAAM,kBAAkB,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,SAAS,SAAS,OAAO;AAE5jE,IAAM,4BAA4B;AAClC,IAAM,4BAA4B;AAClC,IAAM,kBAAkB,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAUjE,IAAM,uBAAuB;AAC7B,IAAM,uBAAuB;AAC7B,IAAM,aAAa,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,MAAM;;;ACbrzD,IAAM,YAAY,CAAC,QAAQ,cAAc;AAC/C,MAAI,MAAM;AACV,MAAI,OAAO,KAAK,MAAM,OAAO,SAAS,CAAC,IAAI;AAC3C,SAAO,OAAO,MAAM;AACnB,UAAM,MAAM,KAAK,OAAO,MAAM,QAAQ,CAAC;AACvC,UAAM,IAAI,MAAM;AAChB,QAAI,YAAY,OAAO,CAAC,GAAG;AAC1B,aAAO,MAAM;AAAA,IACd,WAAW,YAAY,OAAO,IAAI,CAAC,GAAG;AACrC,YAAM,MAAM;AAAA,IACb,OAAO;AACN,aAAO;AAAA,IACR;AAAA,EACD;AAEA,SAAO;AACR;;;ACAA,IAAM,qBAAqB;AAC3B,IAAM,CAAC,mBAAmB,eAAe,IAAoB,sCAAsB,UAAU;AAK7F,SAAS,sBAAsB,QAAQ;AACtC,MAAI,gBAAgB,OAAO,CAAC;AAC5B,MAAI,cAAc,OAAO,CAAC;AAE1B,WAAS,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;AACtD,UAAM,QAAQ,OAAO,KAAK;AAC1B,UAAM,MAAM,OAAO,QAAQ,CAAC;AAE5B,QACC,sBAAsB,SACnB,sBAAsB,KACxB;AACD,aAAO,CAAC,OAAO,GAAG;AAAA,IACnB;AAEA,QAAK,MAAM,QAAU,cAAc,eAAgB;AAClD,sBAAgB;AAChB,oBAAc;AAAA,IACf;AAAA,EACD;AAEA,SAAO,CAAC,eAAe,WAAW;AACnC;AAEO,IAAM,cAAc,eAAa;AACvC,MACC,YAAY,6BACT,YAAY,2BACd;AACD,WAAO;AAAA,EACR;AAEA,SAAO,UAAU,iBAAiB,SAAS;AAC5C;AAEO,IAAM,cAAc,eAAa;AACvC,MACC,YAAY,6BACT,YAAY,2BACd;AACD,WAAO;AAAA,EACR;AAEA,SAAO,UAAU,iBAAiB,SAAS;AAC5C;AAwBO,IAAM,SAAS,eAAa;AAClC,MACC,aAAa,qBACV,aAAa,iBACf;AACD,WAAO;AAAA,EACR;AAEA,MACC,YAAY,wBACT,YAAY,sBACd;AACD,WAAO;AAAA,EACR;AAEA,SAAO,UAAU,YAAY,SAAS;AACvC;;;AC/GA,SAAS,SAAS,WAAW;AAC5B,MAAI,CAAC,OAAO,cAAc,SAAS,GAAG;AACrC,UAAM,IAAI,UAAU,gCAAgC,OAAO,SAAS,KAAK;AAAA,EAC1E;AACD;AAQO,SAAS,eAAe,WAAW,EAAC,kBAAkB,MAAK,IAAI,CAAC,GAAG;AACzE,WAAS,SAAS;AAElB,MACC,YAAY,SAAS,KAClB,OAAO,SAAS,KACf,mBAAmB,YAAY,SAAS,GAC3C;AACD,WAAO;AAAA,EACR;AAEA,SAAO;AACR;;;ACXA,IAAM,YAAY,IAAI,KAAK,UAAU;AAIrC,IAAM,wBAAwB,WAAC,oHAA2G,GAAC;AAC3I,IAAM,mBAAmB,WAAC,qBAAiB,GAAC;AAG5C,IAAM,gBAAgB,WAAC,oBAAgB,GAAC;AAGxC,IAAM,yBAAyB;AAC/B,IAAM,4BAA4B,WAAC,8BAA0B,IAAE;AAE/D,SAAS,iCAAiC,SAAS;AAElD,MAAI,QAAQ,SAAS,IAAI;AACxB,WAAO;AAAA,EACR;AAEA,MAAI,uBAAuB,KAAK,OAAO,GAAG;AACzC,WAAO;AAAA,EACR;AAGA,MAAI,QAAQ,SAAS,QAAQ,GAAG;AAC/B,UAAM,gBAAgB,QAAQ,MAAM,yBAAyB;AAC7D,WAAO,kBAAkB,QAAQ,cAAc,UAAU;AAAA,EAC1D;AAEA,SAAO;AACR;AAGA,SAAS,YAAY,SAAS;AAC7B,QAAM,QAAQ,QAAQ,OAAO,qBAAqB;AAClD,SAAO,UAAU,KAAK,SAAY,QAAQ,MAAM,KAAK;AACtD;AAEA,SAAS,oBAAoB,WAAW;AACvC,SAAQ,aAAa,QAAW,aAAa,QACxC,aAAa,SAAW,aAAa;AAC3C;AAEA,SAAS,kBAAkB,WAAW;AACrC,SAAQ,aAAa,QAAW,aAAa,QACxC,aAAa,SAAW,aAAa;AAC3C;AAEA,SAAS,qBAAqB,WAAW;AACxC,SAAQ,aAAa,QAAW,aAAa,QACxC,aAAa,SAAW,aAAa;AAC3C;AAEA,SAAS,aAAa,WAAW;AAChC,SAAO,oBAAoB,SAAS,KAChC,kBAAkB,SAAS,KAC3B,qBAAqB,SAAS;AACnC;AAEA,SAAS,mBAAmB,gBAAgB,uBAAuB;AAClE,QAAM,aAAa,CAAC;AAEpB,aAAW,aAAa,gBAAgB;AACvC,QAAI,CAAC,sBAAsB,KAAK,SAAS,GAAG;AAC3C;AAAA,IACD;AAEA,eAAW,KAAK,UAAU,YAAY,CAAC,CAAC;AAAA,EACzC;AAEA,MAAI,WAAW,WAAW,GAAG;AAC5B,WAAO;AAAA,EACR;AAEA,MAAI,QAAQ;AAEZ,WAAS,QAAQ,GAAG,QAAQ,WAAW,QAAQ,SAAS;AACvD,UAAM,YAAY,WAAW,KAAK;AAClC,QAAI,CAAC,aAAa,SAAS,GAAG;AAC7B,UAAI,UAAU,GAAG;AAChB,eAAO;AAAA,MACR;AAGA,eAAS,YAAY,OAAO,YAAY,WAAW,QAAQ,aAAa;AACvE,iBAAS,eAAe,WAAW,SAAS,GAAG,qBAAqB;AAAA,MACrE;AAEA,aAAO;AAAA,IACR;AAIA,QACC,oBAAoB,SAAS,KAC1B,kBAAkB,WAAW,QAAQ,CAAC,CAAC,GACzC;AACD,eAAS;AACT,eAAS,qBAAqB,WAAW,QAAQ,CAAC,CAAC,IAAI,IAAI;AAC3D;AAAA,IACD;AAEA,aAAS,eAAe,WAAW,qBAAqB;AAAA,EACzD;AAEA,SAAO;AACR;AAEA,SAAS,cAAc,gBAAgB,uBAAuB;AAC7D,MAAI,QAAQ;AACZ,MAAI,QAAQ;AAEZ,aAAW,aAAa,gBAAgB;AACvC,QAAI,OAAO;AACV,cAAQ;AACR;AAAA,IACD;AAEA,QACC,iBAAiB,KAAK,SAAS,KAC3B,aAAa,YAAY,aAAa,UACzC;AACD,eAAS,eAAe,UAAU,YAAY,CAAC,GAAG,qBAAqB;AAAA,IACxE;AAAA,EACD;AAEA,SAAO;AACR;AAEe,SAAR,YAA6B,OAAO,UAAU,CAAC,GAAG;AACxD,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAAG;AACpD,WAAO;AAAA,EACR;AAEA,QAAM;AAAA,IACL,oBAAoB;AAAA,IACpB,uBAAuB;AAAA,EACxB,IAAI;AAEJ,MAAI,SAAS;AAGb,MAAI,CAAC,yBAAyB,OAAO,SAAS,MAAQ,KAAK,OAAO,SAAS,MAAQ,IAAI;AACtF,aAAS,UAAU,MAAM;AAAA,EAC1B;AAEA,MAAI,OAAO,WAAW,GAAG;AACxB,WAAO;AAAA,EACR;AAGA,MAAI,qBAAqB,KAAK,MAAM,GAAG;AACtC,WAAO,OAAO;AAAA,EACf;AAEA,MAAI,QAAQ;AACZ,QAAM,wBAAwB,EAAC,iBAAiB,CAAC,kBAAiB;AAElE,aAAW,EAAC,QAAO,KAAK,UAAU,QAAQ,MAAM,GAAG;AAElD,UAAM,iBAAiB,YAAY,OAAO;AAC1C,QAAI,mBAAmB,QAAW;AACjC;AAAA,IACD;AAGA,QAAI,cAAc,KAAK,OAAO,KAAK,iCAAiC,OAAO,GAAG;AAC7E,eAAS;AACT;AAAA,IACD;AAEA,UAAM,cAAc,mBAAmB,gBAAgB,qBAAqB;AAC5E,QAAI,gBAAgB,QAAW;AAC9B,eAAS;AACT;AAAA,IACD;AAGA,UAAM,YAAY,eAAe,YAAY,CAAC;AAC9C,aAAS,eAAe,WAAW,qBAAqB;AAGxD,aAAS,cAAc,gBAAgB,qBAAqB;AAAA,EAC7D;AAEA,SAAO;AACR;;;AC/LA,SAAS,aAAa;AAwBtB,IAAM,UAAU,CAAC,MAAwB,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAI3E,IAAM,eAAe,MAAe,QAAQ,QAAQ,IAAI,IAAI;AAGnE,SAAS,SAAS,SAAkD;AAClE,MAAI,YAAY,OAAQ,QAAO,EAAE,OAAO,IAAI,MAAM,GAAG;AACrD,UAAQ,eAAe,GAAG;AAAA,IACxB,KAAK;AACH,aAAO,EAAE,OAAO,eAAe,MAAM,cAAc;AAAA,IACrD,KAAK;AACH,aAAO,EAAE,OAAO,qBAAqB,MAAM,oCAAoC;AAAA,IACjF,KAAK;AACH,aAAO,EAAE,OAAO,iBAAiB,MAAM,oCAAoC;AAAA,EAC/E;AACF;AAGA,eAAsB,gBAAiC;AACrD,MAAI;AACF,UAAM,EAAE,MAAM,IAAI,UAAU,MAAM,UAAU,GAAG,IAAI;AACnD,WAAO,UAAU,KAAK,aAAa,aAAa,KAAK;AAAA,EACvD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,eAAsB,WAAW,GAAuC;AACtE,MAAI;AACF,UAAM,MAAM,MAAM,UAAU;AAC5B,UAAM,SAAS,EAAE,SAAS,MAAM,EAAE,UAAU,IAAI,QAAQ,EAAE,OAAO,EAAE,KAAK;AACxE,UAAM,SAAS,aAAa;AAC5B,UAAM,QAAQ,MAAM,IAAI,eAAe,EAAE,GAAG,QAAQ,OAAO,CAAC;AAE5D,UAAM,UAAU,MAAM,IAAI,eAAe,EAAE,GAAG,QAAQ,QAAQ,OAAO,SAAS,KAAK,CAAC;AACpF,UAAM,EAAE,KAAK,IAAI,SAAS,IAAI,IAAI;AAClC,UAAMC,UAAS,aAAa,OAAO,OAAO,IAAI,OAAO,MAAM,GAAG,SAAS,KAAK,KAAK,SAAM,IAAI,EAAE;AAC7F,WAAO,EAAE,IAAI,MAAM,OAAO,MAAM,gBAAgB,OAAO,GAAG,QAAAA,QAAO;AAAA,EACnE,SAAS,GAAG;AACV,WAAO,EAAE,IAAI,OAAO,QAAQ,QAAQ,CAAC,GAAG,MAAM,KAAK;AAAA,EACrD;AACF;AAcO,IAAM,YAAwB,CAAC,SACpC,IAAI,QAAQ,CAAC,YAAY;AACvB,MAAI,SAAS;AAEb,QAAM,MAAM,EAAE,GAAG,QAAQ,IAAI;AAC7B,MAAI,KAAK,WAAW,KAAM,QAAO,IAAI;AACrC,QAAM,QAAQ,MAAM,KAAK,SAAS,CAAC,GAAG,KAAK,IAAI,GAAG;AAAA,IAChD,OAAO,CAAC,WAAW,WAAW,MAAM;AAAA,IACpC;AAAA,EACF,CAAC;AACD,QAAM,OAAO,GAAG,QAAQ,CAAC,MAAc;AACrC,cAAU,SAAS,EAAE,SAAS,GAAG,MAAM,IAAI;AAAA,EAC7C,CAAC;AACD,QAAM,GAAG,SAAS,CAAC,MAAM,QAAQ,EAAE,MAAM,MAAM,OAAO,EAAE,SAAS,OAAO,CAAC,CAAC;AAC1E,QAAM,GAAG,SAAS,CAAC,SAAS,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC;AACvD,CAAC;AAUH,IAAM,UAAU,CAAC,SAA6B,CAAC,KAAK,SAAS,GAAG,KAAK,IAAI,EAAE,IAAI,SAAS,EAAE,KAAK,GAAG;AAGlG,eAAsB,UACpB,OACA,KACuB;AACvB,QAAM,WAAqB,CAAC;AAC5B,aAAW,QAAQ,OAAO;AACxB,QAAI;AACJ,QAAI;AACF,UAAI,MAAM,IAAI,IAAI;AAAA,IACpB,SAAS,GAAG;AACV,UAAI,EAAE,MAAM,MAAM,OAAO,QAAQ,CAAC,GAAG,QAAQ,GAAG;AAAA,IAClD;AACA,QAAI,EAAE,SAAS,EAAG;AAClB,UAAM,MACJ,EAAE,SAAS,QAAQ,EAAE,QAAQ,GAAG,GAAG,EAAE,OAAO,KAAK,MAAM,KAAK,KAAK,KAAK,EAAE,OAAO,KAAK,CAAC,EAAE;AACzF,QAAI,KAAK,aAAa,MAAM;AAC1B,eAAS,KAAK,GAAG,KAAK,UAAU,QAAQ,IAAI,CAAC,KAAK,GAAG,GAAG;AACxD;AAAA,IACF;AACA,WAAO,EAAE,IAAI,OAAO,QAAQ,GAAG,QAAQ,IAAI,CAAC,YAAY,GAAG,KAAK,SAAS;AAAA,EAC3E;AACA,SAAO,EAAE,IAAI,MAAM,SAAS;AAC9B;AAGO,IAAM,iBAAiB;AAG9B,IAAM,UAAU;AAGT,SAAS,aACd,SAC6D;AAC7D,MAAI,QAAQ,KAAK,OAAO,EAAG,QAAO,EAAE,IAAI,OAAO,KAAK,4BAA4B;AAChF,MAAI,OAAO,WAAW,OAAO,IAAI,eAAgB,QAAO,EAAE,IAAI,OAAO,KAAK,iBAAiB;AAC3F,SAAO,EAAE,IAAI,MAAM,UAAU,aAAe,OAAO,KAAK,OAAO,EAAE,SAAS,QAAQ,CAAC,OAAS;AAC9F;AAGO,SAAS,YACd,GACA,OAAsD,CAAC,GAC/C;AACR,UAAQ,EAAE,MAAM;AAAA,IACd,KAAK;AACH,aAAO,gBAAgB,UAAU,EAAE,EAAE,CAAC,OAAO,UAAU,EAAE,UAAU,CAAC,GAAG,KAAK,QAAQ,OAAO,WAAW,EAAE;AAAA,IAC1G,KAAK;AACH,aAAO,KAAK,cAAc,iBAAiB,UAAU,EAAE,IAAI,CAAC,OAAO,UAAU,EAAE,UAAU,CAAC;AAAA,IAC5F,KAAK;AACH,aAAO,wBAAwB,KAAK,IAAI,GAAG,EAAE,KAAK,MAAM,CAAC,CAAC;AAAA,EAC9D;AACF;;;AC9JA,SAAS,OAAAC,MAAK,QAAAC,OAAM,UAAU,WAAW,qBAAqB;AAC9D,SAAS,WAAW,SAAS,QAAQ,gBAAgB;;;ACNrD,SAAS,KAAK,YAAY;;;ACA1B,IAAM,UAAU;AAEhB,IAAMC,WAAU;AAGT,SAAS,MAAM,GAAmB;AACvC,SAAO,EAAE,QAAQ,SAAS,EAAE,EAAE,QAAQA,UAAS,GAAG;AACpD;AAEA,IAAMC,aAAY,IAAI,KAAK,UAAU;AAG9B,SAAS,KAAK,GAAW,OAAuB;AACrD,MAAI,SAAS,EAAG,QAAO;AACvB,QAAM,OAAO,MAAM,CAAC;AACpB,QAAM,IAAI,YAAY,IAAI;AAC1B,MAAI,KAAK,MAAO,QAAO,OAAO,IAAI,OAAO,QAAQ,CAAC;AAClD,MAAI,MAAM;AACV,MAAI,OAAO;AACX,aAAW,EAAE,QAAQ,KAAKA,WAAU,QAAQ,IAAI,GAAG;AACjD,UAAM,KAAK,YAAY,OAAO;AAC9B,QAAI,OAAO,KAAK,QAAQ,EAAG;AAC3B,WAAO;AACP,YAAQ;AAAA,EACV;AACA,SAAO,GAAG,GAAG,SAAI,IAAI,OAAO,QAAQ,OAAO,CAAC,CAAC;AAC/C;AAMO,SAAS,UAAU,KAAa,UAAkB,OAAe,QAAwB;AAC9F,QAAM,IAAI,KAAK,IAAI,GAAG,MAAM;AAC5B,MAAI,OAAO;AACX,MAAI,WAAW,KAAM,QAAO;AAAA,WACnB,YAAY,OAAO,EAAG,QAAO,WAAW,IAAI;AACrD,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,QAAQ,CAAC,CAAC;AAC9C;AAMO,IAAM,WAAW,CAAC,SAAuB,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE;AAGxE,SAAS,QAAQ,MAAY,OAAsB;AACxD,MAAI,SAAS,EAAG,QAAO,CAAC;AACxB,QAAM,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,MAAM,EAAE,IAAI,EAAE,EAAE;AAC5D,QAAM,QAAQ,YAAY,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC1D,MAAI,SAAS,MAAO,QAAO,CAAC,GAAG,MAAM,EAAE,MAAM,IAAI,OAAO,QAAQ,KAAK,EAAE,CAAC;AACxE,QAAM,MAAa,CAAC;AACpB,MAAI,OAAO;AACX,aAAW,OAAO,MAAM;AACtB,QAAI,OAAO;AACX,eAAW,EAAE,QAAQ,KAAKA,WAAU,QAAQ,IAAI,IAAI,GAAG;AACrD,YAAM,KAAK,YAAY,OAAO;AAC9B,UAAI,OAAO,KAAK,QAAQ,GAAG;AACzB,YAAI,KAAK,EAAE,GAAG,KAAK,MAAM,GAAG,IAAI,SAAI,CAAC;AACrC,eAAO,CAAC,GAAG,KAAK,EAAE,MAAM,IAAI,OAAO,QAAQ,OAAO,CAAC,EAAE,CAAC;AAAA,MACxD;AACA,cAAQ;AACR,cAAQ;AAAA,IACV;AACA,QAAI,KAAK,EAAE,GAAG,KAAK,KAAK,CAAC;AAAA,EAC3B;AACA,SAAO;AACT;;;ACzDA,IAAM,SAAS;AAAA;AAAA,EAEb,MAAM,CAAC;AAAA;AAAA,EAEP,QAAQ,EAAE,OAAO,OAAO;AAAA;AAAA,EAExB,OAAO,EAAE,OAAO,QAAQ,MAAM,KAAK;AAAA;AAAA,EAEnC,OAAO,EAAE,UAAU,KAAK;AAAA;AAAA,EAExB,IAAI,EAAE,MAAM,KAAK;AAAA;AAAA,EAEjB,QAAQ,EAAE,MAAM,KAAK;AAAA;AAAA,EAErB,MAAM,EAAE,OAAO,OAAO;AAAA;AAAA,EAEtB,SAAS,EAAE,OAAO,WAAW,MAAM,KAAK;AAAA;AAAA,EAExC,MAAM,EAAE,OAAO,OAAO;AAAA;AAAA,EAEtB,QAAQ,EAAE,OAAO,OAAO;AAAA;AAAA,EAExB,UAAU,EAAE,OAAO,SAAS;AAAA;AAAA,EAE5B,MAAM,EAAE,OAAO,QAAQ;AAAA;AAAA,EAEvB,QAAQ,EAAE,OAAO,MAAM;AAAA;AAAA,EAEvB,MAAM,EAAE,OAAO,OAAO;AAAA;AAAA,EAEtB,YAAY,EAAE,OAAO,UAAU;AAAA;AAAA,EAE/B,MAAM,EAAE,OAAO,QAAQ;AAAA;AAAA,EAEvB,MAAM,EAAE,OAAO,SAAS;AAAA;AAAA,EAExB,KAAK,EAAE,OAAO,MAAM;AACtB;AAWA,IAAM,UAAU,MAAe,QAAQ,IAAI,aAAa;AAGjD,SAAS,MAAM,OAAa,QAAmB;AACpD,QAAM,IAAe,OAAO,IAAI;AAChC,MAAI,QAAQ,KAAK,EAAE,UAAU,OAAW,QAAO;AAC/C,QAAM,EAAE,OAAO,GAAG,GAAG,KAAK,IAAI;AAC9B,SAAO;AACT;AAGO,SAAS,WAAW,QAAgB,UAAwB;AACjE,MAAI,WAAW,OAAQ,QAAO,aAAa,YAAY,aAAa,WAAW,WAAW;AAC1F,MAAI,WAAW,cAAe,QAAO;AACrC,MAAI,WAAW,UAAU;AACvB,UAAM,OAAO,aAAa,MAAM,IAAI,iBAAiB,MAAM,IAAI;AAC/D,WAAO,aAAa,MAAM,aAAa,OAAO,SAAS;AAAA,EACzD;AACA,SAAO;AACT;AAGO,SAAS,eAAe,OAAwC;AACrE,MAAI,UAAU,OAAQ,QAAO;AAC7B,MAAI,UAAU,mBAAoB,QAAO;AACzC,SAAO;AACT;AAGO,SAAS,aAAa,MAAoB;AAC/C,MAAI,SAAS,QAAS,QAAO;AAC7B,MAAI,SAAS,YAAY,SAAS,QAAS,QAAO;AAClD,MAAI,SAAS,UAAW,QAAO;AAC/B,SAAO;AACT;;;AF3CI,mBAGI,KA6CE,YAhDN;AA3CG,IAAM,eAAe;AAErB,IAAM,cAAc;AAepB,SAAS,YACd,OACA,MACA,OACA,OAC+C;AAC/C,MAAI,QAAQ,EAAG,QAAO,EAAE,MAAM,SAAI,OAAO,KAAK,IAAI,GAAG,KAAK,CAAC,GAAG,OAAO,IAAI,MAAM,GAAG;AAClF,QAAM,QAAQ,QAAQ;AACtB,QAAM,OAAO,MAAM,KAAK;AACxB,MAAI,SAAS,GAAI,QAAO,EAAE,MAAM,OAAO,SAAI,OAAO,KAAK,IAAI,OAAO,OAAO,IAAI,MAAM,GAAG;AACtF,QAAM,OAAO,KAAK,IAAI,GAAG,QAAQ,CAAC;AAClC,QAAM,QAAQ,YAAY,IAAI,KAAK,OAAO,OAAO,KAAK,MAAM,IAAI,EAAE,QAAQ;AAC1E,QAAM,OAAO,SAAI,OAAO,KAAK,IAAI,GAAG,QAAQ,IAAI,YAAY,KAAK,CAAC,CAAC;AACnE,SAAO,EAAE,MAAM,GAAG,IAAI,WAAM,OAAO,MAAM,IAAI,IAAI,GAAG,KAAK,GAAG;AAC9D;AAUO,SAAS,KAAK,EAAE,KAAK,GAA+C;AACzE,SACE,gCACG,eAAK,IAAI,CAAC,KAAK;AAAA;AAAA,IAEd,oBAAC,QAAc,GAAG,MAAM,IAAI,IAAI,GAC7B,cAAI,QADI,CAEX;AAAA,GACD,GACH;AAEJ;AAGA,SAAS,WACP,OACA,MACA,OACA,OACA,MACO;AACP,QAAM,QAAQ,UAAU,MAAM,SAAS,KAAK,GAAG,KAAK,SAAM,IAAI,KAAK,SAAS;AAC5E,QAAM,EAAE,MAAM,OAAO,KAAK,IAAI,YAAY,OAAO,MAAM,OAAO,KAAK;AACnE,QAAM,IAAI,UAAU,KAAK,IAAI,KAAK,IAAI,MAAM,QAAQ,MAAM,KAAK,EAAE,MAAM;AACvE,QAAM,MAAM,UAAU,MAAM,SAAS,KAAK,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI;AAClE,QAAM,QAAe;AAAA,IACnB,EAAE,MAAM,MAAM,MAAM,SAAS;AAAA,IAC7B,EAAE,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,QAAQ;AAAA,IACzC,EAAE,MAAM,KAAK,MAAM,SAAS;AAAA,IAC5B,EAAE,MAAM,MAAM,MAAM,IAAI,IAAI,MAAM,GAAG,MAAM,QAAQ;AAAA,IACnD,EAAE,MAAM,MAAM,MAAM,SAAS;AAAA,EAC/B;AACA,SAAO,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE;AAC1C;AAEO,SAAS,MAAM,EAAE,MAAM,UAAU,GAAG,KAAK,GAAoC;AAClF,MAAI,KAAK,SAAS,gBAAgB,KAAK,QAAQ,YAAa,QAAO;AACnE,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,SAAS,YAAY;AACnD,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,QAAQ,WAAW;AACjD,QAAM,SAAS,CAAC,MACd,OAAO,MAAM,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC,IAAK,KAAK,CAAC;AACjD,SACE,qBAAC,OAAI,eAAc,UAAS,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,YAAY,GAC9E;AAAA,wBAAC,QAAK,MAAK,YACT,8BAAC,QAAK,MAAM,WAAW,KAAK,OAAO,UAAK,UAAK,KAAK,OAAO,KAAK,YAAY,EAAE,GAAG,GACjF;AAAA,IACC,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,MAAM;AACtC,YAAM,SAAS,QAAQ,OAAO,KAAK,CAAC,CAAC,GAAG,IAAI;AAC5C;AAAA;AAAA,QAEE,qBAAC,QAAa,MAAK,YACjB;AAAA,8BAAC,QAAM,GAAG,MAAM,QAAQ,GAAG,qBAAE;AAAA,UAC5B,MAAM,WACL,oBAAC,QAAK,SAAO,MAAE,iBAAO,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAE,IAElD,oBAAC,QAAK,MAAM,QAAQ;AAAA,UAEtB,oBAAC,QAAM,GAAG,MAAM,QAAQ,GAAG,qBAAE;AAAA,aAPpB,CAQX;AAAA;AAAA,IAEJ,CAAC;AAAA,IACD,oBAAC,QAAK,MAAK,YACT,8BAAC,QAAK,MAAM,WAAW,KAAK,OAAO,UAAK,UAAK,IAAI,KAAK,UAAU,EAAE,GAAG,GACvE;AAAA,KACF;AAEJ;;;AG5GO,SAAS,OAAO,OAAe,KAAU,MAAc,QAAQ,OAAuB;AAC3F,QAAM,OAAO,KAAK,IAAI,GAAG,IAAI;AAC7B,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,CAAC,CAAC;AAC7C,MAAI,IAAI,QAAQ,UAAU,IAAK,QAAO,EAAE,IAAI,KAAK;AACjD,MAAI,IAAI,QAAQ,UAAU,IAAK,QAAO,EAAE,IAAI,CAAC,KAAK;AAClD,MAAI,IAAI,QAAQ,IAAI,KAAM,QAAO;AACjC,MAAI,IAAI,aAAa,UAAU,IAAK,QAAO,EAAE,IAAI,EAAE;AACnD,MAAI,IAAI,WAAW,UAAU,IAAK,QAAO,EAAE,IAAI,GAAG;AAClD,MAAI,IAAI,YAAa,SAAS,UAAU,IAAM,QAAO,EAAE,IAAI,KAAK;AAChE,MAAI,IAAI,OAAQ,QAAO,EAAE,IAAI,CAAC,KAAK;AACnC,MAAI,UAAU,OAAO,IAAI,KAAM,QAAO,EAAE,IAAI,MAAM;AAClD,MAAI,UAAU,OAAO,IAAI,IAAK,QAAO,EAAE,IAAI,SAAS;AACpD,SAAO;AACT;AAGO,IAAM,WAAW;;;AJmVpB,SACE,OAAAC,MADF,QAAAC,aAAA;AAnVG,IAAM,mBAAmB;AAChC,IAAM,MAAM,OAAO;AAEnB,IAAMC,aAAY,IAAI,KAAK,UAAU;AAO9B,SAAS,KAAK,MAAc,OAAyB;AAC1D,QAAM,MAAM,KAAK,IAAI,GAAG,KAAK;AAC7B,QAAM,MAAgB,CAAC;AACvB,aAAW,OAAO,KAAK,MAAM,YAAY,GAAG;AAC1C,QAAI,MAAM;AACV,QAAI,OAAO;AACX,QAAI,UAAU;AACd,QAAI,QAAQ;AACZ,eAAW,EAAE,QAAQ,KAAKA,WAAU,QAAQ,MAAM,IAAI,QAAQ,OAAO,MAAM,CAAC,CAAC,GAAG;AAC9E,YAAM,KAAK,YAAY,OAAO;AAC9B,UAAI,OAAO,KAAK,KAAK;AACnB,YAAI,YAAY,KAAK;AAEnB,cAAI,KAAK,IAAI,QAAQ,CAAC;AACtB,gBAAM;AACN,iBAAO;AACP,oBAAU;AACV,kBAAQ;AACR;AAAA,QACF;AACA,YAAI,UAAU,GAAG;AACf,cAAI,KAAK,IAAI,MAAM,GAAG,OAAO,EAAE,QAAQ,CAAC;AACxC,gBAAM,IAAI,MAAM,OAAO;AAAA,QACzB,OAAO;AACL,cAAI,QAAQ,GAAI,KAAI,KAAK,GAAG;AAC5B,gBAAM;AAAA,QACR;AACA,eAAO,YAAY,GAAG;AACtB,kBAAU;AACV,gBAAQ;AAAA,MACV;AACA,UAAI,SAAS,QAAQ,MAAM,YAAY,IAAK;AAC5C,aAAO;AACP,cAAQ;AACR,UAAI,YAAY,OAAO,IAAI,KAAK,MAAM,GAAI,WAAU,IAAI;AAAA,IAC1D;AACA,QAAI,KAAK,IAAI,QAAQ,CAAC;AAAA,EACxB;AACA,SAAO;AACT;AAGO,IAAM,WAAW,CAAC,KAAa,OAAe,WACnD,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,QAAQ,KAAK,IAAI,GAAG,MAAM,CAAC,CAAC;AAGxD,IAAM,cAAc;AAGpB,IAAM,WAAW,CAAC,QAChB,sCAAsC,KAAK,GAAG,GAAG,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK;AAG5E,IAAM,cAAc,CAAC,UACnB,UAAU,cAAc,SAAS,UAAU,YAAY,QAAQ;AAQ1D,SAAS,WAAW,KAAoB,OAAuB;AACpE,QAAM,MAAc,CAAC;AACrB,aAAW,KAAK,IAAI,OAAO;AACzB,UAAM,OAAc;AAAA,MAClB,EAAE,MAAM,iBAAO,MAAM,SAAS;AAAA,MAC9B,EAAE,MAAM,IAAI,EAAE,CAAC,KAAK,MAAM,QAAQ;AAAA,MAClC,EAAE,MAAM,EAAE,MAAM,MAAM,aAAa,EAAE,IAAI,EAAE;AAAA,MAC3C,GAAI,IAAI,OAAO,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,WAAW,MAAM,QAAiB,CAAC,IAAI,CAAC;AAAA,MAChF,EAAE,MAAM,UAAO,MAAM,SAAS;AAAA,MAC9B,EAAE,MAAM,EAAE,UAAU,KAAK,MAAM,KAAK;AAAA,MACpC,EAAE,MAAM,UAAO,MAAM,SAAS;AAAA,MAC9B,EAAE,MAAM,SAAS,EAAE,SAAS,GAAG,MAAM,QAAQ;AAAA,MAC7C,EAAE,MAAM,KAAK,MAAM,SAAS;AAAA,IAC9B;AACA,UAAM,OAAO,YAAY,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAEzD,QAAI;AAAA,MACF,OAAO,QACH,QAAQ,MAAM,KAAK,IACnB,CAAC,GAAG,MAAM,EAAE,MAAM,SAAI,OAAO,QAAQ,IAAI,GAAG,MAAM,SAAS,CAAC;AAAA,IAClE;AACA,UAAM,MAAM,IAAI,OAAO,WAAW;AAElC,QAAI,cAAc;AAClB,eAAW,OAAO,EAAE,QAAQ,QAAQ,QAAQ,EAAE,EAAE,MAAM,YAAY,GAAG;AACnE,YAAM,QAAQ,cAAc,OAAO,iBAAiB,GAAG;AACvD,UAAI,UAAU,KAAM,eAAc;AAClC,YAAM,OAAO,UAAU,OAAO,SAAS,YAAY,KAAK;AACxD,iBAAW,KAAK,KAAK,KAAK,QAAQ,WAAW,EAAG,KAAI,KAAK,CAAC,EAAE,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC;AAAA,IACpF;AACA,QAAI,KAAK,CAAC,CAAC;AAAA,EACb;AACA,SAAO;AACT;AAEO,SAAS,QAAQ,GAAwB;AAC9C,UAAQ,EAAE,MAAM;AAAA,IACd,KAAK;AACH,aAAO,UAAU,EAAE,UAAU,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK;AAAA,IACnD,KAAK;AACH,aAAO,eAAe,EAAE,UAAU,IAAI,EAAE,IAAI,KAAK,EAAE,MAAM,WAAW,gBAAgB;AAAA,IACtF,KAAK;AACH,aAAO,SAAS,EAAE,KAAK,GAAG;AAAA,EAC9B;AACF;AAEA,SAAS,QAAQ,GAAkD;AACjE,QAAM,IAAI,EAAE;AACZ,SAAO;AAAA,IACL,EAAE,KAAK;AAAA,IACP;AAAA,IACA,QAAQ,EAAE,GAAG;AAAA,IACb,SAAS,EAAE,UAAU;AAAA,IACrB,UAAU,EAAE,KAAK,SAAS,GAAG;AAAA,IAC7B,UAAU,EAAE,KAAK;AAAA,IACjB,WAAW,EAAE,UAAU,GAAG;AAAA,IAC1B,OAAO,EAAE,EAAE;AAAA,IACX,WAAW,EAAE,MAAM;AAAA,IACnB,QAAQ,EAAE,QAAQ,KAAK,MAAM,EAAE,GAAG;AAAA,IAClC,YAAY,EAAE,OAAO;AAAA,IACrB,GAAI,EAAE,QAAQ,UAAa,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE,GAAG,iCAAiC,IAAI,CAAC;AAAA,EACzF,EAAE,KAAK,IAAI;AACb;AAeO,SAAS,SAAS,GAAgC;AACvD,MAAI,MAAM,OAAW,QAAO;AAC5B,SAAO,GAAG,WAAW,CAAC,CAAC,KAAK,EAAE,cAAc,OAAO,YAAY,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK;AAC9F;AAOO,SAAS,UAAmE;AACjF,QAAM,EAAE,OAAO,IAAI,UAAU;AAC7B,SAAO,OAAO,QAAQ,MAAM,UAAU;AACpC,UAAM,OAAO,OAAO,SAAS,eAAe,MAAM,WAAW,MAAM,IAAI;AACvE,UAAM,UAAU,YAAY,QAAQ,EAAE,KAAK,YAAY,MAAM,QAAQ,KAAK,CAAC;AAC3E,UAAM,IAAI,aAAa,OAAO;AAC9B,UAAM,MAAM,SAAS,QAAQ,CAAC,KAAK,KAAK,0BAA0B,KAAK,MAAM,MAAM;AACnF,QAAI,CAAC,EAAE,GAAI,QAAO,eAAe,EAAE,GAAG,MAAM,OAAO,GAAG,GAAG;AACzD,WAAO,MAAM,EAAE,QAAQ;AACvB,WAAO,WAAW,OAAO,GAAG,GAAG;AAAA,EACjC;AACF;AAmBO,SAAS,MAAM;AAAA,EACpB;AAAA,EACA;AAAA,EACA,QAAAC;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,YAAY;AACd,GAAe;AACb,QAAM,EAAE,SAAS,KAAK,IAAI,cAAc;AACxC,QAAM,OAAO,QAAQ;AACrB,QAAM,CAAC,KAAK,MAAM,IAAI,SAAS,KAAK;AACpC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,CAAC;AACtC,QAAM,CAAC,MAAM,OAAO,IAAI,SAAe,EAAE,OAAO,UAAU,CAAC;AAC3D,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AACtD,QAAM,CAAC,KAAK,MAAM,IAAI,SAAS,OAAO,SAAS,eAAe,MAAM,CAAC;AACrE,QAAM,UAAU,OAAO,CAAC;AACxB,QAAM,YAAY,OAAO,KAAK;AAG9B,QAAM,OAAO,OAAO,SAAS,eAAe,YAAY;AAGxD,QAAM,SAAS,OAAgB,IAAI;AAInC,YAAU,MAAM;AACd,QAAI,OAAO;AACX,QAAI,OAAO,YAAY,UAAU,QAAQ,UAAU,SAAS;AAC1D,aAAO,UAAU;AACjB,gBAAU,UAAU;AACpB,cAAQ,EAAE,OAAO,UAAU,CAAC;AAAA,IAC9B;AACA,UAAM,OAAO,CAAC,MAAkB;AAC9B,UAAI;AAEF,gBAAQ,CAAC,SAAU,KAAK,UAAU,IAAI,MAAM,KAAK,UAAU,CAAC,IAAI,OAAO,CAAE;AAAA,IAC7E;AACA,QAAI;AACF,UAAI,OAAO,SAAS,SAAS;AAC3B,cAAM,MAAM,QAAQ,MAAM,OAAO,YAAY,OAAO,IAAI,GAAG;AAC3D,aAAK;AAAA,UACH,OAAO;AAAA,UACP,MAAM;AAAA,UACN,GAAI,IAAI,MAAM,SAAS,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC;AAAA,UAC7C,SACE,IAAI,OAAO,IACP,CAAC,GAAG,IAAI,IAAI,OAAO,IAAI,KAAK,mDAAmD,IAC/E,CAAC;AAAA,UACP,QAAQ,SAAS,QAAQ,KAAK,OAAO,YAAY,OAAO,EAAE,CAAC;AAAA,QAC7D,CAAC;AAAA,MACH,WAAW,OAAO,SAAS,OAAO;AAEhC,cAAM,EAAE,YAAY,MAAM,IAAI,WAAW,OAAO,KAAK,QAAQ,KAAK,OAAO,OAAO,KAAK,GAAG;AACxF,cAAM,MACJ,eAAe,UAAa,UAAU,UAAa,UAAU,KACzD;AAAA;AAAA,YAAiB,SAAS,QAAQ,KAAK,YAAY,KAAK,CAAC,CAAC,KAC1D;AACN,aAAK,EAAE,OAAO,SAAS,MAAM,GAAG,QAAQ,MAAM,CAAC,GAAG,GAAG,IAAI,SAAS,CAAC,EAAE,CAAC;AAAA,MACxE,OAAO;AACL,cAAM,YAAY;AAChB,cAAI;AACF,kBAAM,MAAM,MAAM,UAAU;AAC5B,kBAAM,OAAO,MAAM,IAAI,QAAQ,OAAO,QAAQ,EAAE,OAAO,iBAAiB,CAAC;AACzE,iBAAK,EAAE,OAAO,SAAS,MAAM,KAAK,QAAQ,QAAQ,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC;AAAA,UACtE,SAAS,GAAG;AACV,iBAAK,EAAE,OAAO,SAAS,SAAS,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,EAAE,CAAC;AAAA,UAC9E;AAAA,QACF,GAAG;AAAA,MACL;AAAA,IACF,SAAS,GAAG;AACV,WAAK,EAAE,OAAO,SAAS,SAAS,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,EAAE,CAAC;AAAA,IAC9E;AACA,WAAO,MAAM;AACX,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,QAAQ,SAAS,KAAK,QAAQ,IAAI,CAAC;AAEvC,QAAM,QAAQ,QAAQ,MAAM;AAC1B,UAAM,QAAQ,CAAC,GAAGA,SAAQ,GAAI,UAAU,OAAO,CAAC,IAAI,CAAC,KAAK,CAAE;AAC5D,UAAM,QAAQ,KAAK,UAAU,UAAU,OAAO;AAC9C,UAAM,OAAO;AAAA,MACX,GAAI,OAAO,WAAW,SAAY,CAAC,MAAM,MAAM,IAAI,CAAC;AAAA,MACpD,GAAI,OAAO,WAAW,CAAC;AAAA,MACvB,GAAG;AAAA,IACL,EAAE,QAAQ,CAAC,MAAM,KAAK,GAAG,OAAO,CAAC;AACjC,UAAM,QAAQ,CAAC,GAAW,OAAa,WACrC,KAAK,GAAG,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;AACjD,UAAM,OACJ,KAAK,UAAU,YACX,MAAM,eAAU,IAChB,KAAK,UAAU,UACb,MAAM,UAAU,KAAK,OAAO,IAAI,KAAK,IACrC,KAAK,UAAU,SACb,WAAW,KAAK,OAAO,OAAO,IAC9B,MAAM,KAAK,IAAI;AACzB,WAAO,EAAE,MAAM,KAAK;AAAA,EACtB,GAAG,CAAC,MAAMA,SAAQ,OAAO,OAAO,CAAC;AAMjC,QAAM,YAAY,UAAU,QAAQ,QAAQ;AAC5C,QAAM,OAAO,KAAK,IAAI,GAAG,OAAO,KAAK,QAAQ,IAAI,IAAI,MAAM,YAAY,IAAI,EAAE;AAC7E,QAAM,SAAS,MAAM,KAAK,MAAM,GAAG,KAAK,MAAM,OAAO,CAAC,CAAC;AACvD,QAAM,SAAS,OAAO,OAAO;AAC7B,QAAM,QAAQ,SAAS,KAAK,MAAM,KAAK,QAAQ,MAAM;AACrD,UAAQ,UAAU;AAClB,QAAM,OACJ,OAAO,SAAS,UACZ,GAAG,QAAQ,yDACX,OAAO,SAAS,eACd,GAAG,QAAQ,sDACX,GAAG,QAAQ;AAEnB,WAAS,CAAC,OAAO,QAAQ;AACvB,QAAI,KAAK,QAAS;AAClB,aAAS,IAAI;AACb,UAAM,KAAK,QAAQ;AACnB,QAAI,IAAI,UAAU,UAAU,IAAK,QAAO,QAAQ;AAChD,UAAM,MAAM,OAAO,OAAO,KAAK,QAAQ,IAAI;AAE3C,UAAM,MAAM,KAAK,IAAI,GAAG,MAAM,KAAK,SAAS,KAAK,IAAI,GAAG,MAAM,CAAC;AAC/D,QAAI,QAAQ;AACV;AAAA,QACE,QAAQ,MACJ,KAAK,IAAI,MAAM,MACb,MACA,KAAK,IAAI,GAAG,KAAK,IAAI,EAAE,IACzB,IAAI,OAAO,QACT,IACA;AAAA,MACR;AAAA,aACO,UAAU,IAAK,WAAU,CAAC,MAAM,IAAI,CAAC;AAAA,aACrC,UAAU,OAAO,OAAO,SAAS,QAAS,QAAO,CAAC,MAAM,CAAC,CAAC;AAAA,aAC1D,UAAU,OAAO,OAAO,SAAS,aAAc,UAAS,MAAM;AAAA,aAC9D,UAAU,IAAK,MAAK,KAAK,QAAQ,GAAG,EAAE,KAAK,QAAQ;AAAA,EAC9D,CAAC;AAED,QAAM,UAAU,MAAM,KAAK,MAAM,OAAO,QAAQ,MAAM;AACtD,QAAM,QACJ,MAAM,KAAK,WAAW,IAClB,KACA,GAAG,QAAQ,CAAC,IAAI,KAAK,IAAI,MAAM,KAAK,QAAQ,QAAQ,MAAM,CAAC,IAAI,MAAM,KAAK,MAAM;AACtF;AAAA;AAAA,IAEE,gBAAAF,MAACG,MAAA,EAAI,eAAc,UAAS,QAAQ,MAClC;AAAA,sBAAAJ,KAACK,OAAA,EAAK,MAAK,YAAY,GAAG,MAAM,SAAS,GACtC,eAAK,QAAQ,MAAM,GAAG,OAAO,GAChC;AAAA,MACC,YACC,gBAAAL,KAACK,OAAA,EAAK,MAAK,YACT,0BAAAL,KAAC,QAAK,MAAM,QAAQ,OAAO,OAAO,GAAG,GACvC,IACE;AAAA,MACH,OAAO,IAAI,CAAC,GAAG;AAAA;AAAA,QAEd,gBAAAA,KAACK,OAAA,EAAmB,MAAK,YAAY,GAAG,MAAM,QAAQ,GACnD,eAAK,GAAG,OAAO,KADP,IAAI,CAAC,EAEhB;AAAA,OACD;AAAA,MACA,QAAQ,IAAI,CAAC,GAAG;AAAA;AAAA,QAEf,gBAAAL,KAACK,OAAA,EAAqB,MAAK,YACzB,0BAAAL,KAAC,QAAK,MAAM,QAAQ,GAAG,OAAO,GAAG,KADxB,QAAQ,CAEnB;AAAA,OACD;AAAA,MACD,gBAAAA,KAACI,MAAA,EAAI,UAAU,GAAG;AAAA,MACjB,QAAQ,IACP,gBAAAJ,KAACK,OAAA,EAAK,MAAK,YAAY,GAAG,MAAM,OAAO,GACpC,eAAK,GAAG,KAAK,GAAG,IAAI,IAAI,OAAO,GAClC,IACE;AAAA,OACN;AAAA;AAEJ;;;AK3YA,SAAS,OAAAC,YAAW;;;ACkBb,IAAM,aAAa;AAEnB,SAAS,YAAY,MAAyB;AACnD,MAAI,QAAQ,IAAK,QAAO;AACxB,MAAI,QAAQ,IAAK,QAAO;AACxB,SAAO;AACT;AAGO,SAAS,WAAW,OAAe,GAAqB;AAC7D,MAAI,KAAK,EAAG,QAAO,CAAC;AACpB,QAAM,SAAS,KAAK,IAAI,GAAG,QAAQ,cAAc,IAAI,EAAE;AACvD,QAAM,OAAO,KAAK,MAAM,SAAS,CAAC;AAClC,QAAM,QAAQ,SAAS,OAAO;AAC9B,SAAO,MAAM,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,MAAM,QAAQ,IAAI,QAAQ,IAAI,EAAE;AACvE;AAMA,IAAM,YAA2E;AAAA,EAC/E,GAAG,CAAC;AAAA,EACJ,GAAG,EAAE,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,EAAE;AAAA,EACrE,GAAG,EAAE,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,EAAE;AACvE;AAMO,SAAS,WAAW,KAAwB,GAA0B;AAC3E,QAAM,QAAQ,UAAU,CAAC;AACzB,QAAM,OAAmB,MAAM,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,CAAC;AAC3D,aAAW,MAAM,IAAK,MAAK,KAAK,IAAI,IAAI,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,KAAK,EAAE;AACxE,SAAO,KAAK,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AACxC;AAEA,IAAM,QAAQ,CAAC,GAAW,IAAY,OAAuB,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC;AAOlF,SAAS,mBACd,eACA,OACqB;AACrB,QAAM,MAAM,oBAAI,IAAoB;AACpC,QAAM,UAAU,MAAM,IAAI,CAAC,MAAM;AAC/B,UAAM,MAAM,KAAK,IAAI,GAAG,EAAE,GAAG;AAC7B,UAAM,MAAM,KAAK,IAAI,KAAK,EAAE,GAAG;AAC/B,UAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,KAAK,CAAC;AAC7C,WAAO,EAAE,IAAI,EAAE,IAAI,KAAK,KAAK,OAAO,SAAS,MAAM,OAAO,KAAK,GAAG,EAAE;AAAA,EACtE,CAAC;AACD,MAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,QAAM,OAAO,KAAK,IAAI,GAAG,gBAAgB,eAAe,QAAQ,MAAM;AACtE,QAAM,MAAM,CAAC,IAAY,MAAoB,KAAK,IAAI,IAAI,IAAI,CAAC;AAE/D,QAAM,eAAe,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,SAAS,CAAC;AAC9D,MAAI,gBAAgB,MAAM;AACxB,eAAW,KAAK,QAAS,KAAI,EAAE,IAAI,EAAE,OAAO;AAC5C,WAAO,WAAW,KAAK,SAAS,IAAI;AAAA,EACtC;AACA,QAAM,WAAW,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,KAAK,CAAC;AACtD,aAAW,KAAK,QAAS,KAAI,EAAE,IAAI,EAAE,GAAG;AACxC,MAAI,QAAQ,SAAU,QAAO;AAG7B,QAAM,OAAO,OAAO;AACpB,QAAM,SAAS,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,SAAS,CAAC;AACxD,QAAM,SAAS,QAAQ,IAAI,CAAC,GAAG,UAAU;AACvC,UAAM,MAAM,WAAW,IAAI,OAAO,QAAQ,SAAU,OAAO,EAAE,UAAW;AACxE,WAAO,EAAE,GAAG,OAAO,KAAK,KAAK,KAAK,IAAI,EAAE,MAAM,EAAE,KAAK,KAAK,MAAM,GAAG,CAAC,EAAE;AAAA,EACxE,CAAC;AACD,MAAI,YAAY;AAChB,aAAW,KAAK,QAAQ;AACtB,QAAI,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG;AAC3B,iBAAa,EAAE;AAAA,EACjB;AACA,QAAM,cAAc,CAAC,GAAG,MAAM,EAAE;AAAA,IAC9B,CAAC,GAAG,MAAM,EAAE,MAAM,KAAK,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,KAAK,MAAM,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE;AAAA,EACnF;AACA,SAAO,YAAY,GAAG;AACpB,QAAI,UAAU;AACd,eAAW,KAAK,aAAa;AAC3B,UAAI,aAAa,EAAG;AACpB,YAAM,OAAO,IAAI,IAAI,EAAE,EAAE,EAAE,KAAK;AAChC,UAAI,QAAQ,EAAE,EAAE,IAAK;AACrB,UAAI,EAAE,EAAE,IAAI,OAAO,CAAC;AACpB,mBAAa;AACb,gBAAU;AAAA,IACZ;AACA,QAAI,CAAC,QAAS;AAAA,EAChB;AACA,SAAO,WAAW,KAAK,SAAS,IAAI;AACtC;AAMA,SAAS,WACP,KACA,SACA,MACqB;AACrB,MAAI,QAAQ,OAAO,QAAQ,OAAO,CAAC,GAAG,MAAM,KAAK,IAAI,IAAI,EAAE,EAAE,KAAK,IAAI,CAAC;AACvE,SAAO,QAAQ,GAAG;AAChB,UAAM,SAAS,QACZ,IAAI,CAAC,GAAG,WAAW,EAAE,IAAI,EAAE,IAAI,OAAO,MAAM,KAAK,IAAI,GAAG,EAAE,SAAS,IAAI,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAC1F,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC;AAC3B,UAAM,QAAQ,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,MAAM,CAAC;AACnD,QAAI,UAAU,EAAG;AACjB,UAAM,OAAO,KAAK,IAAI,OAAO,KAAK;AAClC,UAAM,SAAS,OAAO,IAAI,CAAC,MAAM;AAC/B,YAAM,MAAO,OAAO,EAAE,OAAQ;AAC9B,aAAO,EAAE,GAAG,GAAG,KAAK,KAAK,MAAM,GAAG,GAAG,KAAK,MAAM,KAAK,MAAM,GAAG,EAAE;AAAA,IAClE,CAAC;AACD,QAAI,QAAQ;AACZ,eAAW,KAAK,QAAQ;AACtB,UAAI,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,EAAE,KAAK,KAAK,EAAE,GAAG;AAC1C,eAAS,EAAE;AAAA,IACb;AACA,WAAO,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK;AACxD,eAAW,KAAK,QAAQ;AACtB,UAAI,SAAS,KAAM;AACnB,YAAM,QAAQ,QAAQ,EAAE,KAAK,GAAG,SAAS;AACzC,WAAK,IAAI,IAAI,EAAE,EAAE,KAAK,MAAM,MAAO;AACnC,UAAI,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,EAAE,KAAK,KAAK,CAAC;AACtC,eAAS;AAAA,IACX;AACA,QAAI,UAAU,EAAG;AACjB,aAAS;AAAA,EACX;AACA,SAAO;AACT;AAkBO,SAAS,UAAU,eAAuB,OAA0C;AACzF,QAAM,UAAU,mBAAmB,eAAe,KAAK;AACvD,QAAM,MAAoB,CAAC;AAC3B,MAAI,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,aAAa,CAAC;AAChD,aAAW,KAAK,OAAO;AACrB,UAAM,OAAO,KAAK,IAAI,QAAQ,IAAI,EAAE,EAAE,KAAK,GAAG,KAAK,IAAI,GAAG,OAAO,YAAY,CAAC;AAC9E,QAAI,SAAS,KAAK,EAAE,MAAM,KAAK,IAAI,SAAS,EAAG;AAC/C,QAAI,OAAO,aAAc;AACzB,QAAI,KAAK,EAAE,IAAI,EAAE,IAAI,QAAQ,eAAe,MAAM,MAAM,QAAQ,KAAK,IAAI,GAAG,EAAE,QAAQ,IAAI,EAAE,CAAC;AAC7F,YAAQ,eAAe;AAAA,EACzB;AACA,SAAO;AACT;;;ACzKO,IAAM,SAAS;AAGf,SAAS,cAAc,MAA4C,OAAyB;AACjG,QAAM,SAAS,IAAI,MAAc,KAAK,EAAE,KAAK,CAAC;AAC9C,aAAW,OAAO,MAAM;AACtB,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,IAAI,YAAY,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;AACzC,UAAI,KAAK,OAAO,CAAC,KAAK,GAAI,QAAO,CAAC,IAAI;AAAA,IACxC;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,aACd,MACA,OACU;AACV,QAAM,UAAU,cAAc,MAAM,MAAM,MAAM;AAChD,SAAO,MAAM,IAAI,CAAC,GAAG,MAAM;AACzB,QAAI,IAAI,QAAQ,CAAC,KAAK;AACtB,QAAI,EAAE,QAAQ,OAAW,KAAI,KAAK,IAAI,GAAG,EAAE,GAAG;AAC9C,QAAI,EAAE,QAAQ,OAAW,KAAI,KAAK,IAAI,GAAG,EAAE,GAAG;AAC9C,WAAO;AAAA,EACT,CAAC;AACH;AAGO,SAAS,QAAQ,GAAW,OAAe,QAA0B,QAAgB;AAC1F,QAAM,OAAO,MAAM,CAAC;AACpB,QAAM,IAAI,YAAY,IAAI;AAC1B,MAAI,UAAU,WAAW,IAAI,MAAO,QAAO,IAAI,OAAO,QAAQ,CAAC,IAAI;AACnE,SAAO,KAAK,MAAM,KAAK;AACzB;AAGO,SAAS,YACd,OACA,QACA,OACU;AACV,SAAO,MAAM,IAAI,CAAC,GAAG,MAAM,QAAQ,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,GAAG,EAAE,KAAK,CAAC;AAC7E;;;ACtCO,IAAM,OAAgD;AAAA,EAC3D,EAAE,IAAI,YAAY,OAAO,WAAW;AAAA,EACpC,EAAE,IAAI,SAAS,OAAO,QAAQ;AAAA,EAC9B,EAAE,IAAI,OAAO,OAAO,MAAM;AAAA,EAC1B,EAAE,IAAI,UAAU,OAAO,SAAS;AAAA,EAChC,EAAE,IAAI,OAAO,OAAO,MAAM;AAC5B;AAkBA,IAAM,gBAAgB,CAAC,UAAU,QAAQ,eAAe,UAAU,KAAK;AAIvE,IAAM,cAAc,CAAC,YAAY,OAAO,OAAO,IAAI;AAI5C,IAAM,cAAyC;AAAA,EACpD,UAAU;AAAA;AAAA,EACV,KAAK;AAAA;AAAA,EACL,KAAK;AAAA;AAAA,EACL,IAAI;AACN;AAOO,IAAM,YAAoB,EAAE,QAAQ,UAAU,MAAM,IAAI,MAAM,WAAW;AAEhF,IAAM,cAA0D;AAAA,EAC9D,QAAQ,CAAC,QAAQ,aAAa;AAAA,EAC9B,MAAM,CAAC,MAAM;AAAA,EACb,aAAa,CAAC,aAAa;AAAA,EAC3B,QAAQ,CAAC,QAAQ;AAAA,EACjB,KAAK,CAAC,QAAQ,eAAe,QAAQ;AACvC;AAEO,IAAM,aAAa,CAAC,UAA8C,YAAY,KAAK;AAEnF,SAAS,gBAAgB,OAAiC;AAC/D,QAAM,IAAI,cAAc,QAAQ,KAAK;AACrC,SAAO,eAAe,IAAI,KAAK,cAAc,MAAM,KAAK;AAC1D;AAEO,SAAS,cAAc,OAA6B;AACzD,QAAM,IAAI,YAAY,QAAQ,KAAK;AACnC,SAAO,aAAa,IAAI,KAAK,YAAY,MAAM,KAAK;AACtD;AAGO,IAAM,WAAW,CAAC,KAAY,eACnC,GAAG,GAAG,KAAS,cAAc,EAAE;AAO1B,SAAS,eACd,aACA,MACe;AACf,MAAI,SAAS,UAAa,YAAY,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,EAAG,QAAO;AAC3E,MAAI;AACJ,aAAW,KAAK,aAAa;AAC3B,QAAI,SAAS,UAAa,EAAE,aAAa,KAAK,WAAY,QAAO;AAAA,EACnE;AACA,SAAO,MAAM,QAAQ;AACvB;AAGO,IAAM,kBAAkB,CAAC,MAC9B,EAAE,UAAU,GAAG,EAAE,IAAI,MAAM,EAAE;AAGxB,SAAS,SAAS,MAAiC;AACxD,MAAI,KAAK,gBAAgB,WAAY,QAAO;AAC5C,MAAI,KAAK,SAAS,KAAM,QAAO;AAC/B,SAAO,SAAS,KAAK,KAAK,IAAI,MAAM,KAAK,KAAK,SAAS,KAAK,KAAK,CAAC;AACpE;AAGO,IAAM,aAAa,CAAC,QAAgB,aACzC,aAAa,KAAK,SAAS,WAAW,EAAE,QAAQ,SAAS,CAAa;AAExE,IAAM,eAAe,CAAC,OAAoC;AAAA,EACxD,MAAM;AAAA,EACN,YAAY,EAAE;AAAA,EACd,MAAM,EAAE;AAAA,EACR,QAAQ,EAAE;AAAA,EACV,KAAK,EAAE;AACT;AAMA,IAAM,eAAe,KAAK;AAAA,EACxB,GAAG,cAAc,QAAQ,CAAC,OAAO,eAAe,EAAE,EAAE,IAAI,CAAC,QAAQ,WAAW,IAAI,GAAG,EAAE,MAAM,CAAC;AAC9F;AACA,IAAM,cAAc,mBAAmB;AACvC,IAAM,aAAa;AACnB,IAAM,QAAQ;AACd,IAAM,aAAa;AAEnB,IAAM,UAAU,CAAC,MAAM,GAAG,SAA8B;AAAA,EACtD,MAAM;AAAA,EACN;AAAA,EACA,GAAI,QAAQ,SAAY,EAAE,IAAI,IAAI,CAAC;AACrC;AACA,IAAM,QAAQ,CAAC,OAA2B,EAAE,MAAM,WAAW,KAAK,GAAG,KAAK,EAAE;AAC5E,IAAM,OAAmB,EAAE,MAAM,OAAO;AAOxC,SAAS,WACP,OACA,OAC0E;AAC1E,QAAM,SAAS,aAAa,OAAO,KAAK;AACxC,QAAM,OAAO,MAAM,SAAS;AAC5B,SAAO,CAAC,OAAO,UAAU;AACvB,UAAM,SAAS,YAAY,OAAO,QAAQ,KAAK;AAC/C,UAAM,QAAQ,MAAM;AAAA,MAAQ,CAAC,GAAG,MAC9B,MAAM,OACF,CAAC,EAAE,MAAM,MAAM,MAAM,IAAI,KAAK,EAAE,GAAG,MAAM,MAAM,IAAI,EAAE,CAAC,KACrD,OAAO,CAAC,KAAK,KAAK,IACjB,CAAC,EAAE,MAAM,OAAO,CAAC,KAAK,IAAI,MAAM,MAAM,CAAC,EAAE,CAAC,IAC1C,CAAC;AAAA,IACT;AACA,UAAM,MAAa,MAAM,QAAQ,CAAC,KAAK,MAAM;AAAA,MAC3C,GAAI,IAAI,IAAI,CAAC,EAAE,MAAM,IAAI,OAAO,MAAM,EAAE,CAAC,IAAI,CAAC;AAAA,MAC9C,IAAI,SAAS,SAAY,EAAE,MAAM,IAAI,KAAK,IAAI,EAAE,MAAM,IAAI,MAAM,MAAM,IAAI,KAAK;AAAA,IACjF,CAAC;AAED,WAAO,IAAI,SAAS,GAAG;AACrB,YAAM,OAAO,IAAI,IAAI,SAAS,CAAC;AAC/B,YAAM,UAAU,KAAK,KAAK,QAAQ;AAClC,UAAI,YAAY,IAAI;AAClB,YAAI,IAAI,SAAS,CAAC,IAAI,EAAE,GAAG,MAAM,MAAM,QAAQ;AAC/C;AAAA,MACF;AACA,UAAI,IAAI;AAAA,IACV;AACA,WAAO;AAAA,EACT;AACF;AAGA,IAAM,QAAQ,CAAC,KAAa,MAAY,OAA2C,CAAC,OAAY;AAAA,EAC9F;AAAA,EACA,MAAM,SAAS,IAAI;AAAA,EACnB;AAAA,EACA,GAAG;AACL;AAGA,IAAM,aAAa,CAAC,MAClB,EAAE,UAAU,OACR,KACA,IAAI,EAAE,qBAAqB,QAAQ,EAAE,qBAAqB,EAAE,aAAa,GAAG,EAAE,gBAAgB,MAAM,EAAE,GAAG,EAAE,KAAK;AAGtH,SAAS,UAAU,OAAwB,MAAkC;AAC3E,QAAM,MAAM,CAAC,MAA6B,EAAE,SAAS,KAAK,IAAI,EAAE,aAAa,IAAI;AACjF,QAAM,MAAM,CAAC,GAAG,KAAK;AACrB,MAAI,SAAS,MAAO,KAAI,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,cAAc,EAAE,WAAW;AAAA,WAC9E,SAAS;AAChB,QAAI,KAAK,CAAC,GAAG,MAAO,EAAE,aAAa,EAAE,aAAa,KAAK,EAAE,aAAa,EAAE,aAAa,IAAI,CAAE;AAAA,WACpF,SAAS,KAAM,KAAI,KAAK,CAAC,GAAG,MAAO,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAE;AACnF,SAAO;AACT;AAGO,SAAS,SAAS,GAA0B;AACjD,QAAM,IAAI,EAAE;AACZ,MAAI,MAAM,OAAW,QAAO;AAC5B,QAAM,SAAS,EAAE,WAAW,OAAO,KAAK,MAAM,EAAE,MAAM;AACtD,SAAO,GAAG,EAAE,KAAK,GAAG,EAAE,YAAY,OAAO,KAAK,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM;AACxE;AAGA,IAAM,WAAW,CAAC,MAChB,EAAE,MAAM,UAAU,WAAW,QAAQ,EAAE,MAAM,UAAU,YAAY,SAAS;AAMvE,SAAS,SACd,MACA,IACA,GACA,OAA2B,CAAC,GACrB;AACP,QAAM,SAAS,KAAK,SAAS,QAAQ,MAAM,KAAK;AAChD,QAAM,WAA8B,WAAW,EAAE,MAAM;AACvD,QAAM,OAAO,KAAK,MAAM,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE;AACzD,QAAM,QAAQ;AAAA,IACZ,KAAK;AAAA,MACH,CAAC,MACC,SAAS,SAAS,EAAE,MAAM,KAC1B,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,IAClE;AAAA,IACA,EAAE;AAAA,EACJ;AAEA,QAAM,QAAQ,CAAC,QAAQ,GAAG,EAAE,GAAG,MAAM,YAAY,GAAG,QAAQ,GAAG,EAAE,GAAG,QAAQ,GAAG,EAAE,GAAG,IAAI;AAGxF,QAAM,aAAa,KAAK,OAAO,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE,IAAI,EAAE;AACzF,QAAM,OAAO;AAAA,IACX;AAAA,MACE,GAAG,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,IAAI,WAAW,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;AAAA,MACvD,GAAG,WAAW,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;AAAA,IAC1C;AAAA,IACA;AAAA,EACF;AACA,SAAO,MAAM;AAAA,IAAI,CAAC,MAChB;AAAA,MACE,EAAE;AAAA,MACF;AAAA,QACE,CAAC,EAAE,IAAI,WAAW,EAAE,QAAQ,EAAE,QAAQ,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,KAAK;AAAA,QAC1E,CAAC,MAAM,WAAW,EAAE,QAAQ,EAAE,QAAQ,GAAG,SAAS,SAAS,CAAC,GAAG,MAAS;AAAA,MAC1E;AAAA,MACA,EAAE,OAAO,EAAE,MAAM,SAAS,YAAY,EAAE,YAAY,IAAI,EAAE,IAAI,OAAO,EAAE,MAAM,EAAE;AAAA,IACjF;AAAA,EACF;AACF;AAEA,SAAS,UAAU,GAA0B;AAC3C,QAAM,QAAQ;AAAA,IACZ,EAAE,QAAQ,wBAAwB;AAAA,IAClC,EAAE,OAAO,IAAI,IAAI,EAAE,IAAI,UAAU;AAAA,IACjC,EAAE,SAAS,IAAI,GAAG,EAAE,MAAM,YAAY;AAAA,IACtC,EAAE,UAAU,IAAI,GAAG,EAAE,OAAO,gBAAgB;AAAA,EAC9C,EAAE,OAAO,CAAC,MAAM,MAAM,EAAE;AACxB,SAAO,MAAM,SAAS,IAAI,MAAM,MAAM,KAAK,IAAI,CAAC,MAAM;AACxD;AAGA,IAAM,SAAS,CAAC,KAAa,SAAsB,MAAM,KAAK,CAAC,EAAE,MAAM,MAAM,OAAO,CAAC,CAAC;AAGtF,IAAM,SAAS,CAAC,MAA6B,GAAG,KAAK,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE,EAAE;AAS3E,SAAS,QAAQ,MAAyB,IAAmB,GAAkB;AAC7E,QAAM,OAAc,CAAC;AACrB,QAAM,OAAO,KAAK,MAAM,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE;AACzD,QAAM,QAAQ,CAAC,QAAQ,GAAG,EAAE,GAAG,MAAM,YAAY,GAAG,IAAI;AACxD,QAAM,OAAO;AAAA,IACX,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC;AAAA,IACnC;AAAA,EACF;AACA,aAAW,KAAK,MAAM;AACpB,QAAI,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,GAAG;AAC/C,WAAK;AAAA,QACH;AAAA,UACE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG;AAAA,UAC1B;AAAA,YACE,GAAG;AAAA,cACD,CAAC,OAAO,CAAC,GAAG,WAAW,EAAE,QAAQ,EAAE,QAAQ,GAAG,EAAE,KAAK;AAAA,cACrD,CAAC,MAAM,WAAW,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAS;AAAA,YACpD;AAAA,YACA,GAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,UAAU,CAAC,GAAG,MAAM,QAAiB,CAAC;AAAA,UAChF;AAAA,UACA,EAAE,OAAO,EAAE,MAAM,SAAS,YAAY,EAAE,YAAY,IAAI,EAAE,IAAI,OAAO,EAAE,MAAM,EAAE;AAAA,QACjF;AAAA,MACF;AAAA,IACF,WAAW,EAAE,UAAU,GAAG;AAGxB,WAAK;AAAA,QACH;AAAA,UACE,WAAW,EAAE,GAAG;AAAA,UAChB,UAAK,EAAE,OAAO,aAAa,EAAE,YAAY,IAAI,KAAK,GAAG,UAAU,EAAE,EAAE;AAAA,QACrE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,QAAM,MAAM,KAAK,SAAS,KAAK,CAAC,MAAM,EAAE,eAAe,EAAE;AACzD,MAAI,QAAQ,UAAa,IAAI,YAAY,GAAG;AAC1C,SAAK;AAAA,MACH;AAAA,QACE;AAAA,QACA,UAAK,IAAI,SAAS,mBAAmB,IAAI,cAAc,IAAI,KAAK,GAAG;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AACA,MAAI,QAAQ,UAAa,IAAI,YAAY,GAAG;AAC1C,SAAK;AAAA,MACH;AAAA,QACE;AAAA,QACA,UAAK,IAAI,SAAS,eAAe,IAAI,cAAc,IAAI,KAAK,GAAG;AAAA,MACjE;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,SAAS,GAAmB,KAAqB;AACxD,MAAI,EAAE,SAAS,OAAW,QAAO;AACjC,MAAI,EAAE,SAAS,KAAM,QAAO;AAC5B,QAAM,KAAK,EAAE,KAAK,cAAc,MAAM,EAAE,KAAK;AAC7C,SAAO,GAAG,EAAE,KAAK,IAAI,IAAI,cAAc,EAAE,CAAC;AAC5C;AAEA,SAAS,UAAU,MAAyB,IAAmB,GAAW,KAAoB;AAC5F,QAAM,OAAO,KAAK,OAAO,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE;AAC1D,QAAM,SAAS,KAAK,OAAO,CAAC,MAAM,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,GAAG,EAAE,KAAK,CAAC;AAG3F,QAAM,SAAS,CAAC,MACd,EAAE,SAAS,OACP,MACA,EAAE,KAAK,WAAW,GAAG,EAAE,UAAU,GAAG,IAClC,EAAE,KAAK,MAAM,EAAE,WAAW,SAAS,CAAC,IACpC,EAAE;AACV,QAAM,QAAQ,CAAC,QAAQ,GAAG,EAAE,GAAG,MAAM,UAAU,GAAG,MAAM,WAAW,GAAG,QAAQ,GAAG,EAAE,GAAG,IAAI;AAC1F,QAAM,OAAO;AAAA;AAAA;AAAA,IAGX;AAAA,MACE,GAAG,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC;AAAA,MAC9C,GAAG,KAAK,MAAM,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;AAAA,IAChF;AAAA,IACA;AAAA,EACF;AAEA,QAAM,UAAU,CAAC,MAAc,QAC7B,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,WAAW,GAAG;AAChE,SAAO,OAAO;AAAA,IAAI,CAAC,MACjB;AAAA,MACE,EAAE;AAAA,MACF;AAAA,QACE,CAAC,EAAE,MAAM,EAAE,QAAQ,OAAO,EAAE,SAAS,KAAK,OAAO,CAAC,GAAG,SAAS,GAAG,GAAG,CAAC;AAAA,QACrE;AAAA,UACE;AAAA,UACA;AAAA,UACA,QAAQ,QAAQ,EAAE,GAAG,IAAI,QAAQ,eAAe,EAAE,KAAK;AAAA,UACvD;AAAA,UACA,QAAQ,WAAW,EAAE,GAAG,IAAI,SAAS;AAAA,QACvC;AAAA,MACF;AAAA,MACA,EAAE,OAAO,aAAa,CAAC,EAAE;AAAA,IAC3B;AAAA,EACF;AACF;AAEA,IAAM,SAAS,CAAC,QAAwB,oBAAoB,KAAK,GAAG,IAAI,CAAC,KAAK;AAG9E,SAAS,QAAQ,MAAyB,IAAmB,GAAkB;AAC7E,QAAM,OAAO,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE;AAClD,QAAM,QAAsB,CAAC,EAAE,MAAM,WAAW,OAAO,QAAQ,GAAG,MAAM,UAAU,GAAG,IAAI;AACzF,QAAM,OAAO;AAAA,IACX,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,EAAE,CAAC;AAAA,IACvC;AAAA,EACF;AACA,SAAO,KACJ,OAAO,CAAC,MAAM,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,EAC3D,IAAI,CAAC,MAAM;AACV,UAAM,OAAO,KAAK,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,EAAE,UAAU,GAAG,EAAE,GAAG,CAAC,SAAS,SAAS,MAAS,CAAC;AAC1F,WAAO,MAAM,OAAO,EAAE,GAAG,GAAG,CAAC,GAAG,MAAM,EAAE,MAAM,IAAI,OAAO,MAAM,EAAE,GAAG,GAAG,SAAS,CAAC,CAAC,GAAG;AAAA,MACnF,OAAO,EAAE,MAAM,OAAO,MAAM,EAAE;AAAA,IAChC,CAAC;AAAA,EACH,CAAC;AACL;AAGA,IAAM,YAAY,CAAC,GAAG,aAAa,eAAe,UAAU,UAAU,IAAI,EAAE;AAAA,EAC1E,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE;AACzB;AAGA,SAAS,SAAS,GAA4B;AAC5C,QAAM,OAAO,MAAM,EAAE,QAAQ;AAC7B,QAAM,OAAO,EAAE,SAAS,UAAU,KAAK,CAAC,MAAM,SAAS,KAAK,KAAK,WAAW,GAAG,CAAC,GAAG,CAAC,IAAI;AACxF,MAAI,SAAS,OAAW,QAAO,CAAC,EAAE,KAAK,CAAC;AACxC,SAAO;AAAA,IACL,EAAE,MAAM,MAAM,MAAM,OAAO;AAAA,IAC3B,GAAI,KAAK,SAAS,KAAK,SAAS,CAAC,EAAE,MAAM,KAAK,MAAM,KAAK,MAAM,EAAE,CAAC,IAAI,CAAC;AAAA,EACzE;AACF;AAGA,SAAS,eAAe,GAAuB,IAA2B;AACxE,QAAM,QAAQ,EAAE,eAAe,QAAQ,EAAE,eAAe,KAAK,GAAG,EAAE,UAAU,MAAM;AAClF,SAAO,GAAG,KAAK,GAAG,EAAE,SAAS,UAAU,UAAU,EAAE,IAAI,KAAK,EAAE,IAAI;AACpE;AAGO,SAAS,eAAe,WAA0C,IAAyB;AAChG,MAAI,UAAU,WAAW,EAAG,QAAO,CAAC,EAAE,MAAM,oBAAe,MAAM,OAAO,CAAC;AACzE,SAAO;AAAA,IACL,EAAE,MAAM,UAAK,UAAU,MAAM,eAAe,MAAM,OAAO;AAAA,IACzD,GAAG,UAAU,QAAQ,CAAC,GAAG,MAAa;AAAA,MACpC,GAAI,IAAI,IAAI,CAAC,EAAE,MAAM,UAAO,MAAM,QAAiB,CAAC,IAAI,CAAC;AAAA,MACzD,EAAE,MAAM,eAAe,GAAG,EAAE,GAAG,MAAM,cAAc,CAAC,EAAE;AAAA,IACxD,CAAC;AAAA,EACH;AACF;AAGA,IAAM,gBAAgB,CAAC,MACrB,EAAE,SAAS,UAAW,EAAE,SAAS,cAAc,EAAE,KAAK,WAAW,iBAAiB,IAC9E,QACA;AAGN,SAAS,cAAc,MAAyB,IAA0B;AACxE,SAAO,KAAK,UAAU,IAAI,CAAC,MAAM;AAC/B,UAAM,QAAQ,KAAK,OAAO,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM;AAExD,UAAM,KACJ,EAAE,SAAS,WAAW,EAAE,SAAS,aAC7B,EAAE,QAAQ,OAAO,EAAE,YAAY,UAAU,KAAK,CAAC,IAC/C;AACN,UAAM,QAAiC,QACnC,aAAa,KAAK,IAClB,EAAE,eAAe,QAAQ,KACvB,EAAE,MAAM,SAAS,YAAY,EAAE,YAAY,IAAI,OAAO,EAAE,KAAK,IAC7D;AACN,WAAO;AAAA,MACL,EAAE;AAAA,MACF,CAAC,EAAE,MAAM,eAAe,GAAG,EAAE,GAAG,MAAM,cAAc,CAAC,EAAE,CAAC;AAAA,MACxD,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IACvB;AAAA,EACF,CAAC;AACH;AAGO,SAAS,SAAS,GAA0B;AACjD,QAAM,QAAQ;AAAA,IACZ,GAAG,EAAE,KAAK,QAAQ,EAAE,UAAU,IAAI,KAAK,GAAG;AAAA,IAC1C,EAAE,YAAY,IAAI,GAAG,EAAE,SAAS,eAAe;AAAA,IAC/C,EAAE,UAAU,IAAI,GAAG,EAAE,OAAO,aAAa;AAAA,IACzC,EAAE,aAAa,IAAI,GAAG,EAAE,UAAU,gBAAgB;AAAA,IAClD,EAAE,UAAU,IAAI,GAAG,EAAE,OAAO,WAAW,EAAE,UAAU,IAAI,KAAK,EAAE,OAAO,cAAc,EAAE,KAAK;AAAA,EAC5F,EAAE,OAAO,CAAC,MAAM,MAAM,EAAE;AACxB,SAAO,MAAM,KAAK,IAAI;AACxB;AAGO,SAAS,SAAS,MAAyB,IAA0B;AAC1E,QAAM,OAAO,KAAK,MAAM,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE;AACzD,QAAM,OAAO;AAAA,IACX,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;AAAA,IAC5B,CAAC,QAAQ,GAAG,EAAE,GAAG,IAAI;AAAA,EACvB;AACA,SAAO,KAAK;AAAA,IAAI,CAAC,MACf;AAAA,MACE,EAAE;AAAA,MACF;AAAA,QACE,CAAC,EAAE,MAAM,SAAS,CAAC,CAAC;AAAA,QACpB,CAAC,MAAM,EAAE,UAAU,IAAI,SAAS,EAAE,UAAU,IAAI,aAAa,OAAO;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,QACd,KACA,MACA,IACA,GACA,KACO;AACP,UAAQ,KAAK;AAAA,IACX,KAAK;AACH,aAAO,cAAc,MAAM,EAAE;AAAA,IAC/B,KAAK;AACH,aAAO,SAAS,MAAM,IAAI,CAAC;AAAA,IAC7B,KAAK;AACH,aAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,IAC5B,KAAK;AACH,aAAO,UAAU,MAAM,IAAI,GAAG,GAAG;AAAA,IACnC,KAAK;AACH,aAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,EAC9B;AACF;AAOO,SAAS,YACd,MACA,KACA,KACA,KACQ;AACR,QAAM,IAAI,QAAQ,OAAO,KAAK,KAAK,UAAU,CAAC,MAAM,EAAE,QAAQ,GAAG;AACjE,MAAI,KAAK,EAAG,QAAO;AACnB,MAAI,QAAQ,QAAQ,QAAQ,OAAW,QAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC;AACxF,SAAO,QAAQ,QAAQ,KAAK,IAAI,GAAG,KAAK,SAAS,CAAC,IAAI;AACxD;AAGO,SAAS,WACd,MACA,KACA,KACA,OACA,KACe;AACf,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,SAAS,GAAG,YAAY,MAAM,KAAK,KAAK,GAAG,IAAI,KAAK,CAAC;AACzF,SAAO,KAAK,CAAC,GAAG,OAAO;AACzB;;;AH5cgB,gBAAAC,YAAA;AAjFT,SAAS,cAAc,MAAyB,IAAmB,KAAqB;AAC7F,QAAM,QAAQ,CAAC,QACb,QAAQ,KAAK,MAAM,IAAI,WAAW,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI;AAC1D,QAAM,QAAQ,CAAC,MACb,SAAS,MAAM,IAAI,GAAG,EAAE,MAAM,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI;AAC1D,QAAM,QAAQ,SAAS,MAAM,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI;AAClD,SAAO;AAAA,IACL;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,OAAO,MAAM,UAAU;AAAA,MACvB,OAAO;AAAA,MACP,WAAW;AAAA,MACX,KAAK;AAAA,IACP;AAAA,IACA,EAAE,IAAI,UAAU,OAAO,UAAU,OAAO,MAAM,QAAQ,GAAG,OAAO,aAAa,KAAK,EAAE;AAAA,IACpF;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,OAAO,MAAM,EAAE,GAAG,WAAW,QAAQ,cAAc,CAAC;AAAA,MACpD,OAAO;AAAA,MACP,KAAK;AAAA,IACP;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,OAAO,MAAM,EAAE,GAAG,WAAW,QAAQ,QAAQ,MAAM,MAAM,CAAC;AAAA,MAC1D,OAAO;AAAA,MACP,KAAK;AAAA,IACP;AAAA,IACA,GAAI,MAAM,SAAS,IACf,CAAC,EAAE,IAAI,SAAS,OAAO,SAAS,OAAO,OAAO,OAAO,YAAY,KAAK,EAAE,CAAC,IACzE,CAAC;AAAA,IACL,EAAE,IAAI,OAAO,OAAO,OAAO,OAAO,MAAM,KAAK,GAAG,OAAO,eAAe,KAAK,IAAI,MAAM,KAAK;AAAA,EAC5F;AACF;AAGO,SAAS,SAAS,GAKR;AACf,QAAM,UAAU;AAAA,IACd,EAAE,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,IACvB,YAAY,EAAE,KAAK;AAAA,EACrB;AACA,QAAM,SAAS,WAAW,EAAE,OAAO,QAAQ,MAAM;AACjD,SACE,gBAAAA,KAACC,MAAA,EAAI,QAAQ,EAAE,QAAQ,OAAO,EAAE,OAAO,WAAW,YAC/C,kBAAQ,IAAI,CAAC,KAAK,OAAO;AACxB,UAAM,QAAQ,IAAI,QAAQ,CAAC,OAAO,EAAE,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AACxE,UAAM,SAAS;AAAA,MACb,EAAE;AAAA,MACF,MAAM,IAAI,CAAC,OAAO;AAAA,QAChB,IAAI,EAAE;AAAA;AAAA,QAEN,KAAK,EAAE,OAAO,cAAc,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,EAAE,MAAM,MAAM,CAAC,IAAI;AAAA,QACvE,KAAK,EAAE;AAAA,QACP,OAAO,EAAE,MAAM;AAAA,MACjB,EAAE;AAAA,IACJ;AACA,WACE,gBAAAD,KAACC,MAAA,EAAqB,eAAc,UAAS,OAAO,OAAO,EAAE,GAAG,YAAY,GACzE,iBAAO,IAAI,CAAC,OAAO;AAClB,YAAM,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,EAAE;AAC7C,UAAI,SAAS,OAAW,QAAO;AAC/B,YAAM,YAAY,KAAK,OAAO;AAC9B,YAAM,OAAO,KAAK,OACd,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,GAAG,IAAI,IACvC,YACE,UAAU,GAAG,EAAE,KAAK,KAAK,MAAM,QAAQ,GAAG,IAAI,IAC9C;AACN,YAAM,OAAO,KAAK,MACf,MAAM,MAAM,OAAO,GAAG,IAAI,EAC1B;AAAA,QACC,CAAC,GAAG,MACF,YAAY,CAAC,EAAE,MAAM,OAAO,MAAM,EAAE,MAAM,OAAO,KAAK,GAAG,GAAG,CAAC,IAAI;AAAA,MACrE;AACF,aACE,gBAAAD;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO,OAAO,EAAE,KAAK;AAAA,UACrB,QAAQ,GAAG;AAAA,UACX,OAAO,KAAK;AAAA,UACZ,UAAU,KAAK,MAAM,SAAS,IAAI,OAAO,KAAK,MAAM,MAAM,IAAI;AAAA,UAC9D,QAAQ,GAAG,SAAS,IAAI,IAAI,GAAG,MAAM,IAAI,KAAK,OAAO,UAAU,MAAM,KAAK;AAAA,UAC1E,MACE,KAAK,MAAM,WAAW,IAClB,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,MAAM,KAAK,aAAa,QAAQ,CAAC,CAAC,IACxD;AAAA,UAEL,GAAI,aAAa,KAAK,MAAM,SAAS,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;AAAA;AAAA,QAXnE,KAAK;AAAA,MAYZ;AAAA,IAEJ,CAAC,KAhCO,IAAI,KAAK,CAiCnB;AAAA,EAEJ,CAAC,GACH;AAEJ;;;AIjHA,SAAS,aAAa,aAAAE,YAAW,UAAAC,SAAQ,YAAAC,iBAAgB;AAKlD,IAAM,eAAe;AACrB,IAAM,gBAAgB;AACtB,IAAM,kBAAkB;AAGxB,IAAM,YAAY,CAAC,OACxB,KAAK,IAAI,eAAe,KAAK,IAAI,iBAAiB,EAAE,CAAC;AAEhD,IAAM,aAAa,CAAC,OAAuB,UAAU,KAAK,MAAM,KAAK,CAAC,CAAC;AAEvE,IAAM,aAAa,CAAC,OAAuB,UAAU,KAAK,CAAC;AAM3D,IAAM,cAAc,CAAC,MAC1B,KAAK;AAAA,EAAU;AAAA,EAAG,CAAC,GAAG,MACpB,MAAM,gBAAgB,OAAO,MAAM,WAAW,KAAK,MAAM,IAAI,GAAI,IAAI;AACvE;AA4BK,SAAS,YACd,SACA,OACA,QACA,SAAiB,cACF;AACf,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAoB;AAAA,IAC5C,SAAS;AAAA,IACT,OAAO;AAAA,IACP,UAAU;AAAA,IACV,KAAK;AAAA,IACL,OAAO;AAAA,IACP,WAAW;AAAA,EACb,CAAC;AAED,QAAM,WAAW,KAAK,UAAU,KAAK;AACrC,QAAM,OAAOD,QAA4B,IAAI;AAC7C,QAAM,YAAYA,QAAO,KAAK;AAC9B,QAAM,YAAYA,QAAO,EAAE;AAE3B,QAAM,WAAWA,QAAO,OAAO,iBAAiB;AAEhD,EAAAD,WAAU,MAAM;AACd,QAAI,YAAY;AAChB,QAAI;AACJ,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,UAAM,OAAO,YAA2B;AACtC,aAAO,CAAC,WAAW;AACjB,cAAM,OAAO,UAAU,WAAW,KAAK,IAAI,IAAI,SAAS,WAAW;AACnE,kBAAU,UAAU;AACpB,YAAI,KAAM,UAAS,UAAU,KAAK,IAAI;AACtC,YAAI;AACF,gBAAM,IAAI,MAAM,QAAQ,QAAQ,GAAG,EAAE,KAAK,CAAC;AAC3C,cAAI,UAAW;AACf,gBAAMG,OAAM,GAAG,QAAQ,KAAS,YAAY,EAAE,QAAQ,CAAC;AACvD,gBAAM,UAAUA,SAAQ,UAAU;AAClC,oBAAU,UAAUA;AACpB,cAAI,WAAW;AACb,qBAAS,CAAC,MAAM;AACd,oBAAM,OAAO;AAAA,gBACX,GAAG;AAAA,gBACH,SAAS;AAAA,gBACT,OAAO;AAAA,gBACP,KAAK;AAAA,gBACL,WAAW,OAAO,EAAE,YAAY,IAAI,EAAE;AAAA,cACxC;AACA,kBAAI,CAAC,WAAW,EAAE,UAAU,QAAQ,CAAC,EAAE;AACrC,uBAAO,EAAE,GAAG,MAAM,UAAU,EAAE,SAAS;AACzC,qBAAO,EAAE,GAAG,MAAM,UAAU,EAAE,UAAU,OAAO,EAAE,QAAQ,EAAE;AAAA,YAC7D,CAAC;AAAA;AAED;AAAA,cAAS,CAAC;AAAA;AAAA,gBAER,EAAE,UAAU,QAAQ,CAAC,EAAE,UAAU,IAAI,EAAE,GAAG,GAAG,SAAS,OAAO,OAAO,KAAK;AAAA;AAAA,YAC3E;AAAA,QACJ,SAAS,KAAK;AACZ,cAAI,UAAW;AACf,gBAAM,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC7D,mBAAS,CAAC,MAAO,EAAE,UAAU,SAAS,CAAC,EAAE,UAAU,IAAI,EAAE,GAAG,GAAG,SAAS,OAAO,MAAM,CAAE;AAAA,QACzF;AACA,YAAI,WAAW,KAAM;AACrB,cAAM,IAAI,QAAc,CAAC,YAAY;AACnC,kBAAQ,WAAW,SAAS,MAAM;AAClC,eAAK,UAAU;AAAA,QACjB,CAAC;AACD,aAAK,UAAU;AAAA,MACjB;AAAA,IACF;AACA,SAAK,KAAK;AACV,WAAO,MAAM;AACX,kBAAY;AACZ,UAAI,UAAU,OAAW,cAAa,KAAK;AAC3C,WAAK,UAAU;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,SAAS,UAAU,QAAQ,MAAM,CAAC;AAEtC,QAAM,UAAU,YAAY,MAAM;AAChC,cAAU,UAAU;AACpB,SAAK,UAAU;AAAA,EACjB,GAAG,CAAC,CAAC;AACL,QAAM,EAAE,KAAK,GAAG,KAAK,IAAI;AACzB,SAAO,EAAE,GAAG,MAAM,OAAO,MAAM,aAAa,QAAQ,QAAQ,UAAU,QAAQ;AAChF;;;AlBoPM,gBAAAC,MAoBF,QAAAC,aApBE;AAvUN,IAAM,oBAAoB,CAAC,UAAU,SAAS,UAAU,MAAM;AAE9D,IAAM,YAAY;AAMX,SAAS,OACd,MACA,QAA8B,mBACqB;AACnD,QAAM,QAAQ,KAAK,IAAI,GAAG,OAAO,YAAY,CAAC;AAC9C,QAAM,QAAQ,IAAI,IAAI,MAAM,MAAM,GAAG,KAAK,CAAC;AAC3C,SAAO,EAAE,OAAO,QAAQ,KAAK,IAAI,GAAG,OAAO,YAAY,MAAM,IAAI,EAAE;AACrE;AAGA,IAAM,YAAY,8CAAoC,QAAQ;AAC9D,IAAM,gBAAgB,GAAG,SAAS;AAClC,IAAM,OAAO,GAAG,SAAS;AACzB,IAAM,aAAa,GAAG,SAAS;AAC/B,IAAM,aAAa,CAAC,cAClB,GAAG,SAAS,uBAAuB,SAAS;AAM9C,SAAS,eAAe,QAA2B,UAAkB,OAAsB;AACzF,QAAMC,QAAO,CAAC,MAAuB,MAAM,WAAW,IAAI,OAAO,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC;AACtF,MAAI,QAAQ;AAEZ,QAAM,QAAQ,CAAC,UACZ,OAAO,IAAI,IAAI,KAChB,OAAO,MAAM,IAAI,EAAE,OAAO,CAAC,GAAG,GAAG,MAAM,IAAI,YAAY,MAAMA,MAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AAClF,SAAO,QAAQ,YAAY,MAAM,KAAK,IAAI,MAAO;AACjD,SAAO;AAAA,IACL,GAAI,QAAQ,IAAI,CAAC,EAAE,MAAM,UAAK,MAAM,QAAiB,CAAC,IAAI,CAAC;AAAA,IAC3D,GAAG,OAAO;AAAA,MAAQ,CAAC,GAAG,MACpB,KAAK,QAAQ,CAAC,EAAE,MAAMA,MAAK,CAAC,GAAG,MAAM,MAAM,WAAW,UAAU,QAAQ,CAAC,IAAI,CAAC;AAAA,IAChF;AAAA,EACF;AACF;AAeO,SAAS,IAAI;AAAA,EAClB;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA,MAAM,KAAK;AAAA,EACX,UAAU;AACZ,GAAa;AACX,QAAM,EAAE,MAAM,gBAAgB,IAAI,OAAO;AACzC,QAAM,EAAE,MAAM,IAAI,SAAS;AAC3B,QAAM,EAAE,OAAO,IAAIC,WAAU;AAC7B,QAAM,OAAO,QAAQ;AACrB,QAAM,CAAC,OAAO,QAAQ,IAAIC,UAAsB,IAAI;AAIpD,QAAM,OAAOC,QAAO,KAAK;AACzB,QAAM,CAAC,OAAO,QAAQ,IAAID,UAAwB,IAAI;AACtD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,UAAU;AACrD,EAAAE,WAAU,MAAM;AACd,SAAK,cAAc,EAAE,KAAK,YAAY;AAAA,EACxC,GAAG,CAAC,CAAC;AACL,QAAM,EAAE,SAAS,MAAM,WAAW,IAAIC,eAAc;AACpD,QAAM,CAAC,KAAK,MAAM,IAAIH,UAAgB,UAAU;AAChD,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAwB,IAAI;AACxD,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAA+B,CAAC,CAAC;AAC3D,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAoC,IAAI;AACtE,QAAM,OAAOC,QAA+B,CAAC,CAAC;AAE9C,QAAM,UAAUA,QAA+B,CAAC,CAAC;AACjD,QAAM,CAAC,MAAM,OAAO,IAAID,UAAS,MAAM;AAEvC,QAAM,SAAS,CAAC,GAAU,MACxB,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,QAAQ,WAAW,QAAQ,KAAK;AAK7D,QAAM,QAAQC,QAAgD,IAAI;AAClE,QAAM,YAAY,CAAC,SACjB,SAAS,OACJ,UAAU,qBAAqB,OAChC,WAAW,QAAQ,KAAK,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM,IACnD,SACA,eAAe,MAAM,iBAAiB;AAC9C,QAAM,UAAU,UAAU,MAAM,OAAO;AAMvC,QAAM,cACJ,QAAQ,WAAW,WAAW,OAAO,SAAS,OAAO,EAAE,OAAO,MAAM,EAAE,SAAS,QAAQ;AACzF,QAAM,QAAwB;AAAA,IAC5B,iBAAiB;AAAA,IACjB,GAAI,cAAc,EAAE,QAAQ,CAAC,GAAG,WAAW,KAAK,CAAC,EAAE,IAAI,CAAC;AAAA,IACxD,GAAI,YAAY,OAAO,EAAE,eAAe,QAAQ,IAAI,CAAC;AAAA,EACvD;AACA,QAAM,QAAQ,YAAY,SAAS,OAAO,MAAM,MAAM;AACtD,QAAM,OAAiC,MAAM;AAC7C,QAAM,QAAQ,MAAM,eAAe,CAAC;AACpC,QAAM,UAAU,MAAM,eAAe,MAAM;AAC3C,QAAM,KAAK,OAAO,UAAU,KAAK,IAAI;AAGrC,EAAAC,WAAU,MAAM;AACd,QAAI,OAAO,QAAQ,OAAO,OAAQ,WAAU,EAAE;AAAA,EAChD,GAAG,CAAC,IAAI,MAAM,CAAC;AAEf,QAAM,OAAO,OAAO,KAAK,EAAE;AAC3B,QAAM,MAAa,OAAO,QAAQ,KAAK,MAAM,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC;AACxE,QAAM,WAAW,QAAQ;AACzB,QAAM,EAAE,OAAO,QAAQ,KAAK,IAAI;AAAA,IAC9B;AAAA;AAAA,IAEA,kBAAkB,OAAO,CAAC,MAAM,EAAE,YAAY,MAAM,SAAS;AAAA,EAC/D;AAEA,QAAM,SAAS,CAAC,YAAY,OAAO,gBAAgB,UAAU,cAAc;AAC3E,QAAM,SAAS,SAAS,OAAO,eAAe;AAC9C,QAAM,QAAQ,SAAS,KAAK,EAAE;AAC9B,QAAM,MAAM,YAAY,KAAK,KAAK,QAAQ,KAAK,QAAQ,QAAQ,KAAK,CAAC;AACrE,UAAQ,QAAQ,KAAK,IAAI;AACzB,QAAM,MAAM,UAAU,KAAK,QAAQ,KAAK,KAAK,GAAG,KAAK,IAAI,QAAQ,MAAM;AACvE,OAAK,QAAQ,KAAK,IAAI;AAEtB,QAAM,QAAQ,CAAC,QAAuB,IAAW,QAC/C,SAAS,CAAC,MAAM;AACd,UAAM,IAAI,SAAS,GAAG,EAAE;AACxB,WAAO,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,QAAQ,WAAW,QAAQ,MAAM,GAAG,EAAE,CAAC,GAAG,GAAG,OAAO,EAAE;AAAA,EAC9E,CAAC;AACH,QAAM,YAAY,CAAC,WACjB,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,QAAQ,GAAG,OAAO,GAAG,QAAQ,KAAK,CAAC;AAC/D,QAAM,OAAO,CAAC,UACZ,MAAM,EAAE,QAAQ,WAAW,KAAK,KAAK,QAAQ,KAAK,OAAO,QAAQ,QAAQ,KAAK,CAAC,EAAE,CAAC;AAMpF,EAAAA,WAAU,MAAM;AACd,UAAM,MAAM,IAAI,GAAG,GAAG;AACtB,QAAI,KAAK,WAAW,QAAQ,QAAQ,SAAS,CAAC,MAAM,SAAS,QAAQ;AACnE,eAAS,CAAC,MAAM;AACd,cAAM,IAAI,SAAS,KAAK,EAAE;AAE1B,YAAI,EAAE,CAAC,GAAG,UAAU,KAAM,QAAO;AACjC,eAAO,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,QAAQ,WAAW,GAAG,EAAE,CAAC,GAAG,QAAQ,IAAI,EAAE;AAAA,MAClE,CAAC;AAAA,EACL,CAAC;AACD,QAAM,QAAQ,CAAC,MAAyB,KAAoB,MAC1D,KAAK,WAAW,IACZ,OACC,MAAM,KAAK,IAAI,GAAG,KAAK,QAAQ,OAAO,EAAE,CAAC,IAAI,IAAI,KAAK,UAAU,KAAK,MAAM,KAAK;AAMvF,QAAM,SAAS,OAAO,MAAmC;AACvD,QAAI,KAAK,QAAS;AAClB,SAAK,UAAU;AACf,aAAS,IAAI;AACb,QAAI;AACJ,UAAM,OAAO,MAAM,WAAW,CAAC;AAC/B,QAAI,CAAC,KAAK,GAAI,WAAU,EAAE,IAAI,OAAO,QAAQ,KAAK,QAAQ,UAAU,CAAC,EAAE;AAAA,SAClE;AACH,gBAAU,EAAE,IAAI,OAAO,QAAQ,wBAAwB,UAAU,CAAC,EAAE;AACpE,UAAI;AACF,cAAM,gBAAgB,YAAY;AAEhC,iBAAO,MAAM,GAAG,KAAK,MAAM;AAAA,CAAI;AAC/B,oBAAU,MAAM,UAAU,KAAK,OAAO,OAAO;AAI7C,gBAAM,IAAI,QAAc,CAAC,MAAM,aAAa,CAAC,CAAC;AAC9C,iBAAO,MAAM,KAAK,MAAM,MAAM;AAAA,UAAC;AAC/B,eAAK,UAAU;AAAA,QACjB,CAAC;AAAA,MACH,SAAS,GAAG;AACV,kBAAU,EAAE,IAAI,OAAO,QAAQ,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,GAAG,UAAU,CAAC,EAAE;AAAA,MAC1F;AAAA,IACF;AACA,SAAK,UAAU;AACf,QAAI,CAAC,QAAQ;AACX,eAAS;AAAA,QACP,QAAQ;AAAA,QACR,QAAQ;AAAA,UACN,qBAAqB,QAAQ,MAAM;AAAA,UACnC,GAAI,KAAK,SAAS,OAAO,CAAC,IAAI,CAAC,iCAAiC,KAAK,IAAI,EAAE;AAAA,QAC7E;AAAA,MACF,CAAC;AAAA,aACM,QAAQ,SAAS,SAAS,EAAG,UAAS,WAAW,QAAQ,SAAS,KAAK,IAAI,CAAC,EAAE;AAAA,EACzF;AAEA,EAAAE;AAAA,IACE,CAAC,OAAO,QAAQ;AACd,UAAI,KAAK,QAAS;AAClB,eAAS,IAAI;AACb,UAAI,YAAY,MAAM;AACpB,YAAI,IAAI,OAAQ,YAAW,IAAI;AAAA,iBACtB,IAAI,QAAQ;AACnB,oBAAU,EAAE,MAAM,QAAQ,OAAO,CAAC;AAClC,qBAAW,IAAI;AAAA,QACjB,WAAW,IAAI,aAAa,IAAI,OAAQ,WAAU,EAAE,MAAM,KAAK,OAAO,KAAK,MAAM,GAAG,EAAE,EAAE,CAAC;AAAA,iBAChF,UAAU,MAAM,CAAC,IAAI,QAAQ,CAAC,IAAI;AACzC,oBAAU,EAAE,MAAM,KAAK,OAAO,OAAO,MAAM,KAAK,EAAE,CAAC;AACrD;AAAA,MACF;AACA,UAAI,UAAU,OAAO,IAAI,OAAQ,QAAO,KAAK;AAE7C,YAAM,MAAM,OAAO,OAAO,KAAK,MAAM;AACrC,YAAM,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE;AAChC,UAAI,IAAI,OAAO,IAAI,cAAc,IAAI,WAAW;AAC9C,cAAM,OAAO,IAAI,aAAc,IAAI,OAAO,IAAI;AAC9C,eAAQ,MAAM,KAAK,KAAK,OAAO,KAAK,CAAC,KAAK,GAAa;AACvD,cAAM,QAAQ;AAAA,MAChB,WAAW,UAAU,OAAO,UAAU,KAAK;AACzC,cAAM,OAAO;AAAA,UACX,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,UACvB;AAAA,UACA,UAAU,MAAM,IAAI;AAAA,QACtB;AACA,YAAI,SAAS,KAAM,WAAU,IAAI;AAAA,MACnC,WAAW,QAAQ;AACjB,aAAK,QAAQ,MAAM,IAAI,KAAK,IAAI,OAAO,QAAQ,CAAC,IAAI,SAAS,IAAI,MAAM;AAAA,eAChE,UAAU,OAAO,QAAQ;AAChC,kBAAU,EAAE,MAAM,cAAc,KAAK,OAAO,IAAI,EAAE,CAAC;AAAA,eAC5C,UAAU,OAAO,QAAQ;AAChC,kBAAU,EAAE,QAAQ,gBAAgB,KAAK,OAAO,MAAM,EAAE,CAAC;AAAA,eAClD,UAAU,OAAO,CAAC,SAAU,YAAW,EAAE,QAAQ,KAAK,OAAO,KAAK,CAAC;AAAA,eACnE,UAAU,OAAO,CAAC;AACzB,kBAAU;AAAA,UACR,MAAM;AAAA,UACN,GAAI,QAAQ,UAAU,EAAE,QAAQ,UAAmB,MAAM,WAAoB,IAAI,CAAC;AAAA,QACpF,CAAC;AAAA,eACM,UAAU,IAAK,OAAM,QAAQ;AAAA,gBAC5B,UAAU,OAAO,UAAU,OAAO,UAAU,QAAQ,SAAS,MAAM;AAC3E,cAAM,OAAO,UAAU,MAAM,WAAW,IAAI,IAAI,WAAW,IAAI;AAC/D,gBAAQ,IAAI;AACZ,iBAAS,iBAAiB,QAAQ,MAAO,GAAG,OAAO,GAAI,MAAM,GAAG,IAAI,IAAI,EAAE;AAAA,MAC5E,WAAW,IAAI,QAAQ;AACrB,cAAM,SAAS,IAAI,GAAG,GAAG;AACzB,YAAI,WAAW,OAAW,UAAS,EAAE,QAAQ,QAAQ,CAAC,EAAE,CAAC;AAAA,MAC3D,WAAW,UAAU,OAAO,QAAQ,UAAU;AAC5C,cAAM,SAAS,IAAI,GAAG,GAAG;AACzB,YAAI,QAAQ,SAAS,aAAc,MAAK,OAAO,MAAM;AAAA,MACvD,WAAW,UAAU,KAAK;AACxB,cAAM,SAAS,IAAI,GAAG,GAAG;AACzB,YAAI,WAAW,OAAW,MAAK,KAAK,MAAM,EAAE,KAAK,QAAQ;AAAA,MAC3D;AAAA,IACF;AAAA;AAAA,IAEA,EAAE,UAAU,UAAU,KAAK;AAAA,EAC7B;AAEA,QAAM,OAAO,CAAC,MAAc,KAAK,GAAG,OAAO;AAC3C,QAAM,YAAY,MAAM,aAAa,CAAC;AACtC,QAAM,SAAS,CAAC,GAAQ,MAAoB,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,KAAK,GAAG,GAAG,EAAE,IAAI;AACzF,QAAM,UAAU,IAAI,MAAM,KAAK,MAAM,MAAM;AAC3C,QAAM,IAAI,KAAK;AACf,QAAM,aAAa;AAAA,IACjB,QAAQ,UAAU,WAAW,EAAE,MAAM,KAAK;AAAA,IAC1C,QAAQ,UAAU,SAAS,EAAE,IAAI,IAAI,YAAY,EAAE,IAAI,CAAC,KAAK;AAAA,IAC7D,WAAW,EAAE,IAAI,GAAG,UAAU,MAAM,EAAE;AAAA,IACtC,OAAO,GAAG,IAAI,MAAM,OAAO,IAAI,WAAW,IAAI,KAAK,GAAG,KAAK;AAAA,IAC3D,MAAM,SAAU,MAAM,WAAW,CAAC,OAAQ,kBAAa;AAAA,EACzD,EACG,OAAO,CAAC,MAAM,MAAM,EAAE,EACtB,KAAK,KAAK;AACb,QAAM,WAAW,KAAK,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG;AACnD,QAAM,UAAU,KAAK,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,MAAM,SAAS,GAAG,CAAC,KAAK;AACpE,QAAM,WAAW,MAAM,IAAI,eAAe;AAC1C,QAAM,UAAU,KAAK;AAAA,IACnB;AAAA,IACA,MAAM,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE;AAAA,EACtC;AACA,QAAM,QAAQ,eAAe,WAAW,EAAE;AAC1C,QAAM,QACJ,SAAS,OACL,MAAM,QACJ,KACA,kBACF,IAAI,WAAW,IACb,EAAE,SAAS,KACT,6BACA,iBACF;AACR,QAAM,SAAS,QACX,EAAE,MAAM,OAAO,MAAM,OAAgB,IACrC,MAAM,QACJ,EAAE,MAAM,UAAU,MAAM,KAAK,IAAI,MAAM,MAAe,IACtD;AAAA,IACE,MAAM,UACF,2CACA,WACE,gBACA,QAAQ,WACN,WAAW,SAAS,IACpB,QAAQ,UACN,aACA;AAAA,IACV,MAAM;AAAA,EACR;AAEN,MAAI,UAAU;AACZ,WACE,gBAAAR;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ,MAAM;AAAA,QACd,QAAQ,MAAM;AAAA,QACd;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,MAAM;AAAA,QACb,WAAW,MAAM;AAAA,QACjB,SAAS,MAAM,SAAS,IAAI;AAAA,QAC5B,UAAU,CAAC,MAAM,KAAK,OAAO,CAAC;AAAA;AAAA,IAChC;AAGJ,QAAM,YAAoB;AAAA,IACxB,GAAG,QAAQ,IAAI,CAAC,GAAG,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC;AAAA,IAC3C,GAAI,QAAQ,CAAC,CAAC,EAAE,MAAM,KAAK,KAAK,IAAI,MAAM,QAAiB,CAAC,CAAC,IAAI,CAAC;AAAA,EACpE;AACA,QAAM,WAAW,KAAK,QAAQ,GAAG,SAAS;AAE1C,SACE,gBAAAC,MAACQ,MAAA,EAAI,eAAc,UAAS,QAAQ,YAClC;AAAA,oBAAAT,KAACU,OAAA,EAAK,MAAK,YACT,0BAAAV;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,UACJ,SAAS,SAAS,IACd,eAAe,UAAU,SAAS,OAAO,IACzC,CAAC,EAAE,MAAM,kBAAkB,MAAM,QAAQ,CAAC;AAAA,UAC9C;AAAA,QACF;AAAA;AAAA,IACF,GACF;AAAA,IACC,UACC,gBAAAA,KAACS,MAAA,EACE,eAAK,IAAI,CAAC,MACT,gBAAAT,KAACU,OAAA,EAAgB,SAAS,EAAE,OAAO,KAAM,GAAG,MAAM,EAAE,OAAO,MAAM,UAAU,OAAO,GAC/E,cAAI,EAAE,KAAK,OADH,EAAE,EAEb,CACD,GACH;AAAA;AAAA;AAAA,MAIA,gBAAAV,KAACU,OAAA,EAAK,MAAK,YAAW,SAAO,MAAE,GAAG,MAAM,OAAO,GAC5C,eAAK,IAAI,QAAQ,IAAI,WAAW,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,GAC9D;AAAA;AAAA,IAED,MAAM,IAAI,OAAO,IAChB,gBAAAV,KAACU,OAAA,EAAK,MAAK,YACT,0BAAAV,KAAC,QAAK,MAAM,QAAQ,OAAO,OAAO,GAAG,GACvC,IACE;AAAA,IACH,MAAM,IAAI,QAAQ,IACjB,gBAAAA,KAACU,OAAA,EAAK,MAAK,YAAY,GAAG,MAAM,OAAO,GACpC,eAAK,UAAU,GAClB,IACE;AAAA,IACH,WACC,gBAAAV;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,OAAO,cAAc,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC;AAAA,QAChD;AAAA,QACA,OAAO;AAAA,QACP,QAAQ;AAAA;AAAA,IACV,IACE,SACF,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,UAAU,OAAO,OAAO,IAAI,MAAM,IAAI;AAAA,QACtC,QAAQ,IAAI,SAAS,SAAS,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,KAAK;AAAA,QAC3D,MAAM;AAAA,QACN,UAAU,MAAM;AAAA;AAAA,IAClB,IAEA,UAAU,IAAI,CAAC,GAAG;AAAA;AAAA,MAEhB,gBAAAA,KAACU,OAAA,EAAa,MAAK,YAChB,gBAAM,MAAM,MACX,gBAAAV,KAACU,OAAA,EAAK,SAAO,MAAE,eAAK,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,GAAE,IAEnD,gBAAAV,KAAC,QAAK,MAAM,QAAQ,GAAG,OAAO,GAAG,KAJ1B,CAMX;AAAA,KACD;AAAA,IAEH,gBAAAA,KAACS,MAAA,EAAI,UAAU,GAAG;AAAA,IACjB,MAAM,IAAI,MAAM,IACf,gBAAAT,KAACU,OAAA,EAAK,MAAK,YAAY,GAAG,MAAM,OAAO,GACpC,eAAK,OAAO,SAAS,IAAI,IAAI,mBAAmB,GACnD,IACE;AAAA,IACH,MAAM,IAAI,QAAQ,IACjB,gBAAAV,KAACU,OAAA,EAAK,MAAK,YAAY,GAAG,MAAM,OAAO,IAAI,GACxC,eAAK,OAAO,IAAI,GACnB,IACE;AAAA,KACN;AAEJ;;;AmBvaA,IAAM,wBAAwB;AAEvB,SAAS,cAAc,MAAwC;AACpE,QAAM,KAAK,OAAO,EAAE,MAAM,KAAK,QAAQ,UAAU,KAAK,CAAC;AACvD,QAAM,MAAM,KAAK,OAAO,KAAK;AAC7B,QAAM,QAAQ,KAAK,eAAe;AAClC,MAAI,WAA0C;AAC9C,MAAI,gBAAgB;AACpB,MAAI,WAAW,OAAO;AAGtB,MAAI,WAA8B,CAAC;AAGnC,MAAI,YAAY;AAChB,MAAI,SAAS;AAEb,QAAM,cAAc,oBAAI,IAA0B;AAElD,iBAAe,IAAI,OAAuB,MAAuC;AAC/E,QAAI,YAAY,KAAK,IAAI,IAAI,YAAY,OAAO;AAC9C,iBAAW,IAAI;AACf,kBAAY,MAAM,cAAc,KAAK,QAAQ,EAAE,OAAO,KAAK,CAAC,GAAG;AAAA,IACjE;AACA,UAAM,QACJ,GAAG,QAAQ,uEAAuE,EAAE,IAAI,EAIvF,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI;AACZ,UAAM,WAAW,UAAU;AAC3B,gBAAY;AACZ,UAAM,WAAW,MAAM,cAAc,IAAI;AAAA,MACvC,GAAG;AAAA,MACH;AAAA,MACA,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK,WAAW,eAAe;AAAA,MACxC,cAAc;AAAA,MACd,aAAa,EAAE,OAAO,aAAa,OAAO,KAAK;AAAA,IACjD,CAAC;AACD,WAAO,EAAE,UAAU,SAAS;AAAA,EAC9B;AAEA,SAAO;AAAA,IACL,QAAQ,QAAQ,CAAC,GAAG,EAAE,OAAO,MAAM,IAAI,CAAC,GAAG;AACzC,UAAI,OAAQ,QAAO,QAAQ,OAAO,IAAI,MAAM,6BAA6B,CAAC;AAC1E,YAAM,MAAM,GAAG,OAAO,SAAS,MAAM,IAAI,KAAK,UAAU,KAAK,CAAC;AAI9D,UAAI,aAAa,QAAQ,kBAAkB,IAAK,QAAO;AACvD,YAAM,QAAQ,UAAU,MAAM,MAAM,MAAS,KAAK,QAAQ,QAAQ;AAClE,sBAAgB;AAChB,YAAM,OAA+B,MAClC,KAAK,MAAM,IAAI,OAAO,IAAI,CAAC,EAC3B,QAAQ,MAAM;AACb,YAAI,aAAa,KAAM,YAAW;AAAA,MACpC,CAAC;AACH,iBAAW;AACX,aAAO;AAAA,IACT;AAAA,IACA,MAAM,YAAY,IAAI,KAAK;AACzB,UAAI,OAAQ,OAAM,IAAI,MAAM,6BAA6B;AACzD,aAAO,gBAAgB,IAAI,IAAI,EAAE,YAAY,IAAI,CAAC;AAAA,IACpD;AAAA,IACA,KAAK,YAAY,IAAI;AACnB,UAAI,OAAQ,OAAM,IAAI,MAAM,6BAA6B;AACzD,aAAO,QAAQ,IAAI,IAAI,UAAU;AAAA,IACnC;AAAA,IACA,MAAM,QAAQ;AACZ,UAAI,OAAQ;AACZ,eAAS;AACT,UAAI;AACF,cAAM,UAAU,MAAM,MAAM,MAAS;AAAA,MACvC,UAAE;AACA,WAAG,MAAM;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;;;ApB1HA,eAAsB,aAAa,MAA0C;AAC3E,QAAM,UAAU,cAAc;AAAA,IAC5B,QAAQ,KAAK;AAAA,IACb,QAAQ,KAAK;AAAA,IACb,QAAQ,eAAe;AAAA,EACzB,CAAC;AACD,MAAI;AAEJ,OAAK,SAAS,IAAI,MAAM,KAAK,QAAQ,CAAC;AACtC,OAAK,SAAS,IAAI,MAAM,QAAQ,MAAM,CAAC;AACvC,QAAM;AAAA,IACJ,cAAc,KAAK;AAAA,MACjB;AAAA,MACA,mBACE,KAAK,qBAAsB,MAAM,gCAAgC,KAAM;AAAA,MACzE,QAAQ,KAAK,UAAU;AAAA,IACzB,CAAC;AAAA,IACD,EAAE,iBAAiB,MAAM,aAAa,KAAK;AAAA,EAC7C;AACA,QAAM,IAAI,cAAc;AAC1B;","names":["Box","Text","useInput","useStdout","useWindowSize","useEffect","useRef","useState","notice","Box","Text","CONTROL","segmenter","jsx","jsxs","segmenter","notice","Box","Text","Box","jsx","Box","useEffect","useRef","useState","key","jsx","jsxs","cell","useStdout","useState","useRef","useEffect","useWindowSize","useInput","Box","Text"]}
|
|
File without changes
|
|
File without changes
|