@0xbuff/throughline 0.0.0-stage → 0.0.2

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/model.ts","../src/limits.ts","../src/compiler.ts","../src/domains/lines.ts","../src/authoring.ts","../src/dsl.ts","../src/tracer.ts","../src/domains/binary.ts","../src/domains/bindings.ts","../src/domains/callstack.ts","../src/domains/matrix.ts","../src/domains/registry.ts"],"sourcesContent":["export type Value =\n\t| null\n\t| boolean\n\t| number\n\t| string\n\t| Value[]\n\t| { [key: string]: Value };\nexport const VIEWS = [\n\t\"auto\",\n\t\"text\",\n\t\"number\",\n\t\"array\",\n\t\"stack\",\n\t\"matrix\",\n\t\"bits\",\n\t\"record\",\n] as const;\nexport type View = (typeof VIEWS)[number];\nexport type Entity = {\n\tid: string;\n\tlabel: string;\n\tvalue: Value;\n\tlane?: string;\n\tview?: View;\n\t/** Absent from the scene until explicitly shown; identity stays stable. */\n\thidden?: boolean;\n};\nexport type Relation = {\n\tid: string;\n\tfrom: string;\n\tto: string;\n\tlabel?: string;\n\thidden?: boolean;\n};\nexport type SourceLocation = { line: number };\n/** Targets address an entity or a position inside its value: `arr`, `arr[3]`, `grid[1][2]`, `cfg.mode`. */\nexport type Event = (\n\t| { op: \"set\"; target: string; value: Value }\n\t| { op: \"focus\"; targets: string[] }\n\t| { op: \"send\"; relation: string; value?: Value }\n\t| { op: \"note\"; text: string }\n\t| { op: \"show\" | \"hide\"; kind: \"node\" | \"link\"; id: string }\n) & { source?: SourceLocation };\nexport type Beat = { label: string; events: Event[]; source?: SourceLocation };\nexport const GROUP_LAYOUTS = [\"row\", \"column\", \"tree\"] as const;\nexport type GroupLayout = (typeof GROUP_LAYOUTS)[number];\nexport type SceneGroup = { name: string; layout: GroupLayout };\nexport type Program = {\n\tversion: 1;\n\tentities: Entity[];\n\trelations: Relation[];\n\tbeats: Beat[];\n\tgroups?: SceneGroup[];\n};\nexport type Snapshot = {\n\tentities: Entity[];\n\trelations: Relation[];\n\tactive: string[];\n\tchanged: string[];\n\ttransfers: { relation: string; value?: Value }[];\n\tnotes: string[];\n};\nexport type Frame = {\n\tindex: number;\n\tlabel: string;\n\tstate: Snapshot;\n\tevents: Event[];\n\tsource?: SourceLocation;\n};\nexport type Trace = { version: 1; frames: Frame[]; groups?: SceneGroup[] };\nexport type Diagnostic = { message: string; line?: number; beat?: number };\nexport class ProgramError extends Error {\n\tconstructor(public diagnostics: Diagnostic[]) {\n\t\tsuper(\n\t\t\tdiagnostics\n\t\t\t\t.map(\n\t\t\t\t\t({ message, line, beat }) =>\n\t\t\t\t\t\t`${line ? `Line ${line}: ` : beat !== undefined ? `Step ${beat + 1}: ` : \"\"}${message}`,\n\t\t\t\t)\n\t\t\t\t.join(\"\\n\"),\n\t\t);\n\t\tthis.name = \"ProgramError\";\n\t}\n}\n","import { ProgramError } from \"./model.js\";\n\n/** Fixed v1 safety ceilings, independent of machine speed or wall-clock timing. */\nexport const COMPILATION_LIMITS = Object.freeze({\n\tsourceCharacters: 262_144,\n\tprogramUnits: 1_000_000,\n\ttraceUnits: 8_000_000,\n\tentities: 200,\n\trelations: 1000,\n\tsteps: 2000,\n\tevents: 10_000,\n});\n\n/**\n * Account for expanded JSON, including repeated references. One unit per\n * UTF-16 code unit in strings/keys, eight per scalar/container. This is a\n * deterministic work/payload budget, not a claim about exact heap bytes.\n * Memoization makes shared immutable snapshots cheap to measure without\n * discounting their cost when serialized. Use a fresh budget for mutable data.\n */\nexport function createBudget(\n\tname: string,\n\tlimit: number,\n): (value: unknown) => void {\n\tconst sizes = new WeakMap<object, number>();\n\tconst visiting = new WeakSet<object>();\n\tlet total = 0;\n\tconst fail = (message: string): never => {\n\t\tthrow new ProgramError([{ message: `${name}: ${message}` }]);\n\t};\n\tconst check = (size: number): number => {\n\t\tif (size > limit) fail(`exceeds compilation limit (${limit} units).`);\n\t\treturn size;\n\t};\n\tconst measure = (value: unknown, depth: number): number => {\n\t\tif (depth > 64) fail(\"JSON nesting exceeds the compilation limit.\");\n\t\tif (value === null || typeof value === \"boolean\") return 8;\n\t\tif (typeof value === \"string\") return check(8 + value.length);\n\t\tif (typeof value === \"number\" && Number.isFinite(value)) return 8;\n\t\tif (typeof value !== \"object\" || value === null)\n\t\t\treturn fail(\"expected finite JSON data.\");\n\t\tif (visiting.has(value)) fail(\"cyclic values are not JSON data.\");\n\t\tconst cached = sizes.get(value);\n\t\tif (cached !== undefined) return cached;\n\t\tif (\n\t\t\t!Array.isArray(value) &&\n\t\t\tObject.getPrototypeOf(value) !== Object.prototype\n\t\t)\n\t\t\tfail(\"expected plain JSON objects.\");\n\t\tvisiting.add(value);\n\t\tlet size = 8;\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (const item of value) size = check(size + measure(item, depth + 1));\n\t\t} else {\n\t\t\tfor (const [key, item] of Object.entries(value)) {\n\t\t\t\t// Optional object fields are omitted by JSON.stringify too.\n\t\t\t\tif (item !== undefined)\n\t\t\t\t\tsize = check(size + key.length + measure(item, depth + 1));\n\t\t\t}\n\t\t}\n\t\tvisiting.delete(value);\n\t\tsizes.set(value, size);\n\t\treturn size;\n\t};\n\treturn (value) => {\n\t\ttotal = check(total + measure(value, 0));\n\t};\n}\n\nexport function checkSourceSize(characters: number): void {\n\tif (characters > COMPILATION_LIMITS.sourceCharacters)\n\t\tthrow new ProgramError([\n\t\t\t{\n\t\t\t\tmessage: `Source exceeds compilation limit (${COMPILATION_LIMITS.sourceCharacters} characters).`,\n\t\t\t},\n\t\t]);\n}\n","import { COMPILATION_LIMITS, createBudget } from \"./limits.js\";\nimport {\n\ttype Diagnostic,\n\ttype Event,\n\tGROUP_LAYOUTS,\n\ttype Program,\n\tProgramError,\n\ttype Snapshot,\n\ttype Trace,\n\ttype Value,\n\tVIEWS,\n} from \"./model.js\";\nimport { overlaps, parseTarget, setAt, type Target } from \"./path.js\";\n\nconst owns = (object: object, key: string) => Object.hasOwn(object, key);\nconst isValue = (value: unknown, depth = 0): boolean => {\n\tif (depth > 32) return false;\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\")\n\t\treturn true;\n\tif (typeof value === \"number\") return Number.isFinite(value);\n\tif (Array.isArray(value))\n\t\treturn value.every((item) => isValue(item, depth + 1));\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\tObject.getPrototypeOf(value) === Object.prototype &&\n\t\tObject.values(value).every((item) => isValue(item, depth + 1))\n\t);\n};\nconst record = (value: unknown): value is Record<string, unknown> =>\n\ttypeof value === \"object\" && value !== null && !Array.isArray(value);\nconst identifier = (value: unknown): value is string =>\n\ttypeof value === \"string\" && /^[A-Za-z][\\w-]*$/.test(value);\n\nexport function validateProgram(input: unknown): asserts input is Program {\n\tif (\n\t\t!record(input) ||\n\t\tinput.version !== 1 ||\n\t\t!Array.isArray(input.entities) ||\n\t\t!Array.isArray(input.relations) ||\n\t\t!Array.isArray(input.beats)\n\t) {\n\t\tthrow new ProgramError([\n\t\t\t{ message: \"Expected version: 1 and entities, relations, beats arrays.\" },\n\t\t]);\n\t}\n\tif (\n\t\tinput.entities.length > COMPILATION_LIMITS.entities ||\n\t\tinput.relations.length > COMPILATION_LIMITS.relations ||\n\t\tinput.beats.length > COMPILATION_LIMITS.steps\n\t) {\n\t\tthrow new ProgramError([\n\t\t\t{\n\t\t\t\tmessage:\n\t\t\t\t\t\"Program exceeds limits (200 entities, 1000 relations, 2000 steps).\",\n\t\t\t},\n\t\t]);\n\t}\n\tlet eventCount = 0;\n\tfor (const beat of input.beats) {\n\t\tif (record(beat) && Array.isArray(beat.events))\n\t\t\teventCount += beat.events.length;\n\t\tif (eventCount > COMPILATION_LIMITS.events)\n\t\t\tthrow new ProgramError([\n\t\t\t\t{ message: `Program exceeds ${COMPILATION_LIMITS.events} events.` },\n\t\t\t]);\n\t}\n\tcreateBudget(\"Program\", COMPILATION_LIMITS.programUnits)(input);\n\tconst diagnostics: Diagnostic[] = [];\n\tif (input.groups !== undefined) {\n\t\tif (\n\t\t\t!Array.isArray(input.groups) ||\n\t\t\tinput.groups.length > 200 ||\n\t\t\tinput.groups.some(\n\t\t\t\t(group) =>\n\t\t\t\t\t!record(group) ||\n\t\t\t\t\ttypeof group.name !== \"string\" ||\n\t\t\t\t\t!(GROUP_LAYOUTS as readonly unknown[]).includes(group.layout),\n\t\t\t)\n\t\t)\n\t\t\tdiagnostics.push({\n\t\t\t\tmessage:\n\t\t\t\t\t\"Groups require a name and a row, column, or tree layout (at most 200).\",\n\t\t\t});\n\t\telse if (\n\t\t\tnew Set(input.groups.map((group) => group.name)).size !==\n\t\t\tinput.groups.length\n\t\t)\n\t\t\tdiagnostics.push({ message: \"Duplicate group name.\" });\n\t}\n\tconst entities = new Set<string>();\n\tconst relations = new Set<string>();\n\tfor (const entity of input.entities) {\n\t\tif (\n\t\t\t!record(entity) ||\n\t\t\t!identifier(entity.id) ||\n\t\t\ttypeof entity.label !== \"string\" ||\n\t\t\t!owns(entity, \"value\") ||\n\t\t\t!isValue(entity.value) ||\n\t\t\t(entity.hidden !== undefined && typeof entity.hidden !== \"boolean\") ||\n\t\t\t(entity.lane !== undefined && typeof entity.lane !== \"string\") ||\n\t\t\t(entity.view !== undefined &&\n\t\t\t\t!(VIEWS as readonly unknown[]).includes(entity.view))\n\t\t) {\n\t\t\tdiagnostics.push({\n\t\t\t\tmessage: `Each entity needs a valid id, label, JSON value, optional string lane, and optional view (${VIEWS.join(\", \")}).`,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tif (entities.has(entity.id))\n\t\t\tdiagnostics.push({ message: `Duplicate entity “${entity.id}”.` });\n\t\tentities.add(entity.id);\n\t}\n\tfor (const relation of input.relations) {\n\t\tif (\n\t\t\t!record(relation) ||\n\t\t\t!identifier(relation.id) ||\n\t\t\ttypeof relation.from !== \"string\" ||\n\t\t\ttypeof relation.to !== \"string\" ||\n\t\t\t(relation.hidden !== undefined && typeof relation.hidden !== \"boolean\") ||\n\t\t\t(relation.label !== undefined && typeof relation.label !== \"string\")\n\t\t) {\n\t\t\tdiagnostics.push({\n\t\t\t\tmessage:\n\t\t\t\t\t\"Each relation needs an id, from, to, and optional string label.\",\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tif (relations.has(relation.id))\n\t\t\tdiagnostics.push({ message: `Duplicate relation “${relation.id}”.` });\n\t\trelations.add(relation.id);\n\t\tif (!entities.has(relation.from) || !entities.has(relation.to))\n\t\t\tdiagnostics.push({\n\t\t\t\tmessage: `Relation “${relation.id}” references an unknown entity.`,\n\t\t\t});\n\t}\n\tinput.beats.forEach((beat, index) => {\n\t\tif (\n\t\t\t!record(beat) ||\n\t\t\ttypeof beat.label !== \"string\" ||\n\t\t\t!Array.isArray(beat.events)\n\t\t) {\n\t\t\tdiagnostics.push({\n\t\t\t\tmessage: \"Each step needs a label and events array.\",\n\t\t\t\tbeat: index,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst writes: Target[] = [];\n\t\tconst visibility = new Set<string>();\n\t\tfor (const event of beat.events) {\n\t\t\tconst fail = (message: string) =>\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\tmessage,\n\t\t\t\t\tbeat: index,\n\t\t\t\t\tline:\n\t\t\t\t\t\trecord(event) &&\n\t\t\t\t\t\trecord(event.source) &&\n\t\t\t\t\t\tNumber.isInteger(event.source.line)\n\t\t\t\t\t\t\t? Number(event.source.line)\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t});\n\t\t\tif (!record(event)) {\n\t\t\t\tfail(\"Expected an event object.\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (event.op === \"show\" || event.op === \"hide\") {\n\t\t\t\tconst ids =\n\t\t\t\t\tevent.kind === \"node\"\n\t\t\t\t\t\t? entities\n\t\t\t\t\t\t: event.kind === \"link\"\n\t\t\t\t\t\t\t? relations\n\t\t\t\t\t\t\t: null;\n\t\t\t\tif (!ids || typeof event.id !== \"string\" || !ids.has(event.id))\n\t\t\t\t\tfail(`Unknown ${String(event.kind)} “${String(event.id)}”.`);\n\t\t\t\tconst key = `${event.kind}:${event.id}`;\n\t\t\t\tif (visibility.has(key))\n\t\t\t\t\tfail(`Conflicting visibility for “${String(event.id)}” in one step.`);\n\t\t\t\tvisibility.add(key);\n\t\t\t} else if (event.op === \"set\") {\n\t\t\t\tconst target =\n\t\t\t\t\ttypeof event.target === \"string\" ? parseTarget(event.target) : null;\n\t\t\t\tif (!target || !entities.has(target.id))\n\t\t\t\t\tfail(`Unknown set target “${String(event.target)}”.`);\n\t\t\t\tif (!owns(event, \"value\") || !isValue(event.value))\n\t\t\t\t\tfail(\"set requires a finite JSON value.\");\n\t\t\t\tif (target) {\n\t\t\t\t\tif (\n\t\t\t\t\t\twrites.some(\n\t\t\t\t\t\t\t(write) =>\n\t\t\t\t\t\t\t\twrite.id === target.id && overlaps(write.path, target.path),\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t\t\tfail(\n\t\t\t\t\t\t\t`Conflicting writes to “${event.target}” in one step; split into separate steps.`,\n\t\t\t\t\t\t);\n\t\t\t\t\twrites.push(target);\n\t\t\t\t}\n\t\t\t} else if (event.op === \"focus\") {\n\t\t\t\tif (\n\t\t\t\t\t!Array.isArray(event.targets) ||\n\t\t\t\t\tevent.targets.some((text) => {\n\t\t\t\t\t\tconst target = typeof text === \"string\" ? parseTarget(text) : null;\n\t\t\t\t\t\treturn !target || !entities.has(target.id);\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t\t\tfail(\n\t\t\t\t\t\t\"focus requires known entity ids, optionally with a position such as data[3].\",\n\t\t\t\t\t);\n\t\t\t} else if (event.op === \"send\") {\n\t\t\t\tif (\n\t\t\t\t\ttypeof event.relation !== \"string\" ||\n\t\t\t\t\t!relations.has(event.relation)\n\t\t\t\t)\n\t\t\t\t\tfail(`Unknown relation “${String(event.relation)}”.`);\n\t\t\t\tif (owns(event, \"value\") && !isValue(event.value))\n\t\t\t\t\tfail(\"send requires a finite JSON value.\");\n\t\t\t} else if (event.op === \"note\") {\n\t\t\t\tif (typeof event.text !== \"string\") fail(\"note requires text.\");\n\t\t\t} else fail(`Unknown event operation “${String(event.op)}”.`);\n\t\t\tif (\n\t\t\t\tevent.source !== undefined &&\n\t\t\t\t(!record(event.source) ||\n\t\t\t\t\t!Number.isInteger(event.source.line) ||\n\t\t\t\t\tNumber(event.source.line) < 1)\n\t\t\t)\n\t\t\t\tfail(\"Source line must be a positive integer.\");\n\t\t}\n\t\tif (\n\t\t\tbeat.source !== undefined &&\n\t\t\t(!record(beat.source) ||\n\t\t\t\t!Number.isInteger(beat.source.line) ||\n\t\t\t\tNumber(beat.source.line) < 1)\n\t\t)\n\t\t\tdiagnostics.push({\n\t\t\t\tmessage: \"Step source line must be a positive integer.\",\n\t\t\t\tbeat: index,\n\t\t\t});\n\t});\n\tif (diagnostics.length) throw new ProgramError(diagnostics);\n}\n\nexport function reduceBeat(\n\tprevious: Snapshot,\n\tevents: readonly Event[],\n): Snapshot {\n\tconst writes = new Map<string, { path: Target[\"path\"]; value: Value }[]>();\n\tconst nodes = new Map<string, boolean>();\n\tconst links = new Map<string, boolean>();\n\tfor (const event of events) {\n\t\tif (event.op === \"show\" || event.op === \"hide\")\n\t\t\t(event.kind === \"node\" ? nodes : links).set(\n\t\t\t\tevent.id,\n\t\t\t\tevent.op === \"hide\",\n\t\t\t);\n\t\tif (event.op !== \"set\") continue;\n\t\tconst target = parseTarget(event.target);\n\t\tif (!target) throw new Error(`Invalid target “${event.target}”.`);\n\t\twrites.set(target.id, [\n\t\t\t...(writes.get(target.id) ?? []),\n\t\t\t{ path: target.path, value: event.value },\n\t\t]);\n\t}\n\tconst state: Snapshot = {\n\t\tentities: previous.entities.map((entity) => {\n\t\t\tconst list = writes.get(entity.id);\n\t\t\treturn list || nodes.has(entity.id)\n\t\t\t\t? {\n\t\t\t\t\t\t...entity,\n\t\t\t\t\t\t...(nodes.has(entity.id) ? { hidden: nodes.get(entity.id)! } : {}),\n\t\t\t\t\t\tvalue: list\n\t\t\t\t\t\t\t? list.reduce(\n\t\t\t\t\t\t\t\t\t(value, write) => setAt(value, write.path, write.value),\n\t\t\t\t\t\t\t\t\tentity.value,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: entity.value,\n\t\t\t\t\t}\n\t\t\t\t: entity;\n\t\t}),\n\t\trelations: previous.relations.map((relation) =>\n\t\t\tlinks.has(relation.id)\n\t\t\t\t? { ...relation, hidden: links.get(relation.id)! }\n\t\t\t\t: relation,\n\t\t),\n\t\tactive: [\n\t\t\t...new Set(\n\t\t\t\tevents.flatMap((event) =>\n\t\t\t\t\tevent.op === \"focus\"\n\t\t\t\t\t\t? event.targets\n\t\t\t\t\t\t: event.op === \"set\"\n\t\t\t\t\t\t\t? [event.target]\n\t\t\t\t\t\t\t: [],\n\t\t\t\t),\n\t\t\t),\n\t\t],\n\t\tchanged: events.flatMap((event) =>\n\t\t\tevent.op === \"set\" ? [event.target] : [],\n\t\t),\n\t\ttransfers: events.flatMap((event) =>\n\t\t\tevent.op === \"send\"\n\t\t\t\t? [{ relation: event.relation, value: event.value }]\n\t\t\t\t: [],\n\t\t),\n\t\tnotes: events.flatMap((event) => (event.op === \"note\" ? [event.text] : [])),\n\t};\n\tfor (const transfer of state.transfers) {\n\t\tconst relation = state.relations.find(\n\t\t\t(candidate) => candidate.id === transfer.relation,\n\t\t)!;\n\t\tif (relation.hidden)\n\t\t\tthrow new Error(`Cannot send along hidden link “${relation.id}”.`);\n\t\tif (\n\t\t\tstate.entities.some(\n\t\t\t\t(entity) =>\n\t\t\t\t\tentity.hidden &&\n\t\t\t\t\t(entity.id === relation.from || entity.id === relation.to),\n\t\t\t)\n\t\t)\n\t\t\tthrow new Error(`Cannot send along “${relation.id}” with a hidden node.`);\n\t}\n\treturn state;\n}\n\nexport function compileProgram(input: unknown): Trace {\n\tvalidateProgram(input);\n\tconst program: Program = JSON.parse(JSON.stringify(input));\n\tlet state: Snapshot = {\n\t\tentities: program.entities,\n\t\trelations: program.relations,\n\t\tactive: [],\n\t\tchanged: [],\n\t\ttransfers: [],\n\t\tnotes: [],\n\t};\n\tconst frames: Trace[\"frames\"] = [\n\t\t{ index: 0, label: \"Initial state\", state, events: [] },\n\t];\n\tconst account = createBudget(\"Trace\", COMPILATION_LIMITS.traceUnits);\n\taccount({ version: 1, groups: program.groups, frames });\n\tprogram.beats.forEach((beat, index) => {\n\t\ttry {\n\t\t\tstate = reduceBeat(state, beat.events);\n\t\t\tconst frame = {\n\t\t\t\tindex: index + 1,\n\t\t\t\tlabel: beat.label,\n\t\t\t\tstate,\n\t\t\t\tevents: beat.events,\n\t\t\t\tsource: beat.source,\n\t\t\t};\n\t\t\taccount(frame);\n\t\t\tframes.push(frame);\n\t\t} catch (error) {\n\t\t\tthrow new ProgramError([\n\t\t\t\t{\n\t\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\t\tbeat: index,\n\t\t\t\t\tline: beat.source?.line,\n\t\t\t\t},\n\t\t\t]);\n\t\t}\n\t});\n\treturn {\n\t\tversion: 1,\n\t\tframes,\n\t\t...(program.groups ? { groups: program.groups } : {}),\n\t};\n}\n","import type { ThlBlock } from \"../dsl.js\";\nimport { checkSourceSize } from \"../limits.js\";\nimport { ProgramError } from \"../model.js\";\n\nexport type FenceLine = { text: string; line: number };\n\nexport function sourceLine(ast: ThlBlock, index = 0): number {\n\treturn (ast.source?.line ?? 1) + index + 1;\n}\n\n/**\n * Non-empty, non-comment fence lines with fence line numbers (header is\n * line 1, first body line is line 2). Blank lines are retained by the parser so diagnostics refer to the\n * original source in every domain.\n */\nexport function sourceLines(ast: ThlBlock): FenceLine[] {\n\tif (\n\t\tast.source &&\n\t\t(!Number.isSafeInteger(ast.source.line) || ast.source.line < 1)\n\t)\n\t\tthrow new ProgramError([\n\t\t\t{ message: \"Source line must be a positive safe integer.\" },\n\t\t]);\n\tcheckSourceSize(\n\t\tast.lines.reduce(\n\t\t\t(size, line) => size + line.length + 1,\n\t\t\tast.kind.length + 4,\n\t\t),\n\t);\n\tconst out: FenceLine[] = [];\n\tast.lines.forEach((raw, index) => {\n\t\tconst text = raw.trim();\n\t\tif (!text || text.startsWith(\"#\")) return;\n\t\tout.push({ text, line: sourceLine(ast, index) });\n\t});\n\treturn out;\n}\n","import { validateProgram } from \"./compiler.js\";\nimport { sourceLines } from \"./domains/lines.js\";\nimport type { ThlBlock } from \"./dsl.js\";\nimport {\n\ttype Beat,\n\tGROUP_LAYOUTS,\n\ttype GroupLayout,\n\ttype Program,\n\tProgramError,\n\ttype Value,\n\tVIEWS,\n\ttype View,\n} from \"./model.js\";\nimport { parseTarget } from \"./path.js\";\n\nexport function parseProgram(ast: ThlBlock): Program {\n\tconst program: Program = {\n\t\tversion: 1,\n\t\tentities: [],\n\t\trelations: [],\n\t\tbeats: [],\n\t};\n\tlet beat: Beat | undefined;\n\tsourceLines(ast).forEach(({ text, line }) => {\n\t\tconst source = { line };\n\t\tconst fail = (message: string): never => {\n\t\t\tthrow new ProgramError([{ message, line }]);\n\t\t};\n\t\tconst json = (value: string): Value => {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(value) as Value;\n\t\t\t} catch {\n\t\t\t\treturn fail(\n\t\t\t\t\t\"Expected a JSON value (quote strings; arrays and objects are supported).\",\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\t\tconst quoted = (value: string): string => {\n\t\t\tconst parsed = json(value);\n\t\t\treturn typeof parsed === \"string\"\n\t\t\t\t? parsed\n\t\t\t\t: fail(\"Expected a quoted label.\");\n\t\t};\n\t\tconst group = text.match(/^group\\s+(\"(?:[^\"\\\\]|\\\\.)*\")\\s+as\\s+([a-z]+)$/);\n\t\tif (group) {\n\t\t\tif (beat) fail(\"Declare groups before the first step.\");\n\t\t\tif (!(GROUP_LAYOUTS as readonly string[]).includes(group[2]))\n\t\t\t\tfail(\n\t\t\t\t\t`Unknown group layout “${group[2]}”. Use ${GROUP_LAYOUTS.join(\", \")}.`,\n\t\t\t\t);\n\t\t\tconst name = quoted(group[1]);\n\t\t\tprogram.groups ??= [];\n\t\t\tif (program.groups.some((candidate) => candidate.name === name))\n\t\t\t\tfail(`Duplicate group “${name}”.`);\n\t\t\tprogram.groups.push({ name, layout: group[2] as GroupLayout });\n\t\t\treturn;\n\t\t}\n\t\tconst node = text.match(\n\t\t\t/^node\\s+([\\w-]+)\\s+(\"(?:[^\"\\\\]|\\\\.)*\")(?:\\s+in\\s+(\"(?:[^\"\\\\]|\\\\.)*\"))?(?:\\s+as\\s+([a-z]+))?(\\s+hidden)?(?:\\s*=\\s*(.+))?$/,\n\t\t);\n\t\tif (node) {\n\t\t\tif (beat) fail(\"Declare nodes and links before the first step.\");\n\t\t\tif (node[4] && !(VIEWS as readonly string[]).includes(node[4]))\n\t\t\t\tfail(`Unknown view “${node[4]}”. Use ${VIEWS.join(\", \")}.`);\n\t\t\tprogram.entities.push({\n\t\t\t\tid: node[1],\n\t\t\t\tlabel: quoted(node[2]),\n\t\t\t\tlane: node[3] ? quoted(node[3]) : undefined,\n\t\t\t\t...(node[4] ? { view: node[4] as View } : {}),\n\t\t\t\t...(node[5] ? { hidden: true } : {}),\n\t\t\t\tvalue: node[6] ? json(node[6]) : null,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst link = text.match(\n\t\t\t/^link\\s+([\\w-]+)\\s+([\\w-]+)\\s*->\\s*([\\w-]+)(?:\\s+(\"(?:[^\"\\\\]|\\\\.)*\"))?(\\s+hidden)?$/,\n\t\t);\n\t\tif (link) {\n\t\t\tif (beat) fail(\"Declare nodes and links before the first step.\");\n\t\t\tprogram.relations.push({\n\t\t\t\tid: link[1],\n\t\t\t\tfrom: link[2],\n\t\t\t\tto: link[3],\n\t\t\t\tlabel: link[4] ? quoted(link[4]) : undefined,\n\t\t\t\t...(link[5] ? { hidden: true } : {}),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst step = text.match(/^step\\s+(\"(?:[^\"\\\\]|\\\\.)*\")$/);\n\t\tif (step) {\n\t\t\tbeat = { label: quoted(step[1]), events: [], source };\n\t\t\tprogram.beats.push(beat);\n\t\t\treturn;\n\t\t}\n\t\tif (!beat) fail(\"Expected node, link, or step. Events must follow a step.\");\n\t\tconst set = text.match(/^set\\s+([^\\s=]+)\\s*=\\s*(.+)$/);\n\t\tconst send = text.match(/^send\\s+([\\w-]+)(?:\\s*=\\s*(.+))?$/);\n\t\tconst focus = text.match(/^focus(?:\\s+(.+))?$/);\n\t\tconst note = text.match(/^note\\s+(\"(?:[^\"\\\\]|\\\\.)*\")$/);\n\t\tconst visibility = text.match(/^(show|hide)\\s+(node|link)\\s+([\\w-]+)$/);\n\t\tif (visibility) {\n\t\t\tbeat?.events.push({\n\t\t\t\top: visibility[1] as \"show\" | \"hide\",\n\t\t\t\tkind: visibility[2] as \"node\" | \"link\",\n\t\t\t\tid: visibility[3],\n\t\t\t\tsource,\n\t\t\t});\n\t\t} else if (set) {\n\t\t\tif (!parseTarget(set[1]))\n\t\t\t\tfail(\n\t\t\t\t\t`Invalid target “${set[1]}”. Use an id, optionally followed by [index] or .key.`,\n\t\t\t\t);\n\t\t\tbeat?.events.push({\n\t\t\t\top: \"set\",\n\t\t\t\ttarget: set[1],\n\t\t\t\tvalue: json(set[2]),\n\t\t\t\tsource,\n\t\t\t});\n\t\t} else if (send)\n\t\t\tbeat?.events.push({\n\t\t\t\top: \"send\",\n\t\t\t\trelation: send[1],\n\t\t\t\t...(send[2] ? { value: json(send[2]) } : {}),\n\t\t\t\tsource,\n\t\t\t});\n\t\telse if (focus) {\n\t\t\tconst targets = (focus[1] ?? \"\").split(/[\\s,]+/).filter(Boolean);\n\t\t\tconst bad = targets.find((target) => !parseTarget(target));\n\t\t\tif (bad)\n\t\t\t\tfail(\n\t\t\t\t\t`Invalid target “${bad}”. Use an id, optionally followed by [index] or .key.`,\n\t\t\t\t);\n\t\t\tbeat?.events.push({ op: \"focus\", targets, source });\n\t\t} else if (note)\n\t\t\tbeat?.events.push({ op: \"note\", text: quoted(note[1]), source });\n\t\telse\n\t\t\tfail(\n\t\t\t\t\"Unknown statement. Use node, link, step, set, focus, send, note, show, or hide.\",\n\t\t\t);\n\t});\n\tvalidateProgram(program);\n\treturn program;\n}\n","import { checkSourceSize } from \"./limits.js\";\nimport { ProgramError, type SourceLocation } from \"./model.js\";\n\n/** A single parsed fence. Markdown adapters supply lines directly, without reparsing. */\nexport type ThlBlock = {\n\tkind: string;\n\tlines: string[];\n\t/** Location of the header, so the first body line is source.line + 1. */\n\tsource?: SourceLocation;\n};\n\n/**\n * Parse one thl block, optionally fenced with backticks or tildes. Fence\n * lengths/indentation follow CommonMark; document/container parsing belongs\n * to the host's Markdown parser, not a second parser inside the engine.\n */\nexport function parseThl(src: string): ThlBlock | null {\n\tcheckSourceSize(src.length);\n\tconst lines = src.replace(/^\\uFEFF/, \"\").split(/\\r\\n?|\\n/);\n\tconst start = lines.findIndex((line) => line.trim() !== \"\");\n\tif (start < 0) return null;\n\tconst first = lines[start];\n\tconst fence = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(first);\n\tconst header = (fence ? fence[2] : first).trim().split(/\\s+/);\n\tif (header[0] !== \"thl\") return null;\n\tconst line = start + 1;\n\tif (header.length !== 2) {\n\t\tthrow new ProgramError([\n\t\t\t{\n\t\t\t\tmessage: \"Expected header: thl <domain>, without extra options.\",\n\t\t\t\tline,\n\t\t\t},\n\t\t]);\n\t}\n\tlet end = lines.length;\n\tif (fence) {\n\t\tconst marker = fence[1];\n\t\tfor (let index = start + 1; index < lines.length; index++) {\n\t\t\tconst close = /^ {0,3}(`{3,}|~{3,})[\\t ]*$/.exec(lines[index]);\n\t\t\tif (close?.[1][0] === marker[0] && close[1].length >= marker.length) {\n\t\t\t\tend = index;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tconst trailing = lines.findIndex(\n\t\t\t(text, index) => index > end && text.trim() !== \"\",\n\t\t);\n\t\tif (trailing >= 0) {\n\t\t\tthrow new ProgramError([\n\t\t\t\t{\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t\"Expected one Throughline block; found content after its closing fence.\",\n\t\t\t\t\tline: trailing + 1,\n\t\t\t\t},\n\t\t\t]);\n\t\t}\n\t}\n\treturn {\n\t\tkind: header[1],\n\t\tlines: lines.slice(start + 1, end),\n\t\tsource: { line },\n\t};\n}\n","import { COMPILATION_LIMITS, createBudget } from \"./limits.js\";\nimport type {\n\tBeat,\n\tEntity,\n\tEvent,\n\tGroupLayout,\n\tProgram,\n\tValue,\n\tView,\n} from \"./model.js\";\nimport { ProgramError } from \"./model.js\";\nimport { getAt, parseTarget, setAt } from \"./path.js\";\n\nexport type StepApi = {\n\tset(target: string, value: Value): void;\n\tfocus(...targets: string[]): void;\n\tsend(relation: string, value?: Value): void;\n\tnote(text: string): void;\n\tshow(kind: \"node\" | \"link\", id: string): void;\n\thide(kind: \"node\" | \"link\", id: string): void;\n};\n\nexport type Tracer = {\n\tgroup(name: string, layout: GroupLayout): Tracer;\n\tnode(\n\t\tid: string,\n\t\tlabel: string,\n\t\tvalue: Value,\n\t\toptions?: { lane?: string; view?: View; hidden?: boolean },\n\t): Tracer;\n\tlink(\n\t\tid: string,\n\t\tfrom: string,\n\t\tto: string,\n\t\tlabel?: string,\n\t\toptions?: { hidden?: boolean },\n\t): Tracer;\n\tget(target: string): Value | undefined;\n\tstep(label: string, body: (step: StepApi) => void): Tracer;\n\tprogram(): Program;\n};\n\n/** Detach caller-owned data before it becomes part of the recording. */\nfunction captureData<T>(value: T): T {\n\tcreateBudget(\"Program\", COMPILATION_LIMITS.programUnits)(value);\n\treturn JSON.parse(JSON.stringify(value)) as T;\n}\n\nfunction checkCount(name: string, count: number, maximum: number): void {\n\tif (count > maximum)\n\t\tthrow new ProgramError([\n\t\t\t{ message: `Program exceeds ${maximum} ${name}.` },\n\t\t]);\n}\n\n/**\n * Computation adapter: run any ordinary algorithm and narrate it.\n * Values written in a step become visible together, exactly like authored steps.\n */\nexport function tracer(): Tracer {\n\tconst program: Program = {\n\t\tversion: 1,\n\t\tentities: [],\n\t\trelations: [],\n\t\tbeats: [],\n\t};\n\tlet live = new Map<string, Value>();\n\tlet eventCount = 0;\n\tlet recording = false;\n\tconst account = createBudget(\"Program\", COMPILATION_LIMITS.programUnits);\n\tconst assertIdle = (): void => {\n\t\tif (recording) throw new Error(\"Use the step writer while a step is open.\");\n\t};\n\n\tconst api: Tracer = {\n\t\tgroup(name, layout) {\n\t\t\tassertIdle();\n\t\t\tcheckCount(\n\t\t\t\t\"groups\",\n\t\t\t\t(program.groups?.length ?? 0) + 1,\n\t\t\t\tCOMPILATION_LIMITS.entities,\n\t\t\t);\n\t\t\tconst group = { name, layout };\n\t\t\taccount(group);\n\t\t\tprogram.groups ??= [];\n\t\t\tprogram.groups.push(group);\n\t\t\treturn api;\n\t\t},\n\t\tnode(id, label, value, options = {}) {\n\t\t\tassertIdle();\n\t\t\tcheckCount(\n\t\t\t\t\"entities\",\n\t\t\t\tprogram.entities.length + 1,\n\t\t\t\tCOMPILATION_LIMITS.entities,\n\t\t\t);\n\t\t\tconst entity: Entity = {\n\t\t\t\tid,\n\t\t\t\tlabel,\n\t\t\t\tvalue: captureData(value),\n\t\t\t\t...(options.lane ? { lane: options.lane } : {}),\n\t\t\t\t...(options.view ? { view: options.view } : {}),\n\t\t\t\t...(options.hidden ? { hidden: true } : {}),\n\t\t\t};\n\t\t\taccount(entity);\n\t\t\tprogram.entities.push(entity);\n\t\t\tlive.set(id, entity.value);\n\t\t\treturn api;\n\t\t},\n\t\tlink(id: string, from: string, to: string, label?: string, options = {}) {\n\t\t\tassertIdle();\n\t\t\tcheckCount(\n\t\t\t\t\"relations\",\n\t\t\t\tprogram.relations.length + 1,\n\t\t\t\tCOMPILATION_LIMITS.relations,\n\t\t\t);\n\t\t\tconst relation = {\n\t\t\t\tid,\n\t\t\t\tfrom,\n\t\t\t\tto,\n\t\t\t\t...(label ? { label } : {}),\n\t\t\t\t...(options.hidden ? { hidden: true } : {}),\n\t\t\t};\n\t\t\taccount(relation);\n\t\t\tprogram.relations.push(relation);\n\t\t\treturn api;\n\t\t},\n\t\t/** Current value of a target as of the previous completed step. */\n\t\tget(target: string): Value | undefined {\n\t\t\tconst parsed = parseTarget(target);\n\t\t\tconst value = parsed\n\t\t\t\t? getAt(live.get(parsed.id), parsed.path)\n\t\t\t\t: undefined;\n\t\t\treturn value === undefined ? undefined : captureData(value);\n\t\t},\n\t\tstep(label: string, body: (step: StepApi) => void) {\n\t\t\tassertIdle();\n\t\t\tcheckCount(\"steps\", program.beats.length + 1, COMPILATION_LIMITS.steps);\n\t\t\tconst events: Event[] = [];\n\t\t\tconst stepBudget = createBudget(\n\t\t\t\t\"Program step\",\n\t\t\t\tCOMPILATION_LIMITS.programUnits,\n\t\t\t);\n\t\t\tstepBudget({ label });\n\t\t\tlet open = true;\n\t\t\tconst append = (event: Event): void => {\n\t\t\t\tif (!open) throw new Error(\"This step writer is closed.\");\n\t\t\t\tcheckCount(\n\t\t\t\t\t\"events\",\n\t\t\t\t\teventCount + events.length + 1,\n\t\t\t\t\tCOMPILATION_LIMITS.events,\n\t\t\t\t);\n\t\t\t\tstepBudget(event);\n\t\t\t\tevents.push(event);\n\t\t\t};\n\t\t\trecording = true;\n\t\t\ttry {\n\t\t\t\tconst result: unknown = body({\n\t\t\t\t\tset: (target, value) =>\n\t\t\t\t\t\tappend({ op: \"set\", target, value: captureData(value) }),\n\t\t\t\t\tfocus: (...targets) => append({ op: \"focus\", targets }),\n\t\t\t\t\tsend: (relation, value) =>\n\t\t\t\t\t\tappend({\n\t\t\t\t\t\t\top: \"send\",\n\t\t\t\t\t\t\trelation,\n\t\t\t\t\t\t\t...(value === undefined ? {} : { value: captureData(value) }),\n\t\t\t\t\t\t}),\n\t\t\t\t\tnote: (text) => append({ op: \"note\", text }),\n\t\t\t\t\tshow: (kind, id) => append({ op: \"show\", kind, id }),\n\t\t\t\t\thide: (kind, id) => append({ op: \"hide\", kind, id }),\n\t\t\t\t});\n\t\t\t\tif (\n\t\t\t\t\tresult !== null &&\n\t\t\t\t\ttypeof result === \"object\" &&\n\t\t\t\t\t\"then\" in result &&\n\t\t\t\t\ttypeof result.then === \"function\"\n\t\t\t\t) {\n\t\t\t\t\t// The rejected callback may resume after the writer closes.\n\t\t\t\t\t// Observe that promise so catching this error is sufficient.\n\t\t\t\t\tvoid Promise.resolve(result).catch(() => {});\n\t\t\t\t\tthrow new Error(\"Step callbacks must be synchronous.\");\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\topen = false;\n\t\t\t\trecording = false;\n\t\t\t}\n\t\t\tconst beat: Beat = { label, events };\n\t\t\tconst pending = new Map(live);\n\t\t\tfor (const event of events) {\n\t\t\t\tif (event.op !== \"set\") continue;\n\t\t\t\tconst parsed = parseTarget(event.target);\n\t\t\t\tif (parsed && live.has(parsed.id))\n\t\t\t\t\tpending.set(\n\t\t\t\t\t\tparsed.id,\n\t\t\t\t\t\tsetAt(pending.get(parsed.id)!, parsed.path, event.value),\n\t\t\t\t\t);\n\t\t\t}\n\t\t\taccount(beat);\n\t\t\tprogram.beats.push(beat);\n\t\t\tlive = pending;\n\t\t\teventCount += events.length;\n\t\t\treturn api;\n\t\t},\n\t\tprogram(): Program {\n\t\t\treturn captureData(program);\n\t\t},\n\t};\n\treturn api;\n}\n","import type { ThlBlock } from \"../dsl.js\";\nimport { type Program, ProgramError } from \"../model.js\";\nimport { tracer } from \"../tracer.js\";\nimport { sourceLine, sourceLines } from \"./lines.js\";\n\n/**\n * `thl binary` — ripple-carry addition, one beat per bit (LSB first).\n *\n * ```thl binary\n * a = 1011\n * b = 0110\n * ```\n *\n * Operands are 1–16 binary digits. The sum row is MSB-first with a\n * leading carry-out slot; bits fill right-to-left as carries ripple.\n */\nexport type BinaryParams = { a: string; b: string };\n\nconst BITS = /^[01]{1,16}$/;\n\nexport function parseBinary(ast: ThlBlock): BinaryParams {\n\tconst found = new Map<string, string>();\n\tfor (const { text, line } of sourceLines(ast)) {\n\t\tconst entry = text.match(/^(a|b)\\s*=\\s*([01]+)\\s*$/);\n\t\tif (!entry?.[1] || !entry[2])\n\t\t\tthrow new ProgramError([\n\t\t\t\t{ message: \"Expected a = <bits> or b = <bits>.\", line },\n\t\t\t]);\n\t\tconst key = entry[1];\n\t\tconst digits = entry[2];\n\t\tif (!BITS.test(digits))\n\t\t\tthrow new ProgramError([\n\t\t\t\t{ message: \"Operands are 1–16 binary digits.\", line },\n\t\t\t]);\n\t\tif (found.has(key))\n\t\t\tthrow new ProgramError([\n\t\t\t\t{ message: `Duplicate operand \"${key}\".`, line },\n\t\t\t]);\n\t\tfound.set(key, digits);\n\t}\n\tconst a = found.get(\"a\");\n\tconst b = found.get(\"b\");\n\tif (!a || !b)\n\t\tthrow new ProgramError([\n\t\t\t{\n\t\t\t\tmessage: \"Binary needs both a = <bits> and b = <bits>.\",\n\t\t\t\tline: sourceLine(ast),\n\t\t\t},\n\t\t]);\n\treturn { a, b };\n}\n\nexport function buildBinary({ a, b }: BinaryParams): Program {\n\tconst t = tracer();\n\tconst n = Math.max(a.length, b.length);\n\tconst A = a.padStart(n, \"0\");\n\tconst B = b.padStart(n, \"0\");\n\tt.node(\"a\", \"A\", Number.parseInt(A, 2), { lane: \"Binary\", view: \"bits\" });\n\tt.node(\"b\", \"B\", Number.parseInt(B, 2), { lane: \"Binary\", view: \"bits\" });\n\t// Sum row: MSB-first with a leading carry-out slot (index 0).\n\tt.node(\"sum\", \"Sum\", Array<string | number>(n + 1).fill(\"·\"), {\n\t\tlane: \"Binary\",\n\t\tview: \"array\",\n\t});\n\tt.node(\"carry\", \"Carry\", 0, { lane: \"Binary\", view: \"number\" });\n\tlet carry = 0;\n\tconst sums: number[] = [];\n\tfor (let r = 0; r < n; r++) {\n\t\tconst x = Number(A[n - 1 - r]);\n\t\tconst y = Number(B[n - 1 - r]);\n\t\tconst total = x + y + carry;\n\t\tconst cin = carry;\n\t\tconst bit = total & 1;\n\t\tcarry = total >> 1;\n\t\tsums.unshift(bit);\n\t\tt.step(`bit ${r}`, (s) => {\n\t\t\ts.focus(`a[${r}]`, `b[${r}]`, `sum[${n - r}]`, \"carry\");\n\t\t\ts.set(`sum[${n - r}]`, bit);\n\t\t\ts.set(\"carry\", carry);\n\t\t\ts.note(\n\t\t\t\t`bit ${r}: ${x} + ${y} + carry ${cin} = ${total}, so write ${bit} and carry ${carry}`,\n\t\t\t);\n\t\t});\n\t}\n\tconst carryOut = carry;\n\tconst result = `${carryOut}${sums.join(\"\")}`;\n\tt.step(\"Result\", (s) => {\n\t\ts.focus(\"sum\", \"carry\");\n\t\ts.set(\"sum[0]\", carryOut);\n\t\ts.note(\n\t\t\tcarryOut\n\t\t\t\t? `The last carry becomes the top bit: ${A} + ${B} = ${result}`\n\t\t\t\t: `No final carry: ${A} + ${B} = ${result}`,\n\t\t);\n\t});\n\treturn t.program();\n}\n","import type { ThlBlock } from \"../dsl.js\";\nimport { COMPILATION_LIMITS } from \"../limits.js\";\nimport { type Program, ProgramError, type Value, type View } from \"../model.js\";\nimport { type StepApi, tracer } from \"../tracer.js\";\nimport { sourceLines } from \"./lines.js\";\n\nconst NAME = \"[A-Za-z][\\\\w-]*\";\n\n/**\n * `thl bindings` — variable slots, primitives vs heap references.\n *\n * Subset: `let`/`const <name> = <json>`, `<name> = <json|name>`,\n * `<name>.push(<json>, ...)`. Arrays/objects live on the heap (`o1`…);\n * everything else is a primitive held inline. `const` is not enforced.\n */\nexport type BindOp =\n\t| { kind: \"declare\"; name: string; value: Value; from?: string; line: number }\n\t| {\n\t\t\tkind: \"assign\";\n\t\t\tname: string;\n\t\t\tvalue: Value;\n\t\t\tfrom?: string;\n\t\t\tline: number;\n\t }\n\t| { kind: \"push\"; name: string; items: Value[]; line: number };\n\nexport type BindParams = { ops: BindOp[] };\n\nconst isHeapValue = (value: Value): boolean =>\n\tArray.isArray(value) || (typeof value === \"object\" && value !== null);\n\nconst show = (value: Value): string => JSON.stringify(value) ?? \"null\";\n\nexport function parseBindings(ast: ThlBlock): BindParams {\n\tconst ops: BindOp[] = [];\n\tconst declared = new Set<string>();\n\tconst lines = sourceLines(ast);\n\tif (lines.length > COMPILATION_LIMITS.steps)\n\t\tthrow new ProgramError([\n\t\t\t{\n\t\t\t\tmessage: `Bindings exceed ${COMPILATION_LIMITS.steps} steps.`,\n\t\t\t\tline: lines[COMPILATION_LIMITS.steps].line,\n\t\t\t},\n\t\t]);\n\tfor (const { text, line } of lines) {\n\t\tconst fail = (message: string): never => {\n\t\t\tthrow new ProgramError([{ message, line }]);\n\t\t};\n\t\tconst json = (source: string): Value => {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(source) as Value;\n\t\t\t} catch {\n\t\t\t\treturn fail(\"Expected a JSON value (quote strings).\");\n\t\t\t}\n\t\t};\n\t\tconst bare = (source: string): string | null =>\n\t\t\tnew RegExp(`^${NAME}$`).test(source) &&\n\t\t\t!/^\"(?:[^\"\\\\]|\\\\.)*\"$/.test(source)\n\t\t\t\t? source\n\t\t\t\t: null;\n\t\tconst declare = text.match(\n\t\t\tnew RegExp(`^(?:let|const)\\\\s+(${NAME})\\\\s*=\\\\s*(.+)$`),\n\t\t);\n\t\tif (declare) {\n\t\t\tconst name = declare[1] ?? \"\";\n\t\t\tconst rhs = (declare[2] ?? \"\").trim();\n\t\t\tif (declared.has(name)) fail(`Duplicate variable \"${name}\".`);\n\t\t\tconst ref = bare(rhs);\n\t\t\tif (ref) {\n\t\t\t\tif (!declared.has(ref)) fail(`Unknown variable \"${ref}\".`);\n\t\t\t\tdeclared.add(name);\n\t\t\t\tops.push({ kind: \"declare\", name, value: null, from: ref, line });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tdeclared.add(name);\n\t\t\tops.push({ kind: \"declare\", name, value: json(rhs), line });\n\t\t\tcontinue;\n\t\t}\n\t\tconst push = text.match(new RegExp(`^(${NAME})\\\\.push\\\\((.*)\\\\)$`));\n\t\tif (push) {\n\t\t\tconst name = push[1] ?? \"\";\n\t\t\tif (!declared.has(name)) fail(`Unknown variable \"${name}\".`);\n\t\t\tlet items: Value[];\n\t\t\ttry {\n\t\t\t\titems = JSON.parse(`[${push[2] ?? \"\"}]`) as Value[];\n\t\t\t} catch {\n\t\t\t\tthrow new ProgramError([\n\t\t\t\t\t{ message: \"Expected push arguments as JSON values.\", line },\n\t\t\t\t]);\n\t\t\t}\n\t\t\tops.push({ kind: \"push\", name, items, line });\n\t\t\tcontinue;\n\t\t}\n\t\tconst assign = text.match(new RegExp(`^(${NAME})\\\\s*=\\\\s*(.+)$`));\n\t\tif (assign) {\n\t\t\tconst name = assign[1] ?? \"\";\n\t\t\tif (!declared.has(name)) fail(`Unknown variable \"${name}\".`);\n\t\t\tconst rhs = (assign[2] ?? \"\").trim();\n\t\t\tconst ref = bare(rhs);\n\t\t\tif (ref) {\n\t\t\t\tif (!declared.has(ref)) fail(`Unknown variable \"${ref}\".`);\n\t\t\t\tops.push({ kind: \"assign\", name, value: null, from: ref, line });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tops.push({ kind: \"assign\", name, value: json(rhs), line });\n\t\t\tcontinue;\n\t\t}\n\t\tfail(\n\t\t\t\"Unknown statement. Use let <name> = <json>, <name> = <json|name>, or <name>.push(<json>).\",\n\t\t);\n\t}\n\treturn { ops };\n}\n\nexport function buildBindings(params: BindParams): Program {\n\tconst t = tracer();\n\tt.group(\"Stack\", \"column\").group(\"Heap\", \"column\");\n\t// First pass: discover slots and heap allocations so edges are static.\n\tconst vars: string[] = [];\n\tconst heapViews = new Map<string, View>();\n\tconst slot: Map<string, { heap: string } | { value: Value }> = new Map();\n\tconst edges: { id: string; from: string; to: string }[] = [];\n\tconst edgeId = (from: string, to: string) => `ref_${from}_${to}`;\n\tconst alloc = (value: Value): string => {\n\t\tconst id = `o${heapViews.size + 1}`;\n\t\theapViews.set(id, Array.isArray(value) ? \"array\" : \"record\");\n\t\treturn id;\n\t};\n\tfor (const op of params.ops) {\n\t\tif (op.kind === \"push\") {\n\t\t\tconst target = slot.get(op.name);\n\t\t\tif (!target || !(\"heap\" in target))\n\t\t\t\tthrow new ProgramError([\n\t\t\t\t\t{\n\t\t\t\t\t\tmessage: `Cannot push to \"${op.name}\": not an array.`,\n\t\t\t\t\t\tline: op.line,\n\t\t\t\t\t},\n\t\t\t\t]);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!op.from) {\n\t\t\tconst value = op.value;\n\t\t\tif (!vars.includes(op.name)) vars.push(op.name);\n\t\t\tif (isHeapValue(value)) {\n\t\t\t\tconst heap = alloc(value);\n\t\t\t\tslot.set(op.name, { heap });\n\t\t\t\tedges.push({ id: edgeId(op.name, heap), from: op.name, to: heap });\n\t\t\t} else slot.set(op.name, { value });\n\t\t\tcontinue;\n\t\t}\n\t\tif (!vars.includes(op.name)) vars.push(op.name);\n\t\tconst from = op.from;\n\t\tconst source = slot.get(from);\n\t\tif (!source)\n\t\t\tthrow new ProgramError([\n\t\t\t\t{ message: `Unknown variable \"${from}\".`, line: op.line },\n\t\t\t]);\n\t\tif (\"heap\" in source) {\n\t\t\tslot.set(op.name, { heap: source.heap });\n\t\t\tedges.push({\n\t\t\t\tid: edgeId(op.name, source.heap),\n\t\t\t\tfrom: op.name,\n\t\t\t\tto: source.heap,\n\t\t\t});\n\t\t} else slot.set(op.name, { value: source.value });\n\t}\n\tfor (const name of vars)\n\t\tt.node(name, name, null, { lane: \"Stack\", hidden: true });\n\tfor (const [heap, view] of heapViews)\n\t\tt.node(heap, heap, null, { lane: \"Heap\", view, hidden: true });\n\tconst seen = new Set<string>();\n\tfor (const edge of edges) {\n\t\tif (seen.has(edge.id)) continue;\n\t\tseen.add(edge.id);\n\t\tt.link(edge.id, edge.from, edge.to, \"ref\", { hidden: true });\n\t}\n\t// Second pass: narrate each source line as one beat, replaying bindings\n\t// in order so shared-mutation focus reflects the state at that line.\n\tconst cur = new Map<string, { heap: string } | { value: Value }>();\n\tconst heapLive = new Map<string, Value>();\n\tlet nextHeap = 0;\n\tconst shownPointers = new Map<string, string>();\n\tconst point = (s: StepApi, name: string, heap?: string): void => {\n\t\tconst previous = shownPointers.get(name);\n\t\tif (previous && previous !== heap) s.hide(\"link\", edgeId(name, previous));\n\t\tif (heap && previous !== heap) s.show(\"link\", edgeId(name, heap));\n\t\tif (heap) shownPointers.set(name, heap);\n\t\telse shownPointers.delete(name);\n\t};\n\tconst sharers = (heap: string, except?: string) =>\n\t\t[...cur.entries()]\n\t\t\t.filter(([, binding]) => \"heap\" in binding && binding.heap === heap)\n\t\t\t.map(([name]) => name)\n\t\t\t.filter((name) => name !== except);\n\tfor (const op of params.ops) {\n\t\tif (op.kind === \"push\") {\n\t\t\tconst binding = cur.get(op.name);\n\t\t\tconst heap = binding && \"heap\" in binding ? binding.heap : \"\";\n\t\t\tconst current = heapLive.get(heap);\n\t\t\tif (!Array.isArray(current))\n\t\t\t\tthrow new ProgramError([\n\t\t\t\t\t{\n\t\t\t\t\t\tmessage: `Cannot push to \"${op.name}\": not an array.`,\n\t\t\t\t\t\tline: op.line,\n\t\t\t\t\t},\n\t\t\t\t]);\n\t\t\tconst next = [...current, ...op.items];\n\t\t\theapLive.set(heap, next);\n\t\t\tconst others = sharers(heap, op.name);\n\t\t\tt.step(`${op.name}.push(${op.items.map(show).join(\", \")})`, (s) => {\n\t\t\t\ts.focus(op.name, heap, ...others);\n\t\t\t\ts.set(heap, next);\n\t\t\t\ts.note(\n\t\t\t\t\tothers.length\n\t\t\t\t\t\t? `push mutates the shared object, so ${others.join(\", \")} see it too.`\n\t\t\t\t\t\t: `push appends to ${heap}.`,\n\t\t\t\t);\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tif (!op.from) {\n\t\t\tconst label =\n\t\t\t\top.kind === \"declare\"\n\t\t\t\t\t? `let ${op.name} = ${show(op.value)}`\n\t\t\t\t\t: `${op.name} = ${show(op.value)}`;\n\t\t\tif (isHeapValue(op.value)) {\n\t\t\t\tnextHeap += 1;\n\t\t\t\tconst heap = `o${nextHeap}`;\n\t\t\t\tconst heapValue = op.value;\n\t\t\t\tcur.set(op.name, { heap });\n\t\t\t\theapLive.set(heap, heapValue);\n\t\t\t\tt.step(label, (s) => {\n\t\t\t\t\ts.show(\"node\", op.name);\n\t\t\t\t\ts.show(\"node\", heap);\n\t\t\t\t\tpoint(s, op.name, heap);\n\t\t\t\t\ts.focus(op.name);\n\t\t\t\t\ts.set(op.name, heap);\n\t\t\t\t\ts.set(heap, heapValue);\n\t\t\t\t\ts.send(edgeId(op.name, heap), heapValue);\n\t\t\t\t\ts.note(\n\t\t\t\t\t\top.kind === \"declare\"\n\t\t\t\t\t\t\t? `A new object lives on the heap. ${op.name} holds a reference to it.`\n\t\t\t\t\t\t\t: `Rebinding ${op.name} moves its arrow to a new object.`,\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t} else if (op.kind === \"declare\") {\n\t\t\t\tconst prim = op.value;\n\t\t\t\tcur.set(op.name, { value: prim });\n\t\t\t\tt.step(label, (s) => {\n\t\t\t\t\ts.show(\"node\", op.name);\n\t\t\t\t\ts.focus(op.name);\n\t\t\t\t\ts.set(op.name, prim);\n\t\t\t\t\ts.note(\n\t\t\t\t\t\t`${op.name} is a primitive. The slot holds ${show(prim)} itself.`,\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst prim = op.value;\n\t\t\t\tcur.set(op.name, { value: prim });\n\t\t\t\tt.step(label, (s) => {\n\t\t\t\t\tpoint(s, op.name);\n\t\t\t\t\ts.focus(op.name);\n\t\t\t\t\ts.set(op.name, prim);\n\t\t\t\t\ts.note(`Reassigning ${op.name} changes only ${op.name}.`);\n\t\t\t\t});\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tconst from = op.from;\n\t\tconst keyword = op.kind === \"declare\" ? \"let \" : \"\";\n\t\tconst source = cur.get(from);\n\t\tif (source && \"heap\" in source) {\n\t\t\tconst heap = source.heap;\n\t\t\tcur.set(op.name, { heap });\n\t\t\tconst heapValue: Value = heapLive.get(heap) ?? null;\n\t\t\tt.step(`${keyword}${op.name} = ${from}`, (s) => {\n\t\t\t\ts.show(\"node\", op.name);\n\t\t\t\tpoint(s, op.name, heap);\n\t\t\t\ts.focus(op.name, from);\n\t\t\t\ts.set(op.name, heap);\n\t\t\t\ts.send(edgeId(op.name, heap), heapValue);\n\t\t\t\ts.note(\n\t\t\t\t\t\"Copying a reference copies the arrow, not the array. Two names, one object.\",\n\t\t\t\t);\n\t\t\t});\n\t\t} else {\n\t\t\tconst value: Value = source && \"value\" in source ? source.value : null;\n\t\t\tcur.set(op.name, { value });\n\t\t\tt.step(`${keyword}${op.name} = ${from}`, (s) => {\n\t\t\t\ts.show(\"node\", op.name);\n\t\t\t\tpoint(s, op.name);\n\t\t\t\ts.focus(op.name, from);\n\t\t\t\ts.set(op.name, value);\n\t\t\t\ts.note(\n\t\t\t\t\t`${op.name} gets a copy of ${show(value)}. Two independent slots.`,\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\t}\n\treturn t.program();\n}\n","import type { ThlBlock } from \"../dsl.js\";\nimport { type Program, ProgramError } from \"../model.js\";\nimport { tracer } from \"../tracer.js\";\nimport { sourceLine, sourceLines } from \"./lines.js\";\n\n/**\n * `thl callstack` — factorial recursion, push beats then unwind beats.\n *\n * ```thl callstack\n * fact 4\n * ```\n *\n * Depth is 1–6. Frame slots are stack lanes; popped frames clear back to\n * null while return values accumulate in the returns row.\n */\nexport type CallstackParams = { n: number };\n\nconst fact = (k: number): number => (k <= 1 ? 1 : k * fact(k - 1));\n\nexport function parseCallstack(ast: ThlBlock): CallstackParams {\n\tconst lines = sourceLines(ast);\n\tconst line = lines[0]?.line ?? sourceLine(ast);\n\tif (lines.length !== 1)\n\t\tthrow new ProgramError([\n\t\t\t{ message: \"Callstack takes one line: fact <n>.\", line },\n\t\t]);\n\tconst entry = lines[0]?.text.match(/^fact\\s+(\\d+)$/);\n\tif (!entry || entry[1] === undefined)\n\t\tthrow new ProgramError([{ message: \"Expected fact <n>.\", line }]);\n\tconst n = Number(entry[1]);\n\tif (!Number.isInteger(n) || n < 1 || n > 6)\n\t\tthrow new ProgramError([{ message: \"Depth n is 1–6.\", line }]);\n\treturn { n };\n}\n\nexport function buildCallstack({ n }: CallstackParams): Program {\n\tconst t = tracer();\n\t// slot1 is the bottom of the stack; slot i holds fact(n - i + 1).\n\tconst slot = (k: number): string => `slot${n - k + 1}`;\n\tfor (let i = 1; i <= n; i++)\n\t\tt.node(`slot${i}`, `frame ${i}`, null, { lane: \"Call stack\" });\n\tt.node(\"returns\", \"Returns\", Array<string | number>(n).fill(\"·\"), {\n\t\tlane: \"Returns\",\n\t\tview: \"array\",\n\t});\n\tfor (let k = 1; k < n; k++)\n\t\tt.link(`calls${k}`, slot(k + 1), slot(k), \"calls\");\n\tfor (let k = 1; k <= n; k++) t.link(`ret${k}`, slot(k), \"returns\", \"↩\");\n\tfor (let k = n; k >= 1; k--) {\n\t\tt.step(`call fact(${k})`, (s) => {\n\t\t\ts.focus(slot(k));\n\t\t\ts.set(\n\t\t\t\tslot(k),\n\t\t\t\tk === 1\n\t\t\t\t\t? \"fact(1) · base case\"\n\t\t\t\t\t: `fact(${k}) · waiting on fact(${k - 1})`,\n\t\t\t);\n\t\t\tif (k < n) s.send(`calls${k}`, `fact(${k})`);\n\t\t\ts.note(\n\t\t\t\tk === n\n\t\t\t\t\t? `fact(${n}) is called. Each call gets its own frame.`\n\t\t\t\t\t: k === 1\n\t\t\t\t\t\t? \"Base case: n <= 1. fact(1) returns without another call.\"\n\t\t\t\t\t\t: `fact(${k}) can't finish yet — it needs fact(${k - 1}). A new frame is pushed.`,\n\t\t\t);\n\t\t});\n\t}\n\tfor (let k = 1; k <= n; k++) {\n\t\tconst value = fact(k);\n\t\tt.step(`return fact(${k})`, (s) => {\n\t\t\ts.focus(slot(k), `returns[${k - 1}]`);\n\t\t\ts.set(slot(k), null);\n\t\t\ts.set(`returns[${k - 1}]`, value);\n\t\t\ts.send(`ret${k}`, value);\n\t\t\ts.note(\n\t\t\t\tk === 1\n\t\t\t\t\t? \"fact(1) returns 1. Its frame is popped.\"\n\t\t\t\t\t: `fact(${k}) gets ${fact(k - 1)} back and returns ${k} × ${fact(k - 1)} = ${value}.`,\n\t\t\t);\n\t\t});\n\t}\n\tt.step(\"done\", (s) => {\n\t\ts.focus(\"returns\");\n\t\ts.note(`The stack is empty again. fact(${n}) = ${fact(n)}.`);\n\t});\n\treturn t.program();\n}\n","import type { ThlBlock } from \"../dsl.js\";\nimport { type Program, ProgramError, type Value } from \"../model.js\";\nimport { tracer } from \"../tracer.js\";\nimport { sourceLine, sourceLines } from \"./lines.js\";\n\n/**\n * `thl matrix` — matrix multiplication, one beat per output cell.\n *\n * ```thl matrix\n * A = [[1,2],[3,4]]\n * B = [[5,6],[7,8]]\n * ```\n *\n * Both operands are rectangular number grids, at most 4×4, with matching\n * inner dimensions. Each beat dots one row of A with one column of B.\n */\nexport type MatrixParams = { a: number[][]; b: number[][] };\n\nconst parseGrid = (source: string, line: number): number[][] => {\n\tlet value: Value;\n\ttry {\n\t\tvalue = JSON.parse(source) as Value;\n\t} catch {\n\t\tthrow new ProgramError([\n\t\t\t{ message: \"Expected a JSON grid like [[1,2],[3,4]].\", line },\n\t\t]);\n\t}\n\tif (\n\t\t!Array.isArray(value) ||\n\t\tvalue.length < 1 ||\n\t\tvalue.length > 4 ||\n\t\tvalue.some(\n\t\t\t(row) =>\n\t\t\t\t!Array.isArray(row) ||\n\t\t\t\trow.length < 1 ||\n\t\t\t\trow.length > 4 ||\n\t\t\t\trow.length !== (value[0] as Value[]).length ||\n\t\t\t\trow.some((cell) => typeof cell !== \"number\" || !Number.isFinite(cell)),\n\t\t)\n\t)\n\t\tthrow new ProgramError([\n\t\t\t{\n\t\t\t\tmessage:\n\t\t\t\t\t\"Grids are 1–4 rows of 1–4 finite numbers, all rows equal length.\",\n\t\t\t\tline,\n\t\t\t},\n\t\t]);\n\treturn value as number[][];\n};\n\nexport function parseMatrix(ast: ThlBlock): MatrixParams {\n\tconst found = new Map<string, { grid: number[][]; line: number }>();\n\tfor (const { text, line } of sourceLines(ast)) {\n\t\tconst entry = text.match(/^(A|B)\\s*=\\s*(.+)$/);\n\t\tif (!entry?.[1] || entry[2] === undefined)\n\t\t\tthrow new ProgramError([\n\t\t\t\t{ message: \"Expected A = <grid> or B = <grid>.\", line },\n\t\t\t]);\n\t\tif (found.has(entry[1]))\n\t\t\tthrow new ProgramError([\n\t\t\t\t{ message: `Duplicate operand \"${entry[1]}\".`, line },\n\t\t\t]);\n\t\tfound.set(entry[1], { grid: parseGrid(entry[2], line), line });\n\t}\n\tconst a = found.get(\"A\");\n\tconst b = found.get(\"B\");\n\tif (!a || !b)\n\t\tthrow new ProgramError([\n\t\t\t{\n\t\t\t\tmessage: \"Matrix needs both A = <grid> and B = <grid>.\",\n\t\t\t\tline: sourceLine(ast),\n\t\t\t},\n\t\t]);\n\tif (a.grid[0]?.length !== b.grid.length)\n\t\tthrow new ProgramError([\n\t\t\t{\n\t\t\t\tmessage: `Inner dimensions mismatch: A has ${a.grid[0]?.length} columns but B has ${b.grid.length} rows.`,\n\t\t\t\tline: b.line,\n\t\t\t},\n\t\t]);\n\treturn { a: a.grid, b: b.grid };\n}\n\nexport function buildMatrix({ a, b }: MatrixParams): Program {\n\tconst t = tracer();\n\tt.group(\"Matrices\", \"row\").group(\"Work\", \"row\");\n\tconst rows = a.length;\n\tconst cols = b[0]?.length;\n\tconst inner = b.length;\n\tt.node(\"A\", \"A\", a, { lane: \"Matrices\", view: \"matrix\" });\n\tt.node(\"B\", \"B\", b, { lane: \"Matrices\", view: \"matrix\" });\n\tt.node(\n\t\t\"C\",\n\t\t\"C = A × B\",\n\t\tArray.from({ length: rows }, () => Array<string | number>(cols).fill(\"·\")),\n\t\t{ lane: \"Matrices\", view: \"matrix\" },\n\t);\n\tt.node(\"work\", \"Terms\", [], { lane: \"Work\", view: \"array\" });\n\tt.link(\"readA\", \"A\", \"C\", \"row\");\n\tt.link(\"readB\", \"B\", \"C\", \"col\");\n\tfor (let i = 0; i < rows; i++) {\n\t\tfor (let j = 0; j < cols; j++) {\n\t\t\tconst terms = Array.from({ length: inner }, (_, k) => a[i][k] * b[k][j]);\n\t\t\tconst total = terms.reduce((sum, term) => sum + term, 0);\n\t\t\tconst column = Array.from({ length: inner }, (_, k) => `B[${k}][${j}]`);\n\t\t\tt.step(`C[${i}][${j}]`, (s) => {\n\t\t\t\ts.focus(`A[${i}]`, `C[${i}][${j}]`, ...column);\n\t\t\t\ts.set(`C[${i}][${j}]`, total);\n\t\t\t\ts.set(\"work\", terms);\n\t\t\t\ts.send(\"readA\", a[i]);\n\t\t\t\ts.send(\n\t\t\t\t\t\"readB\",\n\t\t\t\t\tb.map((row) => row[j]),\n\t\t\t\t);\n\t\t\t\ts.note(\n\t\t\t\t\t`C[${i}][${j}] = ${terms.join(\" + \")} = ${total}. Row ${i} of A dot column ${j} of B.`,\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\t}\n\treturn t.program();\n}\n","import { parseProgram } from \"../authoring.js\";\nimport { compileProgram } from \"../compiler.js\";\nimport { parseThl, type ThlBlock } from \"../dsl.js\";\nimport { COMPILATION_LIMITS, createBudget } from \"../limits.js\";\nimport { type Program, ProgramError, type Trace } from \"../model.js\";\nimport { buildBinary, parseBinary } from \"./binary.js\";\nimport { buildBindings, parseBindings } from \"./bindings.js\";\nimport { buildCallstack, parseCallstack } from \"./callstack.js\";\nimport { buildMatrix, parseMatrix } from \"./matrix.js\";\nimport type { DomainName } from \"./types.js\";\n\nexport const SUPPORTED_DOMAINS: readonly DomainName[] = [\n\t\"flow\",\n\t\"bindings\",\n\t\"binary\",\n\t\"matrix\",\n\t\"callstack\",\n];\n\nconst COMPUTED: Record<\n\tExclude<DomainName, \"flow\">,\n\t(ast: ThlBlock) => Program\n> = {\n\tbindings: (ast) => buildBindings(checkParameters(parseBindings(ast))),\n\tbinary: (ast) => buildBinary(checkParameters(parseBinary(ast))),\n\tmatrix: (ast) => buildMatrix(checkParameters(parseMatrix(ast))),\n\tcallstack: (ast) => buildCallstack(checkParameters(parseCallstack(ast))),\n};\n\n/** Adapters may serialize labels before producing a Program. Guard their input first. */\nfunction checkParameters<T>(parameters: T): T {\n\tcreateBudget(\"Program input\", COMPILATION_LIMITS.programUnits)(parameters);\n\treturn parameters;\n}\n\n/** Compile any fenced thl block, routing on the info-string domain. */\nexport function compile(src: string): Trace {\n\tconst ast = parseThl(src);\n\tif (!ast)\n\t\tthrow new ProgramError([{ message: \"Expected a ```thl <domain> block.\" }]);\n\treturn compileAst(ast);\n}\n\nexport function compileAst(ast: ThlBlock): Trace {\n\tif (ast.kind === \"flow\") return compileProgram(parseProgram(ast));\n\tconst build = Object.hasOwn(COMPUTED, ast.kind)\n\t\t? COMPUTED[ast.kind as Exclude<DomainName, \"flow\">]\n\t\t: undefined;\n\tif (!build)\n\t\tthrow new ProgramError([\n\t\t\t{\n\t\t\t\tmessage: `Unknown domain \"${ast.kind}\". Use ${SUPPORTED_DOMAINS.join(\", \")}.`,\n\t\t\t\tline: ast.source?.line ?? 1,\n\t\t\t},\n\t\t]);\n\treturn compileProgram(build(ast));\n}\n"],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ type Value = null | boolean | number | string | Value[] | {
2
+ [key: string]: Value;
3
+ };
4
+ declare const VIEWS: readonly ["auto", "text", "number", "array", "stack", "matrix", "bits", "record"];
5
+ type View = (typeof VIEWS)[number];
6
+ type Entity = {
7
+ id: string;
8
+ label: string;
9
+ value: Value;
10
+ lane?: string;
11
+ view?: View;
12
+ /** Absent from the scene until explicitly shown; identity stays stable. */
13
+ hidden?: boolean;
14
+ };
15
+ type Relation = {
16
+ id: string;
17
+ from: string;
18
+ to: string;
19
+ label?: string;
20
+ hidden?: boolean;
21
+ };
22
+ type SourceLocation = {
23
+ line: number;
24
+ };
25
+ /** Targets address an entity or a position inside its value: `arr`, `arr[3]`, `grid[1][2]`, `cfg.mode`. */
26
+ type Event = ({
27
+ op: "set";
28
+ target: string;
29
+ value: Value;
30
+ } | {
31
+ op: "focus";
32
+ targets: string[];
33
+ } | {
34
+ op: "send";
35
+ relation: string;
36
+ value?: Value;
37
+ } | {
38
+ op: "note";
39
+ text: string;
40
+ } | {
41
+ op: "show" | "hide";
42
+ kind: "node" | "link";
43
+ id: string;
44
+ }) & {
45
+ source?: SourceLocation;
46
+ };
47
+ type Beat = {
48
+ label: string;
49
+ events: Event[];
50
+ source?: SourceLocation;
51
+ };
52
+ declare const GROUP_LAYOUTS: readonly ["row", "column", "tree"];
53
+ type GroupLayout = (typeof GROUP_LAYOUTS)[number];
54
+ type SceneGroup = {
55
+ name: string;
56
+ layout: GroupLayout;
57
+ };
58
+ type Program = {
59
+ version: 1;
60
+ entities: Entity[];
61
+ relations: Relation[];
62
+ beats: Beat[];
63
+ groups?: SceneGroup[];
64
+ };
65
+ type Snapshot = {
66
+ entities: Entity[];
67
+ relations: Relation[];
68
+ active: string[];
69
+ changed: string[];
70
+ transfers: {
71
+ relation: string;
72
+ value?: Value;
73
+ }[];
74
+ notes: string[];
75
+ };
76
+ type Frame = {
77
+ index: number;
78
+ label: string;
79
+ state: Snapshot;
80
+ events: Event[];
81
+ source?: SourceLocation;
82
+ };
83
+ type Trace = {
84
+ version: 1;
85
+ frames: Frame[];
86
+ groups?: SceneGroup[];
87
+ };
88
+ type Diagnostic = {
89
+ message: string;
90
+ line?: number;
91
+ beat?: number;
92
+ };
93
+ declare class ProgramError extends Error {
94
+ diagnostics: Diagnostic[];
95
+ constructor(diagnostics: Diagnostic[]);
96
+ }
97
+ export { Frame as a, ProgramError as c, Snapshot as d, SourceLocation as f, View as h, Event as i, Relation as l, Value as m, Diagnostic as n, GroupLayout as o, Trace as p, Entity as r, Program as s, Beat as t, SceneGroup as u };
@@ -0,0 +1,22 @@
1
+ import { p as Trace } from "../model-Dwy20ibD.js";
2
+ import * as React from "react";
3
+ type SonificationEvent = {
4
+ step: number;
5
+ total: number;
6
+ frequency: number;
7
+ durationMs: number;
8
+ };
9
+ type SonificationHandler = (event: SonificationEvent) => void;
10
+ type SonificationOptions = {
11
+ enabled?: boolean;
12
+ onTone?: SonificationHandler;
13
+ };
14
+ interface ThroughlinePlayerProps {
15
+ trace: Trace;
16
+ className?: string;
17
+ theme?: "light" | "dark" | "auto";
18
+ /** Omit to remove audio controls entirely. */
19
+ sonification?: SonificationOptions;
20
+ }
21
+ export declare function ThroughlinePlayer({ trace, className, theme, sonification }: ThroughlinePlayerProps): React.JSX.Element;
22
+ export type { SonificationEvent, SonificationOptions, ThroughlinePlayerProps };