hayao 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +98 -0
  3. package/dist/app/browser.d.ts +19 -0
  4. package/dist/app/game.d.ts +34 -0
  5. package/dist/art/palette.d.ts +20 -0
  6. package/dist/art/shapes.d.ts +12 -0
  7. package/dist/audio/audio.d.ts +42 -0
  8. package/dist/core/clock.d.ts +37 -0
  9. package/dist/core/events.d.ts +23 -0
  10. package/dist/core/hash.d.ts +6 -0
  11. package/dist/core/math.d.ts +44 -0
  12. package/dist/core/rng.d.ts +38 -0
  13. package/dist/index.d.ts +43 -0
  14. package/dist/index.js +2844 -0
  15. package/dist/index.js.map +7 -0
  16. package/dist/input/actions.d.ts +40 -0
  17. package/dist/input/source.d.ts +25 -0
  18. package/dist/physics/aabb.d.ts +38 -0
  19. package/dist/physics/platformer.d.ts +112 -0
  20. package/dist/physics/raycast.d.ts +22 -0
  21. package/dist/physics/spatialHash.d.ts +15 -0
  22. package/dist/physics/tilemap.d.ts +38 -0
  23. package/dist/render/canvas.d.ts +19 -0
  24. package/dist/render/commands.d.ts +65 -0
  25. package/dist/render/headless.d.ts +17 -0
  26. package/dist/render/renderer.d.ts +16 -0
  27. package/dist/render/svg.d.ts +16 -0
  28. package/dist/render/svgString.d.ts +5 -0
  29. package/dist/scene/node.d.ts +100 -0
  30. package/dist/scene/nodes.d.ts +90 -0
  31. package/dist/scene/particles.d.ts +78 -0
  32. package/dist/scene/registry.d.ts +5 -0
  33. package/dist/scene/tween.d.ts +20 -0
  34. package/dist/ui/overlay.d.ts +25 -0
  35. package/dist/ui/settings.d.ts +23 -0
  36. package/dist/ui/shell.d.ts +19 -0
  37. package/dist/verify/bot.d.ts +21 -0
  38. package/dist/verify/capture.d.ts +21 -0
  39. package/dist/verify/determinism.d.ts +29 -0
  40. package/dist/verify/driver.d.ts +23 -0
  41. package/dist/verify/feel.d.ts +25 -0
  42. package/dist/verify/filmstrip.d.ts +19 -0
  43. package/dist/verify/playthrough.d.ts +21 -0
  44. package/dist/verify/solver.d.ts +37 -0
  45. package/dist/world.d.ts +75 -0
  46. package/docs/API.md +226 -0
  47. package/package.json +44 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/core/math.ts", "../src/core/rng.ts", "../src/core/clock.ts", "../src/core/events.ts", "../src/core/hash.ts", "../src/scene/node.ts", "../src/scene/nodes.ts", "../src/scene/tween.ts", "../src/scene/particles.ts", "../src/scene/registry.ts", "../src/input/actions.ts", "../src/input/source.ts", "../src/physics/tilemap.ts", "../src/physics/aabb.ts", "../src/physics/platformer.ts", "../src/physics/spatialHash.ts", "../src/physics/raycast.ts", "../src/render/commands.ts", "../src/render/svgString.ts", "../src/render/svg.ts", "../src/render/canvas.ts", "../src/render/headless.ts", "../src/art/palette.ts", "../src/art/shapes.ts", "../src/audio/audio.ts", "../src/ui/overlay.ts", "../src/ui/settings.ts", "../src/ui/shell.ts", "../src/verify/solver.ts", "../src/verify/determinism.ts", "../src/verify/playthrough.ts", "../src/verify/capture.ts", "../src/verify/driver.ts", "../src/verify/bot.ts", "../src/verify/feel.ts", "../src/verify/filmstrip.ts", "../src/world.ts", "../src/app/game.ts", "../src/app/browser.ts", "../src/index.ts"],
4
+ "sourcesContent": ["// Deterministic 2D math. Plain data + pure functions (no classes with hidden\n// state) so everything serializes and hashes cleanly.\n\nexport interface Vec2 {\n x: number;\n y: number;\n}\n\nexport const vec2 = (x = 0, y = 0): Vec2 => ({ x, y });\nexport const vadd = (a: Vec2, b: Vec2): Vec2 => ({ x: a.x + b.x, y: a.y + b.y });\nexport const vsub = (a: Vec2, b: Vec2): Vec2 => ({ x: a.x - b.x, y: a.y - b.y });\nexport const vscale = (a: Vec2, s: number): Vec2 => ({ x: a.x * s, y: a.y * s });\nexport const vdot = (a: Vec2, b: Vec2): number => a.x * b.x + a.y * b.y;\nexport const vlen = (a: Vec2): number => Math.hypot(a.x, a.y);\nexport const vdist = (a: Vec2, b: Vec2): number => Math.hypot(a.x - b.x, a.y - b.y);\nexport function vnorm(a: Vec2): Vec2 {\n const l = vlen(a);\n return l === 0 ? { x: 0, y: 0 } : { x: a.x / l, y: a.y / l };\n}\n\nexport const clamp = (v: number, lo: number, hi: number): number => (v < lo ? lo : v > hi ? hi : v);\nexport const lerp = (a: number, b: number, t: number): number => a + (b - a) * t;\nexport const invLerp = (a: number, b: number, v: number): number => (a === b ? 0 : (v - a) / (b - a));\nexport const remap = (v: number, a0: number, a1: number, b0: number, b1: number): number =>\n lerp(b0, b1, invLerp(a0, a1, v));\n\nexport const TAU = Math.PI * 2;\nexport const deg2rad = (d: number): number => (d * Math.PI) / 180;\nexport const rad2deg = (r: number): number => (r * 180) / Math.PI;\n\n/** Axis-aligned rectangle. */\nexport interface Rect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport function rectContains(r: Rect, p: Vec2): boolean {\n return p.x >= r.x && p.x <= r.x + r.w && p.y >= r.y && p.y <= r.y + r.h;\n}\n\nexport function rectsOverlap(a: Rect, b: Rect): boolean {\n return a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y;\n}\n\n/** 2D affine transform as a 6-value matrix [a b c d e f] (like SVG/Canvas). */\nexport interface Transform {\n a: number;\n b: number;\n c: number;\n d: number;\n e: number;\n f: number;\n}\n\nexport const IDENTITY: Transform = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 };\n\nexport function composeTransform(m: Transform, n: Transform): Transform {\n return {\n a: m.a * n.a + m.c * n.b,\n b: m.b * n.a + m.d * n.b,\n c: m.a * n.c + m.c * n.d,\n d: m.b * n.c + m.d * n.d,\n e: m.a * n.e + m.c * n.f + m.e,\n f: m.b * n.e + m.d * n.f + m.f,\n };\n}\n\n/** Build a transform from position, rotation (radians), scale. */\nexport function makeTransform(pos: Vec2, rotation: number, scale: Vec2): Transform {\n const cos = Math.cos(rotation);\n const sin = Math.sin(rotation);\n return {\n a: cos * scale.x,\n b: sin * scale.x,\n c: -sin * scale.y,\n d: cos * scale.y,\n e: pos.x,\n f: pos.y,\n };\n}\n\nexport function applyTransform(m: Transform, p: Vec2): Vec2 {\n return { x: m.a * p.x + m.c * p.y + m.e, y: m.b * p.x + m.d * p.y + m.f };\n}\n\n/** Invert an affine transform (returns identity if singular). */\nexport function invertTransform(m: Transform): Transform {\n const det = m.a * m.d - m.b * m.c;\n if (det === 0) return { ...IDENTITY };\n const id = 1 / det;\n return {\n a: m.d * id,\n b: -m.b * id,\n c: -m.c * id,\n d: m.a * id,\n e: (m.c * m.f - m.d * m.e) * id,\n f: (m.b * m.e - m.a * m.f) * id,\n };\n}\n", "// Deterministic, seedable, splittable RNG. SplitMix64 for seeding, xoshiro128**\n// for the stream \u2014 fast, good distribution, trivially reproducible.\n// Every random draw in a game MUST flow through here (never Math.random()).\n\nfunction splitmix32(seed: number): () => number {\n let a = seed >>> 0;\n return () => {\n a = (a + 0x9e3779b9) >>> 0;\n let t = a;\n t = Math.imul(t ^ (t >>> 16), 0x21f0aaad);\n t = Math.imul(t ^ (t >>> 15), 0x735a2d97);\n return (t ^ (t >>> 15)) >>> 0;\n };\n}\n\nexport interface RngState {\n s: [number, number, number, number];\n}\n\nexport class Rng {\n private s0: number;\n private s1: number;\n private s2: number;\n private s3: number;\n\n constructor(seed: number | RngState = 0) {\n if (typeof seed === 'number') {\n const sm = splitmix32(seed === 0 ? 0x1234abcd : seed);\n this.s0 = sm();\n this.s1 = sm();\n this.s2 = sm();\n this.s3 = sm();\n } else {\n [this.s0, this.s1, this.s2, this.s3] = seed.s;\n }\n }\n\n /** Raw 32-bit unsigned integer. */\n private next(): number {\n const result = (Math.imul(this.rotl(Math.imul(this.s1, 5), 7), 9) >>> 0);\n const t = (this.s1 << 9) >>> 0;\n this.s2 ^= this.s0;\n this.s3 ^= this.s1;\n this.s1 ^= this.s2;\n this.s0 ^= this.s3;\n this.s2 = (this.s2 ^ t) >>> 0;\n this.s3 = this.rotl(this.s3, 11);\n return result >>> 0;\n }\n\n private rotl(x: number, k: number): number {\n return (((x << k) | (x >>> (32 - k))) >>> 0);\n }\n\n /** Float in [0, 1). */\n float(): number {\n return this.next() / 4294967296;\n }\n\n /** Float in [lo, hi). */\n range(lo: number, hi: number): number {\n return lo + this.float() * (hi - lo);\n }\n\n /** Integer in [0, n). */\n int(n: number): number {\n return Math.floor(this.float() * n);\n }\n\n /** Integer in [lo, hi] inclusive. */\n intRange(lo: number, hi: number): number {\n return lo + this.int(hi - lo + 1);\n }\n\n /** True with probability p. */\n chance(p: number): boolean {\n return this.float() < p;\n }\n\n /** Uniform element of an array. */\n pick<T>(arr: readonly T[]): T {\n return arr[this.int(arr.length)];\n }\n\n /** In-place Fisher\u2013Yates shuffle (deterministic). */\n shuffle<T>(arr: T[]): T[] {\n for (let i = arr.length - 1; i > 0; i--) {\n const j = this.int(i + 1);\n [arr[i], arr[j]] = [arr[j], arr[i]];\n }\n return arr;\n }\n\n /**\n * Derive an independent child stream. Same parent state + same key always\n * yields the same child \u2014 so subsystems (enemy AI, loot, terrain) get stable,\n * decorrelated randomness without threading one generator through everything.\n */\n split(key = 0): Rng {\n const mix = (this.s0 ^ Math.imul(key + 1, 0x9e3779b9)) >>> 0;\n const child = new Rng(mix ^ this.s3);\n // Advance parent so repeated splits differ.\n this.next();\n return child;\n }\n\n /** Serialize / restore for saves and replay. */\n getState(): RngState {\n return { s: [this.s0, this.s1, this.s2, this.s3] };\n }\n setState(state: RngState): void {\n [this.s0, this.s1, this.s2, this.s3] = state.s;\n }\n}\n\n/** Deterministic 32-bit FNV-1a hash of a string \u2014 handy for stable ids/seeds. */\nexport function hashString(str: string): number {\n let h = 2166136261 >>> 0;\n for (let i = 0; i < str.length; i++) {\n h ^= str.charCodeAt(i);\n h = Math.imul(h, 16777619);\n }\n return h >>> 0;\n}\n", "// Fixed-timestep clock. Real elapsed milliseconds go in; whole fixed steps come\n// out. This is what makes the sim frame-rate independent AND exactly reproducible:\n// the same input log always yields the same number of steps.\n\nexport interface ClockConfig {\n /** Simulation rate in Hz (steps per second). Default 60. */\n hz?: number;\n /** Max real ms consumed per advance, to avoid a spiral of death. Default 250. */\n maxFrameMs?: number;\n}\n\nexport class Clock {\n readonly stepMs: number;\n readonly dt: number; // fixed delta in seconds, for game logic\n private maxFrameMs: number;\n private accumulator = 0;\n private _frame = 0;\n private _simTimeMs = 0;\n\n constructor(config: ClockConfig = {}) {\n const hz = config.hz ?? 60;\n this.stepMs = 1000 / hz;\n this.dt = 1 / hz;\n this.maxFrameMs = config.maxFrameMs ?? 250;\n }\n\n /**\n * Feed real elapsed ms; returns how many fixed steps to run now.\n * Caller runs the sim exactly that many times.\n */\n advance(realMs: number): number {\n this.accumulator += Math.min(realMs, this.maxFrameMs);\n let steps = 0;\n while (this.accumulator >= this.stepMs) {\n this.accumulator -= this.stepMs;\n steps++;\n }\n return steps;\n }\n\n /** Called by the World once per executed step to keep counters honest. */\n tick(): void {\n this._frame++;\n this._simTimeMs += this.stepMs;\n }\n\n /** Interpolation alpha in [0,1) for smooth rendering between fixed steps. */\n get alpha(): number {\n return this.accumulator / this.stepMs;\n }\n\n get frame(): number {\n return this._frame;\n }\n get simTimeMs(): number {\n return this._simTimeMs;\n }\n get simTimeSec(): number {\n return this._simTimeMs / 1000;\n }\n\n getState() {\n return { accumulator: this.accumulator, frame: this._frame, simTimeMs: this._simTimeMs };\n }\n setState(s: { accumulator: number; frame: number; simTimeMs: number }): void {\n this.accumulator = s.accumulator;\n this._frame = s.frame;\n this._simTimeMs = s.simTimeMs;\n }\n}\n", "// Synchronous typed signal bus (Godot-style signals). Deterministic: listeners\n// fire in connection order, synchronously, within the current step.\n\nexport type Listener<T> = (payload: T) => void;\n\nexport class Signal<T = void> {\n private listeners: Listener<T>[] = [];\n\n connect(fn: Listener<T>): () => void {\n this.listeners.push(fn);\n return () => this.disconnect(fn);\n }\n\n once(fn: Listener<T>): () => void {\n const off = this.connect((p) => {\n off();\n fn(p);\n });\n return off;\n }\n\n disconnect(fn: Listener<T>): void {\n const i = this.listeners.indexOf(fn);\n if (i >= 0) this.listeners.splice(i, 1);\n }\n\n emit(payload: T): void {\n // Copy so a listener disconnecting mid-emit doesn't skip its neighbor.\n for (const fn of this.listeners.slice()) fn(payload);\n }\n\n get count(): number {\n return this.listeners.length;\n }\n\n clear(): void {\n this.listeners.length = 0;\n }\n}\n\n/**\n * A named event bus for cross-cutting game events, keyed by an event map so\n * payloads are typed. Prefer node-local Signals for local wiring; use the bus\n * for global concerns (score changed, level complete, sound cue).\n */\nexport class EventBus<Events extends Record<string, unknown>> {\n private signals = new Map<keyof Events, Signal<unknown>>();\n\n private signalFor<K extends keyof Events>(key: K): Signal<Events[K]> {\n let s = this.signals.get(key);\n if (!s) {\n s = new Signal<unknown>();\n this.signals.set(key, s);\n }\n return s as unknown as Signal<Events[K]>;\n }\n\n on<K extends keyof Events>(key: K, fn: Listener<Events[K]>): () => void {\n return this.signalFor(key).connect(fn);\n }\n\n once<K extends keyof Events>(key: K, fn: Listener<Events[K]>): () => void {\n return this.signalFor(key).once(fn);\n }\n\n emit<K extends keyof Events>(key: K, payload: Events[K]): void {\n this.signalFor(key).emit(payload);\n }\n\n clear(): void {\n this.signals.clear();\n }\n}\n", "// Deterministic structural hash of any JSON-like value. The spine of replay\n// verification: two runs are identical iff their state hashes match.\n\nfunction canonicalNumber(n: number): string {\n if (Number.isNaN(n)) return 'NaN';\n if (n === Infinity) return 'Inf';\n if (n === -Infinity) return '-Inf';\n if (n === 0) return '0'; // collapse -0 and 0\n return n.toString();\n}\n\n/**\n * Walk a value in a canonical order (object keys sorted) and fold it into a\n * 64-bit-ish FNV-1a hash represented as an 8-char hex string. Stable across runs\n * for structurally identical data.\n */\nexport function hashValue(value: unknown): string {\n let h1 = 2166136261 >>> 0;\n let h2 = 0x811c9dc5 >>> 0;\n const push = (s: string) => {\n for (let i = 0; i < s.length; i++) {\n const c = s.charCodeAt(i);\n h1 = Math.imul(h1 ^ c, 16777619) >>> 0;\n h2 = Math.imul(h2 ^ ((c << 3) | (c >>> 5)), 2246822519) >>> 0;\n }\n };\n\n const walk = (v: unknown): void => {\n if (v === null) return push('n');\n if (v === undefined) return push('u');\n switch (typeof v) {\n case 'number':\n return push('#' + canonicalNumber(v));\n case 'boolean':\n return push(v ? 't' : 'f');\n case 'string':\n return push('\"' + v);\n case 'object': {\n if (Array.isArray(v)) {\n push('[');\n for (const el of v) walk(el);\n push(']');\n return;\n }\n const obj = v as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n push('{');\n for (const k of keys) {\n push(k + ':');\n walk(obj[k]);\n }\n push('}');\n return;\n }\n default:\n push('?');\n }\n };\n\n walk(value);\n const hex = (n: number) => n.toString(16).padStart(8, '0');\n return hex(h1) + hex(h2);\n}\n", "// The scene node: a Godot-style tree element with a transform, lifecycle,\n// children, local signals, and attachable behaviors. Updates run in fixed tree\n// order (depth-first, child-index order) which keeps the whole tree deterministic.\n\nimport type { Rng } from '../core/rng';\nimport type { Clock } from '../core/clock';\nimport { Signal } from '../core/events';\nimport {\n IDENTITY,\n composeTransform,\n makeTransform,\n type Transform,\n type Vec2,\n} from '../core/math';\nimport type { DrawCommand } from '../render/commands';\n\n/** What a live node can see of its host world. The World implements this. */\nexport interface WorldContext {\n readonly rng: Rng;\n readonly clock: Clock;\n /** Queue a node to be freed at the end of the current step (safe during iteration). */\n requestFree(node: Node): void;\n /** Seconds elapsed in sim time. */\n readonly time: number;\n}\n\n/** A composable update unit attached to a node (favour over deep inheritance). */\nexport interface Behavior {\n ready?(node: Node): void;\n update?(node: Node, dt: number): void;\n exit?(node: Node): void;\n /** Optional tag for lookup/serialization. */\n readonly kind?: string;\n}\n\nlet __idCounter = 0;\n/** Deterministic id source \u2014 reset by the World on load so ids are reproducible. */\nexport function resetNodeIds(start = 0): void {\n __idCounter = start;\n}\n\nexport interface NodeConfig {\n name?: string;\n pos?: Vec2;\n rotation?: number;\n scale?: Vec2;\n z?: number;\n visible?: boolean;\n}\n\nexport class Node {\n readonly id: string;\n name: string;\n /** Type tag for serialization; subclasses override. */\n readonly type: string = 'Node';\n\n pos: Vec2;\n rotation: number;\n scale: Vec2;\n z: number;\n visible: boolean;\n /**\n * Cosmetic nodes are pure *view* (derived from game state, rebuildable) and are\n * excluded from serialize()/snapshot()/hash(). Mark a container cosmetic when it\n * only renders state that lives elsewhere \u2014 so transient display (move counters,\n * particles, tweened positions) never pollutes the canonical, verifiable state.\n */\n cosmetic = false;\n\n parent: Node | null = null;\n readonly children: Node[] = [];\n world: WorldContext | null = null;\n\n /** Optional inline update without subclassing: node.onUpdate = (n, dt) => {\u2026}. */\n onUpdate?: (node: Node, dt: number) => void;\n\n private behaviors: Behavior[] = [];\n private signals = new Map<string, Signal<unknown>>();\n private _ready = false;\n private _freed = false;\n\n constructor(config: NodeConfig = {}) {\n this.id = `n${__idCounter++}`;\n this.name = config.name ?? this.constructor.name;\n this.pos = config.pos ? { ...config.pos } : { x: 0, y: 0 };\n this.rotation = config.rotation ?? 0;\n this.scale = config.scale ? { ...config.scale } : { x: 1, y: 1 };\n this.z = config.z ?? 0;\n this.visible = config.visible ?? true;\n }\n\n // \u2500\u2500 Tree structure \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n addChild<T extends Node>(child: T): T {\n child.parent = this;\n this.children.push(child);\n if (this.world && this._ready) child.enterTree(this.world);\n return child;\n }\n\n removeChild(child: Node): void {\n const i = this.children.indexOf(child);\n if (i >= 0) {\n this.children.splice(i, 1);\n child.parent = null;\n }\n }\n\n /** Deferred free: runs exit hooks and detaches at the end of the step. */\n free(): void {\n this.world?.requestFree(this);\n }\n\n /** Depth-first find by name. */\n find(name: string): Node | null {\n if (this.name === name) return this;\n for (const c of this.children) {\n const r = c.find(name);\n if (r) return r;\n }\n return null;\n }\n\n /** All descendants (and self) of a given type tag. */\n query(type: string, out: Node[] = []): Node[] {\n if (this.type === type) out.push(this);\n for (const c of this.children) c.query(type, out);\n return out;\n }\n\n // \u2500\u2500 Behaviors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n addBehavior(b: Behavior): this {\n this.behaviors.push(b);\n if (this._ready) b.ready?.(this);\n return this;\n }\n\n // \u2500\u2500 Signals \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n signal<T = void>(name: string): Signal<T> {\n let s = this.signals.get(name);\n if (!s) {\n s = new Signal<unknown>();\n this.signals.set(name, s);\n }\n return s as unknown as Signal<T>;\n }\n emit<T>(name: string, payload: T): void {\n this.signals.get(name)?.emit(payload);\n }\n\n // \u2500\u2500 Lifecycle (engine-called) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n enterTree(world: WorldContext): void {\n this.world = world;\n if (!this._ready) {\n this._ready = true;\n this.onReady();\n for (const b of this.behaviors) b.ready?.(this);\n }\n for (const c of this.children) c.enterTree(world);\n }\n\n updateTree(dt: number): void {\n if (this._freed) return;\n for (const b of this.behaviors) b.update?.(this, dt);\n this.onUpdate?.(this, dt);\n this.onProcess(dt);\n // Copy children so structural changes during update are safe.\n for (const c of this.children.slice()) c.updateTree(dt);\n }\n\n exitTree(): void {\n for (const b of this.behaviors) b.exit?.(this);\n this.onExit();\n for (const c of this.children.slice()) c.exitTree();\n this._freed = true;\n }\n\n get isFreed(): boolean {\n return this._freed;\n }\n\n // \u2500\u2500 Transforms \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n localTransform(): Transform {\n return makeTransform(this.pos, this.rotation, this.scale);\n }\n\n worldTransform(): Transform {\n const local = this.localTransform();\n return this.parent ? composeTransform(this.parent.worldTransform(), local) : local;\n }\n\n // \u2500\u2500 Rendering (projection) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Walk the subtree, appending draw commands with computed world transforms. */\n collectDraw(out: DrawCommand[], parentWorld: Transform = IDENTITY): void {\n if (!this.visible) return;\n const world = composeTransform(parentWorld, this.localTransform());\n this.draw(out, world);\n for (const c of this.children) c.collectDraw(out, world);\n }\n\n /** Subclasses emit their own commands here. Base draws nothing. */\n protected draw(_out: DrawCommand[], _world: Transform): void {}\n\n // \u2500\u2500 Overridable hooks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n protected onReady(): void {}\n protected onProcess(_dt: number): void {}\n protected onExit(): void {}\n\n // \u2500\u2500 Serialization (data only; behaviors/closures are re-attached by scene code) \u2500\u2500\n serialize(): SerializedNode {\n return {\n type: this.type,\n name: this.name,\n pos: { ...this.pos },\n rotation: this.rotation,\n scale: { ...this.scale },\n z: this.z,\n visible: this.visible,\n props: this.serializeProps(),\n children: this.children.filter((c) => !c.cosmetic).map((c) => c.serialize()),\n };\n }\n /** Subclasses persist their own fields here. */\n protected serializeProps(): Record<string, unknown> {\n return {};\n }\n /** Subclasses restore their own fields here. */\n applyProps(_props: Record<string, unknown>): void {}\n}\n\nexport interface SerializedNode {\n type: string;\n name: string;\n pos: Vec2;\n rotation: number;\n scale: Vec2;\n z: number;\n visible: boolean;\n props: Record<string, unknown>;\n children: SerializedNode[];\n}\n", "// Concrete node types built on Node. Code-as-art: a Sprite is a vector shape or\n// glyph, never a bitmap. Text is a DOM-quality label. Camera2D drives the view.\n// Timer is a deterministic countdown that emits a signal.\n\nimport type { Transform } from '../core/math';\nimport type { DrawCommand, Paint, TextAlign } from '../render/commands';\nimport { Node, type NodeConfig, type WorldContext } from './node';\n\n// \u2500\u2500 Sprite \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport type Shape =\n | { kind: 'rect'; w: number; h: number; r?: number }\n | { kind: 'circle'; radius: number }\n | { kind: 'poly'; points: number[]; closed?: boolean }\n | { kind: 'path'; d: string }\n | { kind: 'glyph'; char: string; size: number };\n\nexport interface SpriteConfig extends NodeConfig, Paint {\n shape: Shape;\n}\n\nexport class Sprite extends Node {\n override readonly type = 'Sprite';\n shape: Shape;\n paint: Paint;\n\n constructor(config: SpriteConfig) {\n super(config);\n this.shape = config.shape;\n this.paint = {\n fill: config.fill,\n stroke: config.stroke,\n strokeWidth: config.strokeWidth,\n opacity: config.opacity,\n round: config.round,\n };\n }\n\n protected override draw(out: DrawCommand[], world: Transform): void {\n const p = this.paint;\n const base = { transform: world, z: this.z, ...p };\n switch (this.shape.kind) {\n case 'rect':\n out.push({ kind: 'rect', x: -this.shape.w / 2, y: -this.shape.h / 2, w: this.shape.w, h: this.shape.h, r: this.shape.r, ...base });\n break;\n case 'circle':\n out.push({ kind: 'circle', cx: 0, cy: 0, radius: this.shape.radius, ...base });\n break;\n case 'poly':\n out.push({ kind: 'poly', points: this.shape.points, closed: this.shape.closed ?? true, ...base });\n break;\n case 'path':\n out.push({ kind: 'path', d: this.shape.d, ...base });\n break;\n case 'glyph':\n out.push({ kind: 'text', text: this.shape.char, x: 0, y: 0, size: this.shape.size, align: 'center', ...base });\n break;\n }\n }\n\n protected override serializeProps(): Record<string, unknown> {\n return { shape: this.shape, paint: this.paint };\n }\n override applyProps(props: Record<string, unknown>): void {\n if (props.shape) this.shape = props.shape as Shape;\n if (props.paint) this.paint = props.paint as Paint;\n }\n}\n\n// \u2500\u2500 Text \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport interface TextConfig extends NodeConfig, Paint {\n text: string;\n size?: number;\n font?: string;\n align?: TextAlign;\n weight?: number;\n}\n\nexport class Text extends Node {\n override readonly type = 'Text';\n text: string;\n size: number;\n font?: string;\n align: TextAlign;\n weight?: number;\n paint: Paint;\n\n constructor(config: TextConfig) {\n super(config);\n this.text = config.text;\n this.size = config.size ?? 24;\n this.font = config.font;\n this.align = config.align ?? 'left';\n this.weight = config.weight;\n this.paint = { fill: config.fill ?? '#000', stroke: config.stroke, strokeWidth: config.strokeWidth, opacity: config.opacity };\n }\n\n protected override draw(out: DrawCommand[], world: Transform): void {\n out.push({\n kind: 'text', text: this.text, x: 0, y: 0, size: this.size, font: this.font,\n align: this.align, weight: this.weight, transform: world, z: this.z, ...this.paint,\n });\n }\n\n protected override serializeProps(): Record<string, unknown> {\n return { text: this.text, size: this.size, align: this.align, paint: this.paint };\n }\n override applyProps(props: Record<string, unknown>): void {\n if (typeof props.text === 'string') this.text = props.text;\n if (typeof props.size === 'number') this.size = props.size;\n if (props.align) this.align = props.align as TextAlign;\n if (props.paint) this.paint = props.paint as Paint;\n }\n}\n\n// \u2500\u2500 Camera2D \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport interface CameraConfig extends NodeConfig {\n zoom?: number;\n /** Make this the active camera on ready. */\n current?: boolean;\n}\n\nexport class Camera2D extends Node {\n override readonly type = 'Camera2D';\n zoom: number;\n current: boolean;\n\n constructor(config: CameraConfig = {}) {\n super(config);\n this.zoom = config.zoom ?? 1;\n this.current = config.current ?? true;\n }\n\n protected override onReady(): void {\n if (this.current) (this.world as WorldContext & { activeCamera?: Camera2D }).activeCamera = this;\n }\n\n protected override serializeProps(): Record<string, unknown> {\n return { zoom: this.zoom, current: this.current };\n }\n override applyProps(props: Record<string, unknown>): void {\n if (typeof props.zoom === 'number') this.zoom = props.zoom;\n if (typeof props.current === 'boolean') this.current = props.current;\n }\n}\n\n// \u2500\u2500 Timer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport interface TimerConfig extends NodeConfig {\n duration: number; // seconds\n autostart?: boolean;\n oneShot?: boolean;\n}\n\nexport class Timer extends Node {\n override readonly type = 'Timer';\n duration: number;\n oneShot: boolean;\n private remaining: number;\n private running: boolean;\n\n constructor(config: TimerConfig) {\n super(config);\n this.duration = config.duration;\n this.oneShot = config.oneShot ?? true;\n this.remaining = config.duration;\n this.running = config.autostart ?? true;\n }\n\n start(duration?: number): void {\n if (duration !== undefined) this.duration = duration;\n this.remaining = this.duration;\n this.running = true;\n }\n stop(): void {\n this.running = false;\n }\n\n get timeLeft(): number {\n return this.remaining;\n }\n\n protected override onProcess(dt: number): void {\n if (!this.running) return;\n this.remaining -= dt;\n if (this.remaining <= 0) {\n this.emit('timeout', undefined);\n if (this.oneShot) this.running = false;\n else this.remaining += this.duration;\n }\n }\n\n /** Signal emitted when the countdown reaches zero. */\n get timeout() {\n return this.signal('timeout');\n }\n\n protected override serializeProps(): Record<string, unknown> {\n return { duration: this.duration, oneShot: this.oneShot, remaining: this.remaining, running: this.running };\n }\n override applyProps(props: Record<string, unknown>): void {\n if (typeof props.duration === 'number') this.duration = props.duration;\n if (typeof props.oneShot === 'boolean') this.oneShot = props.oneShot;\n if (typeof props.remaining === 'number') this.remaining = props.remaining;\n if (typeof props.running === 'boolean') this.running = props.running;\n }\n}\n", "// Deterministic tweening. Tweens advance by the fixed dt, so animations are\n// exactly reproducible. Tweens animate via setter closures (transient visual\n// polish \u2014 not part of the hashed logic state), Godot AnimationPlayer-style.\n\nimport { clamp } from '../core/math';\nimport { Node } from './node';\n\nexport type Easing = (t: number) => number;\n\nconst pow = Math.pow;\nexport const EASINGS: Record<string, Easing> = {\n linear: (t) => t,\n quadIn: (t) => t * t,\n quadOut: (t) => 1 - (1 - t) * (1 - t),\n quadInOut: (t) => (t < 0.5 ? 2 * t * t : 1 - pow(-2 * t + 2, 2) / 2),\n cubicIn: (t) => t * t * t,\n cubicOut: (t) => 1 - pow(1 - t, 3),\n cubicInOut: (t) => (t < 0.5 ? 4 * t * t * t : 1 - pow(-2 * t + 2, 3) / 2),\n sineIn: (t) => 1 - Math.cos((t * Math.PI) / 2),\n sineOut: (t) => Math.sin((t * Math.PI) / 2),\n sineInOut: (t) => -(Math.cos(Math.PI * t) - 1) / 2,\n backOut: (t) => {\n const c1 = 1.70158;\n const c3 = c1 + 1;\n return 1 + c3 * pow(t - 1, 3) + c1 * pow(t - 1, 2);\n },\n elasticOut: (t) => {\n const c4 = (2 * Math.PI) / 3;\n return t === 0 ? 0 : t === 1 ? 1 : pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;\n },\n bounceOut: (t) => {\n const n1 = 7.5625;\n const d1 = 2.75;\n if (t < 1 / d1) return n1 * t * t;\n if (t < 2 / d1) return n1 * (t -= 1.5 / d1) * t + 0.75;\n if (t < 2.5 / d1) return n1 * (t -= 2.25 / d1) * t + 0.9375;\n return n1 * (t -= 2.625 / d1) * t + 0.984375;\n },\n};\n\ninterface Track {\n apply: (v: number) => void;\n from: number;\n to: number;\n duration: number;\n elapsed: number;\n ease: Easing;\n onDone?: () => void;\n delay: number;\n}\n\n/** A node that runs one or more property tweens and reports when they finish. */\nexport class AnimationPlayer extends Node {\n override readonly type = 'AnimationPlayer';\n private tracks: Track[] = [];\n\n /**\n * Animate a value from \u2192 to over `duration` seconds via `apply(value)`.\n * Returns this for chaining.\n */\n to(\n apply: (v: number) => void,\n from: number,\n to: number,\n duration: number,\n ease: keyof typeof EASINGS | Easing = 'cubicOut',\n opts: { delay?: number; onDone?: () => void } = {},\n ): this {\n this.tracks.push({\n apply,\n from,\n to,\n duration: Math.max(1e-6, duration),\n elapsed: 0,\n ease: typeof ease === 'function' ? ease : EASINGS[ease] ?? EASINGS.linear,\n delay: opts.delay ?? 0,\n onDone: opts.onDone,\n });\n return this;\n }\n\n get active(): boolean {\n return this.tracks.length > 0;\n }\n\n /** Signal emitted when all tracks complete. */\n get finished() {\n return this.signal('finished');\n }\n\n protected override onProcess(dt: number): void {\n if (this.tracks.length === 0) return;\n for (let i = this.tracks.length - 1; i >= 0; i--) {\n const tk = this.tracks[i];\n if (tk.delay > 0) {\n tk.delay -= dt;\n continue;\n }\n tk.elapsed += dt;\n const t = clamp(tk.elapsed / tk.duration, 0, 1);\n tk.apply(tk.from + (tk.to - tk.from) * tk.ease(t));\n if (t >= 1) {\n tk.onDone?.();\n this.tracks.splice(i, 1);\n }\n }\n if (this.tracks.length === 0) this.emit('finished', undefined);\n }\n}\n", "// Particles + screen shake: the juice kit. Both are COSMETIC by construction \u2014\n// they carry their own tiny Rng stream (never the world's), are excluded from\n// hashing/serialization, and can be deleted without changing any game outcome.\n// Emission is driven by sim events (jumped, landed, hit\u2026), so replays produce\n// identical visuals, but no canonical state ever depends on them.\n\nimport { Rng } from '../core/rng';\nimport { TAU, type Transform, type Vec2 } from '../core/math';\nimport type { DrawCommand } from '../render/commands';\nimport { Node, type NodeConfig } from './node';\n\nexport interface ParticleStyle {\n /** Colors drawn from at random per particle. */\n colors: string[];\n /** Particle radius range (px). */\n sizeMin: number;\n sizeMax: number;\n /** Initial speed range (px/s). */\n speedMin: number;\n speedMax: number;\n /** Emission arc: center angle + spread (radians). Default: full circle. */\n angle?: number;\n spread?: number;\n /** Lifetime range (s). */\n lifeMin: number;\n lifeMax: number;\n /** Gravity applied to particles (px/s\u00B2, +y is down). */\n gravity?: number;\n /** Velocity damping per second (0 = none, 5 = strong). */\n drag?: number;\n /** Shrink to zero over life (default true; also fades opacity). */\n shrink?: boolean;\n}\n\ninterface Particle {\n x: number;\n y: number;\n vx: number;\n vy: number;\n life: number;\n maxLife: number;\n size: number;\n color: string;\n}\n\n/**\n * A pooled particle emitter node. Call `burst(n, at, style)` from game code in\n * response to feel events. Always cosmetic; safe to add anywhere in the tree.\n */\nexport class Particles extends Node {\n override readonly type: string = 'Particles';\n private pool: Particle[] = [];\n private rng: Rng;\n /** Cap on live particles (oldest are recycled first). */\n maxParticles: number;\n\n constructor(config: NodeConfig & { seed?: number; maxParticles?: number } = {}) {\n super(config);\n this.cosmetic = true;\n this.rng = new Rng(config.seed ?? 7);\n this.maxParticles = config.maxParticles ?? 512;\n }\n\n /** Emit a burst at a position (in this node's local space). */\n burst(count: number, at: Vec2, style: ParticleStyle): void {\n const r = this.rng;\n for (let i = 0; i < count; i++) {\n const angle = style.angle !== undefined ? style.angle + (r.float() - 0.5) * (style.spread ?? 0.6) : r.float() * TAU;\n const speed = style.speedMin + r.float() * (style.speedMax - style.speedMin);\n const p: Particle = {\n x: at.x,\n y: at.y,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed,\n life: 0,\n maxLife: style.lifeMin + r.float() * (style.lifeMax - style.lifeMin),\n size: style.sizeMin + r.float() * (style.sizeMax - style.sizeMin),\n color: style.colors[r.int(style.colors.length)],\n };\n if (this.pool.length >= this.maxParticles) this.pool.shift();\n this.pool.push(p);\n }\n // Stash style scalars on the instance for update (single-style emitters are\n // the common case; per-particle style costs memory for no visible gain).\n this.gravity = style.gravity ?? 0;\n this.drag = style.drag ?? 0;\n this.shrink = style.shrink ?? true;\n }\n\n private gravity = 0;\n private drag = 0;\n private shrink = true;\n\n protected override onProcess(dt: number): void {\n const drag = Math.max(0, 1 - this.drag * dt);\n let write = 0;\n for (const p of this.pool) {\n p.life += dt;\n if (p.life >= p.maxLife) continue;\n p.vy += this.gravity * dt;\n p.vx *= drag;\n p.vy *= drag;\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n this.pool[write++] = p;\n }\n this.pool.length = write;\n }\n\n protected override draw(out: DrawCommand[], world: Transform): void {\n for (const p of this.pool) {\n const t = 1 - p.life / p.maxLife;\n out.push({\n kind: 'circle',\n cx: p.x,\n cy: p.y,\n radius: this.shrink ? p.size * t : p.size,\n fill: p.color,\n opacity: Math.min(1, t * 2),\n transform: world,\n z: this.z,\n });\n }\n }\n\n get liveCount(): number {\n return this.pool.length;\n }\n}\n\n/** Ready-made styles for the common feel moments. */\nexport const PARTICLE_PRESETS = {\n dust: (colors = ['#c8c2b6', '#a09a8c']): ParticleStyle => ({ colors, sizeMin: 2, sizeMax: 4, speedMin: 30, speedMax: 90, lifeMin: 0.2, lifeMax: 0.45, gravity: 300, drag: 3, shrink: true }),\n burst: (colors = ['#ffd75e', '#ff9d47', '#fff2c9']): ParticleStyle => ({ colors, sizeMin: 2, sizeMax: 5, speedMin: 120, speedMax: 320, lifeMin: 0.25, lifeMax: 0.6, drag: 4, shrink: true }),\n hit: (colors = ['#ff5e5e', '#ffd0d0']): ParticleStyle => ({ colors, sizeMin: 2, sizeMax: 4, speedMin: 160, speedMax: 380, lifeMin: 0.15, lifeMax: 0.35, drag: 6, shrink: true }),\n sparkle: (colors = ['#9ef7ff', '#e8fdff', '#4ed8e8']): ParticleStyle => ({ colors, sizeMin: 1.5, sizeMax: 3.5, speedMin: 20, speedMax: 70, lifeMin: 0.4, lifeMax: 0.9, gravity: -40, drag: 2, shrink: true }),\n} as const;\n\n/**\n * Screen shake as a cosmetic camera offset with its own Rng and exponential\n * decay. Attach to whatever node the camera follows and read `offset` into the\n * camera's position AFTER canonical follow logic \u2014 or simpler, add the shaker\n * as the camera's parent so the offset composes for free.\n */\nexport class Shaker extends Node {\n override readonly type: string = 'Shaker';\n private rng: Rng;\n private trauma = 0;\n /** Max offset in px at full trauma. */\n amplitude: number;\n /** Trauma decay per second. */\n decay: number;\n\n constructor(config: NodeConfig & { seed?: number; amplitude?: number; decay?: number } = {}) {\n super(config);\n this.cosmetic = true;\n this.rng = new Rng(config.seed ?? 99);\n this.amplitude = config.amplitude ?? 14;\n this.decay = config.decay ?? 2.6;\n }\n\n /** Add shake (0..1). Stacks, clamped to 1. Quadratic falloff feels right. */\n addTrauma(amount: number): void {\n this.trauma = Math.min(1, this.trauma + amount);\n }\n\n protected override onProcess(dt: number): void {\n this.trauma = Math.max(0, this.trauma - this.decay * dt);\n const s = this.trauma * this.trauma * this.amplitude;\n this.pos.x = (this.rng.float() * 2 - 1) * s;\n this.pos.y = (this.rng.float() * 2 - 1) * s;\n }\n}\n", "// Node type registry \u2192 lets a serialized tree (save file / prefab / snapshot)\n// be rebuilt into live nodes. Built-in types register here; games can register\n// custom node types the same way.\n\nimport { Node, type SerializedNode } from './node';\nimport { Sprite, Text, Camera2D, Timer } from './nodes';\nimport { AnimationPlayer } from './tween';\n\nexport type NodeFactory = () => Node;\n\nconst registry = new Map<string, NodeFactory>();\n\nexport function registerNode(type: string, factory: NodeFactory): void {\n registry.set(type, factory);\n}\n\n// Built-ins. Sprite/Text/Timer need required config, so provide safe defaults\n// that applyProps() immediately overwrites during deserialization.\nregisterNode('Node', () => new Node());\nregisterNode('Sprite', () => new Sprite({ shape: { kind: 'rect', w: 1, h: 1 } }));\nregisterNode('Text', () => new Text({ text: '' }));\nregisterNode('Camera2D', () => new Camera2D());\nregisterNode('Timer', () => new Timer({ duration: 1 }));\nregisterNode('AnimationPlayer', () => new AnimationPlayer());\n\n/** Rebuild a live node tree from serialized data. */\nexport function deserializeNode(data: SerializedNode): Node {\n const factory = registry.get(data.type);\n if (!factory) throw new Error(`hayao: unknown node type \"${data.type}\" (register it first)`);\n const node = factory();\n node.name = data.name;\n node.pos = { ...data.pos };\n node.rotation = data.rotation;\n node.scale = { ...data.scale };\n node.z = data.z;\n node.visible = data.visible;\n node.applyProps(data.props);\n for (const child of data.children) node.addChild(deserializeNode(child));\n return node;\n}\n", "// Input as ACTIONS, not keys. Game logic asks \"is 'jump' down?\", never \"is 'KeyZ'\n// down?\". Input is sampled once per fixed step, so a run is a pure function of its\n// input log \u2014 which is what makes replay and scripted playthroughs exact.\n\n/** action name \u2192 physical key codes (KeyboardEvent.code strings). */\nexport type InputMap = Record<string, string[]>;\n\nexport class InputState {\n private down = new Set<string>();\n private prev = new Set<string>();\n /** Analog axes (e.g. from gamepad or pointer), sampled per step. */\n readonly axes = new Map<string, number>();\n\n /** Engine: set which actions are down this step (from live input or replay). */\n beginFrame(actionsDown: Iterable<string>): void {\n this.prev = new Set(this.down);\n this.down = new Set(actionsDown);\n }\n\n isDown(action: string): boolean {\n return this.down.has(action);\n }\n justPressed(action: string): boolean {\n return this.down.has(action) && !this.prev.has(action);\n }\n justReleased(action: string): boolean {\n return !this.down.has(action) && this.prev.has(action);\n }\n axis(name: string): number {\n return this.axes.get(name) ?? 0;\n }\n\n /** The current down-set as a stable sorted array (for recording). */\n snapshot(): string[] {\n return [...this.down].sort();\n }\n\n getState() {\n return { down: [...this.down].sort(), prev: [...this.prev].sort() };\n }\n setState(s: { down: string[]; prev: string[] }): void {\n this.down = new Set(s.down);\n this.prev = new Set(s.prev);\n }\n}\n\n/** Map a set of raw key codes to the set of actions they trigger. */\nexport function keysToActions(map: InputMap, keysDown: Set<string>): string[] {\n const actions: string[] = [];\n for (const action in map) {\n if (map[action].some((k) => keysDown.has(k))) actions.push(action);\n }\n return actions.sort();\n}\n\n/** Records the per-frame action-down sets \u2192 a compact, replayable input log. */\nexport class InputRecorder {\n private frames: string[][] = [];\n\n record(actionsDown: string[]): void {\n this.frames.push(actionsDown.slice().sort());\n }\n\n get length(): number {\n return this.frames.length;\n }\n\n toLog(): InputLog {\n return { frames: this.frames.map((f) => f.slice()) };\n }\n}\n\nexport interface InputLog {\n frames: string[][];\n}\n\n/** Replays a recorded log: returns the action set for frame index i. */\nexport function frameActions(log: InputLog, i: number): string[] {\n return log.frames[i] ?? [];\n}\n\n/** A default set of common bindings games can start from. */\nexport const DEFAULT_INPUT_MAP: InputMap = {\n up: ['ArrowUp', 'KeyW'],\n down: ['ArrowDown', 'KeyS'],\n left: ['ArrowLeft', 'KeyA'],\n right: ['ArrowRight', 'KeyD'],\n confirm: ['Enter', 'Space'],\n cancel: ['Escape', 'Backspace'],\n action: ['KeyZ', 'KeyJ'],\n action2: ['KeyX', 'KeyK'],\n undo: ['KeyU'],\n restart: ['KeyR'],\n};\n", "// Browser input source: tracks physical keys and maps them to actions each step.\n// Kept separate from InputState so the pure sim never imports DOM.\n\nimport { keysToActions, type InputMap } from './actions';\n\nexport class KeyboardSource {\n private keysDown = new Set<string>();\n /** Virtual action taps (from DOM buttons etc.) pending consumption by a step. */\n private pressed = new Set<string>();\n private map: InputMap;\n private target: Document | HTMLElement;\n private onDown: (e: KeyboardEvent) => void;\n private onUp: (e: KeyboardEvent) => void;\n private onBlur: () => void;\n\n constructor(map: InputMap, target: Document | HTMLElement = document) {\n this.map = map;\n this.target = target;\n this.onDown = (e) => {\n this.keysDown.add(e.code);\n // Prevent scroll on arrows/space during play.\n if (e.code.startsWith('Arrow') || e.code === 'Space') e.preventDefault();\n };\n this.onUp = (e) => this.keysDown.delete(e.code);\n this.onBlur = () => this.keysDown.clear();\n target.addEventListener('keydown', this.onDown as EventListener);\n target.addEventListener('keyup', this.onUp as EventListener);\n globalThis.addEventListener?.('blur', this.onBlur);\n }\n\n /** The actions currently held down, as a stable sorted array. */\n currentActions(): string[] {\n const acts = keysToActions(this.map, this.keysDown);\n if (this.pressed.size === 0) return acts;\n const merged = new Set(acts);\n for (const a of this.pressed) merged.add(a);\n return [...merged].sort();\n }\n\n /**\n * Virtually tap an action (DOM button, touch control). The tap is held until\n * at least one fixed step has sampled it \u2014 the driver calls clearPressed()\n * after a successful advance \u2014 so UI clicks enter the SAME deterministic\n * input log as keys, and record/replay covers them.\n */\n press(action: string): void {\n this.pressed.add(action);\n }\n\n /** Consume pending virtual taps (driver-called after \u22651 step ran). */\n clearPressed(): void {\n this.pressed.clear();\n }\n\n setMap(map: InputMap): void {\n this.map = map;\n }\n\n dispose(): void {\n this.target.removeEventListener('keydown', this.onDown as EventListener);\n this.target.removeEventListener('keyup', this.onUp as EventListener);\n globalThis.removeEventListener?.('blur', this.onBlur);\n }\n}\n", "// Tilemaps: grid collision geometry authored as ASCII. Plain data + pure\n// functions (house style) so maps serialize, hash, and diff cleanly.\n\nexport const TILE = {\n EMPTY: 0,\n SOLID: 1,\n /** Passable from below/sides; solid only when landing on its top edge. */\n ONEWAY: 2,\n HAZARD: 3,\n} as const;\nexport type TileId = (typeof TILE)[keyof typeof TILE];\n\nexport interface TilemapData {\n /** Size in tiles. */\n cols: number;\n rows: number;\n /** Tile edge in design-space px. */\n tileSize: number;\n /** Row-major tile ids, length cols*rows. */\n tiles: number[];\n}\n\n/** Default ASCII vocabulary: `#` solid, `-` one-way, `^` hazard, else empty. */\nexport const DEFAULT_TILE_CHARS: Record<string, TileId> = {\n '#': TILE.SOLID,\n '-': TILE.ONEWAY,\n '^': TILE.HAZARD,\n};\n\n/**\n * Build a tilemap from ASCII rows. Unknown characters are EMPTY, so level\n * strings can carry entity markers (`@` spawn, `*` shard\u2026) for game code to\n * read separately via `asciiEntities`.\n */\nexport function tilemapFromAscii(rowsAscii: string[], tileSize = 32, chars: Record<string, TileId> = DEFAULT_TILE_CHARS): TilemapData {\n const rows = rowsAscii.length;\n const cols = Math.max(...rowsAscii.map((r) => r.length));\n const tiles = new Array<number>(cols * rows).fill(TILE.EMPTY);\n rowsAscii.forEach((row, ty) => {\n for (let tx = 0; tx < row.length; tx++) tiles[ty * cols + tx] = chars[row[tx]] ?? TILE.EMPTY;\n });\n return { cols, rows, tileSize, tiles };\n}\n\n/** Extract entity markers (any char not in the tile vocabulary, not space/dot). */\nexport function asciiEntities(rowsAscii: string[], tileSize = 32, chars: Record<string, TileId> = DEFAULT_TILE_CHARS): { char: string; tx: number; ty: number; x: number; y: number }[] {\n const out: { char: string; tx: number; ty: number; x: number; y: number }[] = [];\n rowsAscii.forEach((row, ty) => {\n for (let tx = 0; tx < row.length; tx++) {\n const c = row[tx];\n if (c === ' ' || c === '.' || chars[c] !== undefined) continue;\n out.push({ char: c, tx, ty, x: (tx + 0.5) * tileSize, y: (ty + 0.5) * tileSize });\n }\n });\n return out;\n}\n\n/** Tile id at tile coords; out-of-bounds reads as SOLID (levels are sealed). */\nexport function tileAt(map: TilemapData, tx: number, ty: number): number {\n if (tx < 0 || ty < 0 || tx >= map.cols || ty >= map.rows) return TILE.SOLID;\n return map.tiles[ty * map.cols + tx];\n}\n\nexport function tileAtPoint(map: TilemapData, x: number, y: number): number {\n return tileAt(map, Math.floor(x / map.tileSize), Math.floor(y / map.tileSize));\n}\n\nexport const mapWidth = (map: TilemapData): number => map.cols * map.tileSize;\nexport const mapHeight = (map: TilemapData): number => map.rows * map.tileSize;\n", "// Kinematic AABB movement against a tilemap plus extra solid rects (moving\n// platforms). Axis-separated, analytically clamped to obstacle edges \u2014 no\n// tunneling, exact and deterministic. Pure functions over plain data.\n\nimport type { Rect } from '../core/math';\nimport { TILE, tileAt, type TilemapData } from './tilemap';\n\nconst EPS = 1e-6;\n\n/** An extra solid the body collides with (moving platform, door, crate\u2026). */\nexport interface SolidRect extends Rect {\n /** Solid only when landing on its top (jump-through platform). */\n oneway?: boolean;\n}\n\nexport interface MoveResult {\n x: number;\n y: number;\n hitX: boolean;\n hitY: boolean;\n onFloor: boolean;\n onCeiling: boolean;\n onWallLeft: boolean;\n onWallRight: boolean;\n /** Final rect overlaps a HAZARD tile (with a small forgiveness inset). */\n hazard: boolean;\n /** Index into `solids` of the rect the body stands on, or -1. */\n floorSolid: number;\n}\n\nconst spanTiles = (lo: number, hi: number, ts: number): [number, number] => [Math.floor(lo / ts), Math.floor((hi - EPS) / ts)];\n\nexport interface MoveOpts {\n solids?: SolidRect[];\n /** Pass true while the player holds \"down\" to drop through one-way platforms. */\n dropThrough?: boolean;\n}\n\n/** Would a rect at (x, y) overlap any solid geometry? (Used for corner-correction probes.) */\nexport function rectBlocked(map: TilemapData, x: number, y: number, w: number, h: number, solids: SolidRect[] = []): boolean {\n const ts = map.tileSize;\n const [tx0, tx1] = spanTiles(x, x + w, ts);\n const [ty0, ty1] = spanTiles(y, y + h, ts);\n for (let ty = ty0; ty <= ty1; ty++)\n for (let tx = tx0; tx <= tx1; tx++) if (tileAt(map, tx, ty) === TILE.SOLID) return true;\n for (const s of solids) {\n if (s.oneway) continue;\n if (x < s.x + s.w - EPS && x + w > s.x + EPS && y < s.y + s.h - EPS && y + h > s.y + EPS) return true;\n }\n return false;\n}\n\n/**\n * Move a rect by (dx, dy) with axis-separated collision: X first, then Y.\n * One-way surfaces block only downward motion that starts at-or-above their top.\n */\nexport function moveRect(map: TilemapData, rect: Rect, dx: number, dy: number, opts: MoveOpts = {}): MoveResult {\n const ts = map.tileSize;\n const solids = opts.solids ?? [];\n let { x, y } = rect;\n const { w, h } = rect;\n let hitX = false;\n let hitY = false;\n let onWallLeft = false;\n let onWallRight = false;\n\n // \u2500\u2500 X axis \u2500\u2500\n if (dx !== 0) {\n const [ty0, ty1] = spanTiles(y, y + h, ts);\n if (dx > 0) {\n let limit = x + dx; // furthest allowed left-edge position\n const [c0, c1] = [Math.floor((x + w) / ts), Math.floor((x + w + dx - EPS) / ts)];\n for (let tx = c0; tx <= c1; tx++)\n for (let ty = ty0; ty <= ty1; ty++)\n if (tileAt(map, tx, ty) === TILE.SOLID) limit = Math.min(limit, tx * ts - w);\n for (const s of solids)\n if (!s.oneway && s.y < y + h - EPS && s.y + s.h > y + EPS && s.x >= x + w - EPS) limit = Math.min(limit, s.x - w);\n if (limit < x + dx - EPS) {\n hitX = true;\n onWallRight = true;\n }\n x = Math.min(x + dx, limit);\n } else {\n let limit = x + dx;\n const [c0, c1] = [Math.floor((x - EPS) / ts), Math.floor((x + dx) / ts)];\n for (let tx = c0; tx >= c1; tx--)\n for (let ty = ty0; ty <= ty1; ty++)\n if (tileAt(map, tx, ty) === TILE.SOLID) limit = Math.max(limit, (tx + 1) * ts);\n for (const s of solids)\n if (!s.oneway && s.y < y + h - EPS && s.y + s.h > y + EPS && s.x + s.w <= x + EPS) limit = Math.max(limit, s.x + s.w);\n if (limit > x + dx + EPS) {\n hitX = true;\n onWallLeft = true;\n }\n x = Math.max(x + dx, limit);\n }\n }\n\n // \u2500\u2500 Y axis \u2500\u2500\n const prevBottom = y + h;\n let onFloor = false;\n let onCeiling = false;\n let floorSolid = -1;\n if (dy !== 0) {\n const [tx0, tx1] = spanTiles(x, x + w, ts);\n if (dy > 0) {\n let limit = y + dy; // furthest allowed top position\n const [r0, r1] = [Math.floor(prevBottom / ts), Math.floor((prevBottom + dy - EPS) / ts)];\n for (let ty = r0; ty <= r1; ty++)\n for (let tx = tx0; tx <= tx1; tx++) {\n const t = tileAt(map, tx, ty);\n const blocks = t === TILE.SOLID || (t === TILE.ONEWAY && !opts.dropThrough && prevBottom <= ty * ts + EPS);\n if (blocks) limit = Math.min(limit, ty * ts - h);\n }\n for (let i = 0; i < solids.length; i++) {\n const s = solids[i];\n const inX = s.x < x + w - EPS && s.x + s.w > x + EPS;\n if (!inX || s.y < prevBottom - EPS) continue;\n if (s.oneway && (opts.dropThrough || prevBottom > s.y + EPS)) continue;\n if (s.y - h < limit) {\n limit = s.y - h;\n floorSolid = i;\n }\n }\n if (limit < y + dy - EPS) {\n hitY = true;\n onFloor = true;\n } else floorSolid = -1;\n y = Math.min(y + dy, limit);\n } else {\n let limit = y + dy;\n const [r0, r1] = [Math.floor((y - EPS) / ts), Math.floor((y + dy) / ts)];\n for (let ty = r0; ty >= r1; ty--)\n for (let tx = tx0; tx <= tx1; tx++)\n if (tileAt(map, tx, ty) === TILE.SOLID) limit = Math.max(limit, (ty + 1) * ts);\n for (const s of solids)\n if (!s.oneway && s.x < x + w - EPS && s.x + s.w > x + EPS && s.y + s.h <= y + EPS) limit = Math.max(limit, s.y + s.h);\n if (limit > y + dy + EPS) {\n hitY = true;\n onCeiling = true;\n }\n y = Math.max(y + dy, limit);\n }\n }\n\n // \u2500\u2500 Ground probe (also true when dy was 0 or clamped exactly) \u2500\u2500\n if (!onFloor) {\n const probe = groundAt(map, x, y, w, h, solids, opts.dropThrough ?? false);\n onFloor = probe.grounded;\n floorSolid = probe.solid;\n }\n\n // \u2500\u2500 Hazard overlap (inset for forgiveness) \u2500\u2500\n const inset = 3;\n let hazard = false;\n {\n const [hx0, hx1] = spanTiles(x + inset, x + w - inset, ts);\n const [hy0, hy1] = spanTiles(y + inset, y + h - inset, ts);\n for (let ty = hy0; ty <= hy1 && !hazard; ty++)\n for (let tx = hx0; tx <= hx1 && !hazard; tx++) if (tileAt(map, tx, ty) === TILE.HAZARD) hazard = true;\n }\n\n return { x, y, hitX, hitY, onFloor, onCeiling, onWallLeft, onWallRight, hazard, floorSolid };\n}\n\n/** Is there support directly under the rect (within 1px)? */\nexport function groundAt(map: TilemapData, x: number, y: number, w: number, h: number, solids: SolidRect[] = [], dropThrough = false): { grounded: boolean; solid: number } {\n const ts = map.tileSize;\n const bottom = y + h;\n const [tx0, tx1] = spanTiles(x, x + w, ts);\n const ty = Math.floor((bottom + 1) / ts);\n for (let tx = tx0; tx <= tx1; tx++) {\n const t = tileAt(map, tx, ty);\n if (t === TILE.SOLID) return { grounded: true, solid: -1 };\n if (t === TILE.ONEWAY && !dropThrough && Math.abs(bottom - ty * ts) <= 1 + EPS) return { grounded: true, solid: -1 };\n }\n for (let i = 0; i < solids.length; i++) {\n const s = solids[i];\n const inX = s.x < x + w - EPS && s.x + s.w > x + EPS;\n if (inX && bottom <= s.y + 1 + EPS && bottom >= s.y - 1 - EPS) return { grounded: true, solid: i };\n }\n return { grounded: false, solid: -1 };\n}\n", "// PlatformerController: a state-of-the-art 2D kinematic character controller.\n// Pure and deterministic \u2014 plain-data state, stepped at the fixed timestep, no\n// engine imports beyond physics/math \u2014 so every game-feel feature below is\n// unit-testable in Node by pumping frames.\n//\n// Implements the modern platforming canon:\n// coyote time \u00B7 jump buffering \u00B7 variable jump height \u00B7 halved-gravity apex\n// jump corner correction \u00B7 dash (8-way) \u00B7 dash corner correction\n// wall slide + wall jump \u00B7 moving-platform carry + lift momentum storage\n// one-way platforms + drop-through\n\nimport { moveRect, rectBlocked, type SolidRect } from './aabb';\nimport type { TilemapData } from './tilemap';\n\nexport interface PlatformerConfig {\n width: number;\n height: number;\n /** Ground run speed (px/s) and accelerations (px/s\u00B2). */\n runSpeed: number;\n groundAccel: number;\n groundFriction: number;\n airAccel: number;\n /**\n * Horizontal decel with no input while airborne (px/s\u00B2). Keep LOW: inherited\n * momentum (lift jumps, wall kicks) must survive flight to feel right.\n */\n airFriction: number;\n /** Gravity (px/s\u00B2), terminal fall speed, and the apex modifier. */\n gravity: number;\n maxFall: number;\n /** |vy| below this counts as the jump apex\u2026 */\n apexThreshold: number;\n /** \u2026where gravity is multiplied by this while jump is held (the floaty peak). */\n apexGravityMult: number;\n /** Initial jump velocity (px/s, upward) and early-release cut multiplier. */\n jumpVelocity: number;\n jumpCutMult: number;\n /** Grace timers (seconds). */\n coyoteTime: number;\n jumpBuffer: number;\n /** Max px the body is nudged sideways to slip past a ceiling corner when jumping. */\n jumpCornerNudge: number;\n /** Max px the body is nudged vertically to slip past a corner while dashing. */\n dashCornerNudge: number;\n /** Mid-air jumps (0 = none, 1 = double jump\u2026), refilled on landing/wall. */\n airJumps: number;\n /** Air-jump velocity as a fraction of jumpVelocity. */\n airJumpMult: number;\n /** Dash: speed (px/s), duration (s), cooldown (s), charges refilled on landing. */\n dashSpeed: number;\n dashTime: number;\n dashCooldown: number;\n dashCharges: number;\n /** Wall interaction. */\n wallSlideMaxFall: number;\n wallJumpVelX: number;\n wallJumpVelY: number;\n /** Seconds after a wall jump during which input can't cancel the outward velocity. */\n wallJumpLock: number;\n}\n\n/** Tuned for 32px tiles at 60Hz in the 1280\u00D7720 design space. */\nexport const DEFAULT_PLATFORMER: PlatformerConfig = {\n width: 22,\n height: 28,\n runSpeed: 340,\n groundAccel: 3800,\n groundFriction: 4200,\n airAccel: 2600,\n airFriction: 260,\n gravity: 2300,\n maxFall: 660,\n apexThreshold: 60,\n apexGravityMult: 0.5,\n jumpVelocity: 650,\n jumpCutMult: 0.4,\n coyoteTime: 0.1,\n jumpBuffer: 0.12,\n jumpCornerNudge: 10,\n dashCornerNudge: 12,\n airJumps: 0,\n airJumpMult: 0.92,\n dashSpeed: 640,\n dashTime: 0.14,\n dashCooldown: 0.25,\n dashCharges: 1,\n wallSlideMaxFall: 150,\n wallJumpVelX: 360,\n wallJumpVelY: 600,\n wallJumpLock: 0.13,\n};\n\n/** Per-step intent, sampled from actions by the game (never raw keys). */\nexport interface PadInput {\n moveX: number; // -1 | 0 | 1\n moveY: number; // -1 (up) | 0 | 1 (down)\n jumpHeld: boolean;\n jumpPressed: boolean;\n dashPressed: boolean;\n}\n\nexport const PAD_NEUTRAL: PadInput = { moveX: 0, moveY: 0, jumpHeld: false, jumpPressed: false, dashPressed: false };\n\n/** A moving platform: its current rect, plus its velocity this step (px/s). */\nexport interface Platform extends SolidRect {\n vx: number;\n vy: number;\n}\n\n/** Plain serializable controller state \u2014 put it in `world.state` so it hashes. */\nexport interface PlatformerState {\n x: number; // top-left of the collision box\n y: number;\n vx: number;\n vy: number;\n facing: number; // -1 | 1\n onGround: boolean;\n onWall: number; // -1 touching left wall, 1 right, 0 none\n coyote: number;\n buffer: number;\n jumping: boolean; // rising from a jump (variable-height window)\n wallLock: number;\n airJumpsLeft: number;\n dashing: number; // time left in current dash\n dashCd: number;\n dashesLeft: number;\n dashVx: number;\n dashVy: number;\n /** Velocity inherited from the platform we stand on (lift momentum storage). */\n carryVx: number;\n carryVy: number;\n dead: boolean;\n}\n\nexport function createPlatformerState(x: number, y: number): PlatformerState {\n return { x, y, vx: 0, vy: 0, facing: 1, onGround: false, onWall: 0, coyote: 0, buffer: 0, jumping: false, wallLock: 0, airJumpsLeft: 0, dashing: 0, dashCd: 0, dashesLeft: 1, dashVx: 0, dashVy: 0, carryVx: 0, carryVy: 0, dead: false };\n}\n\n/** Feel events emitted by a step \u2014 hooks for SFX / particles / screen shake. */\nexport interface PlatformerEvents {\n jumped: boolean;\n wallJumped: boolean;\n airJumped: boolean;\n dashed: boolean;\n landed: boolean;\n died: boolean;\n}\n\nconst approach = (v: number, target: number, delta: number): number => (v < target ? Math.min(v + delta, target) : Math.max(v - delta, target));\n\n/**\n * Advance the controller one fixed step. Mutates `s`; returns feel events.\n * `platforms` should already be at their post-move positions for this step,\n * with `vx/vy` set to their velocity, so the body is carried exactly.\n */\nexport function stepPlatformer(s: PlatformerState, input: PadInput, dt: number, map: TilemapData, cfg: PlatformerConfig = DEFAULT_PLATFORMER, platforms: Platform[] = []): PlatformerEvents {\n const ev: PlatformerEvents = { jumped: false, wallJumped: false, airJumped: false, dashed: false, landed: false, died: false };\n if (s.dead) return ev;\n const wasGrounded = s.onGround;\n\n // \u2500\u2500 Timers \u2500\u2500\n s.coyote = Math.max(0, s.coyote - dt);\n s.buffer = Math.max(0, s.buffer - dt);\n s.wallLock = Math.max(0, s.wallLock - dt);\n s.dashCd = Math.max(0, s.dashCd - dt);\n if (input.jumpPressed) s.buffer = cfg.jumpBuffer;\n\n // \u2500\u2500 Dash start \u2500\u2500\n if (input.dashPressed && s.dashing <= 0 && s.dashCd <= 0 && s.dashesLeft > 0) {\n let dx = input.moveX;\n let dy = input.moveY;\n if (dx === 0 && dy === 0) dx = s.facing;\n const inv = 1 / Math.hypot(dx, dy);\n s.dashing = cfg.dashTime;\n s.dashCd = cfg.dashCooldown;\n s.dashesLeft--;\n s.dashVx = dx * inv * cfg.dashSpeed;\n s.dashVy = dy * inv * cfg.dashSpeed;\n s.jumping = false;\n ev.dashed = true;\n }\n\n // \u2500\u2500 Horizontal intent \u2500\u2500\n if (s.dashing > 0) {\n s.vx = s.dashVx;\n s.vy = s.dashVy;\n s.dashing -= dt;\n } else if (s.wallLock <= 0) {\n const target = input.moveX * cfg.runSpeed;\n const accel = s.onGround ? (input.moveX !== 0 ? cfg.groundAccel : cfg.groundFriction) : input.moveX !== 0 ? cfg.airAccel : cfg.airFriction;\n s.vx = approach(s.vx, target, accel * dt);\n if (input.moveX !== 0) s.facing = input.moveX > 0 ? 1 : -1;\n }\n\n // \u2500\u2500 Gravity (skipped while dashing) \u2500\u2500\n if (s.dashing <= 0 && !s.onGround) {\n let g = cfg.gravity;\n if (Math.abs(s.vy) < cfg.apexThreshold && input.jumpHeld && s.jumping) g *= cfg.apexGravityMult; // halved-gravity peak\n s.vy = Math.min(s.vy + g * dt, cfg.maxFall);\n if (s.onWall !== 0 && s.vy > cfg.wallSlideMaxFall && input.moveX === s.onWall) s.vy = cfg.wallSlideMaxFall; // wall slide\n }\n\n // \u2500\u2500 Variable jump height: release cuts upward velocity \u2500\u2500\n if (s.jumping && !input.jumpHeld && s.vy < 0) {\n s.vy *= cfg.jumpCutMult;\n s.jumping = false;\n }\n\n // \u2500\u2500 Jump (buffered + coyote) / wall jump \u2500\u2500\n if (s.buffer > 0 && s.dashing <= 0) {\n if (s.onGround || s.coyote > 0) {\n s.vy = -cfg.jumpVelocity;\n // Lift momentum storage: keep the platform's motion.\n s.vx += s.carryVx;\n if (s.carryVy < 0) s.vy += s.carryVy;\n s.jumping = true;\n s.buffer = 0;\n s.coyote = 0;\n s.onGround = false;\n ev.jumped = true;\n } else if (s.onWall !== 0 && cfg.wallJumpVelY > 0) {\n s.vx = -s.onWall * cfg.wallJumpVelX;\n s.vy = -cfg.wallJumpVelY;\n s.facing = -s.onWall;\n s.jumping = true;\n s.buffer = 0;\n s.wallLock = cfg.wallJumpLock;\n ev.wallJumped = true;\n ev.jumped = true;\n } else if (s.airJumpsLeft > 0) {\n s.vy = -cfg.jumpVelocity * cfg.airJumpMult;\n s.airJumpsLeft--;\n s.jumping = true;\n s.buffer = 0;\n ev.jumped = true;\n ev.airJumped = true;\n }\n }\n\n // \u2500\u2500 Move-and-collide, with platform carry \u2500\u2500\n // Holding down passes through one-ways \u2014 INCLUDING while already falling,\n // or the body re-lands on the platform lip one frame after leaving it.\n const dropThrough = input.moveY > 0 && s.buffer <= 0;\n let dx = s.vx * dt + s.carryVx * dt * (s.onGround ? 1 : 0);\n let dy = s.vy * dt + Math.max(0, s.carryVy) * dt * (s.onGround ? 1 : 0);\n let res = moveRect(map, { x: s.x, y: s.y, w: cfg.width, h: cfg.height }, dx, dy, { solids: platforms, dropThrough });\n\n // \u2500\u2500 Jump corner correction: bonked a ceiling edge while rising \u2192 nudge sideways \u2500\u2500\n if (res.onCeiling && s.vy < 0 && s.dashing <= 0) {\n const slip = cornerSlipX(map, platforms, res.x, res.y, cfg.width, cfg.height, dy, cfg.jumpCornerNudge);\n if (slip !== null) {\n res = moveRect(map, { x: slip, y: res.y, w: cfg.width, h: cfg.height }, 0, dy, { solids: platforms, dropThrough });\n res.x = slip;\n }\n }\n\n // \u2500\u2500 Dash corner correction: clipped a wall edge while dashing \u2192 nudge vertically \u2500\u2500\n if (res.hitX && s.dashing > 0 && Math.abs(s.dashVy) < 1) {\n const slip = cornerSlipY(map, platforms, res.x, res.y, cfg.width, cfg.height, dx, cfg.dashCornerNudge);\n if (slip !== null) {\n res = moveRect(map, { x: res.x, y: slip, w: cfg.width, h: cfg.height }, dx, 0, { solids: platforms, dropThrough });\n res.y = slip;\n }\n }\n\n s.x = res.x;\n s.y = res.y;\n if (res.hitY && s.vy > 0) s.vy = 0;\n if (res.onCeiling) {\n s.vy = Math.max(s.vy, 0);\n s.jumping = false;\n }\n if (res.hitX && s.dashing <= 0) s.vx = 0;\n s.onWall = res.onWallLeft ? -1 : res.onWallRight ? 1 : wallTouch(map, platforms, s.x, s.y, cfg.width, cfg.height);\n s.onGround = res.onFloor;\n\n // \u2500\u2500 Ground bookkeeping: coyote, dash refill, landing, lift momentum \u2500\u2500\n if (s.onGround) {\n s.coyote = cfg.coyoteTime;\n s.dashesLeft = cfg.dashCharges;\n s.airJumpsLeft = cfg.airJumps;\n if (!wasGrounded) ev.landed = true;\n if (res.floorSolid >= 0) {\n const p = platforms[res.floorSolid];\n s.carryVx = p.vx;\n s.carryVy = p.vy;\n // Ride the platform exactly: snap feet to its top.\n s.y = p.y - cfg.height;\n } else {\n s.carryVx = 0;\n s.carryVy = 0;\n }\n if (s.vy > 0) s.vy = 0;\n s.jumping = false;\n } else if (wasGrounded && s.carryVy !== 0) {\n // Walked off a lift: keep stored momentum until landing or jumping.\n }\n\n if (res.hazard) {\n s.dead = true;\n ev.died = true;\n }\n return ev;\n}\n\n// \u2500\u2500 Movement envelope: derive level geometry from the config, never guess \u2500\u2500\n// Conservative closed-form bounds (they ignore the apex-gravity bonus, so the\n// real controller always reaches at least this far). Author levels against\n// these \u2014 \"it looks jumpable\" is how unwinnable geometry ships.\n\n/** Max rise of a full jump (px). */\nexport function jumpHeight(cfg: PlatformerConfig = DEFAULT_PLATFORMER): number {\n return (cfg.jumpVelocity * cfg.jumpVelocity) / (2 * cfg.gravity);\n}\n\n/** Full-jump airtime returning to takeoff height (s). */\nexport function jumpAirtime(cfg: PlatformerConfig = DEFAULT_PLATFORMER): number {\n return (2 * cfg.jumpVelocity) / cfg.gravity;\n}\n\n/** Max horizontal gap clearable by a running jump (px, flat-to-flat). */\nexport function jumpDistance(cfg: PlatformerConfig = DEFAULT_PLATFORMER): number {\n return cfg.runSpeed * jumpAirtime(cfg);\n}\n\n/** Max gap clearable by jump + one apex dash (px, flat-to-flat, horizontal dash). */\nexport function dashJumpDistance(cfg: PlatformerConfig = DEFAULT_PLATFORMER): number {\n return jumpDistance(cfg) + (cfg.dashSpeed - cfg.runSpeed) * cfg.dashTime;\n}\n\n/** Try shifting x by up to \u00B1nudge so a rect moving by dy is unblocked. Prefers the smaller shift. */\nfunction cornerSlipX(map: TilemapData, solids: SolidRect[], x: number, y: number, w: number, h: number, dy: number, nudge: number): number | null {\n for (let n = 1; n <= nudge; n++) {\n for (const dir of [1, -1]) {\n const nx = x + dir * n;\n if (!rectBlocked(map, nx, y + dy, w, h, solids) && !rectBlocked(map, nx, y, w, h, solids)) return nx;\n }\n }\n return null;\n}\n\n/** Try shifting y by up to \u00B1nudge so a rect moving by dx is unblocked. */\nfunction cornerSlipY(map: TilemapData, solids: SolidRect[], x: number, y: number, w: number, h: number, dx: number, nudge: number): number | null {\n for (let n = 1; n <= nudge; n++) {\n for (const dir of [-1, 1]) {\n const ny = y + dir * n;\n if (!rectBlocked(map, x + dx, ny, w, h, solids) && !rectBlocked(map, x, ny, w, h, solids)) return ny;\n }\n }\n return null;\n}\n\n/** Which wall (if any) is the body pressed against? (1px probes) */\nfunction wallTouch(map: TilemapData, solids: SolidRect[], x: number, y: number, w: number, h: number): number {\n if (rectBlocked(map, x + 1, y, w, h, solids)) return 1;\n if (rectBlocked(map, x - 1, y, w, h, solids)) return -1;\n return 0;\n}\n", "// Uniform-grid spatial hash for broad-phase queries over many moving entities\n// (hordes, bullets, RTS units). Deterministic: iteration order is insertion\n// order within cells, and query results preserve first-insertion order.\n// Rebuild-per-step is the intended pattern \u2014 clear() + insert all \u2014 which is\n// O(n) and avoids stale incremental state entirely.\n\nimport type { Rect } from '../core/math';\n\nexport class SpatialHash<T> {\n private cells = new Map<number, T[]>();\n private bounds = new Map<T, Rect>();\n private readonly cellSize: number;\n\n constructor(cellSize = 64) {\n this.cellSize = cellSize;\n }\n\n clear(): void {\n this.cells.clear();\n this.bounds.clear();\n }\n\n get size(): number {\n return this.bounds.size;\n }\n\n private key(cx: number, cy: number): number {\n // Interleave-free packing; fine for worlds within \u00B12^15 cells.\n return (cx + 32768) * 65536 + (cy + 32768);\n }\n\n insert(item: T, rect: Rect): void {\n this.bounds.set(item, rect);\n const cs = this.cellSize;\n const x0 = Math.floor(rect.x / cs);\n const x1 = Math.floor((rect.x + rect.w) / cs);\n const y0 = Math.floor(rect.y / cs);\n const y1 = Math.floor((rect.y + rect.h) / cs);\n for (let cy = y0; cy <= y1; cy++)\n for (let cx = x0; cx <= x1; cx++) {\n const k = this.key(cx, cy);\n const cell = this.cells.get(k);\n if (cell) cell.push(item);\n else this.cells.set(k, [item]);\n }\n }\n\n /** All items whose rects overlap the query rect (deduplicated, deterministic order). */\n query(rect: Rect): T[] {\n const cs = this.cellSize;\n const x0 = Math.floor(rect.x / cs);\n const x1 = Math.floor((rect.x + rect.w) / cs);\n const y0 = Math.floor(rect.y / cs);\n const y1 = Math.floor((rect.y + rect.h) / cs);\n const seen = new Set<T>();\n const out: T[] = [];\n for (let cy = y0; cy <= y1; cy++)\n for (let cx = x0; cx <= x1; cx++) {\n const cell = this.cells.get(this.key(cx, cy));\n if (!cell) continue;\n for (const item of cell) {\n if (seen.has(item)) continue;\n seen.add(item);\n const b = this.bounds.get(item)!;\n if (b.x < rect.x + rect.w && b.x + b.w > rect.x && b.y < rect.y + rect.h && b.y + b.h > rect.y) out.push(item);\n }\n }\n return out;\n }\n\n /** All items within `radius` of a point (circle vs rect-center test on bounds). */\n queryCircle(x: number, y: number, radius: number): T[] {\n const near = this.query({ x: x - radius, y: y - radius, w: radius * 2, h: radius * 2 });\n return near.filter((item) => {\n const b = this.bounds.get(item)!;\n const cx = Math.max(b.x, Math.min(x, b.x + b.w));\n const cy = Math.max(b.y, Math.min(y, b.y + b.h));\n return (x - cx) * (x - cx) + (y - cy) * (y - cy) <= radius * radius;\n });\n }\n}\n", "// Grid raycasting (DDA) over a tilemap \u2014 the sight primitive behind stealth\n// vision cones, sentry line-of-sight, roguelike FOV, and 2D lighting.\n\nimport { TILE, tileAt, type TilemapData } from './tilemap';\n\nexport interface RayHit {\n /** True if a solid tile stopped the ray before reaching (x1, y1). */\n blocked: boolean;\n /** Where the ray stopped (the hit point, or the target if unblocked). */\n x: number;\n y: number;\n /** Distance travelled. */\n dist: number;\n}\n\n/**\n * March a ray from (x0,y0) toward (x1,y1) through the tile grid (DDA \u2014 exact,\n * no step-size tuning). SOLID tiles block; everything else passes.\n */\nexport function raycastTiles(map: TilemapData, x0: number, y0: number, x1: number, y1: number): RayHit {\n const ts = map.tileSize;\n const dx = x1 - x0;\n const dy = y1 - y0;\n const maxDist = Math.hypot(dx, dy);\n if (maxDist === 0) return { blocked: false, x: x1, y: y1, dist: 0 };\n const dirX = dx / maxDist;\n const dirY = dy / maxDist;\n\n let tx = Math.floor(x0 / ts);\n let ty = Math.floor(y0 / ts);\n const stepX = dirX > 0 ? 1 : -1;\n const stepY = dirY > 0 ? 1 : -1;\n const tDeltaX = dirX !== 0 ? Math.abs(ts / dirX) : Infinity;\n const tDeltaY = dirY !== 0 ? Math.abs(ts / dirY) : Infinity;\n let tMaxX = dirX !== 0 ? (dirX > 0 ? (tx + 1) * ts - x0 : x0 - tx * ts) / Math.abs(dirX) : Infinity;\n let tMaxY = dirY !== 0 ? (dirY > 0 ? (ty + 1) * ts - y0 : y0 - ty * ts) / Math.abs(dirY) : Infinity;\n\n let t = 0;\n // The starting tile never blocks (the caster stands in it).\n for (let guard = 0; guard < 512; guard++) {\n if (tMaxX < tMaxY) {\n t = tMaxX;\n tMaxX += tDeltaX;\n tx += stepX;\n } else {\n t = tMaxY;\n tMaxY += tDeltaY;\n ty += stepY;\n }\n if (t >= maxDist) return { blocked: false, x: x1, y: y1, dist: maxDist };\n if (tileAt(map, tx, ty) === TILE.SOLID) {\n return { blocked: true, x: x0 + dirX * t, y: y0 + dirY * t, dist: t };\n }\n }\n return { blocked: true, x: x0 + dirX * t, y: y0 + dirY * t, dist: t };\n}\n\n/** Can a see b with no solid tile between? */\nexport function lineOfSight(map: TilemapData, ax: number, ay: number, bx: number, by: number): boolean {\n return !raycastTiles(map, ax, ay, bx, by).blocked;\n}\n\n/**\n * Is the target inside a vision cone AND visible? (facing is a unit vector;\n * fov is the FULL cone angle in radians.)\n */\nexport function inVisionCone(map: TilemapData, ex: number, ey: number, faceX: number, faceY: number, fov: number, range: number, tx: number, ty: number): boolean {\n const dx = tx - ex;\n const dy = ty - ey;\n const d = Math.hypot(dx, dy);\n if (d > range || d === 0) return false;\n const dot = (dx * faceX + dy * faceY) / d;\n if (dot < Math.cos(fov / 2)) return false;\n return lineOfSight(map, ex, ey, tx, ty);\n}\n", "// The display list: a flat, backend-agnostic vocabulary of draw commands.\n// The scene tree *projects* to DrawCommand[]; a backend (SVG/Canvas/Headless)\n// consumes them. Pure data \u2014 no browser types \u2014 so the projection is testable.\n\nimport type { Transform } from '../core/math';\n\nexport interface Paint {\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n opacity?: number;\n /** Round line joins/caps for organic shapes. */\n round?: boolean;\n}\n\nexport type TextAlign = 'left' | 'center' | 'right';\n\ninterface Base extends Paint {\n /** World transform (design-space). */\n transform: Transform;\n /** Painter's-order key; ties broken by tree order. Default 0. */\n z: number;\n}\n\nexport interface RectCommand extends Base {\n kind: 'rect';\n x: number;\n y: number;\n w: number;\n h: number;\n /** Corner radius. */\n r?: number;\n}\n\nexport interface CircleCommand extends Base {\n kind: 'circle';\n cx: number;\n cy: number;\n radius: number;\n}\n\nexport interface PolyCommand extends Base {\n kind: 'poly';\n /** Flat [x0,y0,x1,y1,\u2026] in local space. */\n points: number[];\n closed: boolean;\n}\n\nexport interface PathCommand extends Base {\n kind: 'path';\n /** SVG path data in local space. */\n d: string;\n}\n\nexport interface TextCommand extends Base {\n kind: 'text';\n text: string;\n x: number;\n y: number;\n size: number;\n font?: string;\n align?: TextAlign;\n weight?: number;\n}\n\nexport interface ImageCommand extends Base {\n kind: 'image';\n /** data: URI or path. */\n href: string;\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport type DrawCommand =\n | RectCommand\n | CircleCommand\n | PolyCommand\n | PathCommand\n | TextCommand\n | ImageCommand;\n\n/** Stable painter's sort: by z, then original index (tree order) as tiebreak. */\nexport function sortCommands(cmds: DrawCommand[]): DrawCommand[] {\n return cmds\n .map((c, i) => [c, i] as const)\n .sort((a, b) => a[0].z - b[0].z || a[1] - b[1])\n .map(([c]) => c);\n}\n", "// Pure display-list \u2192 SVG markup. No DOM required, so it runs in Node \u2014 which\n// means the engine can produce a *vector screenshot* of any frame headlessly\n// (an AI-first win: judge layout from a file, no browser, no GPU, no fuzz).\n// The DOM SvgRenderer reuses this; tests assert on it directly.\n\nimport { sortCommands, type DrawCommand, type Paint } from './commands';\nimport type { Transform } from '../core/math';\n\nconst n = (v: number): string => (Number.isInteger(v) ? String(v) : (Math.round(v * 1000) / 1000).toString());\n\nfunction matrix(t: Transform): string {\n return `matrix(${n(t.a)} ${n(t.b)} ${n(t.c)} ${n(t.d)} ${n(t.e)} ${n(t.f)})`;\n}\n\nfunction paintAttrs(p: Paint): string {\n const parts: string[] = [];\n parts.push(`fill=\"${p.fill ?? 'none'}\"`);\n if (p.stroke) {\n parts.push(`stroke=\"${p.stroke}\"`);\n parts.push(`stroke-width=\"${n(p.strokeWidth ?? 1)}\"`);\n if (p.round) parts.push('stroke-linejoin=\"round\" stroke-linecap=\"round\"');\n }\n if (p.opacity !== undefined && p.opacity !== 1) parts.push(`opacity=\"${n(p.opacity)}\"`);\n return parts.join(' ');\n}\n\nfunction escapeText(s: string): string {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n}\n\nfunction commandToSVG(c: DrawCommand): string {\n const tf = `transform=\"${matrix(c.transform)}\"`;\n const paint = paintAttrs(c);\n switch (c.kind) {\n case 'rect':\n return `<rect x=\"${n(c.x)}\" y=\"${n(c.y)}\" width=\"${n(c.w)}\" height=\"${n(c.h)}\"${c.r ? ` rx=\"${n(c.r)}\"` : ''} ${tf} ${paint}/>`;\n case 'circle':\n return `<circle cx=\"${n(c.cx)}\" cy=\"${n(c.cy)}\" r=\"${n(c.radius)}\" ${tf} ${paint}/>`;\n case 'poly': {\n const pts = [];\n for (let i = 0; i < c.points.length; i += 2) pts.push(`${n(c.points[i])},${n(c.points[i + 1])}`);\n const tag = c.closed ? 'polygon' : 'polyline';\n return `<${tag} points=\"${pts.join(' ')}\" ${tf} ${paint}/>`;\n }\n case 'path':\n return `<path d=\"${c.d}\" ${tf} ${paint}/>`;\n case 'text': {\n const anchor = c.align === 'center' ? 'middle' : c.align === 'right' ? 'end' : 'start';\n const font = c.font ? ` font-family=\"${c.font}\"` : '';\n const weight = c.weight ? ` font-weight=\"${c.weight}\"` : '';\n const fill = c.fill ?? '#000';\n return `<text x=\"${n(c.x)}\" y=\"${n(c.y)}\" font-size=\"${n(c.size)}\" text-anchor=\"${anchor}\" dominant-baseline=\"middle\"${font}${weight} fill=\"${fill}\"${c.opacity !== undefined && c.opacity !== 1 ? ` opacity=\"${n(c.opacity)}\"` : ''} ${tf}>${escapeText(c.text)}</text>`;\n }\n case 'image':\n return `<image href=\"${c.href}\" x=\"${n(c.x)}\" y=\"${n(c.y)}\" width=\"${n(c.w)}\" height=\"${n(c.h)}\" ${tf}${c.opacity !== undefined && c.opacity !== 1 ? ` opacity=\"${n(c.opacity)}\"` : ''}/>`;\n }\n}\n\n/** Inner SVG markup for a display list (no wrapping <svg>). */\nexport function commandsToSVGInner(commands: DrawCommand[]): string {\n return sortCommands(commands).map(commandToSVG).join('');\n}\n\n/** A complete, standalone SVG document string for a frame \u2014 a headless screenshot. */\nexport function renderToSVGString(\n commands: DrawCommand[],\n width: number,\n height: number,\n background = '#ffffff',\n): string {\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\" width=\"${width}\" height=\"${height}\">` +\n `<rect x=\"0\" y=\"0\" width=\"${width}\" height=\"${height}\" fill=\"${background}\"/>` +\n commandsToSVGInner(commands) +\n `</svg>`\n );\n}\n", "// SVG DOM backend. Resolution-independent (crisp at any DPR \u2014 the OHYG lesson:\n// SVG sidesteps canvas text fuzz entirely) and DOM-inspectable, which makes\n// browser verification trivial: querySelector IS the probe.\n\nimport type { DrawCommand } from './commands';\nimport type { Renderer, RendererConfig } from './renderer';\nimport { commandsToSVGInner } from './svgString';\n\nconst SVGNS = 'http://www.w3.org/2000/svg';\n\nexport class SvgRenderer implements Renderer {\n readonly width: number;\n readonly height: number;\n private background: string;\n private svg: SVGSVGElement;\n private bg: SVGRectElement;\n private layer: SVGGElement;\n\n constructor(config: RendererConfig) {\n this.width = config.width;\n this.height = config.height;\n this.background = config.background ?? '#ffffff';\n\n this.svg = document.createElementNS(SVGNS, 'svg');\n this.svg.setAttribute('viewBox', `0 0 ${this.width} ${this.height}`);\n this.svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');\n this.svg.style.width = '100%';\n this.svg.style.height = '100%';\n this.svg.style.display = 'block';\n\n this.bg = document.createElementNS(SVGNS, 'rect');\n this.bg.setAttribute('x', '0');\n this.bg.setAttribute('y', '0');\n this.bg.setAttribute('width', String(this.width));\n this.bg.setAttribute('height', String(this.height));\n this.bg.setAttribute('fill', this.background);\n this.svg.appendChild(this.bg);\n\n this.layer = document.createElementNS(SVGNS, 'g');\n this.svg.appendChild(this.layer);\n }\n\n mount(parent: HTMLElement): void {\n parent.appendChild(this.svg);\n }\n\n draw(commands: DrawCommand[]): void {\n // Simple and correct for v0.1: rebuild the layer markup each frame. SVG is\n // retained-mode so the browser diffs efficiently; heavy scenes use Canvas2D.\n this.layer.innerHTML = commandsToSVGInner(commands);\n }\n\n setBackground(color: string): void {\n this.background = color;\n this.bg.setAttribute('fill', color);\n }\n\n get element(): SVGSVGElement {\n return this.svg;\n }\n\n dispose(): void {\n this.svg.remove();\n }\n}\n", "// Canvas2D backend. For scenes with many primitives/particles where SVG's DOM\n// node count would bite. Same display list, immediate-mode painting, DPR-aware.\n\nimport { sortCommands, type DrawCommand, type Paint } from './commands';\nimport type { Renderer, RendererConfig } from './renderer';\n\nexport class Canvas2DRenderer implements Renderer {\n readonly width: number;\n readonly height: number;\n private background: string;\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private dpr = 1;\n\n constructor(config: RendererConfig) {\n this.width = config.width;\n this.height = config.height;\n this.background = config.background ?? '#ffffff';\n this.canvas = document.createElement('canvas');\n this.canvas.style.width = '100%';\n this.canvas.style.height = '100%';\n this.canvas.style.display = 'block';\n const ctx = this.canvas.getContext('2d');\n if (!ctx) throw new Error('hayao: 2D canvas context unavailable');\n this.ctx = ctx;\n this.resize();\n }\n\n mount(parent: HTMLElement): void {\n parent.appendChild(this.canvas);\n this.resize();\n }\n\n private resize(): void {\n this.dpr = Math.min(3, globalThis.devicePixelRatio || 1);\n this.canvas.width = Math.round(this.width * this.dpr);\n this.canvas.height = Math.round(this.height * this.dpr);\n }\n\n draw(commands: DrawCommand[]): void {\n const ctx = this.ctx;\n ctx.setTransform(this.dpr, 0, 0, this.dpr, 0, 0);\n ctx.fillStyle = this.background;\n ctx.fillRect(0, 0, this.width, this.height);\n\n for (const c of sortCommands(commands)) {\n ctx.save();\n const t = c.transform;\n ctx.transform(t.a, t.b, t.c, t.d, t.e, t.f);\n ctx.globalAlpha = (c as Paint).opacity ?? 1;\n this.paint(ctx, c);\n ctx.restore();\n }\n }\n\n private stroke(ctx: CanvasRenderingContext2D, c: Paint): void {\n if (c.fill && c.fill !== 'none') {\n ctx.fillStyle = c.fill;\n ctx.fill();\n }\n if (c.stroke) {\n ctx.strokeStyle = c.stroke;\n ctx.lineWidth = c.strokeWidth ?? 1;\n if (c.round) {\n ctx.lineJoin = 'round';\n ctx.lineCap = 'round';\n }\n ctx.stroke();\n }\n }\n\n private paint(ctx: CanvasRenderingContext2D, c: DrawCommand): void {\n switch (c.kind) {\n case 'rect':\n ctx.beginPath();\n if (c.r) this.roundRect(ctx, c.x, c.y, c.w, c.h, c.r);\n else ctx.rect(c.x, c.y, c.w, c.h);\n this.stroke(ctx, c);\n break;\n case 'circle':\n ctx.beginPath();\n ctx.arc(c.cx, c.cy, c.radius, 0, Math.PI * 2);\n this.stroke(ctx, c);\n break;\n case 'poly':\n ctx.beginPath();\n for (let i = 0; i < c.points.length; i += 2) {\n if (i === 0) ctx.moveTo(c.points[i], c.points[i + 1]);\n else ctx.lineTo(c.points[i], c.points[i + 1]);\n }\n if (c.closed) ctx.closePath();\n this.stroke(ctx, c);\n break;\n case 'path':\n {\n const p = new Path2D(c.d);\n if (c.fill && c.fill !== 'none') {\n ctx.fillStyle = c.fill;\n ctx.fill(p);\n }\n if (c.stroke) {\n ctx.strokeStyle = c.stroke;\n ctx.lineWidth = c.strokeWidth ?? 1;\n if (c.round) {\n ctx.lineJoin = 'round';\n ctx.lineCap = 'round';\n }\n ctx.stroke(p);\n }\n }\n break;\n case 'text':\n ctx.fillStyle = c.fill ?? '#000';\n ctx.font = `${c.weight ?? 400} ${c.size}px ${c.font ?? 'sans-serif'}`;\n ctx.textAlign = c.align ?? 'left';\n ctx.textBaseline = 'middle';\n ctx.fillText(c.text, c.x, c.y);\n break;\n case 'image':\n break; // images loaded async; omitted in v0.1 canvas backend\n }\n }\n\n private roundRect(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, r: number): void {\n const rr = Math.min(r, w / 2, h / 2);\n ctx.moveTo(x + rr, y);\n ctx.arcTo(x + w, y, x + w, y + h, rr);\n ctx.arcTo(x + w, y + h, x, y + h, rr);\n ctx.arcTo(x, y + h, x, y, rr);\n ctx.arcTo(x, y, x + w, y, rr);\n ctx.closePath();\n }\n\n get element(): HTMLCanvasElement {\n return this.canvas;\n }\n\n dispose(): void {\n this.canvas.remove();\n }\n}\n", "// The headless backend: records the last display list instead of painting it.\n// Tests assert on the commands directly; scripts turn them into a vector\n// screenshot via renderToSVGString. This is why a hayao game is testable with\n// zero browser \u2014 the renderer is just a data sink.\n\nimport type { DrawCommand } from './commands';\nimport type { Renderer, RendererConfig } from './renderer';\nimport { renderToSVGString } from './svgString';\n\nexport class HeadlessRenderer implements Renderer {\n readonly width: number;\n readonly height: number;\n private background: string;\n private last: DrawCommand[] = [];\n frameCount = 0;\n\n constructor(config: RendererConfig) {\n this.width = config.width;\n this.height = config.height;\n this.background = config.background ?? '#ffffff';\n }\n\n draw(commands: DrawCommand[]): void {\n this.last = commands;\n this.frameCount++;\n }\n\n /** The most recently drawn display list. */\n get commands(): DrawCommand[] {\n return this.last;\n }\n\n /** Count commands of a given kind (handy for assertions). */\n count(kind: DrawCommand['kind']): number {\n return this.last.filter((c) => c.kind === kind).length;\n }\n\n /** A vector screenshot of the last frame. */\n toSVGString(): string {\n return renderToSVGString(this.last, this.width, this.height, this.background);\n }\n}\n", "// Curated palettes \u2014 code-as-art means no arbitrary RGB; pick from a named,\n// on-model set. Default is a warm, high-legibility \"Meadow\" palette (a nod to\n// the Ghibli/Miyazaki-ish direction the engine is named for).\n\nexport interface Palette {\n name: string;\n bg: string;\n ink: string;\n inkSoft: string;\n line: string;\n accent: string;\n accent2: string;\n good: string;\n warn: string;\n /** A small ordered ramp for categorical fills. */\n ramp: string[];\n}\n\nexport const MEADOW: Palette = {\n name: 'meadow',\n bg: '#f3ecdb',\n ink: '#3d3323',\n inkSoft: '#6f6047',\n line: '#d9ccae',\n accent: '#a11d3a',\n accent2: '#5a7d4e',\n good: '#4d6b3c',\n warn: '#c8791f',\n ramp: ['#a11d3a', '#c8791f', '#c9a22f', '#5a7d4e', '#3f7d8c', '#6a4c93'],\n};\n\nexport const DUSK: Palette = {\n name: 'dusk',\n bg: '#1c1a24',\n ink: '#efe9f2',\n inkSoft: '#a89fb5',\n line: '#3a3546',\n accent: '#e26d8a',\n accent2: '#6cc4a1',\n good: '#6cc4a1',\n warn: '#e8b64a',\n ramp: ['#e26d8a', '#e8b64a', '#f2e07a', '#6cc4a1', '#5aa9d6', '#b493e6'],\n};\n\nexport const PAPER: Palette = {\n name: 'paper',\n bg: '#faf7f0',\n ink: '#2b2b2b',\n inkSoft: '#666',\n line: '#e2ddd2',\n accent: '#d1495b',\n accent2: '#2e86ab',\n good: '#3c896d',\n warn: '#e0902f',\n ramp: ['#d1495b', '#e0902f', '#edc531', '#3c896d', '#2e86ab', '#8a5a9e'],\n};\n\nexport const PALETTES: Record<string, Palette> = { meadow: MEADOW, dusk: DUSK, paper: PAPER };\n\n/** Blend two hex colors (t in [0,1]). Deterministic, no allocations of note. */\nexport function mix(a: string, b: string, t: number): string {\n const pa = hexToRgb(a);\n const pb = hexToRgb(b);\n const r = Math.round(pa[0] + (pb[0] - pa[0]) * t);\n const g = Math.round(pa[1] + (pb[1] - pa[1]) * t);\n const bl = Math.round(pa[2] + (pb[2] - pa[2]) * t);\n return rgbToHex(r, g, bl);\n}\n\nexport function withAlpha(hex: string, alpha: number): string {\n const [r, g, b] = hexToRgb(hex);\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n}\n\nfunction hexToRgb(hex: string): [number, number, number] {\n let h = hex.replace('#', '');\n if (h.length === 3) h = h.split('').map((c) => c + c).join('');\n const n = parseInt(h, 16);\n return [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n}\nfunction rgbToHex(r: number, g: number, b: number): string {\n return '#' + [r, g, b].map((v) => Math.max(0, Math.min(255, v)).toString(16).padStart(2, '0')).join('');\n}\n", "// Procedural vector shape builders \u2014 the \"code-as-art\" toolkit. All pure and\n// deterministic (any randomness must be passed an Rng), producing point arrays\n// or SVG path strings usable directly in a Sprite.\n\nimport type { Rng } from '../core/rng';\nimport { TAU, type Vec2 } from '../core/math';\n\n/** Regular polygon points (flat [x,y,\u2026]) centered at origin. */\nexport function regularPolygon(sides: number, radius: number, rotation = 0): number[] {\n const pts: number[] = [];\n for (let i = 0; i < sides; i++) {\n const a = rotation + (i / sides) * TAU;\n pts.push(Math.cos(a) * radius, Math.sin(a) * radius);\n }\n return pts;\n}\n\n/** Star with alternating outer/inner radii. */\nexport function star(points: number, outer: number, inner: number, rotation = -Math.PI / 2): number[] {\n const pts: number[] = [];\n for (let i = 0; i < points * 2; i++) {\n const r = i % 2 === 0 ? outer : inner;\n const a = rotation + (i / (points * 2)) * TAU;\n pts.push(Math.cos(a) * r, Math.sin(a) * r);\n }\n return pts;\n}\n\n/** An organic blob outline as an SVG path (deterministic given the Rng). */\nexport function blobPath(rng: Rng, radius: number, wobble = 0.25, lobes = 7): string {\n const pts: Vec2[] = [];\n for (let i = 0; i < lobes; i++) {\n const a = (i / lobes) * TAU;\n const r = radius * (1 - wobble + rng.float() * wobble * 2);\n pts.push({ x: Math.cos(a) * r, y: Math.sin(a) * r });\n }\n return smoothClosedPath(pts);\n}\n\n/** Convert a point list into a smooth closed path (Catmull-Rom \u2192 cubic B\u00E9zier). */\nexport function smoothClosedPath(points: Vec2[], tension = 1): string {\n const nPts = points.length;\n if (nPts < 3) return '';\n const p = (i: number) => points[((i % nPts) + nPts) % nPts];\n const r = (v: number) => Math.round(v * 100) / 100;\n let d = `M ${r(p(0).x)} ${r(p(0).y)}`;\n for (let i = 0; i < nPts; i++) {\n const p0 = p(i - 1);\n const p1 = p(i);\n const p2 = p(i + 1);\n const p3 = p(i + 2);\n const c1x = p1.x + ((p2.x - p0.x) / 6) * tension;\n const c1y = p1.y + ((p2.y - p0.y) / 6) * tension;\n const c2x = p2.x - ((p3.x - p1.x) / 6) * tension;\n const c2y = p2.y - ((p3.y - p1.y) / 6) * tension;\n d += ` C ${r(c1x)} ${r(c1y)}, ${r(c2x)} ${r(c2y)}, ${r(p2.x)} ${r(p2.y)}`;\n }\n return d + ' Z';\n}\n\n/** Smooth open path through points (for trails, curves). */\nexport function smoothOpenPath(points: Vec2[], tension = 1): string {\n const nPts = points.length;\n if (nPts < 2) return '';\n const r = (v: number) => Math.round(v * 100) / 100;\n let d = `M ${r(points[0].x)} ${r(points[0].y)}`;\n for (let i = 0; i < nPts - 1; i++) {\n const p0 = points[Math.max(0, i - 1)];\n const p1 = points[i];\n const p2 = points[i + 1];\n const p3 = points[Math.min(nPts - 1, i + 2)];\n const c1x = p1.x + ((p2.x - p0.x) / 6) * tension;\n const c1y = p1.y + ((p2.y - p0.y) / 6) * tension;\n const c2x = p2.x - ((p3.x - p1.x) / 6) * tension;\n const c2y = p2.y - ((p3.y - p1.y) / 6) * tension;\n d += ` C ${r(c1x)} ${r(c1y)}, ${r(c2x)} ${r(c2y)}, ${r(p2.x)} ${r(p2.y)}`;\n }\n return d;\n}\n", "// Procedural audio bus. Code-as-sound: zzfx-style tone synthesis + an ambient\n// pad, no audio files. A no-op when there's no AudioContext (Node/headless), so\n// automated runs are silent by construction (a narrow-js invariant).\n\nexport interface Volumes {\n master: number;\n music: number;\n sfx: number;\n muted: boolean;\n}\n\nconst DEFAULT_VOLUMES: Volumes = { master: 0.7, music: 0.6, sfx: 0.8, muted: false };\n\n/** A single zzfx-ish tone spec. */\nexport interface Tone {\n freq: number;\n duration: number;\n type?: OscillatorType;\n gain?: number;\n delay?: number;\n}\n\nexport class AudioBus {\n private ctx: AudioContext | null = null;\n private master: GainNode | null = null;\n private musicGain: GainNode | null = null;\n private sfxGain: GainNode | null = null;\n private vol: Volumes = { ...DEFAULT_VOLUMES };\n private padOn = false;\n\n get available(): boolean {\n return typeof globalThis.AudioContext !== 'undefined' || 'webkitAudioContext' in globalThis;\n }\n get started(): boolean {\n return !!this.ctx;\n }\n\n /** Must be called from a user gesture (browser autoplay policy). */\n start(): void {\n if (this.ctx) {\n void this.ctx.resume();\n return;\n }\n if (!this.available) return;\n const Ctx =\n globalThis.AudioContext ||\n (globalThis as unknown as { webkitAudioContext: typeof AudioContext }).webkitAudioContext;\n this.ctx = new Ctx();\n this.master = this.ctx.createGain();\n this.musicGain = this.ctx.createGain();\n this.sfxGain = this.ctx.createGain();\n this.musicGain.connect(this.master);\n this.sfxGain.connect(this.master);\n this.master.connect(this.ctx.destination);\n this.applyVolumes();\n }\n\n setVolumes(v: Partial<Volumes>): void {\n this.vol = { ...this.vol, ...v };\n this.applyVolumes();\n }\n getVolumes(): Volumes {\n return { ...this.vol };\n }\n\n private applyVolumes(): void {\n if (!this.ctx || !this.master || !this.musicGain || !this.sfxGain) return;\n const t = this.ctx.currentTime;\n this.master.gain.setTargetAtTime(this.vol.muted ? 0 : this.vol.master, t, 0.04);\n this.musicGain.gain.setTargetAtTime(this.vol.music * 0.5, t, 0.04);\n this.sfxGain.gain.setTargetAtTime(this.vol.sfx, t, 0.04);\n }\n\n /** Play a single tone (no-op if audio unstarted). */\n tone(spec: Tone): void {\n if (!this.ctx || !this.sfxGain) return;\n const { freq, duration, type = 'sine', gain = 0.2, delay = 0 } = spec;\n const t = this.ctx.currentTime + delay;\n const osc = this.ctx.createOscillator();\n osc.type = type;\n osc.frequency.value = freq;\n const g = this.ctx.createGain();\n g.gain.setValueAtTime(0, t);\n g.gain.linearRampToValueAtTime(gain, t + 0.008);\n g.gain.exponentialRampToValueAtTime(0.0001, t + duration);\n osc.connect(g);\n g.connect(this.sfxGain);\n osc.start(t);\n osc.stop(t + duration + 0.05);\n }\n\n /** Play a sequence of tones as an arpeggio/chord. */\n play(tones: Tone[]): void {\n for (const t of tones) this.tone(t);\n }\n\n /** Convenience SFX. */\n blip(freq = 520): void {\n this.tone({ freq, duration: 0.06, type: 'sine', gain: 0.18 });\n }\n chime(): void {\n [523.25, 659.25, 783.99].forEach((f, i) => this.tone({ freq: f, duration: 0.9 - i * 0.15, type: 'sine', gain: 0.15, delay: i * 0.04 }));\n }\n success(): void {\n [392, 493.88, 587.33, 783.99].forEach((f, i) => this.tone({ freq: f, duration: 0.4, type: 'triangle', gain: 0.15, delay: i * 0.08 }));\n }\n thud(): void {\n this.tone({ freq: 130, duration: 0.14, type: 'sine', gain: 0.22 });\n }\n\n /** Start a soft evolving ambient pad on the music bus. */\n startAmbient(root = 110, voices = [1, 1.5, 2, 2.5]): void {\n if (!this.ctx || !this.musicGain || this.padOn) return;\n this.padOn = true;\n const filter = this.ctx.createBiquadFilter();\n filter.type = 'lowpass';\n filter.frequency.value = 900;\n filter.connect(this.musicGain);\n const bus = this.ctx.createGain();\n bus.gain.value = 0;\n bus.connect(filter);\n for (const mult of voices) {\n const osc = this.ctx.createOscillator();\n osc.type = 'triangle';\n osc.frequency.value = root * mult;\n const g = this.ctx.createGain();\n g.gain.value = 0.1 / voices.length;\n osc.connect(g);\n g.connect(bus);\n osc.start();\n }\n bus.gain.setTargetAtTime(0.9, this.ctx.currentTime, 3);\n }\n}\n\n/** Shared default bus. */\nexport const audio = new AudioBus();\n", "// DOM overlay screens \u2014 titles, menus, game-over, HUD. Crisp DOM type instead of\n// canvas text (narrow-js lesson: humans compare canvas text to DOM and canvas\n// loses). Keyboard-navigable by construction. Browser-only; no-op guards for SSR.\n\nexport interface MenuAction {\n label: string;\n onSelect: () => void;\n primary?: boolean;\n}\n\nexport interface ScreenSpec {\n title?: string;\n /** Subtitle / body text (plain text or HTML string). */\n body?: string;\n /** Menu actions, navigable with up/down + Enter. */\n actions?: MenuAction[];\n /** Dim the game behind the screen. */\n dim?: boolean;\n /** Extra class for theming. */\n className?: string;\n}\n\nexport interface ScreenHandle {\n close(): void;\n readonly element: HTMLElement;\n}\n\nlet active: ScreenHandle | null = null;\n\nconst STYLE_ID = 'hayao-overlay-style';\nconst CSS = `\n.hy-scrim{position:absolute;inset:0;display:grid;place-items:center;z-index:50;font-family:var(--hy-serif,Georgia,serif)}\n.hy-scrim.dim{background:rgba(30,24,14,.5);backdrop-filter:blur(2px)}\n.hy-card{background:var(--hy-paper,#fbf6ea);color:var(--hy-ink,#3d3323);border:1px solid var(--hy-line,#d9ccae);border-radius:14px;box-shadow:0 14px 44px rgba(40,30,15,.3);padding:26px 30px;max-width:440px;text-align:center}\n.hy-card h1{margin:0 0 6px;font-size:30px}\n.hy-card .hy-body{color:var(--hy-ink-soft,#6f6047);font-size:15px;line-height:1.5;margin-bottom:18px}\n.hy-menu{display:flex;flex-direction:column;gap:8px;align-items:stretch}\n.hy-item{font:inherit;font-size:16px;padding:9px 16px;border-radius:9px;border:1px solid var(--hy-line,#d9ccae);background:transparent;color:inherit;cursor:pointer;transition:transform .1s,background .1s}\n.hy-item:hover,.hy-item.sel{background:var(--hy-accent,#a11d3a);color:#fdf3ee;border-color:transparent;transform:translateY(-1px)}\n.hy-item.primary{background:var(--hy-accent,#a11d3a);color:#fdf3ee;border-color:transparent}\n`;\n\nfunction ensureStyle(): void {\n if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return;\n const s = document.createElement('style');\n s.id = STYLE_ID;\n s.textContent = CSS;\n document.head.appendChild(s);\n}\n\nlet host: HTMLElement | null = null;\n/** Set the element overlays mount into (defaults to document.body). */\nexport function setOverlayHost(el: HTMLElement): void {\n host = el;\n}\n\n/** Show a screen (replaces any current one). Returns a handle. */\nexport function showScreen(spec: ScreenSpec): ScreenHandle {\n if (typeof document === 'undefined') {\n return { close() {}, element: null as unknown as HTMLElement };\n }\n ensureStyle();\n hideScreen();\n\n const scrim = document.createElement('div');\n scrim.className = `hy-scrim${spec.dim === false ? '' : ' dim'}${spec.className ? ' ' + spec.className : ''}`;\n const card = document.createElement('div');\n card.className = 'hy-card';\n\n if (spec.title) {\n const h = document.createElement('h1');\n h.textContent = spec.title;\n card.appendChild(h);\n }\n if (spec.body) {\n const b = document.createElement('div');\n b.className = 'hy-body';\n b.innerHTML = spec.body;\n card.appendChild(b);\n }\n\n const actions = spec.actions ?? [];\n let sel = Math.max(0, actions.findIndex((a) => a.primary));\n if (sel < 0) sel = 0;\n const items: HTMLButtonElement[] = [];\n if (actions.length) {\n const menu = document.createElement('div');\n menu.className = 'hy-menu';\n actions.forEach((a, i) => {\n const btn = document.createElement('button');\n btn.className = `hy-item${a.primary ? ' primary' : ''}`;\n btn.textContent = a.label;\n btn.addEventListener('click', () => a.onSelect());\n btn.addEventListener('mouseenter', () => setSel(i));\n menu.appendChild(btn);\n items.push(btn);\n });\n card.appendChild(menu);\n }\n\n function setSel(i: number): void {\n sel = (i + items.length) % items.length;\n items.forEach((el, k) => el.classList.toggle('sel', k === sel));\n }\n if (items.length) setSel(sel);\n\n const onKey = (e: KeyboardEvent) => {\n if (!items.length) return;\n if (e.code === 'ArrowDown') { setSel(sel + 1); e.preventDefault(); }\n else if (e.code === 'ArrowUp') { setSel(sel - 1); e.preventDefault(); }\n else if (e.code === 'Enter' || e.code === 'Space') { actions[sel]?.onSelect(); e.preventDefault(); }\n };\n document.addEventListener('keydown', onKey);\n\n scrim.appendChild(card);\n (host ?? document.body).appendChild(scrim);\n\n const handle: ScreenHandle = {\n element: scrim,\n close() {\n document.removeEventListener('keydown', onKey);\n scrim.remove();\n if (active === handle) active = null;\n },\n };\n active = handle;\n return handle;\n}\n\nexport function hideScreen(): void {\n active?.close();\n}\n", "// Player settings, persisted to localStorage and pushed into the audio bus.\n// Framework-agnostic (plain object + subscribe), so any game/UI can bind to it.\n\nimport { audio } from '../audio/audio';\n\nexport interface Settings {\n master: number;\n music: number;\n sfx: number;\n muted: boolean;\n colorblind: boolean;\n reducedMotion: boolean;\n}\n\nconst KEY = 'hayao.settings.v1';\nconst DEFAULTS: Settings = { master: 0.7, music: 0.6, sfx: 0.8, muted: false, colorblind: false, reducedMotion: false };\n\ntype Sub = (s: Settings) => void;\n\nclass SettingsStore {\n private state: Settings;\n private subs = new Set<Sub>();\n\n constructor() {\n this.state = this.load();\n this.pushToAudio();\n }\n\n get(): Settings {\n return { ...this.state };\n }\n\n set(patch: Partial<Settings>): void {\n this.state = { ...this.state, ...patch };\n this.save();\n this.pushToAudio();\n for (const fn of this.subs) fn(this.get());\n }\n\n subscribe(fn: Sub): () => void {\n this.subs.add(fn);\n return () => this.subs.delete(fn);\n }\n\n private pushToAudio(): void {\n audio.setVolumes({ master: this.state.master, music: this.state.music, sfx: this.state.sfx, muted: this.state.muted });\n }\n\n private load(): Settings {\n try {\n const raw = typeof localStorage !== 'undefined' && localStorage.getItem(KEY);\n if (raw) return { ...DEFAULTS, ...JSON.parse(raw) };\n } catch {\n /* ignore */\n }\n return { ...DEFAULTS };\n }\n private save(): void {\n try {\n localStorage.setItem(KEY, JSON.stringify(this.state));\n } catch {\n /* ignore */\n }\n }\n}\n\nexport const settings = new SettingsStore();\n\n// \u2500\u2500 Fullscreen helper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport function toggleFullscreen(): void {\n if (typeof document === 'undefined') return;\n const doc = document as Document & { webkitFullscreenElement?: Element; webkitExitFullscreen?: () => void };\n const el = document.documentElement as HTMLElement & { webkitRequestFullscreen?: () => void };\n if (document.fullscreenElement || doc.webkitFullscreenElement) {\n (document.exitFullscreen ?? doc.webkitExitFullscreen)?.call(document);\n } else {\n (el.requestFullscreen ?? el.webkitRequestFullscreen)?.call(el);\n }\n}\n", "// The game shell: a pause menu (Esc) with volume, mute, fullscreen, restart, and\n// back-to-hub \u2014 every game gets it for free (narrow-js lesson: the shell owns Esc,\n// kills debug-key landmines, and standardizes chrome). Browser-only.\n\nimport { audio } from '../audio/audio';\nimport { settings, toggleFullscreen } from './settings';\nimport { showScreen, hideScreen } from './overlay';\n\nexport interface ShellOptions {\n onRestart?: () => void;\n onQuit?: () => void;\n /** Called with true when paused, false when resumed. */\n onPause?: (paused: boolean) => void;\n title?: string;\n}\n\nexport class Shell {\n private paused = false;\n private opts: ShellOptions;\n private keyHandler: (e: KeyboardEvent) => void;\n\n constructor(opts: ShellOptions = {}) {\n this.opts = opts;\n this.keyHandler = (e: KeyboardEvent) => {\n if (e.code === 'Escape') {\n e.preventDefault();\n this.toggle();\n }\n };\n if (typeof document !== 'undefined') document.addEventListener('keydown', this.keyHandler);\n }\n\n get isPaused(): boolean {\n return this.paused;\n }\n\n toggle(): void {\n this.paused ? this.resume() : this.pause();\n }\n\n pause(): void {\n if (this.paused) return;\n this.paused = true;\n audio.blip(440);\n this.opts.onPause?.(true);\n this.render();\n }\n\n resume(): void {\n if (!this.paused) return;\n this.paused = false;\n hideScreen();\n this.opts.onPause?.(false);\n }\n\n private render(): void {\n const s = settings.get();\n const vol = (label: string, v: number) => `${label}: ${Math.round(v * 100)}`;\n showScreen({\n title: this.opts.title ?? 'Paused',\n body:\n `<div style=\"font-size:13px;text-align:left;line-height:1.9\">` +\n `${vol('Master', s.master)} \u00B7 ${vol('Music', s.music)} \u00B7 ${vol('Sfx', s.sfx)}` +\n `<br/><span style=\"opacity:.7\">Use the menu, or keys: M mute \u00B7 F fullscreen</span></div>`,\n actions: [\n { label: 'Resume', primary: true, onSelect: () => this.resume() },\n { label: s.muted ? 'Unmute (M)' : 'Mute (M)', onSelect: () => { settings.set({ muted: !settings.get().muted }); this.render(); } },\n { label: 'Music \u2212/+', onSelect: () => { const m = Math.min(1, settings.get().music + 0.1) % 1.05; settings.set({ music: m > 1 ? 0 : m }); this.render(); } },\n { label: 'Fullscreen (F)', onSelect: () => toggleFullscreen() },\n ...(this.opts.onRestart ? [{ label: 'Restart', onSelect: () => { this.resume(); this.opts.onRestart!(); } }] : []),\n ...(this.opts.onQuit ? [{ label: 'Quit', onSelect: () => { this.resume(); this.opts.onQuit!(); } }] : []),\n ],\n });\n }\n\n dispose(): void {\n if (typeof document !== 'undefined') document.removeEventListener('keydown', this.keyHandler);\n hideScreen();\n }\n}\n", "// Generic winnability solver. Turn-based/puzzle logic implements the pure\n// Puzzle interface; the solver proves a level beatable by search. Deterministic\n// opponent (fixed order + tie-breaks) means single-agent BFS \u2014 no adversarial\n// branching. (narrow-js's insight, generalized and typed.)\n//\n// Rule of the house: a hand-authored level is presumed WRONG until the solver\n// proves it winnable. In-head verification has a documented failure rate.\n\nexport interface Puzzle<State, Move> {\n /** Starting state (optionally per level index). */\n initial(level?: number): State;\n /** Legal moves from a state, in deterministic order. */\n moves(state: State): Move[];\n /** Apply a player move (may fold in a deterministic opponent response). */\n apply(state: State, move: Move): State;\n /** Win test. */\n isWin(state: State): boolean;\n /** Optional dead/lost test \u2014 pruned from the search. */\n isDead?(state: State): boolean;\n /** Canonical key for de-duplication (visited set). */\n key(state: State): string;\n}\n\nexport interface SolveResult<Move> {\n solvable: boolean;\n /** Shortest winning move sequence, if found. */\n path?: Move[];\n /** Depth of the shortest solution. */\n depth?: number;\n /** Nodes expanded (a difficulty/complexity proxy). */\n nodes: number;\n /** True if the search hit a cap before proving/\u200Bdisproving. */\n exhausted: boolean;\n}\n\nexport interface SolveOptions {\n level?: number;\n maxDepth?: number;\n nodeCap?: number;\n}\n\n/** Breadth-first search \u2192 the shortest solution and a real winnability proof. */\nexport function solve<State, Move>(\n puzzle: Puzzle<State, Move>,\n options: SolveOptions = {},\n): SolveResult<Move> {\n const maxDepth = options.maxDepth ?? 60;\n const nodeCap = options.nodeCap ?? 1_000_000;\n const start = puzzle.initial(options.level);\n\n if (puzzle.isWin(start)) return { solvable: true, path: [], depth: 0, nodes: 0, exhausted: false };\n\n interface QNode {\n state: State;\n path: Move[];\n }\n let frontier: QNode[] = [{ state: start, path: [] }];\n const seen = new Set<string>([puzzle.key(start)]);\n let nodes = 0;\n\n for (let depth = 0; depth < maxDepth && frontier.length > 0; depth++) {\n const next: QNode[] = [];\n for (const { state, path } of frontier) {\n for (const move of puzzle.moves(state)) {\n if (nodes >= nodeCap) return { solvable: false, nodes, exhausted: true };\n nodes++;\n const after = puzzle.apply(state, move);\n if (puzzle.isDead?.(after)) continue;\n if (puzzle.isWin(after)) {\n return { solvable: true, path: [...path, move], depth: depth + 1, nodes, exhausted: false };\n }\n const k = puzzle.key(after);\n if (!seen.has(k)) {\n seen.add(k);\n next.push({ state: after, path: [...path, move] });\n }\n }\n }\n frontier = next;\n }\n return { solvable: false, nodes, exhausted: frontier.length > 0 };\n}\n\n/**\n * Assert a puzzle level is winnable (throws with detail if not). Use in tests as\n * the content-balance gate.\n */\nexport function assertSolvable<State, Move>(\n puzzle: Puzzle<State, Move>,\n options: SolveOptions = {},\n): SolveResult<Move> {\n const result = solve(puzzle, options);\n if (!result.solvable) {\n throw new Error(\n `hayao: level ${options.level ?? 0} is NOT winnable ` +\n `(expanded ${result.nodes} nodes${result.exhausted ? ', search capped \u2014 raise nodeCap/maxDepth' : ''}).`,\n );\n }\n return result;\n}\n", "// Determinism verification. Re-run the same seed + input log twice; if any step's\n// state hash diverges, some hidden nondeterminism (Math.random, Date.now, Set\n// iteration, unordered map) leaked in. This is the regression net that lets you\n// refactor the sim fearlessly.\n\nimport type { World } from '../world';\nimport type { InputLog } from '../input/actions';\nimport { frameActions } from '../input/actions';\n\nexport type WorldFactory = () => World;\n\n/** Run a world through an input log, returning the final hash and per-frame hashes. */\nexport function replay(makeWorld: WorldFactory, log: InputLog): { finalHash: string; hashes: string[] } {\n const world = makeWorld();\n const hashes: string[] = [];\n for (let i = 0; i < log.frames.length; i++) {\n world.step(frameActions(log, i));\n hashes.push(world.hash());\n }\n return { finalHash: world.hash(), hashes };\n}\n\nexport interface DeterminismReport {\n ok: boolean;\n frames: number;\n /** First frame index where the two runs diverged, or -1. */\n divergedAt: number;\n finalHash: string;\n}\n\n/** Run twice and compare every step's hash. */\nexport function checkDeterministic(makeWorld: WorldFactory, log: InputLog): DeterminismReport {\n const a = replay(makeWorld, log);\n const b = replay(makeWorld, log);\n let divergedAt = -1;\n for (let i = 0; i < a.hashes.length; i++) {\n if (a.hashes[i] !== b.hashes[i]) {\n divergedAt = i;\n break;\n }\n }\n return {\n ok: divergedAt === -1 && a.finalHash === b.finalHash,\n frames: log.frames.length,\n divergedAt,\n finalHash: a.finalHash,\n };\n}\n\n/** Assert determinism (throws with the divergence frame). */\nexport function assertDeterministic(makeWorld: WorldFactory, log: InputLog): DeterminismReport {\n const report = checkDeterministic(makeWorld, log);\n if (!report.ok) {\n throw new Error(\n `hayao: sim is NON-deterministic \u2014 runs diverged at frame ${report.divergedAt} ` +\n `of ${report.frames}. Check for Math.random/Date.now/Set-iteration/unordered-map in the sim.`,\n );\n }\n return report;\n}\n\n/**\n * Assert that restoring a snapshot reproduces the exact same continuation \u2014\n * i.e. save/load is lossless. Runs `warmup` steps, snapshots, runs `tail` more\n * on both the original and a restored copy, and compares final hashes.\n */\nexport function assertSnapshotStable(\n makeWorld: WorldFactory,\n log: InputLog,\n warmup: number,\n): { ok: boolean; hashA: string; hashB: string } {\n const original = makeWorld();\n for (let i = 0; i < warmup; i++) original.step(frameActions(log, i));\n const snap = original.snapshot();\n\n const restored = makeWorld();\n restored.restore(snap);\n\n for (let i = warmup; i < log.frames.length; i++) {\n original.step(frameActions(log, i));\n restored.step(frameActions(log, i));\n }\n const hashA = original.hash();\n const hashB = restored.hash();\n return { ok: hashA === hashB, hashA, hashB };\n}\n", "// Scripted playthroughs: drive a world headlessly with a sequence of held-input\n// segments and collect probe snapshots. This is Channel 1a \u2014 proving behavior on\n// game state, in Node, no browser. (Hold keys \u2265 a few frames: variable-height\n// jumps treat a 1-frame synthetic tap as a real short tap.)\n\nimport type { World } from '../world';\n\nexport interface Segment {\n /** Actions held down for this segment. */\n actions?: string[];\n /** Number of fixed steps to run. */\n frames: number;\n}\n\n/** Build a segment: hold `actions` for `frames` steps. */\nexport function hold(actions: string[], frames: number): Segment {\n return { actions, frames };\n}\n/** Build an idle segment (no input) for `frames` steps. */\nexport function wait(frames: number): Segment {\n return { actions: [], frames };\n}\n\nexport interface PlaythroughResult {\n totalFrames: number;\n finalHash: string;\n /** Probe snapshot after each segment. */\n probes: Record<string, unknown>[];\n}\n\n/** Run a scripted playthrough; returns a probe after each segment. */\nexport function scriptedPlaythrough(world: World, script: Segment[]): PlaythroughResult {\n const probes: Record<string, unknown>[] = [];\n let total = 0;\n for (const seg of script) {\n for (let i = 0; i < seg.frames; i++) world.step(seg.actions ?? []);\n total += seg.frames;\n probes.push(world.probe());\n }\n return { totalFrames: total, finalHash: world.hash(), probes };\n}\n\n/** Convenience: advance a world N frames with a fixed input set. */\nexport function pump(world: World, frames: number, actions: string[] = []): void {\n for (let i = 0; i < frames; i++) world.step(actions);\n}\n", "// Browser capture seam. Because the sim is headless-native \u2014 hayao owns the\n// clock and never touches document.hasFocus \u2014 this is ~30 lines, not the ~100 a\n// canvas engine needs. Exposes window.__hayao for scripted browser sessions and\n// aesthetic screenshots. Enable with ?capture=1.\n\nimport type { World } from '../world';\n\nexport interface CaptureTarget {\n readonly world: World;\n /** Advance one fixed step with the given actions and render. */\n stepOnce(actions?: string[]): void;\n /** Current frame as an SVG string (a vector screenshot). */\n renderSVG(): string;\n setPaused(paused: boolean): void;\n}\n\nexport interface HayaoCapture {\n pump(frames: number, actions?: string[]): Record<string, unknown>;\n probe(): Record<string, unknown>;\n hash(): string;\n shot(): string;\n save(path: string): Promise<boolean>;\n key(type: 'keydown' | 'keyup', code: string): void;\n readonly world: World;\n}\n\nexport function isCaptureMode(): boolean {\n return typeof location !== 'undefined' && new URLSearchParams(location.search).has('capture');\n}\n\n/** Install window.__hayao for scripted browser verification. */\nexport function installCapture(target: CaptureTarget): HayaoCapture {\n const api: HayaoCapture = {\n pump(frames, actions = []) {\n target.setPaused(true);\n for (let i = 0; i < frames; i++) target.stepOnce(actions);\n return target.world.probe();\n },\n probe: () => target.world.probe(),\n hash: () => target.world.hash(),\n shot: () => target.renderSVG(),\n async save(path) {\n const svg = target.renderSVG();\n try {\n const res = await fetch('/__shot', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ path, svg }),\n });\n return res.ok;\n } catch {\n return false;\n }\n },\n key(type, code) {\n document.dispatchEvent(new KeyboardEvent(type, { code, bubbles: true }));\n },\n get world() {\n return target.world;\n },\n };\n (globalThis as unknown as { __hayao: HayaoCapture }).__hayao = api;\n return api;\n}\n", "// Declarative input scripts: the ergonomic way to author headless playthroughs\n// for real-time games, where hand-writing per-frame action arrays is hopeless.\n// A script is a list of segments; each holds actions for N frames, optionally\n// tapping others on its first frame.\n\nimport type { World } from '../world';\n\nexport interface ScriptSegment {\n /** Actions held down for every frame of this segment. */\n hold?: string[];\n /** Actions pressed only on the first frame of this segment (taps). */\n press?: string[];\n /** How many fixed steps this segment lasts (default 1). */\n frames?: number;\n}\n\nexport type InputScript = ScriptSegment[];\n\n/** Expand a script into per-frame action arrays (an InputLog's frames). */\nexport function scriptToFrames(script: InputScript): string[][] {\n const out: string[][] = [];\n for (const seg of script) {\n const n = seg.frames ?? 1;\n const hold = seg.hold ?? [];\n for (let i = 0; i < n; i++) out.push(i === 0 && seg.press ? [...hold, ...seg.press] : [...hold]);\n }\n return out;\n}\n\nexport interface DriveResult {\n frames: number;\n /** True if driving stopped early because `until` matched. */\n matched: boolean;\n}\n\n/**\n * Step a world through a script. Pass `until` to stop as soon as a probe\n * predicate holds (e.g. level solved) \u2014 the tail of the script is slack, so\n * playthrough scripts don't need frame-perfect lengths.\n */\nexport function drive(world: World, script: InputScript, until?: (probe: Record<string, unknown>) => boolean): DriveResult {\n let frames = 0;\n for (const f of scriptToFrames(script)) {\n if (until && until(world.probe())) return { frames, matched: true };\n world.step(f);\n frames++;\n }\n return { frames, matched: until ? until(world.probe()) : false };\n}\n", "// The plan-interpreter bot skeleton \u2014 promoted to the engine after three\n// example games (shard-ascent, sproutveil, gleamvale) each rebuilt the same\n// shape: a plan of semantic steps, executed reactively against the probe each\n// frame, emitting actions. Games supply the step executors (steering is\n// genre-specific); the engine supplies the lifecycle, retries, and telemetry.\n//\n// const bot = createPlanBot(plan, {\n// walk(step, probe, out, ctx) { \u2026steer\u2026; if (arrived) ctx.next(); },\n// });\n// while (!probe.won) world.step(bot(world.probe()));\n\nexport interface BotCtx {\n /** Frames spent in the current step. */\n frames: number;\n /** Free per-step scratch (cleared on step change). */\n mem: Record<string, unknown>;\n /** Advance to the next plan step. */\n next(): void;\n /** Restart the current step (retry) \u2014 clears frames + mem. */\n retry(): void;\n}\n\nexport type StepExec<Step, Probe> = (step: Step, probe: Probe, out: string[], ctx: BotCtx) => void;\n\nexport interface PlanBot<Probe> {\n (probe: Probe): string[];\n stepIndex(): number;\n done(): boolean;\n}\n\nexport function createPlanBot<Step extends { kind: string }, Probe>(plan: Step[], execs: Record<string, StepExec<Step, Probe>>): PlanBot<Probe> {\n let i = 0;\n let frames = 0;\n let mem: Record<string, unknown> = {};\n\n const fn = (probe: Probe): string[] => {\n const out: string[] = [];\n const step = plan[i];\n if (!step) return out;\n frames++;\n const ctx: BotCtx = {\n get frames() {\n return frames;\n },\n mem,\n next() {\n i++;\n frames = 0;\n mem = {};\n },\n retry() {\n frames = 0;\n mem = {};\n },\n };\n const exec = execs[step.kind];\n if (!exec) throw new Error(`plan bot: no executor for step kind \"${step.kind}\"`);\n exec(step, probe, out, ctx);\n return out;\n };\n const bot = fn as PlanBot<Probe>;\n bot.stepIndex = () => i;\n bot.done = () => i >= plan.length;\n return bot;\n}\n\n/** Shared steering helper: 4/8-way movement toward a point. */\nexport function steer2D(px: number, py: number, tx: number, ty: number, out: string[], dead = 8): void {\n if (px < tx - dead) out.push('right');\n else if (px > tx + dead) out.push('left');\n if (py < ty - dead) out.push('down');\n else if (py > ty + dead) out.push('up');\n}\n", "// Feel probes (Channel 3): quality proxies computed from a per-frame probe\n// timeline. The harness cannot feel fun, but it can measure fun's precursors \u2014\n// time-to-first-meaningful-action, event cadence, difficulty ramp, input\n// decision density \u2014 and fail when a game drifts outside its tuned windows.\n// These are proxies, not proof: pair them with the filmstrip and a human-set\n// window per game (see docs/VERIFICATION.md \u00A7Channel 3).\n\nimport type { World } from '../world';\n\nexport type ProbeFrame = Record<string, unknown>;\n\n/**\n * Step a world through per-frame action arrays, probing after every step.\n * Returns frames.length + 1 probes: index 0 is the pre-step state, index i is\n * the state after frame i. (With the default 60Hz clock, index / 60 = sim\n * seconds.) For a segment-level timeline use scriptedPlaythrough instead.\n */\nexport function recordTimeline(world: World, frames: string[][]): ProbeFrame[] {\n const out: ProbeFrame[] = [world.probe()];\n for (const f of frames) {\n world.step(f);\n out.push(world.probe());\n }\n return out;\n}\n\n/** First timeline index where `pred` holds, or -1 if it never does. */\nexport function firstFrame(timeline: ProbeFrame[], pred: (p: ProbeFrame) => boolean): number {\n for (let i = 0; i < timeline.length; i++) if (pred(timeline[i])) return i;\n return -1;\n}\n\n/** The value of one probe key across the timeline. */\nexport function series(timeline: ProbeFrame[], key: string): unknown[] {\n return timeline.map((p) => p[key]);\n}\n\n/** Timeline indices where `key`'s value differs from the previous frame \u2014 an event cadence. */\nexport function changeFrames(timeline: ProbeFrame[], key: string): number[] {\n const out: number[] = [];\n for (let i = 1; i < timeline.length; i++) if (timeline[i][key] !== timeline[i - 1][key]) out.push(i);\n return out;\n}\n\n/** Monotonic within slack: 'up' means every value \u2265 previous \u2212 slack. */\nexport function isMonotonic(values: number[], dir: 'up' | 'down', slack = 0): boolean {\n for (let i = 1; i < values.length; i++) {\n if (dir === 'up' ? values[i] < values[i - 1] - slack : values[i] > values[i - 1] + slack) return false;\n }\n return true;\n}\n\n/**\n * Fraction of frames carrying at least one action \u2014 a crude engagement proxy.\n * Near 0 the player is waiting; near 1 they are mashing; a tuned game usually\n * lives somewhere in between (set the window per genre).\n */\nexport function inputDensity(frames: string[][]): number {\n if (frames.length === 0) return 0;\n return frames.filter((f) => f.length > 0).length / frames.length;\n}\n\n/** Largest gap (in frames) between consecutive events \u2014 dead-air detector. */\nexport function longestLull(eventFrames: number[], totalFrames: number): number {\n const pts = [0, ...eventFrames, totalFrames];\n let worst = 0;\n for (let i = 1; i < pts.length; i++) worst = Math.max(worst, pts[i] - pts[i - 1]);\n return worst;\n}\n", "// Filmstrip: sampled frames of a run composed into ONE SVG contact sheet, so\n// the \"judge looks from a headless screenshot\" step can see MOTION \u2014 pacing,\n// readability during play, layering under load \u2014 not a single posed frame.\n// Looks only, never correctness: state was already proven numerically.\n\nimport type { World } from '../world';\nimport { commandsToSVGInner } from '../render/svgString';\n\nexport interface FilmstripOptions {\n /** The game's view size (defineGame width/height). */\n width: number;\n height: number;\n background?: string;\n /** How many panels to sample across the run (default 12, min 2). */\n panels?: number;\n /** Panels per row (default 4). */\n cols?: number;\n /** Rendered width of one panel in px (default 320). */\n panelWidth?: number;\n}\n\n/**\n * Step `world` through per-frame actions, sampling evenly spaced panels\n * (always including the first and last frame), and return one standalone SVG.\n * Panel labels are frame numbers plus sim seconds at the 60Hz convention.\n */\nexport function renderFilmstrip(world: World, frames: string[][], opts: FilmstripOptions): string {\n const panels = Math.max(2, opts.panels ?? 12);\n const every = Math.max(1, Math.ceil(frames.length / (panels - 1)));\n const shots: { frame: number; inner: string }[] = [{ frame: 0, inner: commandsToSVGInner(world.render()) }];\n for (let i = 0; i < frames.length; i++) {\n world.step(frames[i]);\n if ((i + 1) % every === 0 || i === frames.length - 1) {\n shots.push({ frame: i + 1, inner: commandsToSVGInner(world.render()) });\n }\n }\n\n const cols = Math.max(1, opts.cols ?? 4);\n const pw = opts.panelWidth ?? 320;\n const ph = Math.round((pw * opts.height) / opts.width);\n const labelH = 18;\n const gap = 8;\n const cellW = pw + gap;\n const cellH = ph + labelH + gap;\n const rows = Math.ceil(shots.length / cols);\n const totalW = cols * cellW + gap;\n const totalH = rows * cellH + gap;\n const bg = opts.background ?? '#ffffff';\n\n const cells = shots\n .map((s, i) => {\n const x = gap + (i % cols) * cellW;\n const y = gap + Math.floor(i / cols) * cellH;\n return (\n `<g transform=\"translate(${x} ${y})\">` +\n `<svg width=\"${pw}\" height=\"${ph}\" viewBox=\"0 0 ${opts.width} ${opts.height}\">` +\n `<rect x=\"0\" y=\"0\" width=\"${opts.width}\" height=\"${opts.height}\" fill=\"${bg}\"/>` +\n s.inner +\n `</svg>` +\n `<rect x=\"0\" y=\"0\" width=\"${pw}\" height=\"${ph}\" fill=\"none\" stroke=\"#999\" stroke-width=\"1\"/>` +\n `<text x=\"${pw / 2}\" y=\"${ph + 13}\" font-size=\"11\" font-family=\"monospace\" text-anchor=\"middle\" fill=\"#555\">` +\n `f ${s.frame} \u00B7 ${(s.frame / 60).toFixed(1)}s</text>` +\n `</g>`\n );\n })\n .join('');\n\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${totalW} ${totalH}\" width=\"${totalW}\" height=\"${totalH}\">` +\n `<rect x=\"0\" y=\"0\" width=\"${totalW}\" height=\"${totalH}\" fill=\"#f4f4f2\"/>` +\n cells +\n `</svg>`\n );\n}\n", "// The World: the deterministic simulation container. Owns the root scene, the\n// rng, the clock, the input state, an event bus, and a resource table. Advancing\n// the world is `step()` \u2014 a pure function of (previous state, input frame).\n\nimport { Clock, type ClockConfig } from './core/clock';\nimport { EventBus } from './core/events';\nimport { hashValue } from './core/hash';\nimport { Rng } from './core/rng';\nimport { InputState } from './input/actions';\nimport { Node, resetNodeIds, type WorldContext } from './scene/node';\nimport { deserializeNode } from './scene/registry';\nimport type { Camera2D } from './scene/nodes';\nimport { IDENTITY, composeTransform, invertTransform, makeTransform, type Transform } from './core/math';\nimport type { DrawCommand } from './render/commands';\n\nexport interface WorldConfig {\n seed?: number;\n clock?: ClockConfig;\n /** Design-space dimensions (default 1280\u00D7720). */\n width?: number;\n height?: number;\n}\n\n/** Default engine event map; games extend it with their own keys. */\nexport interface CoreEvents {\n [key: string]: unknown;\n}\n\nexport class World implements WorldContext {\n readonly rng: Rng;\n readonly clock: Clock;\n readonly input = new InputState();\n readonly events = new EventBus<CoreEvents>();\n readonly resources = new Map<string, unknown>();\n /**\n * Canonical game state that lives OUTSIDE the scene tree (pure-sim structs,\n * controllers). Must be plain JSON-serializable data: it is included in\n * `hash()` and `snapshot()`, so hidden state here cannot escape determinism\n * checks the way ad-hoc module variables can.\n */\n state: Record<string, unknown> = {};\n readonly width: number;\n readonly height: number;\n\n root: Node;\n activeCamera: Camera2D | null = null;\n\n private seed: number;\n private freeQueue: Node[] = [];\n private started = false;\n\n constructor(config: WorldConfig = {}) {\n this.seed = config.seed ?? 1;\n this.rng = new Rng(this.seed);\n this.clock = new Clock(config.clock);\n this.width = config.width ?? 1280;\n this.height = config.height ?? 720;\n this.root = new Node({ name: 'root' });\n }\n\n get time(): number {\n return this.clock.simTimeSec;\n }\n get frame(): number {\n return this.clock.frame;\n }\n\n /** Replace the scene root, entering the tree. */\n setRoot(node: Node): void {\n if (this.root) this.root.exitTree();\n this.root = node;\n this.started = false;\n }\n\n requestFree(node: Node): void {\n this.freeQueue.push(node);\n }\n\n private ensureStarted(): void {\n if (!this.started) {\n this.root.enterTree(this);\n this.started = true;\n }\n }\n\n /**\n * Advance exactly one fixed step with the given actions held down.\n * This is THE deterministic transition \u2014 call it from Node or the browser loop.\n */\n step(actionsDown: Iterable<string> = []): void {\n this.ensureStarted();\n this.input.beginFrame(actionsDown);\n this.root.updateTree(this.clock.dt);\n this.flushFree();\n this.clock.tick();\n }\n\n /** Feed real elapsed ms; runs 0+ fixed steps. Returns steps run. */\n advance(realMs: number, actionsDown: Iterable<string> = []): number {\n const steps = this.clock.advance(realMs);\n for (let i = 0; i < steps; i++) this.step(actionsDown);\n return steps;\n }\n\n private flushFree(): void {\n if (this.freeQueue.length === 0) return;\n const q = this.freeQueue;\n this.freeQueue = [];\n for (const node of q) {\n node.exitTree();\n node.parent?.removeChild(node);\n if (this.activeCamera === node) this.activeCamera = null;\n }\n }\n\n // \u2500\u2500 Rendering \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** The view transform (inverse of the active camera), mapping world \u2192 screen. */\n viewTransform(): Transform {\n if (!this.activeCamera) return IDENTITY;\n const cam = this.activeCamera;\n // Center the camera in design space, apply zoom, then invert.\n const camWorld = cam.worldTransform();\n const centered = composeTransform(makeTransform({ x: this.width / 2, y: this.height / 2 }, 0, { x: cam.zoom, y: cam.zoom }), invertTransform(camWorld));\n return centered;\n }\n\n /** Project the whole scene to a display list (already camera-applied). */\n render(): DrawCommand[] {\n this.ensureStarted();\n const out: DrawCommand[] = [];\n this.root.collectDraw(out, this.viewTransform());\n return out;\n }\n\n // \u2500\u2500 Determinism & saves \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Deterministic structural hash of the whole sim state. */\n hash(): string {\n return hashValue({\n seed: this.seed,\n rng: this.rng.getState(),\n clock: this.clock.getState(),\n input: this.input.getState(),\n state: this.state,\n tree: this.root.serialize(),\n });\n }\n\n /** Compact snapshot for undo/time-travel and saves. */\n snapshot(): WorldSnapshot {\n return {\n seed: this.seed,\n rng: this.rng.getState(),\n clock: this.clock.getState(),\n input: this.input.getState(),\n state: structuredClone(this.state),\n tree: this.root.serialize(),\n };\n }\n\n /** Restore a snapshot. Rebuilds the tree from data (behaviors are re-attached by scene code). */\n restore(snap: WorldSnapshot): void {\n this.seed = snap.seed;\n this.rng.setState(snap.rng);\n this.clock.setState(snap.clock);\n this.input.setState(snap.input);\n this.state = structuredClone(snap.state);\n resetNodeIds(1_000_000); // avoid id collisions with the live session\n this.setRoot(deserializeNode(snap.tree));\n this.ensureStarted();\n }\n\n /** A compact probe snapshot for the verification harness (override-friendly). */\n probe(): Record<string, unknown> {\n return {\n frame: this.frame,\n time: this.time,\n hash: this.hash(),\n nodes: this.root.query('Sprite').length + this.root.query('Text').length,\n };\n }\n}\n\nexport interface WorldSnapshot {\n seed: number;\n rng: ReturnType<Rng['getState']>;\n clock: ReturnType<Clock['getState']>;\n input: ReturnType<InputState['getState']>;\n state: Record<string, unknown>;\n tree: ReturnType<Node['serialize']>;\n}\n", "// The project system. A game is a data definition: dimensions, input map, and a\n// build() that constructs the initial scene tree. `createWorld` turns it into a\n// live deterministic World \u2014 used identically by the browser driver, the headless\n// runner, and every test. That symmetry is the whole point.\n\nimport { World } from '../world';\nimport type { Node } from '../scene/node';\nimport { DEFAULT_INPUT_MAP, type InputLog, type InputMap } from '../input/actions';\nimport type { ClockConfig } from '../core/clock';\n\nexport interface GameDefinition {\n title: string;\n width?: number;\n height?: number;\n seed?: number;\n background?: string;\n clock?: ClockConfig;\n inputMap?: InputMap;\n /** Build the initial scene tree for a fresh world. */\n build(world: World): Node;\n /** Optional compact probe snapshot for verification (defaults to World.probe). */\n probe?(world: World): Record<string, unknown>;\n}\n\n/** Identity + defaults. Kept as a function so games read `export default defineGame({\u2026})`. */\nexport function defineGame(def: GameDefinition): Required<Pick<GameDefinition, 'width' | 'height' | 'seed' | 'inputMap' | 'background'>> & GameDefinition {\n return {\n width: 1280,\n height: 720,\n seed: 1,\n background: '#f3ecdb',\n inputMap: DEFAULT_INPUT_MAP,\n ...def,\n };\n}\n\n/** Build a live, deterministic World from a game definition. No browser needed. */\nexport function createWorld(def: GameDefinition, seedOverride?: number): World {\n const world = new World({\n seed: seedOverride ?? def.seed ?? 1,\n width: def.width ?? 1280,\n height: def.height ?? 720,\n clock: def.clock,\n });\n world.setRoot(def.build(world));\n if (def.probe) {\n // Instance override shadows the prototype method.\n (world as unknown as { probe: () => Record<string, unknown> }).probe = () => def.probe!(world);\n }\n return world;\n}\n\n/** The input map a game uses (with defaults applied). */\nexport function gameInputMap(def: GameDefinition): InputMap {\n return def.inputMap ?? DEFAULT_INPUT_MAP;\n}\n\nexport interface HeadlessResult {\n world: World;\n hash: string;\n steps: number;\n}\n\n/**\n * Run a game to completion in Node with no host \u2014 play an input log (or zero\n * steps) and return the final world + state hash. This is what tests, the CI\n * verifier, and replays call. The browser is never involved.\n */\nexport function runHeadless(def: GameDefinition, inputLog?: InputLog): HeadlessResult {\n const world = createWorld(def);\n const frames = inputLog?.frames ?? [];\n for (const f of frames) world.step(f);\n return { world, hash: world.hash(), steps: frames.length };\n}\n", "// Browser driver: mounts a renderer, samples real input into the fixed-step\n// kernel, projects to the renderer each frame, and wires audio + the pause shell.\n// Wall-clock only feeds the accumulator (how many steps to run) \u2014 replays use the\n// input log, not wall time, so the sim stays deterministic.\n\nimport type { GameDefinition } from './game';\nimport { createWorld } from './game';\nimport { KeyboardSource } from '../input/source';\nimport { SvgRenderer } from '../render/svg';\nimport { Canvas2DRenderer } from '../render/canvas';\nimport type { Renderer } from '../render/renderer';\nimport { renderToSVGString } from '../render/svgString';\nimport { audio } from '../audio/audio';\nimport { settings } from '../ui/settings';\nimport { setOverlayHost } from '../ui/overlay';\nimport { Shell } from '../ui/shell';\nimport { installCapture, isCaptureMode } from '../verify/capture';\nimport type { World } from '../world';\n\nexport interface RunOptions {\n renderer?: 'svg' | 'canvas';\n /** Start the pause/settings shell (Esc). Default true. */\n shell?: boolean;\n onRestart?: () => void;\n}\n\nexport interface GameHandle {\n world: World;\n renderer: Renderer;\n /** The live input source \u2014 game UI calls input.press('action') for buttons. */\n input: KeyboardSource;\n stop(): void;\n restart(): void;\n}\n\nexport function runBrowser(def: GameDefinition, mount: HTMLElement, opts: RunOptions = {}): GameHandle {\n const width = def.width ?? 1280;\n const height = def.height ?? 720;\n const background = def.background ?? '#f3ecdb';\n\n let world = createWorld(def);\n const renderer: Renderer =\n opts.renderer === 'canvas'\n ? new Canvas2DRenderer({ width, height, background })\n : new SvgRenderer({ width, height, background });\n\n mount.style.position = mount.style.position || 'relative';\n renderer.mount?.(mount);\n setOverlayHost(mount);\n\n const input = new KeyboardSource(def.inputMap ?? {}, document);\n const capture = isCaptureMode();\n\n // Start audio on first user gesture (autoplay policy).\n const startAudio = () => {\n audio.start();\n const s = settings.get();\n audio.setVolumes(s);\n window.removeEventListener('pointerdown', startAudio);\n window.removeEventListener('keydown', startAudio);\n };\n window.addEventListener('pointerdown', startAudio);\n window.addEventListener('keydown', startAudio);\n\n const renderFrame = () => renderer.draw(world.render());\n const restart = () => {\n world = createWorld(def);\n renderFrame();\n };\n\n const shell =\n opts.shell === false\n ? null\n : new Shell({\n title: def.title,\n onRestart: opts.onRestart ?? restart,\n onPause: () => {},\n });\n\n let raf = 0;\n let last = performance.now();\n const loop = (now: number) => {\n const dt = now - last;\n last = now;\n if (!capture && !(shell?.isPaused)) {\n const steps = world.advance(dt, input.currentActions());\n if (steps > 0) input.clearPressed(); // virtual taps held until sampled\n }\n renderFrame();\n raf = requestAnimationFrame(loop);\n };\n raf = requestAnimationFrame(loop);\n\n const handle: GameHandle = {\n get world() {\n return world;\n },\n renderer,\n input,\n stop() {\n cancelAnimationFrame(raf);\n input.dispose();\n shell?.dispose();\n renderer.dispose?.();\n },\n restart,\n };\n\n if (capture) {\n installCapture({\n get world() {\n return world;\n },\n stepOnce: (actions = []) => {\n world.step(actions);\n renderFrame();\n },\n renderSVG: () => renderToSVGString(world.render(), width, height, background),\n setPaused: () => {},\n });\n }\n\n return handle;\n}\n", "// @hayao \u2014 the single public seam. Games and examples import ONLY from here.\n// Everything below the barrel is swappable; this file is the whole API surface,\n// greppable in one place (an AI-first invariant).\n\n// \u2500\u2500 core: the deterministic kernel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './core/math';\nexport * from './core/rng';\nexport * from './core/clock';\nexport * from './core/events';\nexport * from './core/hash';\n\n// \u2500\u2500 scene: the Godot-style node tree \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './scene/node';\n// Node2D is an alias for Node \u2014 the base node already carries a 2D transform.\nexport { Node as Node2D } from './scene/node';\nexport * from './scene/nodes';\nexport * from './scene/tween';\nexport * from './scene/particles';\nexport * from './scene/registry';\n\n// \u2500\u2500 input: actions, sampling, record/replay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './input/actions';\nexport * from './input/source';\n\n// \u2500\u2500 physics: tilemaps, kinematic AABB, character controllers \u2500\u2500\u2500\u2500\nexport * from './physics/tilemap';\nexport * from './physics/aabb';\nexport * from './physics/platformer';\nexport * from './physics/spatialHash';\nexport * from './physics/raycast';\n\n// \u2500\u2500 render: display list + backends \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './render/commands';\nexport * from './render/renderer';\nexport * from './render/svgString';\nexport * from './render/svg';\nexport * from './render/canvas';\nexport * from './render/headless';\n\n// \u2500\u2500 art: code-as-art helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './art/palette';\nexport * from './art/shapes';\n\n// \u2500\u2500 audio \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './audio/audio';\n\n// \u2500\u2500 ui: DOM overlays + shell + settings \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './ui/overlay';\nexport * from './ui/settings';\nexport * from './ui/shell';\n\n// \u2500\u2500 verify: the AI-first harness \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './verify/solver';\nexport * from './verify/determinism';\nexport * from './verify/playthrough';\nexport * from './verify/capture';\nexport * from './verify/driver';\nexport * from './verify/bot';\nexport * from './verify/feel';\nexport * from './verify/filmstrip';\n\n// \u2500\u2500 world + app \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './world';\nexport * from './app/game';\nexport * from './app/browser';\n\n/** Engine version. */\nexport const VERSION = '0.1.0';\n"],
5
+ "mappings": ";AAQO,IAAM,OAAO,CAAC,IAAI,GAAG,IAAI,OAAa,EAAE,GAAG,EAAE;AAC7C,IAAM,OAAO,CAAC,GAAS,OAAmB,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,EAAE;AACvE,IAAM,OAAO,CAAC,GAAS,OAAmB,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,EAAE;AACvE,IAAM,SAAS,CAAC,GAAS,OAAqB,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,EAAE;AACvE,IAAM,OAAO,CAAC,GAAS,MAAoB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAC/D,IAAM,OAAO,CAAC,MAAoB,KAAK,MAAM,EAAE,GAAG,EAAE,CAAC;AACrD,IAAM,QAAQ,CAAC,GAAS,MAAoB,KAAK,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AAC3E,SAAS,MAAM,GAAe;AACnC,QAAM,IAAI,KAAK,CAAC;AAChB,SAAO,MAAM,IAAI,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,EAAE;AAC7D;AAEO,IAAM,QAAQ,CAAC,GAAW,IAAY,OAAwB,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK;AAC1F,IAAM,OAAO,CAAC,GAAW,GAAW,MAAsB,KAAK,IAAI,KAAK;AACxE,IAAM,UAAU,CAAC,GAAW,GAAW,MAAuB,MAAM,IAAI,KAAK,IAAI,MAAM,IAAI;AAC3F,IAAM,QAAQ,CAAC,GAAW,IAAY,IAAY,IAAY,OACnE,KAAK,IAAI,IAAI,QAAQ,IAAI,IAAI,CAAC,CAAC;AAE1B,IAAM,MAAM,KAAK,KAAK;AACtB,IAAM,UAAU,CAAC,MAAuB,IAAI,KAAK,KAAM;AACvD,IAAM,UAAU,CAAC,MAAuB,IAAI,MAAO,KAAK;AAUxD,SAAS,aAAa,GAAS,GAAkB;AACtD,SAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE;AACxE;AAEO,SAAS,aAAa,GAAS,GAAkB;AACtD,SAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE;AAChF;AAYO,IAAM,WAAsB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAEjE,SAAS,iBAAiB,GAAcA,IAAyB;AACtE,SAAO;AAAA,IACL,GAAG,EAAE,IAAIA,GAAE,IAAI,EAAE,IAAIA,GAAE;AAAA,IACvB,GAAG,EAAE,IAAIA,GAAE,IAAI,EAAE,IAAIA,GAAE;AAAA,IACvB,GAAG,EAAE,IAAIA,GAAE,IAAI,EAAE,IAAIA,GAAE;AAAA,IACvB,GAAG,EAAE,IAAIA,GAAE,IAAI,EAAE,IAAIA,GAAE;AAAA,IACvB,GAAG,EAAE,IAAIA,GAAE,IAAI,EAAE,IAAIA,GAAE,IAAI,EAAE;AAAA,IAC7B,GAAG,EAAE,IAAIA,GAAE,IAAI,EAAE,IAAIA,GAAE,IAAI,EAAE;AAAA,EAC/B;AACF;AAGO,SAAS,cAAc,KAAW,UAAkB,OAAwB;AACjF,QAAM,MAAM,KAAK,IAAI,QAAQ;AAC7B,QAAM,MAAM,KAAK,IAAI,QAAQ;AAC7B,SAAO;AAAA,IACL,GAAG,MAAM,MAAM;AAAA,IACf,GAAG,MAAM,MAAM;AAAA,IACf,GAAG,CAAC,MAAM,MAAM;AAAA,IAChB,GAAG,MAAM,MAAM;AAAA,IACf,GAAG,IAAI;AAAA,IACP,GAAG,IAAI;AAAA,EACT;AACF;AAEO,SAAS,eAAe,GAAc,GAAe;AAC1D,SAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;AAC1E;AAGO,SAAS,gBAAgB,GAAyB;AACvD,QAAM,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAChC,MAAI,QAAQ,EAAG,QAAO,EAAE,GAAG,SAAS;AACpC,QAAM,KAAK,IAAI;AACf,SAAO;AAAA,IACL,GAAG,EAAE,IAAI;AAAA,IACT,GAAG,CAAC,EAAE,IAAI;AAAA,IACV,GAAG,CAAC,EAAE,IAAI;AAAA,IACV,GAAG,EAAE,IAAI;AAAA,IACT,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK;AAAA,IAC7B,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK;AAAA,EAC/B;AACF;;;AChGA,SAAS,WAAW,MAA4B;AAC9C,MAAI,IAAI,SAAS;AACjB,SAAO,MAAM;AACX,QAAK,IAAI,eAAgB;AACzB,QAAI,IAAI;AACR,QAAI,KAAK,KAAK,IAAK,MAAM,IAAK,SAAU;AACxC,QAAI,KAAK,KAAK,IAAK,MAAM,IAAK,UAAU;AACxC,YAAQ,IAAK,MAAM,QAAS;AAAA,EAC9B;AACF;AAMO,IAAM,MAAN,MAAM,KAAI;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,OAA0B,GAAG;AACvC,QAAI,OAAO,SAAS,UAAU;AAC5B,YAAM,KAAK,WAAW,SAAS,IAAI,YAAa,IAAI;AACpD,WAAK,KAAK,GAAG;AACb,WAAK,KAAK,GAAG;AACb,WAAK,KAAK,GAAG;AACb,WAAK,KAAK,GAAG;AAAA,IACf,OAAO;AACL,OAAC,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE,IAAI,KAAK;AAAA,IAC9C;AAAA,EACF;AAAA;AAAA,EAGQ,OAAe;AACrB,UAAM,SAAU,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM;AACtE,UAAM,IAAK,KAAK,MAAM,MAAO;AAC7B,SAAK,MAAM,KAAK;AAChB,SAAK,MAAM,KAAK;AAChB,SAAK,MAAM,KAAK;AAChB,SAAK,MAAM,KAAK;AAChB,SAAK,MAAM,KAAK,KAAK,OAAO;AAC5B,SAAK,KAAK,KAAK,KAAK,KAAK,IAAI,EAAE;AAC/B,WAAO,WAAW;AAAA,EACpB;AAAA,EAEQ,KAAK,GAAW,GAAmB;AACzC,YAAU,KAAK,IAAM,MAAO,KAAK,OAAS;AAAA,EAC5C;AAAA;AAAA,EAGA,QAAgB;AACd,WAAO,KAAK,KAAK,IAAI;AAAA,EACvB;AAAA;AAAA,EAGA,MAAM,IAAY,IAAoB;AACpC,WAAO,KAAK,KAAK,MAAM,KAAK,KAAK;AAAA,EACnC;AAAA;AAAA,EAGA,IAAIC,IAAmB;AACrB,WAAO,KAAK,MAAM,KAAK,MAAM,IAAIA,EAAC;AAAA,EACpC;AAAA;AAAA,EAGA,SAAS,IAAY,IAAoB;AACvC,WAAO,KAAK,KAAK,IAAI,KAAK,KAAK,CAAC;AAAA,EAClC;AAAA;AAAA,EAGA,OAAO,GAAoB;AACzB,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AAAA;AAAA,EAGA,KAAQ,KAAsB;AAC5B,WAAO,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC;AAAA,EACjC;AAAA;AAAA,EAGA,QAAW,KAAe;AACxB,aAAS,IAAI,IAAI,SAAS,GAAG,IAAI,GAAG,KAAK;AACvC,YAAM,IAAI,KAAK,IAAI,IAAI,CAAC;AACxB,OAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AAAA,IACpC;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,MAAM,GAAQ;AAClB,UAAMC,QAAO,KAAK,KAAK,KAAK,KAAK,MAAM,GAAG,UAAU,OAAO;AAC3D,UAAM,QAAQ,IAAI,KAAIA,OAAM,KAAK,EAAE;AAEnC,SAAK,KAAK;AACV,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,WAAqB;AACnB,WAAO,EAAE,GAAG,CAAC,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE,EAAE;AAAA,EACnD;AAAA,EACA,SAAS,OAAuB;AAC9B,KAAC,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE,IAAI,MAAM;AAAA,EAC/C;AACF;AAGO,SAAS,WAAW,KAAqB;AAC9C,MAAI,IAAI,eAAe;AACvB,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,SAAK,IAAI,WAAW,CAAC;AACrB,QAAI,KAAK,KAAK,GAAG,QAAQ;AAAA,EAC3B;AACA,SAAO,MAAM;AACf;;;AChHO,IAAM,QAAN,MAAY;AAAA,EACR;AAAA,EACA;AAAA;AAAA,EACD;AAAA,EACA,cAAc;AAAA,EACd,SAAS;AAAA,EACT,aAAa;AAAA,EAErB,YAAY,SAAsB,CAAC,GAAG;AACpC,UAAM,KAAK,OAAO,MAAM;AACxB,SAAK,SAAS,MAAO;AACrB,SAAK,KAAK,IAAI;AACd,SAAK,aAAa,OAAO,cAAc;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQ,QAAwB;AAC9B,SAAK,eAAe,KAAK,IAAI,QAAQ,KAAK,UAAU;AACpD,QAAI,QAAQ;AACZ,WAAO,KAAK,eAAe,KAAK,QAAQ;AACtC,WAAK,eAAe,KAAK;AACzB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,OAAa;AACX,SAAK;AACL,SAAK,cAAc,KAAK;AAAA,EAC1B;AAAA;AAAA,EAGA,IAAI,QAAgB;AAClB,WAAO,KAAK,cAAc,KAAK;AAAA,EACjC;AAAA,EAEA,IAAI,QAAgB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA,EACA,IAAI,YAAoB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA,EACA,IAAI,aAAqB;AACvB,WAAO,KAAK,aAAa;AAAA,EAC3B;AAAA,EAEA,WAAW;AACT,WAAO,EAAE,aAAa,KAAK,aAAa,OAAO,KAAK,QAAQ,WAAW,KAAK,WAAW;AAAA,EACzF;AAAA,EACA,SAAS,GAAoE;AAC3E,SAAK,cAAc,EAAE;AACrB,SAAK,SAAS,EAAE;AAChB,SAAK,aAAa,EAAE;AAAA,EACtB;AACF;;;AChEO,IAAM,SAAN,MAAuB;AAAA,EACpB,YAA2B,CAAC;AAAA,EAEpC,QAAQ,IAA6B;AACnC,SAAK,UAAU,KAAK,EAAE;AACtB,WAAO,MAAM,KAAK,WAAW,EAAE;AAAA,EACjC;AAAA,EAEA,KAAK,IAA6B;AAChC,UAAM,MAAM,KAAK,QAAQ,CAAC,MAAM;AAC9B,UAAI;AACJ,SAAG,CAAC;AAAA,IACN,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,IAAuB;AAChC,UAAM,IAAI,KAAK,UAAU,QAAQ,EAAE;AACnC,QAAI,KAAK,EAAG,MAAK,UAAU,OAAO,GAAG,CAAC;AAAA,EACxC;AAAA,EAEA,KAAK,SAAkB;AAErB,eAAW,MAAM,KAAK,UAAU,MAAM,EAAG,IAAG,OAAO;AAAA,EACrD;AAAA,EAEA,IAAI,QAAgB;AAClB,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA,EAEA,QAAc;AACZ,SAAK,UAAU,SAAS;AAAA,EAC1B;AACF;AAOO,IAAM,WAAN,MAAuD;AAAA,EACpD,UAAU,oBAAI,IAAmC;AAAA,EAEjD,UAAkC,KAA2B;AACnE,QAAI,IAAI,KAAK,QAAQ,IAAI,GAAG;AAC5B,QAAI,CAAC,GAAG;AACN,UAAI,IAAI,OAAgB;AACxB,WAAK,QAAQ,IAAI,KAAK,CAAC;AAAA,IACzB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,GAA2B,KAAQ,IAAqC;AACtE,WAAO,KAAK,UAAU,GAAG,EAAE,QAAQ,EAAE;AAAA,EACvC;AAAA,EAEA,KAA6B,KAAQ,IAAqC;AACxE,WAAO,KAAK,UAAU,GAAG,EAAE,KAAK,EAAE;AAAA,EACpC;AAAA,EAEA,KAA6B,KAAQ,SAA0B;AAC7D,SAAK,UAAU,GAAG,EAAE,KAAK,OAAO;AAAA,EAClC;AAAA,EAEA,QAAc;AACZ,SAAK,QAAQ,MAAM;AAAA,EACrB;AACF;;;ACrEA,SAAS,gBAAgBC,IAAmB;AAC1C,MAAI,OAAO,MAAMA,EAAC,EAAG,QAAO;AAC5B,MAAIA,OAAM,SAAU,QAAO;AAC3B,MAAIA,OAAM,UAAW,QAAO;AAC5B,MAAIA,OAAM,EAAG,QAAO;AACpB,SAAOA,GAAE,SAAS;AACpB;AAOO,SAAS,UAAU,OAAwB;AAChD,MAAI,KAAK,eAAe;AACxB,MAAI,KAAK,eAAe;AACxB,QAAM,OAAO,CAAC,MAAc;AAC1B,aAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,YAAM,IAAI,EAAE,WAAW,CAAC;AACxB,WAAK,KAAK,KAAK,KAAK,GAAG,QAAQ,MAAM;AACrC,WAAK,KAAK,KAAK,MAAO,KAAK,IAAM,MAAM,IAAK,UAAU,MAAM;AAAA,IAC9D;AAAA,EACF;AAEA,QAAM,OAAO,CAAC,MAAqB;AACjC,QAAI,MAAM,KAAM,QAAO,KAAK,GAAG;AAC/B,QAAI,MAAM,OAAW,QAAO,KAAK,GAAG;AACpC,YAAQ,OAAO,GAAG;AAAA,MAChB,KAAK;AACH,eAAO,KAAK,MAAM,gBAAgB,CAAC,CAAC;AAAA,MACtC,KAAK;AACH,eAAO,KAAK,IAAI,MAAM,GAAG;AAAA,MAC3B,KAAK;AACH,eAAO,KAAK,MAAM,CAAC;AAAA,MACrB,KAAK,UAAU;AACb,YAAI,MAAM,QAAQ,CAAC,GAAG;AACpB,eAAK,GAAG;AACR,qBAAW,MAAM,EAAG,MAAK,EAAE;AAC3B,eAAK,GAAG;AACR;AAAA,QACF;AACA,cAAM,MAAM;AACZ,cAAM,OAAO,OAAO,KAAK,GAAG,EAAE,KAAK;AACnC,aAAK,GAAG;AACR,mBAAW,KAAK,MAAM;AACpB,eAAK,IAAI,GAAG;AACZ,eAAK,IAAI,CAAC,CAAC;AAAA,QACb;AACA,aAAK,GAAG;AACR;AAAA,MACF;AAAA,MACA;AACE,aAAK,GAAG;AAAA,IACZ;AAAA,EACF;AAEA,OAAK,KAAK;AACV,QAAM,MAAM,CAACA,OAAcA,GAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AACzD,SAAO,IAAI,EAAE,IAAI,IAAI,EAAE;AACzB;;;AC3BA,IAAI,cAAc;AAEX,SAAS,aAAa,QAAQ,GAAS;AAC5C,gBAAc;AAChB;AAWO,IAAM,OAAN,MAAW;AAAA,EACP;AAAA,EACT;AAAA;AAAA,EAES,OAAe;AAAA,EAExB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAW;AAAA,EAEX,SAAsB;AAAA,EACb,WAAmB,CAAC;AAAA,EAC7B,QAA6B;AAAA;AAAA,EAG7B;AAAA,EAEQ,YAAwB,CAAC;AAAA,EACzB,UAAU,oBAAI,IAA6B;AAAA,EAC3C,SAAS;AAAA,EACT,SAAS;AAAA,EAEjB,YAAY,SAAqB,CAAC,GAAG;AACnC,SAAK,KAAK,IAAI,aAAa;AAC3B,SAAK,OAAO,OAAO,QAAQ,KAAK,YAAY;AAC5C,SAAK,MAAM,OAAO,MAAM,EAAE,GAAG,OAAO,IAAI,IAAI,EAAE,GAAG,GAAG,GAAG,EAAE;AACzD,SAAK,WAAW,OAAO,YAAY;AACnC,SAAK,QAAQ,OAAO,QAAQ,EAAE,GAAG,OAAO,MAAM,IAAI,EAAE,GAAG,GAAG,GAAG,EAAE;AAC/D,SAAK,IAAI,OAAO,KAAK;AACrB,SAAK,UAAU,OAAO,WAAW;AAAA,EACnC;AAAA;AAAA,EAGA,SAAyB,OAAa;AACpC,UAAM,SAAS;AACf,SAAK,SAAS,KAAK,KAAK;AACxB,QAAI,KAAK,SAAS,KAAK,OAAQ,OAAM,UAAU,KAAK,KAAK;AACzD,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,OAAmB;AAC7B,UAAM,IAAI,KAAK,SAAS,QAAQ,KAAK;AACrC,QAAI,KAAK,GAAG;AACV,WAAK,SAAS,OAAO,GAAG,CAAC;AACzB,YAAM,SAAS;AAAA,IACjB;AAAA,EACF;AAAA;AAAA,EAGA,OAAa;AACX,SAAK,OAAO,YAAY,IAAI;AAAA,EAC9B;AAAA;AAAA,EAGA,KAAK,MAA2B;AAC9B,QAAI,KAAK,SAAS,KAAM,QAAO;AAC/B,eAAW,KAAK,KAAK,UAAU;AAC7B,YAAM,IAAI,EAAE,KAAK,IAAI;AACrB,UAAI,EAAG,QAAO;AAAA,IAChB;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,MAAc,MAAc,CAAC,GAAW;AAC5C,QAAI,KAAK,SAAS,KAAM,KAAI,KAAK,IAAI;AACrC,eAAW,KAAK,KAAK,SAAU,GAAE,MAAM,MAAM,GAAG;AAChD,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,YAAY,GAAmB;AAC7B,SAAK,UAAU,KAAK,CAAC;AACrB,QAAI,KAAK,OAAQ,GAAE,QAAQ,IAAI;AAC/B,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,OAAiB,MAAyB;AACxC,QAAI,IAAI,KAAK,QAAQ,IAAI,IAAI;AAC7B,QAAI,CAAC,GAAG;AACN,UAAI,IAAI,OAAgB;AACxB,WAAK,QAAQ,IAAI,MAAM,CAAC;AAAA,IAC1B;AACA,WAAO;AAAA,EACT;AAAA,EACA,KAAQ,MAAc,SAAkB;AACtC,SAAK,QAAQ,IAAI,IAAI,GAAG,KAAK,OAAO;AAAA,EACtC;AAAA;AAAA,EAGA,UAAU,OAA2B;AACnC,SAAK,QAAQ;AACb,QAAI,CAAC,KAAK,QAAQ;AAChB,WAAK,SAAS;AACd,WAAK,QAAQ;AACb,iBAAW,KAAK,KAAK,UAAW,GAAE,QAAQ,IAAI;AAAA,IAChD;AACA,eAAW,KAAK,KAAK,SAAU,GAAE,UAAU,KAAK;AAAA,EAClD;AAAA,EAEA,WAAW,IAAkB;AAC3B,QAAI,KAAK,OAAQ;AACjB,eAAW,KAAK,KAAK,UAAW,GAAE,SAAS,MAAM,EAAE;AACnD,SAAK,WAAW,MAAM,EAAE;AACxB,SAAK,UAAU,EAAE;AAEjB,eAAW,KAAK,KAAK,SAAS,MAAM,EAAG,GAAE,WAAW,EAAE;AAAA,EACxD;AAAA,EAEA,WAAiB;AACf,eAAW,KAAK,KAAK,UAAW,GAAE,OAAO,IAAI;AAC7C,SAAK,OAAO;AACZ,eAAW,KAAK,KAAK,SAAS,MAAM,EAAG,GAAE,SAAS;AAClD,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,IAAI,UAAmB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,iBAA4B;AAC1B,WAAO,cAAc,KAAK,KAAK,KAAK,UAAU,KAAK,KAAK;AAAA,EAC1D;AAAA,EAEA,iBAA4B;AAC1B,UAAM,QAAQ,KAAK,eAAe;AAClC,WAAO,KAAK,SAAS,iBAAiB,KAAK,OAAO,eAAe,GAAG,KAAK,IAAI;AAAA,EAC/E;AAAA;AAAA;AAAA,EAIA,YAAY,KAAoB,cAAyB,UAAgB;AACvE,QAAI,CAAC,KAAK,QAAS;AACnB,UAAM,QAAQ,iBAAiB,aAAa,KAAK,eAAe,CAAC;AACjE,SAAK,KAAK,KAAK,KAAK;AACpB,eAAW,KAAK,KAAK,SAAU,GAAE,YAAY,KAAK,KAAK;AAAA,EACzD;AAAA;AAAA,EAGU,KAAK,MAAqB,QAAyB;AAAA,EAAC;AAAA;AAAA,EAGpD,UAAgB;AAAA,EAAC;AAAA,EACjB,UAAU,KAAmB;AAAA,EAAC;AAAA,EAC9B,SAAe;AAAA,EAAC;AAAA;AAAA,EAG1B,YAA4B;AAC1B,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,KAAK,EAAE,GAAG,KAAK,IAAI;AAAA,MACnB,UAAU,KAAK;AAAA,MACf,OAAO,EAAE,GAAG,KAAK,MAAM;AAAA,MACvB,GAAG,KAAK;AAAA,MACR,SAAS,KAAK;AAAA,MACd,OAAO,KAAK,eAAe;AAAA,MAC3B,UAAU,KAAK,SAAS,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC;AAAA,IAC7E;AAAA,EACF;AAAA;AAAA,EAEU,iBAA0C;AAClD,WAAO,CAAC;AAAA,EACV;AAAA;AAAA,EAEA,WAAW,QAAuC;AAAA,EAAC;AACrD;;;AC/MO,IAAM,SAAN,cAAqB,KAAK;AAAA,EACb,OAAO;AAAA,EACzB;AAAA,EACA;AAAA,EAEA,YAAY,QAAsB;AAChC,UAAM,MAAM;AACZ,SAAK,QAAQ,OAAO;AACpB,SAAK,QAAQ;AAAA,MACX,MAAM,OAAO;AAAA,MACb,QAAQ,OAAO;AAAA,MACf,aAAa,OAAO;AAAA,MACpB,SAAS,OAAO;AAAA,MAChB,OAAO,OAAO;AAAA,IAChB;AAAA,EACF;AAAA,EAEmB,KAAK,KAAoB,OAAwB;AAClE,UAAM,IAAI,KAAK;AACf,UAAM,OAAO,EAAE,WAAW,OAAO,GAAG,KAAK,GAAG,GAAG,EAAE;AACjD,YAAQ,KAAK,MAAM,MAAM;AAAA,MACvB,KAAK;AACH,YAAI,KAAK,EAAE,MAAM,QAAQ,GAAG,CAAC,KAAK,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,MAAM,IAAI,GAAG,GAAG,KAAK,MAAM,GAAG,GAAG,KAAK,MAAM,GAAG,GAAG,KAAK,MAAM,GAAG,GAAG,KAAK,CAAC;AACjI;AAAA,MACF,KAAK;AACH,YAAI,KAAK,EAAE,MAAM,UAAU,IAAI,GAAG,IAAI,GAAG,QAAQ,KAAK,MAAM,QAAQ,GAAG,KAAK,CAAC;AAC7E;AAAA,MACF,KAAK;AACH,YAAI,KAAK,EAAE,MAAM,QAAQ,QAAQ,KAAK,MAAM,QAAQ,QAAQ,KAAK,MAAM,UAAU,MAAM,GAAG,KAAK,CAAC;AAChG;AAAA,MACF,KAAK;AACH,YAAI,KAAK,EAAE,MAAM,QAAQ,GAAG,KAAK,MAAM,GAAG,GAAG,KAAK,CAAC;AACnD;AAAA,MACF,KAAK;AACH,YAAI,KAAK,EAAE,MAAM,QAAQ,MAAM,KAAK,MAAM,MAAM,GAAG,GAAG,GAAG,GAAG,MAAM,KAAK,MAAM,MAAM,OAAO,UAAU,GAAG,KAAK,CAAC;AAC7G;AAAA,IACJ;AAAA,EACF;AAAA,EAEmB,iBAA0C;AAC3D,WAAO,EAAE,OAAO,KAAK,OAAO,OAAO,KAAK,MAAM;AAAA,EAChD;AAAA,EACS,WAAW,OAAsC;AACxD,QAAI,MAAM,MAAO,MAAK,QAAQ,MAAM;AACpC,QAAI,MAAM,MAAO,MAAK,QAAQ,MAAM;AAAA,EACtC;AACF;AAWO,IAAM,OAAN,cAAmB,KAAK;AAAA,EACX,OAAO;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,QAAoB;AAC9B,UAAM,MAAM;AACZ,SAAK,OAAO,OAAO;AACnB,SAAK,OAAO,OAAO,QAAQ;AAC3B,SAAK,OAAO,OAAO;AACnB,SAAK,QAAQ,OAAO,SAAS;AAC7B,SAAK,SAAS,OAAO;AACrB,SAAK,QAAQ,EAAE,MAAM,OAAO,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,aAAa,OAAO,aAAa,SAAS,OAAO,QAAQ;AAAA,EAC9H;AAAA,EAEmB,KAAK,KAAoB,OAAwB;AAClE,QAAI,KAAK;AAAA,MACP,MAAM;AAAA,MAAQ,MAAM,KAAK;AAAA,MAAM,GAAG;AAAA,MAAG,GAAG;AAAA,MAAG,MAAM,KAAK;AAAA,MAAM,MAAM,KAAK;AAAA,MACvE,OAAO,KAAK;AAAA,MAAO,QAAQ,KAAK;AAAA,MAAQ,WAAW;AAAA,MAAO,GAAG,KAAK;AAAA,MAAG,GAAG,KAAK;AAAA,IAC/E,CAAC;AAAA,EACH;AAAA,EAEmB,iBAA0C;AAC3D,WAAO,EAAE,MAAM,KAAK,MAAM,MAAM,KAAK,MAAM,OAAO,KAAK,OAAO,OAAO,KAAK,MAAM;AAAA,EAClF;AAAA,EACS,WAAW,OAAsC;AACxD,QAAI,OAAO,MAAM,SAAS,SAAU,MAAK,OAAO,MAAM;AACtD,QAAI,OAAO,MAAM,SAAS,SAAU,MAAK,OAAO,MAAM;AACtD,QAAI,MAAM,MAAO,MAAK,QAAQ,MAAM;AACpC,QAAI,MAAM,MAAO,MAAK,QAAQ,MAAM;AAAA,EACtC;AACF;AASO,IAAM,WAAN,cAAuB,KAAK;AAAA,EACf,OAAO;AAAA,EACzB;AAAA,EACA;AAAA,EAEA,YAAY,SAAuB,CAAC,GAAG;AACrC,UAAM,MAAM;AACZ,SAAK,OAAO,OAAO,QAAQ;AAC3B,SAAK,UAAU,OAAO,WAAW;AAAA,EACnC;AAAA,EAEmB,UAAgB;AACjC,QAAI,KAAK,QAAS,CAAC,KAAK,MAAqD,eAAe;AAAA,EAC9F;AAAA,EAEmB,iBAA0C;AAC3D,WAAO,EAAE,MAAM,KAAK,MAAM,SAAS,KAAK,QAAQ;AAAA,EAClD;AAAA,EACS,WAAW,OAAsC;AACxD,QAAI,OAAO,MAAM,SAAS,SAAU,MAAK,OAAO,MAAM;AACtD,QAAI,OAAO,MAAM,YAAY,UAAW,MAAK,UAAU,MAAM;AAAA,EAC/D;AACF;AASO,IAAM,QAAN,cAAoB,KAAK;AAAA,EACZ,OAAO;AAAA,EACzB;AAAA,EACA;AAAA,EACQ;AAAA,EACA;AAAA,EAER,YAAY,QAAqB;AAC/B,UAAM,MAAM;AACZ,SAAK,WAAW,OAAO;AACvB,SAAK,UAAU,OAAO,WAAW;AACjC,SAAK,YAAY,OAAO;AACxB,SAAK,UAAU,OAAO,aAAa;AAAA,EACrC;AAAA,EAEA,MAAM,UAAyB;AAC7B,QAAI,aAAa,OAAW,MAAK,WAAW;AAC5C,SAAK,YAAY,KAAK;AACtB,SAAK,UAAU;AAAA,EACjB;AAAA,EACA,OAAa;AACX,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,IAAI,WAAmB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEmB,UAAU,IAAkB;AAC7C,QAAI,CAAC,KAAK,QAAS;AACnB,SAAK,aAAa;AAClB,QAAI,KAAK,aAAa,GAAG;AACvB,WAAK,KAAK,WAAW,MAAS;AAC9B,UAAI,KAAK,QAAS,MAAK,UAAU;AAAA,UAC5B,MAAK,aAAa,KAAK;AAAA,IAC9B;AAAA,EACF;AAAA;AAAA,EAGA,IAAI,UAAU;AACZ,WAAO,KAAK,OAAO,SAAS;AAAA,EAC9B;AAAA,EAEmB,iBAA0C;AAC3D,WAAO,EAAE,UAAU,KAAK,UAAU,SAAS,KAAK,SAAS,WAAW,KAAK,WAAW,SAAS,KAAK,QAAQ;AAAA,EAC5G;AAAA,EACS,WAAW,OAAsC;AACxD,QAAI,OAAO,MAAM,aAAa,SAAU,MAAK,WAAW,MAAM;AAC9D,QAAI,OAAO,MAAM,YAAY,UAAW,MAAK,UAAU,MAAM;AAC7D,QAAI,OAAO,MAAM,cAAc,SAAU,MAAK,YAAY,MAAM;AAChE,QAAI,OAAO,MAAM,YAAY,UAAW,MAAK,UAAU,MAAM;AAAA,EAC/D;AACF;;;ACnMA,IAAM,MAAM,KAAK;AACV,IAAM,UAAkC;AAAA,EAC7C,QAAQ,CAAC,MAAM;AAAA,EACf,QAAQ,CAAC,MAAM,IAAI;AAAA,EACnB,SAAS,CAAC,MAAM,KAAK,IAAI,MAAM,IAAI;AAAA,EACnC,WAAW,CAAC,MAAO,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,GAAG,CAAC,IAAI;AAAA,EAClE,SAAS,CAAC,MAAM,IAAI,IAAI;AAAA,EACxB,UAAU,CAAC,MAAM,IAAI,IAAI,IAAI,GAAG,CAAC;AAAA,EACjC,YAAY,CAAC,MAAO,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,GAAG,CAAC,IAAI;AAAA,EACvE,QAAQ,CAAC,MAAM,IAAI,KAAK,IAAK,IAAI,KAAK,KAAM,CAAC;AAAA,EAC7C,SAAS,CAAC,MAAM,KAAK,IAAK,IAAI,KAAK,KAAM,CAAC;AAAA,EAC1C,WAAW,CAAC,MAAM,EAAE,KAAK,IAAI,KAAK,KAAK,CAAC,IAAI,KAAK;AAAA,EACjD,SAAS,CAAC,MAAM;AACd,UAAM,KAAK;AACX,UAAM,KAAK,KAAK;AAChB,WAAO,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC;AAAA,EACnD;AAAA,EACA,YAAY,CAAC,MAAM;AACjB,UAAM,KAAM,IAAI,KAAK,KAAM;AAC3B,WAAO,MAAM,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,GAAG,MAAM,CAAC,IAAI,KAAK,KAAK,IAAI,KAAK,QAAQ,EAAE,IAAI;AAAA,EACxF;AAAA,EACA,WAAW,CAAC,MAAM;AAChB,UAAM,KAAK;AACX,UAAM,KAAK;AACX,QAAI,IAAI,IAAI,GAAI,QAAO,KAAK,IAAI;AAChC,QAAI,IAAI,IAAI,GAAI,QAAO,MAAM,KAAK,MAAM,MAAM,IAAI;AAClD,QAAI,IAAI,MAAM,GAAI,QAAO,MAAM,KAAK,OAAO,MAAM,IAAI;AACrD,WAAO,MAAM,KAAK,QAAQ,MAAM,IAAI;AAAA,EACtC;AACF;AAcO,IAAM,kBAAN,cAA8B,KAAK;AAAA,EACtB,OAAO;AAAA,EACjB,SAAkB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAM3B,GACE,OACA,MACA,IACA,UACA,OAAsC,YACtC,OAAgD,CAAC,GAC3C;AACN,SAAK,OAAO,KAAK;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,KAAK,IAAI,MAAM,QAAQ;AAAA,MACjC,SAAS;AAAA,MACT,MAAM,OAAO,SAAS,aAAa,OAAO,QAAQ,IAAI,KAAK,QAAQ;AAAA,MACnE,OAAO,KAAK,SAAS;AAAA,MACrB,QAAQ,KAAK;AAAA,IACf,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,SAAkB;AACpB,WAAO,KAAK,OAAO,SAAS;AAAA,EAC9B;AAAA;AAAA,EAGA,IAAI,WAAW;AACb,WAAO,KAAK,OAAO,UAAU;AAAA,EAC/B;AAAA,EAEmB,UAAU,IAAkB;AAC7C,QAAI,KAAK,OAAO,WAAW,EAAG;AAC9B,aAAS,IAAI,KAAK,OAAO,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAM,KAAK,KAAK,OAAO,CAAC;AACxB,UAAI,GAAG,QAAQ,GAAG;AAChB,WAAG,SAAS;AACZ;AAAA,MACF;AACA,SAAG,WAAW;AACd,YAAM,IAAI,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,CAAC;AAC9C,SAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,CAAC,CAAC;AACjD,UAAI,KAAK,GAAG;AACV,WAAG,SAAS;AACZ,aAAK,OAAO,OAAO,GAAG,CAAC;AAAA,MACzB;AAAA,IACF;AACA,QAAI,KAAK,OAAO,WAAW,EAAG,MAAK,KAAK,YAAY,MAAS;AAAA,EAC/D;AACF;;;AC3DO,IAAM,YAAN,cAAwB,KAAK;AAAA,EAChB,OAAe;AAAA,EACzB,OAAmB,CAAC;AAAA,EACpB;AAAA;AAAA,EAER;AAAA,EAEA,YAAY,SAAgE,CAAC,GAAG;AAC9E,UAAM,MAAM;AACZ,SAAK,WAAW;AAChB,SAAK,MAAM,IAAI,IAAI,OAAO,QAAQ,CAAC;AACnC,SAAK,eAAe,OAAO,gBAAgB;AAAA,EAC7C;AAAA;AAAA,EAGA,MAAM,OAAe,IAAU,OAA4B;AACzD,UAAM,IAAI,KAAK;AACf,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAQ,MAAM,UAAU,SAAY,MAAM,SAAS,EAAE,MAAM,IAAI,QAAQ,MAAM,UAAU,OAAO,EAAE,MAAM,IAAI;AAChH,YAAM,QAAQ,MAAM,WAAW,EAAE,MAAM,KAAK,MAAM,WAAW,MAAM;AACnE,YAAM,IAAc;AAAA,QAClB,GAAG,GAAG;AAAA,QACN,GAAG,GAAG;AAAA,QACN,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,MAAM;AAAA,QACN,SAAS,MAAM,UAAU,EAAE,MAAM,KAAK,MAAM,UAAU,MAAM;AAAA,QAC5D,MAAM,MAAM,UAAU,EAAE,MAAM,KAAK,MAAM,UAAU,MAAM;AAAA,QACzD,OAAO,MAAM,OAAO,EAAE,IAAI,MAAM,OAAO,MAAM,CAAC;AAAA,MAChD;AACA,UAAI,KAAK,KAAK,UAAU,KAAK,aAAc,MAAK,KAAK,MAAM;AAC3D,WAAK,KAAK,KAAK,CAAC;AAAA,IAClB;AAGA,SAAK,UAAU,MAAM,WAAW;AAChC,SAAK,OAAO,MAAM,QAAQ;AAC1B,SAAK,SAAS,MAAM,UAAU;AAAA,EAChC;AAAA,EAEQ,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EAEE,UAAU,IAAkB;AAC7C,UAAM,OAAO,KAAK,IAAI,GAAG,IAAI,KAAK,OAAO,EAAE;AAC3C,QAAI,QAAQ;AACZ,eAAW,KAAK,KAAK,MAAM;AACzB,QAAE,QAAQ;AACV,UAAI,EAAE,QAAQ,EAAE,QAAS;AACzB,QAAE,MAAM,KAAK,UAAU;AACvB,QAAE,MAAM;AACR,QAAE,MAAM;AACR,QAAE,KAAK,EAAE,KAAK;AACd,QAAE,KAAK,EAAE,KAAK;AACd,WAAK,KAAK,OAAO,IAAI;AAAA,IACvB;AACA,SAAK,KAAK,SAAS;AAAA,EACrB;AAAA,EAEmB,KAAK,KAAoB,OAAwB;AAClE,eAAW,KAAK,KAAK,MAAM;AACzB,YAAM,IAAI,IAAI,EAAE,OAAO,EAAE;AACzB,UAAI,KAAK;AAAA,QACP,MAAM;AAAA,QACN,IAAI,EAAE;AAAA,QACN,IAAI,EAAE;AAAA,QACN,QAAQ,KAAK,SAAS,EAAE,OAAO,IAAI,EAAE;AAAA,QACrC,MAAM,EAAE;AAAA,QACR,SAAS,KAAK,IAAI,GAAG,IAAI,CAAC;AAAA,QAC1B,WAAW;AAAA,QACX,GAAG,KAAK;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,IAAI,YAAoB;AACtB,WAAO,KAAK,KAAK;AAAA,EACnB;AACF;AAGO,IAAM,mBAAmB;AAAA,EAC9B,MAAM,CAAC,SAAS,CAAC,WAAW,SAAS,OAAsB,EAAE,QAAQ,SAAS,GAAG,SAAS,GAAG,UAAU,IAAI,UAAU,IAAI,SAAS,KAAK,SAAS,MAAM,SAAS,KAAK,MAAM,GAAG,QAAQ,KAAK;AAAA,EAC1L,OAAO,CAAC,SAAS,CAAC,WAAW,WAAW,SAAS,OAAsB,EAAE,QAAQ,SAAS,GAAG,SAAS,GAAG,UAAU,KAAK,UAAU,KAAK,SAAS,MAAM,SAAS,KAAK,MAAM,GAAG,QAAQ,KAAK;AAAA,EAC1L,KAAK,CAAC,SAAS,CAAC,WAAW,SAAS,OAAsB,EAAE,QAAQ,SAAS,GAAG,SAAS,GAAG,UAAU,KAAK,UAAU,KAAK,SAAS,MAAM,SAAS,MAAM,MAAM,GAAG,QAAQ,KAAK;AAAA,EAC9K,SAAS,CAAC,SAAS,CAAC,WAAW,WAAW,SAAS,OAAsB,EAAE,QAAQ,SAAS,KAAK,SAAS,KAAK,UAAU,IAAI,UAAU,IAAI,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,MAAM,GAAG,QAAQ,KAAK;AAC7M;AAQO,IAAM,SAAN,cAAqB,KAAK;AAAA,EACb,OAAe;AAAA,EACzB;AAAA,EACA,SAAS;AAAA;AAAA,EAEjB;AAAA;AAAA,EAEA;AAAA,EAEA,YAAY,SAA6E,CAAC,GAAG;AAC3F,UAAM,MAAM;AACZ,SAAK,WAAW;AAChB,SAAK,MAAM,IAAI,IAAI,OAAO,QAAQ,EAAE;AACpC,SAAK,YAAY,OAAO,aAAa;AACrC,SAAK,QAAQ,OAAO,SAAS;AAAA,EAC/B;AAAA;AAAA,EAGA,UAAU,QAAsB;AAC9B,SAAK,SAAS,KAAK,IAAI,GAAG,KAAK,SAAS,MAAM;AAAA,EAChD;AAAA,EAEmB,UAAU,IAAkB;AAC7C,SAAK,SAAS,KAAK,IAAI,GAAG,KAAK,SAAS,KAAK,QAAQ,EAAE;AACvD,UAAM,IAAI,KAAK,SAAS,KAAK,SAAS,KAAK;AAC3C,SAAK,IAAI,KAAK,KAAK,IAAI,MAAM,IAAI,IAAI,KAAK;AAC1C,SAAK,IAAI,KAAK,KAAK,IAAI,MAAM,IAAI,IAAI,KAAK;AAAA,EAC5C;AACF;;;AClKA,IAAM,WAAW,oBAAI,IAAyB;AAEvC,SAAS,aAAa,MAAc,SAA4B;AACrE,WAAS,IAAI,MAAM,OAAO;AAC5B;AAIA,aAAa,QAAQ,MAAM,IAAI,KAAK,CAAC;AACrC,aAAa,UAAU,MAAM,IAAI,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;AAChF,aAAa,QAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC;AACjD,aAAa,YAAY,MAAM,IAAI,SAAS,CAAC;AAC7C,aAAa,SAAS,MAAM,IAAI,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;AACtD,aAAa,mBAAmB,MAAM,IAAI,gBAAgB,CAAC;AAGpD,SAAS,gBAAgB,MAA4B;AAC1D,QAAM,UAAU,SAAS,IAAI,KAAK,IAAI;AACtC,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,6BAA6B,KAAK,IAAI,uBAAuB;AAC3F,QAAM,OAAO,QAAQ;AACrB,OAAK,OAAO,KAAK;AACjB,OAAK,MAAM,EAAE,GAAG,KAAK,IAAI;AACzB,OAAK,WAAW,KAAK;AACrB,OAAK,QAAQ,EAAE,GAAG,KAAK,MAAM;AAC7B,OAAK,IAAI,KAAK;AACd,OAAK,UAAU,KAAK;AACpB,OAAK,WAAW,KAAK,KAAK;AAC1B,aAAW,SAAS,KAAK,SAAU,MAAK,SAAS,gBAAgB,KAAK,CAAC;AACvE,SAAO;AACT;;;AChCO,IAAM,aAAN,MAAiB;AAAA,EACd,OAAO,oBAAI,IAAY;AAAA,EACvB,OAAO,oBAAI,IAAY;AAAA;AAAA,EAEtB,OAAO,oBAAI,IAAoB;AAAA;AAAA,EAGxC,WAAW,aAAqC;AAC9C,SAAK,OAAO,IAAI,IAAI,KAAK,IAAI;AAC7B,SAAK,OAAO,IAAI,IAAI,WAAW;AAAA,EACjC;AAAA,EAEA,OAAO,QAAyB;AAC9B,WAAO,KAAK,KAAK,IAAI,MAAM;AAAA,EAC7B;AAAA,EACA,YAAY,QAAyB;AACnC,WAAO,KAAK,KAAK,IAAI,MAAM,KAAK,CAAC,KAAK,KAAK,IAAI,MAAM;AAAA,EACvD;AAAA,EACA,aAAa,QAAyB;AACpC,WAAO,CAAC,KAAK,KAAK,IAAI,MAAM,KAAK,KAAK,KAAK,IAAI,MAAM;AAAA,EACvD;AAAA,EACA,KAAK,MAAsB;AACzB,WAAO,KAAK,KAAK,IAAI,IAAI,KAAK;AAAA,EAChC;AAAA;AAAA,EAGA,WAAqB;AACnB,WAAO,CAAC,GAAG,KAAK,IAAI,EAAE,KAAK;AAAA,EAC7B;AAAA,EAEA,WAAW;AACT,WAAO,EAAE,MAAM,CAAC,GAAG,KAAK,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC,GAAG,KAAK,IAAI,EAAE,KAAK,EAAE;AAAA,EACpE;AAAA,EACA,SAAS,GAA6C;AACpD,SAAK,OAAO,IAAI,IAAI,EAAE,IAAI;AAC1B,SAAK,OAAO,IAAI,IAAI,EAAE,IAAI;AAAA,EAC5B;AACF;AAGO,SAAS,cAAc,KAAe,UAAiC;AAC5E,QAAM,UAAoB,CAAC;AAC3B,aAAW,UAAU,KAAK;AACxB,QAAI,IAAI,MAAM,EAAE,KAAK,CAAC,MAAM,SAAS,IAAI,CAAC,CAAC,EAAG,SAAQ,KAAK,MAAM;AAAA,EACnE;AACA,SAAO,QAAQ,KAAK;AACtB;AAGO,IAAM,gBAAN,MAAoB;AAAA,EACjB,SAAqB,CAAC;AAAA,EAE9B,OAAO,aAA6B;AAClC,SAAK,OAAO,KAAK,YAAY,MAAM,EAAE,KAAK,CAAC;AAAA,EAC7C;AAAA,EAEA,IAAI,SAAiB;AACnB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,QAAkB;AAChB,WAAO,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE;AAAA,EACrD;AACF;AAOO,SAAS,aAAa,KAAe,GAAqB;AAC/D,SAAO,IAAI,OAAO,CAAC,KAAK,CAAC;AAC3B;AAGO,IAAM,oBAA8B;AAAA,EACzC,IAAI,CAAC,WAAW,MAAM;AAAA,EACtB,MAAM,CAAC,aAAa,MAAM;AAAA,EAC1B,MAAM,CAAC,aAAa,MAAM;AAAA,EAC1B,OAAO,CAAC,cAAc,MAAM;AAAA,EAC5B,SAAS,CAAC,SAAS,OAAO;AAAA,EAC1B,QAAQ,CAAC,UAAU,WAAW;AAAA,EAC9B,QAAQ,CAAC,QAAQ,MAAM;AAAA,EACvB,SAAS,CAAC,QAAQ,MAAM;AAAA,EACxB,MAAM,CAAC,MAAM;AAAA,EACb,SAAS,CAAC,MAAM;AAClB;;;ACxFO,IAAM,iBAAN,MAAqB;AAAA,EAClB,WAAW,oBAAI,IAAY;AAAA;AAAA,EAE3B,UAAU,oBAAI,IAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,KAAe,SAAiC,UAAU;AACpE,SAAK,MAAM;AACX,SAAK,SAAS;AACd,SAAK,SAAS,CAAC,MAAM;AACnB,WAAK,SAAS,IAAI,EAAE,IAAI;AAExB,UAAI,EAAE,KAAK,WAAW,OAAO,KAAK,EAAE,SAAS,QAAS,GAAE,eAAe;AAAA,IACzE;AACA,SAAK,OAAO,CAAC,MAAM,KAAK,SAAS,OAAO,EAAE,IAAI;AAC9C,SAAK,SAAS,MAAM,KAAK,SAAS,MAAM;AACxC,WAAO,iBAAiB,WAAW,KAAK,MAAuB;AAC/D,WAAO,iBAAiB,SAAS,KAAK,IAAqB;AAC3D,eAAW,mBAAmB,QAAQ,KAAK,MAAM;AAAA,EACnD;AAAA;AAAA,EAGA,iBAA2B;AACzB,UAAM,OAAO,cAAc,KAAK,KAAK,KAAK,QAAQ;AAClD,QAAI,KAAK,QAAQ,SAAS,EAAG,QAAO;AACpC,UAAM,SAAS,IAAI,IAAI,IAAI;AAC3B,eAAW,KAAK,KAAK,QAAS,QAAO,IAAI,CAAC;AAC1C,WAAO,CAAC,GAAG,MAAM,EAAE,KAAK;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,QAAsB;AAC1B,SAAK,QAAQ,IAAI,MAAM;AAAA,EACzB;AAAA;AAAA,EAGA,eAAqB;AACnB,SAAK,QAAQ,MAAM;AAAA,EACrB;AAAA,EAEA,OAAO,KAAqB;AAC1B,SAAK,MAAM;AAAA,EACb;AAAA,EAEA,UAAgB;AACd,SAAK,OAAO,oBAAoB,WAAW,KAAK,MAAuB;AACvE,SAAK,OAAO,oBAAoB,SAAS,KAAK,IAAqB;AACnE,eAAW,sBAAsB,QAAQ,KAAK,MAAM;AAAA,EACtD;AACF;;;AC5DO,IAAM,OAAO;AAAA,EAClB,OAAO;AAAA,EACP,OAAO;AAAA;AAAA,EAEP,QAAQ;AAAA,EACR,QAAQ;AACV;AAcO,IAAM,qBAA6C;AAAA,EACxD,KAAK,KAAK;AAAA,EACV,KAAK,KAAK;AAAA,EACV,KAAK,KAAK;AACZ;AAOO,SAAS,iBAAiB,WAAqB,WAAW,IAAI,QAAgC,oBAAiC;AACpI,QAAM,OAAO,UAAU;AACvB,QAAM,OAAO,KAAK,IAAI,GAAG,UAAU,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;AACvD,QAAM,QAAQ,IAAI,MAAc,OAAO,IAAI,EAAE,KAAK,KAAK,KAAK;AAC5D,YAAU,QAAQ,CAAC,KAAK,OAAO;AAC7B,aAAS,KAAK,GAAG,KAAK,IAAI,QAAQ,KAAM,OAAM,KAAK,OAAO,EAAE,IAAI,MAAM,IAAI,EAAE,CAAC,KAAK,KAAK;AAAA,EACzF,CAAC;AACD,SAAO,EAAE,MAAM,MAAM,UAAU,MAAM;AACvC;AAGO,SAAS,cAAc,WAAqB,WAAW,IAAI,QAAgC,oBAAsF;AACtL,QAAM,MAAwE,CAAC;AAC/E,YAAU,QAAQ,CAAC,KAAK,OAAO;AAC7B,aAAS,KAAK,GAAG,KAAK,IAAI,QAAQ,MAAM;AACtC,YAAM,IAAI,IAAI,EAAE;AAChB,UAAI,MAAM,OAAO,MAAM,OAAO,MAAM,CAAC,MAAM,OAAW;AACtD,UAAI,KAAK,EAAE,MAAM,GAAG,IAAI,IAAI,IAAI,KAAK,OAAO,UAAU,IAAI,KAAK,OAAO,SAAS,CAAC;AAAA,IAClF;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAGO,SAAS,OAAO,KAAkB,IAAY,IAAoB;AACvE,MAAI,KAAK,KAAK,KAAK,KAAK,MAAM,IAAI,QAAQ,MAAM,IAAI,KAAM,QAAO,KAAK;AACtE,SAAO,IAAI,MAAM,KAAK,IAAI,OAAO,EAAE;AACrC;AAEO,SAAS,YAAY,KAAkB,GAAW,GAAmB;AAC1E,SAAO,OAAO,KAAK,KAAK,MAAM,IAAI,IAAI,QAAQ,GAAG,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC;AAC/E;AAEO,IAAM,WAAW,CAAC,QAA6B,IAAI,OAAO,IAAI;AAC9D,IAAM,YAAY,CAAC,QAA6B,IAAI,OAAO,IAAI;;;AC7DtE,IAAM,MAAM;AAuBZ,IAAM,YAAY,CAAC,IAAY,IAAY,OAAiC,CAAC,KAAK,MAAM,KAAK,EAAE,GAAG,KAAK,OAAO,KAAK,OAAO,EAAE,CAAC;AAStH,SAAS,YAAY,KAAkB,GAAW,GAAW,GAAW,GAAW,SAAsB,CAAC,GAAY;AAC3H,QAAM,KAAK,IAAI;AACf,QAAM,CAAC,KAAK,GAAG,IAAI,UAAU,GAAG,IAAI,GAAG,EAAE;AACzC,QAAM,CAAC,KAAK,GAAG,IAAI,UAAU,GAAG,IAAI,GAAG,EAAE;AACzC,WAAS,KAAK,KAAK,MAAM,KAAK;AAC5B,aAAS,KAAK,KAAK,MAAM,KAAK,KAAM,KAAI,OAAO,KAAK,IAAI,EAAE,MAAM,KAAK,MAAO,QAAO;AACrF,aAAW,KAAK,QAAQ;AACtB,QAAI,EAAE,OAAQ;AACd,QAAI,IAAI,EAAE,IAAI,EAAE,IAAI,OAAO,IAAI,IAAI,EAAE,IAAI,OAAO,IAAI,EAAE,IAAI,EAAE,IAAI,OAAO,IAAI,IAAI,EAAE,IAAI,IAAK,QAAO;AAAA,EACnG;AACA,SAAO;AACT;AAMO,SAAS,SAAS,KAAkB,MAAY,IAAY,IAAY,OAAiB,CAAC,GAAe;AAC9G,QAAM,KAAK,IAAI;AACf,QAAM,SAAS,KAAK,UAAU,CAAC;AAC/B,MAAI,EAAE,GAAG,EAAE,IAAI;AACf,QAAM,EAAE,GAAG,EAAE,IAAI;AACjB,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,aAAa;AACjB,MAAI,cAAc;AAGlB,MAAI,OAAO,GAAG;AACZ,UAAM,CAAC,KAAK,GAAG,IAAI,UAAU,GAAG,IAAI,GAAG,EAAE;AACzC,QAAI,KAAK,GAAG;AACV,UAAI,QAAQ,IAAI;AAChB,YAAM,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,OAAO,IAAI,KAAK,EAAE,GAAG,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;AAC/E,eAAS,KAAK,IAAI,MAAM,IAAI;AAC1B,iBAAS,KAAK,KAAK,MAAM,KAAK;AAC5B,cAAI,OAAO,KAAK,IAAI,EAAE,MAAM,KAAK,MAAO,SAAQ,KAAK,IAAI,OAAO,KAAK,KAAK,CAAC;AAC/E,iBAAW,KAAK;AACd,YAAI,CAAC,EAAE,UAAU,EAAE,IAAI,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,OAAO,EAAE,KAAK,IAAI,IAAI,IAAK,SAAQ,KAAK,IAAI,OAAO,EAAE,IAAI,CAAC;AAClH,UAAI,QAAQ,IAAI,KAAK,KAAK;AACxB,eAAO;AACP,sBAAc;AAAA,MAChB;AACA,UAAI,KAAK,IAAI,IAAI,IAAI,KAAK;AAAA,IAC5B,OAAO;AACL,UAAI,QAAQ,IAAI;AAChB,YAAM,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,OAAO,IAAI,OAAO,EAAE,GAAG,KAAK,OAAO,IAAI,MAAM,EAAE,CAAC;AACvE,eAAS,KAAK,IAAI,MAAM,IAAI;AAC1B,iBAAS,KAAK,KAAK,MAAM,KAAK;AAC5B,cAAI,OAAO,KAAK,IAAI,EAAE,MAAM,KAAK,MAAO,SAAQ,KAAK,IAAI,QAAQ,KAAK,KAAK,EAAE;AACjF,iBAAW,KAAK;AACd,YAAI,CAAC,EAAE,UAAU,EAAE,IAAI,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,IAAK,SAAQ,KAAK,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;AACtH,UAAI,QAAQ,IAAI,KAAK,KAAK;AACxB,eAAO;AACP,qBAAa;AAAA,MACf;AACA,UAAI,KAAK,IAAI,IAAI,IAAI,KAAK;AAAA,IAC5B;AAAA,EACF;AAGA,QAAM,aAAa,IAAI;AACvB,MAAI,UAAU;AACd,MAAI,YAAY;AAChB,MAAI,aAAa;AACjB,MAAI,OAAO,GAAG;AACZ,UAAM,CAAC,KAAK,GAAG,IAAI,UAAU,GAAG,IAAI,GAAG,EAAE;AACzC,QAAI,KAAK,GAAG;AACV,UAAI,QAAQ,IAAI;AAChB,YAAM,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,MAAM,aAAa,EAAE,GAAG,KAAK,OAAO,aAAa,KAAK,OAAO,EAAE,CAAC;AACvF,eAAS,KAAK,IAAI,MAAM,IAAI;AAC1B,iBAAS,KAAK,KAAK,MAAM,KAAK,MAAM;AAClC,gBAAM,IAAI,OAAO,KAAK,IAAI,EAAE;AAC5B,gBAAM,SAAS,MAAM,KAAK,SAAU,MAAM,KAAK,UAAU,CAAC,KAAK,eAAe,cAAc,KAAK,KAAK;AACtG,cAAI,OAAQ,SAAQ,KAAK,IAAI,OAAO,KAAK,KAAK,CAAC;AAAA,QACjD;AACF,eAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,cAAM,IAAI,OAAO,CAAC;AAClB,cAAM,MAAM,EAAE,IAAI,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI;AACjD,YAAI,CAAC,OAAO,EAAE,IAAI,aAAa,IAAK;AACpC,YAAI,EAAE,WAAW,KAAK,eAAe,aAAa,EAAE,IAAI,KAAM;AAC9D,YAAI,EAAE,IAAI,IAAI,OAAO;AACnB,kBAAQ,EAAE,IAAI;AACd,uBAAa;AAAA,QACf;AAAA,MACF;AACA,UAAI,QAAQ,IAAI,KAAK,KAAK;AACxB,eAAO;AACP,kBAAU;AAAA,MACZ,MAAO,cAAa;AACpB,UAAI,KAAK,IAAI,IAAI,IAAI,KAAK;AAAA,IAC5B,OAAO;AACL,UAAI,QAAQ,IAAI;AAChB,YAAM,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,OAAO,IAAI,OAAO,EAAE,GAAG,KAAK,OAAO,IAAI,MAAM,EAAE,CAAC;AACvE,eAAS,KAAK,IAAI,MAAM,IAAI;AAC1B,iBAAS,KAAK,KAAK,MAAM,KAAK;AAC5B,cAAI,OAAO,KAAK,IAAI,EAAE,MAAM,KAAK,MAAO,SAAQ,KAAK,IAAI,QAAQ,KAAK,KAAK,EAAE;AACjF,iBAAW,KAAK;AACd,YAAI,CAAC,EAAE,UAAU,EAAE,IAAI,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,IAAK,SAAQ,KAAK,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;AACtH,UAAI,QAAQ,IAAI,KAAK,KAAK;AACxB,eAAO;AACP,oBAAY;AAAA,MACd;AACA,UAAI,KAAK,IAAI,IAAI,IAAI,KAAK;AAAA,IAC5B;AAAA,EACF;AAGA,MAAI,CAAC,SAAS;AACZ,UAAM,QAAQ,SAAS,KAAK,GAAG,GAAG,GAAG,GAAG,QAAQ,KAAK,eAAe,KAAK;AACzE,cAAU,MAAM;AAChB,iBAAa,MAAM;AAAA,EACrB;AAGA,QAAM,QAAQ;AACd,MAAI,SAAS;AACb;AACE,UAAM,CAAC,KAAK,GAAG,IAAI,UAAU,IAAI,OAAO,IAAI,IAAI,OAAO,EAAE;AACzD,UAAM,CAAC,KAAK,GAAG,IAAI,UAAU,IAAI,OAAO,IAAI,IAAI,OAAO,EAAE;AACzD,aAAS,KAAK,KAAK,MAAM,OAAO,CAAC,QAAQ;AACvC,eAAS,KAAK,KAAK,MAAM,OAAO,CAAC,QAAQ,KAAM,KAAI,OAAO,KAAK,IAAI,EAAE,MAAM,KAAK,OAAQ,UAAS;AAAA,EACrG;AAEA,SAAO,EAAE,GAAG,GAAG,MAAM,MAAM,SAAS,WAAW,YAAY,aAAa,QAAQ,WAAW;AAC7F;AAGO,SAAS,SAAS,KAAkB,GAAW,GAAW,GAAW,GAAW,SAAsB,CAAC,GAAG,cAAc,OAA6C;AAC1K,QAAM,KAAK,IAAI;AACf,QAAM,SAAS,IAAI;AACnB,QAAM,CAAC,KAAK,GAAG,IAAI,UAAU,GAAG,IAAI,GAAG,EAAE;AACzC,QAAM,KAAK,KAAK,OAAO,SAAS,KAAK,EAAE;AACvC,WAAS,KAAK,KAAK,MAAM,KAAK,MAAM;AAClC,UAAM,IAAI,OAAO,KAAK,IAAI,EAAE;AAC5B,QAAI,MAAM,KAAK,MAAO,QAAO,EAAE,UAAU,MAAM,OAAO,GAAG;AACzD,QAAI,MAAM,KAAK,UAAU,CAAC,eAAe,KAAK,IAAI,SAAS,KAAK,EAAE,KAAK,IAAI,IAAK,QAAO,EAAE,UAAU,MAAM,OAAO,GAAG;AAAA,EACrH;AACA,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,IAAI,OAAO,CAAC;AAClB,UAAM,MAAM,EAAE,IAAI,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI;AACjD,QAAI,OAAO,UAAU,EAAE,IAAI,IAAI,OAAO,UAAU,EAAE,IAAI,IAAI,IAAK,QAAO,EAAE,UAAU,MAAM,OAAO,EAAE;AAAA,EACnG;AACA,SAAO,EAAE,UAAU,OAAO,OAAO,GAAG;AACtC;;;ACxHO,IAAM,qBAAuC;AAAA,EAClD,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS;AAAA,EACT,SAAS;AAAA,EACT,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW;AAAA,EACX,UAAU;AAAA,EACV,cAAc;AAAA,EACd,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAChB;AAWO,IAAM,cAAwB,EAAE,OAAO,GAAG,OAAO,GAAG,UAAU,OAAO,aAAa,OAAO,aAAa,MAAM;AAiC5G,SAAS,sBAAsB,GAAW,GAA4B;AAC3E,SAAO,EAAE,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,QAAQ,GAAG,UAAU,OAAO,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,OAAO,UAAU,GAAG,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,MAAM;AAC1O;AAYA,IAAM,WAAW,CAAC,GAAW,QAAgB,UAA2B,IAAI,SAAS,KAAK,IAAI,IAAI,OAAO,MAAM,IAAI,KAAK,IAAI,IAAI,OAAO,MAAM;AAOtI,SAAS,eAAe,GAAoB,OAAiB,IAAY,KAAkB,MAAwB,oBAAoB,YAAwB,CAAC,GAAqB;AAC1L,QAAM,KAAuB,EAAE,QAAQ,OAAO,YAAY,OAAO,WAAW,OAAO,QAAQ,OAAO,QAAQ,OAAO,MAAM,MAAM;AAC7H,MAAI,EAAE,KAAM,QAAO;AACnB,QAAM,cAAc,EAAE;AAGtB,IAAE,SAAS,KAAK,IAAI,GAAG,EAAE,SAAS,EAAE;AACpC,IAAE,SAAS,KAAK,IAAI,GAAG,EAAE,SAAS,EAAE;AACpC,IAAE,WAAW,KAAK,IAAI,GAAG,EAAE,WAAW,EAAE;AACxC,IAAE,SAAS,KAAK,IAAI,GAAG,EAAE,SAAS,EAAE;AACpC,MAAI,MAAM,YAAa,GAAE,SAAS,IAAI;AAGtC,MAAI,MAAM,eAAe,EAAE,WAAW,KAAK,EAAE,UAAU,KAAK,EAAE,aAAa,GAAG;AAC5E,QAAIC,MAAK,MAAM;AACf,QAAIC,MAAK,MAAM;AACf,QAAID,QAAO,KAAKC,QAAO,EAAG,CAAAD,MAAK,EAAE;AACjC,UAAM,MAAM,IAAI,KAAK,MAAMA,KAAIC,GAAE;AACjC,MAAE,UAAU,IAAI;AAChB,MAAE,SAAS,IAAI;AACf,MAAE;AACF,MAAE,SAASD,MAAK,MAAM,IAAI;AAC1B,MAAE,SAASC,MAAK,MAAM,IAAI;AAC1B,MAAE,UAAU;AACZ,OAAG,SAAS;AAAA,EACd;AAGA,MAAI,EAAE,UAAU,GAAG;AACjB,MAAE,KAAK,EAAE;AACT,MAAE,KAAK,EAAE;AACT,MAAE,WAAW;AAAA,EACf,WAAW,EAAE,YAAY,GAAG;AAC1B,UAAM,SAAS,MAAM,QAAQ,IAAI;AACjC,UAAM,QAAQ,EAAE,WAAY,MAAM,UAAU,IAAI,IAAI,cAAc,IAAI,iBAAkB,MAAM,UAAU,IAAI,IAAI,WAAW,IAAI;AAC/H,MAAE,KAAK,SAAS,EAAE,IAAI,QAAQ,QAAQ,EAAE;AACxC,QAAI,MAAM,UAAU,EAAG,GAAE,SAAS,MAAM,QAAQ,IAAI,IAAI;AAAA,EAC1D;AAGA,MAAI,EAAE,WAAW,KAAK,CAAC,EAAE,UAAU;AACjC,QAAI,IAAI,IAAI;AACZ,QAAI,KAAK,IAAI,EAAE,EAAE,IAAI,IAAI,iBAAiB,MAAM,YAAY,EAAE,QAAS,MAAK,IAAI;AAChF,MAAE,KAAK,KAAK,IAAI,EAAE,KAAK,IAAI,IAAI,IAAI,OAAO;AAC1C,QAAI,EAAE,WAAW,KAAK,EAAE,KAAK,IAAI,oBAAoB,MAAM,UAAU,EAAE,OAAQ,GAAE,KAAK,IAAI;AAAA,EAC5F;AAGA,MAAI,EAAE,WAAW,CAAC,MAAM,YAAY,EAAE,KAAK,GAAG;AAC5C,MAAE,MAAM,IAAI;AACZ,MAAE,UAAU;AAAA,EACd;AAGA,MAAI,EAAE,SAAS,KAAK,EAAE,WAAW,GAAG;AAClC,QAAI,EAAE,YAAY,EAAE,SAAS,GAAG;AAC9B,QAAE,KAAK,CAAC,IAAI;AAEZ,QAAE,MAAM,EAAE;AACV,UAAI,EAAE,UAAU,EAAG,GAAE,MAAM,EAAE;AAC7B,QAAE,UAAU;AACZ,QAAE,SAAS;AACX,QAAE,SAAS;AACX,QAAE,WAAW;AACb,SAAG,SAAS;AAAA,IACd,WAAW,EAAE,WAAW,KAAK,IAAI,eAAe,GAAG;AACjD,QAAE,KAAK,CAAC,EAAE,SAAS,IAAI;AACvB,QAAE,KAAK,CAAC,IAAI;AACZ,QAAE,SAAS,CAAC,EAAE;AACd,QAAE,UAAU;AACZ,QAAE,SAAS;AACX,QAAE,WAAW,IAAI;AACjB,SAAG,aAAa;AAChB,SAAG,SAAS;AAAA,IACd,WAAW,EAAE,eAAe,GAAG;AAC7B,QAAE,KAAK,CAAC,IAAI,eAAe,IAAI;AAC/B,QAAE;AACF,QAAE,UAAU;AACZ,QAAE,SAAS;AACX,SAAG,SAAS;AACZ,SAAG,YAAY;AAAA,IACjB;AAAA,EACF;AAKA,QAAM,cAAc,MAAM,QAAQ,KAAK,EAAE,UAAU;AACnD,MAAI,KAAK,EAAE,KAAK,KAAK,EAAE,UAAU,MAAM,EAAE,WAAW,IAAI;AACxD,MAAI,KAAK,EAAE,KAAK,KAAK,KAAK,IAAI,GAAG,EAAE,OAAO,IAAI,MAAM,EAAE,WAAW,IAAI;AACrE,MAAI,MAAM,SAAS,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,IAAI,OAAO,GAAG,IAAI,OAAO,GAAG,IAAI,IAAI,EAAE,QAAQ,WAAW,YAAY,CAAC;AAGnH,MAAI,IAAI,aAAa,EAAE,KAAK,KAAK,EAAE,WAAW,GAAG;AAC/C,UAAM,OAAO,YAAY,KAAK,WAAW,IAAI,GAAG,IAAI,GAAG,IAAI,OAAO,IAAI,QAAQ,IAAI,IAAI,eAAe;AACrG,QAAI,SAAS,MAAM;AACjB,YAAM,SAAS,KAAK,EAAE,GAAG,MAAM,GAAG,IAAI,GAAG,GAAG,IAAI,OAAO,GAAG,IAAI,OAAO,GAAG,GAAG,IAAI,EAAE,QAAQ,WAAW,YAAY,CAAC;AACjH,UAAI,IAAI;AAAA,IACV;AAAA,EACF;AAGA,MAAI,IAAI,QAAQ,EAAE,UAAU,KAAK,KAAK,IAAI,EAAE,MAAM,IAAI,GAAG;AACvD,UAAM,OAAO,YAAY,KAAK,WAAW,IAAI,GAAG,IAAI,GAAG,IAAI,OAAO,IAAI,QAAQ,IAAI,IAAI,eAAe;AACrG,QAAI,SAAS,MAAM;AACjB,YAAM,SAAS,KAAK,EAAE,GAAG,IAAI,GAAG,GAAG,MAAM,GAAG,IAAI,OAAO,GAAG,IAAI,OAAO,GAAG,IAAI,GAAG,EAAE,QAAQ,WAAW,YAAY,CAAC;AACjH,UAAI,IAAI;AAAA,IACV;AAAA,EACF;AAEA,IAAE,IAAI,IAAI;AACV,IAAE,IAAI,IAAI;AACV,MAAI,IAAI,QAAQ,EAAE,KAAK,EAAG,GAAE,KAAK;AACjC,MAAI,IAAI,WAAW;AACjB,MAAE,KAAK,KAAK,IAAI,EAAE,IAAI,CAAC;AACvB,MAAE,UAAU;AAAA,EACd;AACA,MAAI,IAAI,QAAQ,EAAE,WAAW,EAAG,GAAE,KAAK;AACvC,IAAE,SAAS,IAAI,aAAa,KAAK,IAAI,cAAc,IAAI,UAAU,KAAK,WAAW,EAAE,GAAG,EAAE,GAAG,IAAI,OAAO,IAAI,MAAM;AAChH,IAAE,WAAW,IAAI;AAGjB,MAAI,EAAE,UAAU;AACd,MAAE,SAAS,IAAI;AACf,MAAE,aAAa,IAAI;AACnB,MAAE,eAAe,IAAI;AACrB,QAAI,CAAC,YAAa,IAAG,SAAS;AAC9B,QAAI,IAAI,cAAc,GAAG;AACvB,YAAM,IAAI,UAAU,IAAI,UAAU;AAClC,QAAE,UAAU,EAAE;AACd,QAAE,UAAU,EAAE;AAEd,QAAE,IAAI,EAAE,IAAI,IAAI;AAAA,IAClB,OAAO;AACL,QAAE,UAAU;AACZ,QAAE,UAAU;AAAA,IACd;AACA,QAAI,EAAE,KAAK,EAAG,GAAE,KAAK;AACrB,MAAE,UAAU;AAAA,EACd,WAAW,eAAe,EAAE,YAAY,GAAG;AAAA,EAE3C;AAEA,MAAI,IAAI,QAAQ;AACd,MAAE,OAAO;AACT,OAAG,OAAO;AAAA,EACZ;AACA,SAAO;AACT;AAQO,SAAS,WAAW,MAAwB,oBAA4B;AAC7E,SAAQ,IAAI,eAAe,IAAI,gBAAiB,IAAI,IAAI;AAC1D;AAGO,SAAS,YAAY,MAAwB,oBAA4B;AAC9E,SAAQ,IAAI,IAAI,eAAgB,IAAI;AACtC;AAGO,SAAS,aAAa,MAAwB,oBAA4B;AAC/E,SAAO,IAAI,WAAW,YAAY,GAAG;AACvC;AAGO,SAAS,iBAAiB,MAAwB,oBAA4B;AACnF,SAAO,aAAa,GAAG,KAAK,IAAI,YAAY,IAAI,YAAY,IAAI;AAClE;AAGA,SAAS,YAAY,KAAkB,QAAqB,GAAW,GAAW,GAAW,GAAW,IAAY,OAA8B;AAChJ,WAASC,KAAI,GAAGA,MAAK,OAAOA,MAAK;AAC/B,eAAW,OAAO,CAAC,GAAG,EAAE,GAAG;AACzB,YAAM,KAAK,IAAI,MAAMA;AACrB,UAAI,CAAC,YAAY,KAAK,IAAI,IAAI,IAAI,GAAG,GAAG,MAAM,KAAK,CAAC,YAAY,KAAK,IAAI,GAAG,GAAG,GAAG,MAAM,EAAG,QAAO;AAAA,IACpG;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,YAAY,KAAkB,QAAqB,GAAW,GAAW,GAAW,GAAW,IAAY,OAA8B;AAChJ,WAASA,KAAI,GAAGA,MAAK,OAAOA,MAAK;AAC/B,eAAW,OAAO,CAAC,IAAI,CAAC,GAAG;AACzB,YAAM,KAAK,IAAI,MAAMA;AACrB,UAAI,CAAC,YAAY,KAAK,IAAI,IAAI,IAAI,GAAG,GAAG,MAAM,KAAK,CAAC,YAAY,KAAK,GAAG,IAAI,GAAG,GAAG,MAAM,EAAG,QAAO;AAAA,IACpG;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,UAAU,KAAkB,QAAqB,GAAW,GAAW,GAAW,GAAmB;AAC5G,MAAI,YAAY,KAAK,IAAI,GAAG,GAAG,GAAG,GAAG,MAAM,EAAG,QAAO;AACrD,MAAI,YAAY,KAAK,IAAI,GAAG,GAAG,GAAG,GAAG,MAAM,EAAG,QAAO;AACrD,SAAO;AACT;;;AC7VO,IAAM,cAAN,MAAqB;AAAA,EAClB,QAAQ,oBAAI,IAAiB;AAAA,EAC7B,SAAS,oBAAI,IAAa;AAAA,EACjB;AAAA,EAEjB,YAAY,WAAW,IAAI;AACzB,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,QAAc;AACZ,SAAK,MAAM,MAAM;AACjB,SAAK,OAAO,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,OAAe;AACjB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEQ,IAAI,IAAY,IAAoB;AAE1C,YAAQ,KAAK,SAAS,SAAS,KAAK;AAAA,EACtC;AAAA,EAEA,OAAO,MAAS,MAAkB;AAChC,SAAK,OAAO,IAAI,MAAM,IAAI;AAC1B,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,KAAK,MAAM,KAAK,IAAI,EAAE;AACjC,UAAM,KAAK,KAAK,OAAO,KAAK,IAAI,KAAK,KAAK,EAAE;AAC5C,UAAM,KAAK,KAAK,MAAM,KAAK,IAAI,EAAE;AACjC,UAAM,KAAK,KAAK,OAAO,KAAK,IAAI,KAAK,KAAK,EAAE;AAC5C,aAAS,KAAK,IAAI,MAAM,IAAI;AAC1B,eAAS,KAAK,IAAI,MAAM,IAAI,MAAM;AAChC,cAAM,IAAI,KAAK,IAAI,IAAI,EAAE;AACzB,cAAM,OAAO,KAAK,MAAM,IAAI,CAAC;AAC7B,YAAI,KAAM,MAAK,KAAK,IAAI;AAAA,YACnB,MAAK,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC;AAAA,MAC/B;AAAA,EACJ;AAAA;AAAA,EAGA,MAAM,MAAiB;AACrB,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,KAAK,MAAM,KAAK,IAAI,EAAE;AACjC,UAAM,KAAK,KAAK,OAAO,KAAK,IAAI,KAAK,KAAK,EAAE;AAC5C,UAAM,KAAK,KAAK,MAAM,KAAK,IAAI,EAAE;AACjC,UAAM,KAAK,KAAK,OAAO,KAAK,IAAI,KAAK,KAAK,EAAE;AAC5C,UAAM,OAAO,oBAAI,IAAO;AACxB,UAAM,MAAW,CAAC;AAClB,aAAS,KAAK,IAAI,MAAM,IAAI;AAC1B,eAAS,KAAK,IAAI,MAAM,IAAI,MAAM;AAChC,cAAM,OAAO,KAAK,MAAM,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;AAC5C,YAAI,CAAC,KAAM;AACX,mBAAW,QAAQ,MAAM;AACvB,cAAI,KAAK,IAAI,IAAI,EAAG;AACpB,eAAK,IAAI,IAAI;AACb,gBAAM,IAAI,KAAK,OAAO,IAAI,IAAI;AAC9B,cAAI,EAAE,IAAI,KAAK,IAAI,KAAK,KAAK,EAAE,IAAI,EAAE,IAAI,KAAK,KAAK,EAAE,IAAI,KAAK,IAAI,KAAK,KAAK,EAAE,IAAI,EAAE,IAAI,KAAK,EAAG,KAAI,KAAK,IAAI;AAAA,QAC/G;AAAA,MACF;AACF,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,YAAY,GAAW,GAAW,QAAqB;AACrD,UAAM,OAAO,KAAK,MAAM,EAAE,GAAG,IAAI,QAAQ,GAAG,IAAI,QAAQ,GAAG,SAAS,GAAG,GAAG,SAAS,EAAE,CAAC;AACtF,WAAO,KAAK,OAAO,CAAC,SAAS;AAC3B,YAAM,IAAI,KAAK,OAAO,IAAI,IAAI;AAC9B,YAAM,KAAK,KAAK,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/C,YAAM,KAAK,KAAK,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/C,cAAQ,IAAI,OAAO,IAAI,OAAO,IAAI,OAAO,IAAI,OAAO,SAAS;AAAA,IAC/D,CAAC;AAAA,EACH;AACF;;;AC7DO,SAAS,aAAa,KAAkB,IAAY,IAAY,IAAY,IAAoB;AACrG,QAAM,KAAK,IAAI;AACf,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,UAAU,KAAK,MAAM,IAAI,EAAE;AACjC,MAAI,YAAY,EAAG,QAAO,EAAE,SAAS,OAAO,GAAG,IAAI,GAAG,IAAI,MAAM,EAAE;AAClE,QAAM,OAAO,KAAK;AAClB,QAAM,OAAO,KAAK;AAElB,MAAI,KAAK,KAAK,MAAM,KAAK,EAAE;AAC3B,MAAI,KAAK,KAAK,MAAM,KAAK,EAAE;AAC3B,QAAM,QAAQ,OAAO,IAAI,IAAI;AAC7B,QAAM,QAAQ,OAAO,IAAI,IAAI;AAC7B,QAAM,UAAU,SAAS,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI;AACnD,QAAM,UAAU,SAAS,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI;AACnD,MAAI,QAAQ,SAAS,KAAK,OAAO,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MAAM,KAAK,IAAI,IAAI,IAAI;AAC3F,MAAI,QAAQ,SAAS,KAAK,OAAO,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MAAM,KAAK,IAAI,IAAI,IAAI;AAE3F,MAAI,IAAI;AAER,WAAS,QAAQ,GAAG,QAAQ,KAAK,SAAS;AACxC,QAAI,QAAQ,OAAO;AACjB,UAAI;AACJ,eAAS;AACT,YAAM;AAAA,IACR,OAAO;AACL,UAAI;AACJ,eAAS;AACT,YAAM;AAAA,IACR;AACA,QAAI,KAAK,QAAS,QAAO,EAAE,SAAS,OAAO,GAAG,IAAI,GAAG,IAAI,MAAM,QAAQ;AACvE,QAAI,OAAO,KAAK,IAAI,EAAE,MAAM,KAAK,OAAO;AACtC,aAAO,EAAE,SAAS,MAAM,GAAG,KAAK,OAAO,GAAG,GAAG,KAAK,OAAO,GAAG,MAAM,EAAE;AAAA,IACtE;AAAA,EACF;AACA,SAAO,EAAE,SAAS,MAAM,GAAG,KAAK,OAAO,GAAG,GAAG,KAAK,OAAO,GAAG,MAAM,EAAE;AACtE;AAGO,SAAS,YAAY,KAAkB,IAAY,IAAY,IAAY,IAAqB;AACrG,SAAO,CAAC,aAAa,KAAK,IAAI,IAAI,IAAI,EAAE,EAAE;AAC5C;AAMO,SAAS,aAAa,KAAkB,IAAY,IAAY,OAAe,OAAe,KAAa,OAAe,IAAY,IAAqB;AAChK,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,IAAI,KAAK,MAAM,IAAI,EAAE;AAC3B,MAAI,IAAI,SAAS,MAAM,EAAG,QAAO;AACjC,QAAM,OAAO,KAAK,QAAQ,KAAK,SAAS;AACxC,MAAI,MAAM,KAAK,IAAI,MAAM,CAAC,EAAG,QAAO;AACpC,SAAO,YAAY,KAAK,IAAI,IAAI,IAAI,EAAE;AACxC;;;ACUO,SAAS,aAAa,MAAoC;AAC/D,SAAO,KACJ,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAU,EAC7B,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAC7C,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AACnB;;;ACjFA,IAAM,IAAI,CAAC,MAAuB,OAAO,UAAU,CAAC,IAAI,OAAO,CAAC,KAAK,KAAK,MAAM,IAAI,GAAI,IAAI,KAAM,SAAS;AAE3G,SAAS,OAAO,GAAsB;AACpC,SAAO,UAAU,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC3E;AAEA,SAAS,WAAW,GAAkB;AACpC,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,SAAS,EAAE,QAAQ,MAAM,GAAG;AACvC,MAAI,EAAE,QAAQ;AACZ,UAAM,KAAK,WAAW,EAAE,MAAM,GAAG;AACjC,UAAM,KAAK,iBAAiB,EAAE,EAAE,eAAe,CAAC,CAAC,GAAG;AACpD,QAAI,EAAE,MAAO,OAAM,KAAK,gDAAgD;AAAA,EAC1E;AACA,MAAI,EAAE,YAAY,UAAa,EAAE,YAAY,EAAG,OAAM,KAAK,YAAY,EAAE,EAAE,OAAO,CAAC,GAAG;AACtF,SAAO,MAAM,KAAK,GAAG;AACvB;AAEA,SAAS,WAAW,GAAmB;AACrC,SAAO,EAAE,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM;AAC5E;AAEA,SAAS,aAAa,GAAwB;AAC5C,QAAM,KAAK,cAAc,OAAO,EAAE,SAAS,CAAC;AAC5C,QAAM,QAAQ,WAAW,CAAC;AAC1B,UAAQ,EAAE,MAAM;AAAA,IACd,KAAK;AACH,aAAO,YAAY,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,QAAQ,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK;AAAA,IAC7H,KAAK;AACH,aAAO,eAAe,EAAE,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,KAAK;AAAA,IAClF,KAAK,QAAQ;AACX,YAAM,MAAM,CAAC;AACb,eAAS,IAAI,GAAG,IAAI,EAAE,OAAO,QAAQ,KAAK,EAAG,KAAI,KAAK,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE;AAC/F,YAAM,MAAM,EAAE,SAAS,YAAY;AACnC,aAAO,IAAI,GAAG,YAAY,IAAI,KAAK,GAAG,CAAC,KAAK,EAAE,IAAI,KAAK;AAAA,IACzD;AAAA,IACA,KAAK;AACH,aAAO,YAAY,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK;AAAA,IACxC,KAAK,QAAQ;AACX,YAAM,SAAS,EAAE,UAAU,WAAW,WAAW,EAAE,UAAU,UAAU,QAAQ;AAC/E,YAAM,OAAO,EAAE,OAAO,iBAAiB,EAAE,IAAI,MAAM;AACnD,YAAM,SAAS,EAAE,SAAS,iBAAiB,EAAE,MAAM,MAAM;AACzD,YAAM,OAAO,EAAE,QAAQ;AACvB,aAAO,YAAY,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,gBAAgB,EAAE,EAAE,IAAI,CAAC,kBAAkB,MAAM,+BAA+B,IAAI,GAAG,MAAM,UAAU,IAAI,IAAI,EAAE,YAAY,UAAa,EAAE,YAAY,IAAI,aAAa,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,WAAW,EAAE,IAAI,CAAC;AAAA,IAClQ;AAAA,IACA,KAAK;AACH,aAAO,gBAAgB,EAAE,IAAI,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,YAAY,UAAa,EAAE,YAAY,IAAI,aAAa,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE;AAAA,EAC1L;AACF;AAGO,SAAS,mBAAmB,UAAiC;AAClE,SAAO,aAAa,QAAQ,EAAE,IAAI,YAAY,EAAE,KAAK,EAAE;AACzD;AAGO,SAAS,kBACd,UACA,OACA,QACA,aAAa,WACL;AACR,SACE,wDAAwD,KAAK,IAAI,MAAM,YAAY,KAAK,aAAa,MAAM,8BAC/E,KAAK,aAAa,MAAM,WAAW,UAAU,QACzE,mBAAmB,QAAQ,IAC3B;AAEJ;;;ACpEA,IAAM,QAAQ;AAEP,IAAM,cAAN,MAAsC;AAAA,EAClC;AAAA,EACA;AAAA,EACD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,QAAwB;AAClC,SAAK,QAAQ,OAAO;AACpB,SAAK,SAAS,OAAO;AACrB,SAAK,aAAa,OAAO,cAAc;AAEvC,SAAK,MAAM,SAAS,gBAAgB,OAAO,KAAK;AAChD,SAAK,IAAI,aAAa,WAAW,OAAO,KAAK,KAAK,IAAI,KAAK,MAAM,EAAE;AACnE,SAAK,IAAI,aAAa,uBAAuB,eAAe;AAC5D,SAAK,IAAI,MAAM,QAAQ;AACvB,SAAK,IAAI,MAAM,SAAS;AACxB,SAAK,IAAI,MAAM,UAAU;AAEzB,SAAK,KAAK,SAAS,gBAAgB,OAAO,MAAM;AAChD,SAAK,GAAG,aAAa,KAAK,GAAG;AAC7B,SAAK,GAAG,aAAa,KAAK,GAAG;AAC7B,SAAK,GAAG,aAAa,SAAS,OAAO,KAAK,KAAK,CAAC;AAChD,SAAK,GAAG,aAAa,UAAU,OAAO,KAAK,MAAM,CAAC;AAClD,SAAK,GAAG,aAAa,QAAQ,KAAK,UAAU;AAC5C,SAAK,IAAI,YAAY,KAAK,EAAE;AAE5B,SAAK,QAAQ,SAAS,gBAAgB,OAAO,GAAG;AAChD,SAAK,IAAI,YAAY,KAAK,KAAK;AAAA,EACjC;AAAA,EAEA,MAAM,QAA2B;AAC/B,WAAO,YAAY,KAAK,GAAG;AAAA,EAC7B;AAAA,EAEA,KAAK,UAA+B;AAGlC,SAAK,MAAM,YAAY,mBAAmB,QAAQ;AAAA,EACpD;AAAA,EAEA,cAAc,OAAqB;AACjC,SAAK,aAAa;AAClB,SAAK,GAAG,aAAa,QAAQ,KAAK;AAAA,EACpC;AAAA,EAEA,IAAI,UAAyB;AAC3B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,UAAgB;AACd,SAAK,IAAI,OAAO;AAAA,EAClB;AACF;;;AC1DO,IAAM,mBAAN,MAA2C;AAAA,EACvC;AAAA,EACA;AAAA,EACD;AAAA,EACA;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EAEd,YAAY,QAAwB;AAClC,SAAK,QAAQ,OAAO;AACpB,SAAK,SAAS,OAAO;AACrB,SAAK,aAAa,OAAO,cAAc;AACvC,SAAK,SAAS,SAAS,cAAc,QAAQ;AAC7C,SAAK,OAAO,MAAM,QAAQ;AAC1B,SAAK,OAAO,MAAM,SAAS;AAC3B,SAAK,OAAO,MAAM,UAAU;AAC5B,UAAM,MAAM,KAAK,OAAO,WAAW,IAAI;AACvC,QAAI,CAAC,IAAK,OAAM,IAAI,MAAM,sCAAsC;AAChE,SAAK,MAAM;AACX,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,MAAM,QAA2B;AAC/B,WAAO,YAAY,KAAK,MAAM;AAC9B,SAAK,OAAO;AAAA,EACd;AAAA,EAEQ,SAAe;AACrB,SAAK,MAAM,KAAK,IAAI,GAAG,WAAW,oBAAoB,CAAC;AACvD,SAAK,OAAO,QAAQ,KAAK,MAAM,KAAK,QAAQ,KAAK,GAAG;AACpD,SAAK,OAAO,SAAS,KAAK,MAAM,KAAK,SAAS,KAAK,GAAG;AAAA,EACxD;AAAA,EAEA,KAAK,UAA+B;AAClC,UAAM,MAAM,KAAK;AACjB,QAAI,aAAa,KAAK,KAAK,GAAG,GAAG,KAAK,KAAK,GAAG,CAAC;AAC/C,QAAI,YAAY,KAAK;AACrB,QAAI,SAAS,GAAG,GAAG,KAAK,OAAO,KAAK,MAAM;AAE1C,eAAW,KAAK,aAAa,QAAQ,GAAG;AACtC,UAAI,KAAK;AACT,YAAM,IAAI,EAAE;AACZ,UAAI,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAC1C,UAAI,cAAe,EAAY,WAAW;AAC1C,WAAK,MAAM,KAAK,CAAC;AACjB,UAAI,QAAQ;AAAA,IACd;AAAA,EACF;AAAA,EAEQ,OAAO,KAA+B,GAAgB;AAC5D,QAAI,EAAE,QAAQ,EAAE,SAAS,QAAQ;AAC/B,UAAI,YAAY,EAAE;AAClB,UAAI,KAAK;AAAA,IACX;AACA,QAAI,EAAE,QAAQ;AACZ,UAAI,cAAc,EAAE;AACpB,UAAI,YAAY,EAAE,eAAe;AACjC,UAAI,EAAE,OAAO;AACX,YAAI,WAAW;AACf,YAAI,UAAU;AAAA,MAChB;AACA,UAAI,OAAO;AAAA,IACb;AAAA,EACF;AAAA,EAEQ,MAAM,KAA+B,GAAsB;AACjE,YAAQ,EAAE,MAAM;AAAA,MACd,KAAK;AACH,YAAI,UAAU;AACd,YAAI,EAAE,EAAG,MAAK,UAAU,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAAA,YAC/C,KAAI,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAChC,aAAK,OAAO,KAAK,CAAC;AAClB;AAAA,MACF,KAAK;AACH,YAAI,UAAU;AACd,YAAI,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,GAAG,KAAK,KAAK,CAAC;AAC5C,aAAK,OAAO,KAAK,CAAC;AAClB;AAAA,MACF,KAAK;AACH,YAAI,UAAU;AACd,iBAAS,IAAI,GAAG,IAAI,EAAE,OAAO,QAAQ,KAAK,GAAG;AAC3C,cAAI,MAAM,EAAG,KAAI,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,IAAI,CAAC,CAAC;AAAA,cAC/C,KAAI,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,IAAI,CAAC,CAAC;AAAA,QAC9C;AACA,YAAI,EAAE,OAAQ,KAAI,UAAU;AAC5B,aAAK,OAAO,KAAK,CAAC;AAClB;AAAA,MACF,KAAK;AACH;AACE,gBAAM,IAAI,IAAI,OAAO,EAAE,CAAC;AACxB,cAAI,EAAE,QAAQ,EAAE,SAAS,QAAQ;AAC/B,gBAAI,YAAY,EAAE;AAClB,gBAAI,KAAK,CAAC;AAAA,UACZ;AACA,cAAI,EAAE,QAAQ;AACZ,gBAAI,cAAc,EAAE;AACpB,gBAAI,YAAY,EAAE,eAAe;AACjC,gBAAI,EAAE,OAAO;AACX,kBAAI,WAAW;AACf,kBAAI,UAAU;AAAA,YAChB;AACA,gBAAI,OAAO,CAAC;AAAA,UACd;AAAA,QACF;AACA;AAAA,MACF,KAAK;AACH,YAAI,YAAY,EAAE,QAAQ;AAC1B,YAAI,OAAO,GAAG,EAAE,UAAU,GAAG,IAAI,EAAE,IAAI,MAAM,EAAE,QAAQ,YAAY;AACnE,YAAI,YAAY,EAAE,SAAS;AAC3B,YAAI,eAAe;AACnB,YAAI,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AAC7B;AAAA,MACF,KAAK;AACH;AAAA,IACJ;AAAA,EACF;AAAA,EAEQ,UAAU,KAA+B,GAAW,GAAW,GAAW,GAAW,GAAiB;AAC5G,UAAM,KAAK,KAAK,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACnC,QAAI,OAAO,IAAI,IAAI,CAAC;AACpB,QAAI,MAAM,IAAI,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,EAAE;AACpC,QAAI,MAAM,IAAI,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,EAAE;AACpC,QAAI,MAAM,GAAG,IAAI,GAAG,GAAG,GAAG,EAAE;AAC5B,QAAI,MAAM,GAAG,GAAG,IAAI,GAAG,GAAG,EAAE;AAC5B,QAAI,UAAU;AAAA,EAChB;AAAA,EAEA,IAAI,UAA6B;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,UAAgB;AACd,SAAK,OAAO,OAAO;AAAA,EACrB;AACF;;;ACnIO,IAAM,mBAAN,MAA2C;AAAA,EACvC;AAAA,EACA;AAAA,EACD;AAAA,EACA,OAAsB,CAAC;AAAA,EAC/B,aAAa;AAAA,EAEb,YAAY,QAAwB;AAClC,SAAK,QAAQ,OAAO;AACpB,SAAK,SAAS,OAAO;AACrB,SAAK,aAAa,OAAO,cAAc;AAAA,EACzC;AAAA,EAEA,KAAK,UAA+B;AAClC,SAAK,OAAO;AACZ,SAAK;AAAA,EACP;AAAA;AAAA,EAGA,IAAI,WAA0B;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,MAAM,MAAmC;AACvC,WAAO,KAAK,KAAK,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI,EAAE;AAAA,EAClD;AAAA;AAAA,EAGA,cAAsB;AACpB,WAAO,kBAAkB,KAAK,MAAM,KAAK,OAAO,KAAK,QAAQ,KAAK,UAAU;AAAA,EAC9E;AACF;;;ACvBO,IAAM,SAAkB;AAAA,EAC7B,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AACzE;AAEO,IAAM,OAAgB;AAAA,EAC3B,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AACzE;AAEO,IAAM,QAAiB;AAAA,EAC5B,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AACzE;AAEO,IAAM,WAAoC,EAAE,QAAQ,QAAQ,MAAM,MAAM,OAAO,MAAM;AAGrF,SAAS,IAAI,GAAW,GAAW,GAAmB;AAC3D,QAAM,KAAK,SAAS,CAAC;AACrB,QAAM,KAAK,SAAS,CAAC;AACrB,QAAM,IAAI,KAAK,MAAM,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;AAChD,QAAM,IAAI,KAAK,MAAM,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;AAChD,QAAM,KAAK,KAAK,MAAM,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;AACjD,SAAO,SAAS,GAAG,GAAG,EAAE;AAC1B;AAEO,SAAS,UAAU,KAAa,OAAuB;AAC5D,QAAM,CAAC,GAAG,GAAG,CAAC,IAAI,SAAS,GAAG;AAC9B,SAAO,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK;AACxC;AAEA,SAAS,SAAS,KAAuC;AACvD,MAAI,IAAI,IAAI,QAAQ,KAAK,EAAE;AAC3B,MAAI,EAAE,WAAW,EAAG,KAAI,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,KAAK,EAAE;AAC7D,QAAMC,KAAI,SAAS,GAAG,EAAE;AACxB,SAAO,CAAEA,MAAK,KAAM,KAAMA,MAAK,IAAK,KAAKA,KAAI,GAAG;AAClD;AACA,SAAS,SAAS,GAAW,GAAW,GAAmB;AACzD,SAAO,MAAM,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AACxG;;;AC1EO,SAAS,eAAe,OAAe,QAAgB,WAAW,GAAa;AACpF,QAAM,MAAgB,CAAC;AACvB,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,IAAI,WAAY,IAAI,QAAS;AACnC,QAAI,KAAK,KAAK,IAAI,CAAC,IAAI,QAAQ,KAAK,IAAI,CAAC,IAAI,MAAM;AAAA,EACrD;AACA,SAAO;AACT;AAGO,SAAS,KAAK,QAAgB,OAAe,OAAe,WAAW,CAAC,KAAK,KAAK,GAAa;AACpG,QAAM,MAAgB,CAAC;AACvB,WAAS,IAAI,GAAG,IAAI,SAAS,GAAG,KAAK;AACnC,UAAM,IAAI,IAAI,MAAM,IAAI,QAAQ;AAChC,UAAM,IAAI,WAAY,KAAK,SAAS,KAAM;AAC1C,QAAI,KAAK,KAAK,IAAI,CAAC,IAAI,GAAG,KAAK,IAAI,CAAC,IAAI,CAAC;AAAA,EAC3C;AACA,SAAO;AACT;AAGO,SAAS,SAAS,KAAU,QAAgB,SAAS,MAAM,QAAQ,GAAW;AACnF,QAAM,MAAc,CAAC;AACrB,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,IAAK,IAAI,QAAS;AACxB,UAAM,IAAI,UAAU,IAAI,SAAS,IAAI,MAAM,IAAI,SAAS;AACxD,QAAI,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC,IAAI,GAAG,GAAG,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;AAAA,EACrD;AACA,SAAO,iBAAiB,GAAG;AAC7B;AAGO,SAAS,iBAAiB,QAAgB,UAAU,GAAW;AACpE,QAAM,OAAO,OAAO;AACpB,MAAI,OAAO,EAAG,QAAO;AACrB,QAAM,IAAI,CAAC,MAAc,QAAS,IAAI,OAAQ,QAAQ,IAAI;AAC1D,QAAM,IAAI,CAAC,MAAc,KAAK,MAAM,IAAI,GAAG,IAAI;AAC/C,MAAI,IAAI,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;AACnC,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,UAAM,KAAK,EAAE,IAAI,CAAC;AAClB,UAAM,KAAK,EAAE,CAAC;AACd,UAAM,KAAK,EAAE,IAAI,CAAC;AAClB,UAAM,KAAK,EAAE,IAAI,CAAC;AAClB,UAAM,MAAM,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK;AACzC,UAAM,MAAM,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK;AACzC,UAAM,MAAM,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK;AACzC,UAAM,MAAM,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK;AACzC,SAAK,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAAA,EACzE;AACA,SAAO,IAAI;AACb;AAGO,SAAS,eAAe,QAAgB,UAAU,GAAW;AAClE,QAAM,OAAO,OAAO;AACpB,MAAI,OAAO,EAAG,QAAO;AACrB,QAAM,IAAI,CAAC,MAAc,KAAK,MAAM,IAAI,GAAG,IAAI;AAC/C,MAAI,IAAI,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;AAC7C,WAAS,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK;AACjC,UAAM,KAAK,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC;AACpC,UAAM,KAAK,OAAO,CAAC;AACnB,UAAM,KAAK,OAAO,IAAI,CAAC;AACvB,UAAM,KAAK,OAAO,KAAK,IAAI,OAAO,GAAG,IAAI,CAAC,CAAC;AAC3C,UAAM,MAAM,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK;AACzC,UAAM,MAAM,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK;AACzC,UAAM,MAAM,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK;AACzC,UAAM,MAAM,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK;AACzC,SAAK,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAAA,EACzE;AACA,SAAO;AACT;;;ACnEA,IAAM,kBAA2B,EAAE,QAAQ,KAAK,OAAO,KAAK,KAAK,KAAK,OAAO,MAAM;AAW5E,IAAM,WAAN,MAAe;AAAA,EACZ,MAA2B;AAAA,EAC3B,SAA0B;AAAA,EAC1B,YAA6B;AAAA,EAC7B,UAA2B;AAAA,EAC3B,MAAe,EAAE,GAAG,gBAAgB;AAAA,EACpC,QAAQ;AAAA,EAEhB,IAAI,YAAqB;AACvB,WAAO,OAAO,WAAW,iBAAiB,eAAe,wBAAwB;AAAA,EACnF;AAAA,EACA,IAAI,UAAmB;AACrB,WAAO,CAAC,CAAC,KAAK;AAAA,EAChB;AAAA;AAAA,EAGA,QAAc;AACZ,QAAI,KAAK,KAAK;AACZ,WAAK,KAAK,IAAI,OAAO;AACrB;AAAA,IACF;AACA,QAAI,CAAC,KAAK,UAAW;AACrB,UAAM,MACJ,WAAW,gBACV,WAAsE;AACzE,SAAK,MAAM,IAAI,IAAI;AACnB,SAAK,SAAS,KAAK,IAAI,WAAW;AAClC,SAAK,YAAY,KAAK,IAAI,WAAW;AACrC,SAAK,UAAU,KAAK,IAAI,WAAW;AACnC,SAAK,UAAU,QAAQ,KAAK,MAAM;AAClC,SAAK,QAAQ,QAAQ,KAAK,MAAM;AAChC,SAAK,OAAO,QAAQ,KAAK,IAAI,WAAW;AACxC,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,WAAW,GAA2B;AACpC,SAAK,MAAM,EAAE,GAAG,KAAK,KAAK,GAAG,EAAE;AAC/B,SAAK,aAAa;AAAA,EACpB;AAAA,EACA,aAAsB;AACpB,WAAO,EAAE,GAAG,KAAK,IAAI;AAAA,EACvB;AAAA,EAEQ,eAAqB;AAC3B,QAAI,CAAC,KAAK,OAAO,CAAC,KAAK,UAAU,CAAC,KAAK,aAAa,CAAC,KAAK,QAAS;AACnE,UAAM,IAAI,KAAK,IAAI;AACnB,SAAK,OAAO,KAAK,gBAAgB,KAAK,IAAI,QAAQ,IAAI,KAAK,IAAI,QAAQ,GAAG,IAAI;AAC9E,SAAK,UAAU,KAAK,gBAAgB,KAAK,IAAI,QAAQ,KAAK,GAAG,IAAI;AACjE,SAAK,QAAQ,KAAK,gBAAgB,KAAK,IAAI,KAAK,GAAG,IAAI;AAAA,EACzD;AAAA;AAAA,EAGA,KAAK,MAAkB;AACrB,QAAI,CAAC,KAAK,OAAO,CAAC,KAAK,QAAS;AAChC,UAAM,EAAE,MAAM,UAAU,OAAO,QAAQ,OAAO,KAAK,QAAQ,EAAE,IAAI;AACjE,UAAM,IAAI,KAAK,IAAI,cAAc;AACjC,UAAM,MAAM,KAAK,IAAI,iBAAiB;AACtC,QAAI,OAAO;AACX,QAAI,UAAU,QAAQ;AACtB,UAAM,IAAI,KAAK,IAAI,WAAW;AAC9B,MAAE,KAAK,eAAe,GAAG,CAAC;AAC1B,MAAE,KAAK,wBAAwB,MAAM,IAAI,IAAK;AAC9C,MAAE,KAAK,6BAA6B,MAAQ,IAAI,QAAQ;AACxD,QAAI,QAAQ,CAAC;AACb,MAAE,QAAQ,KAAK,OAAO;AACtB,QAAI,MAAM,CAAC;AACX,QAAI,KAAK,IAAI,WAAW,IAAI;AAAA,EAC9B;AAAA;AAAA,EAGA,KAAK,OAAqB;AACxB,eAAW,KAAK,MAAO,MAAK,KAAK,CAAC;AAAA,EACpC;AAAA;AAAA,EAGA,KAAK,OAAO,KAAW;AACrB,SAAK,KAAK,EAAE,MAAM,UAAU,MAAM,MAAM,QAAQ,MAAM,KAAK,CAAC;AAAA,EAC9D;AAAA,EACA,QAAc;AACZ,KAAC,QAAQ,QAAQ,MAAM,EAAE,QAAQ,CAAC,GAAG,MAAM,KAAK,KAAK,EAAE,MAAM,GAAG,UAAU,MAAM,IAAI,MAAM,MAAM,QAAQ,MAAM,MAAM,OAAO,IAAI,KAAK,CAAC,CAAC;AAAA,EACxI;AAAA,EACA,UAAgB;AACd,KAAC,KAAK,QAAQ,QAAQ,MAAM,EAAE,QAAQ,CAAC,GAAG,MAAM,KAAK,KAAK,EAAE,MAAM,GAAG,UAAU,KAAK,MAAM,YAAY,MAAM,MAAM,OAAO,IAAI,KAAK,CAAC,CAAC;AAAA,EACtI;AAAA,EACA,OAAa;AACX,SAAK,KAAK,EAAE,MAAM,KAAK,UAAU,MAAM,MAAM,QAAQ,MAAM,KAAK,CAAC;AAAA,EACnE;AAAA;AAAA,EAGA,aAAa,OAAO,KAAK,SAAS,CAAC,GAAG,KAAK,GAAG,GAAG,GAAS;AACxD,QAAI,CAAC,KAAK,OAAO,CAAC,KAAK,aAAa,KAAK,MAAO;AAChD,SAAK,QAAQ;AACb,UAAM,SAAS,KAAK,IAAI,mBAAmB;AAC3C,WAAO,OAAO;AACd,WAAO,UAAU,QAAQ;AACzB,WAAO,QAAQ,KAAK,SAAS;AAC7B,UAAM,MAAM,KAAK,IAAI,WAAW;AAChC,QAAI,KAAK,QAAQ;AACjB,QAAI,QAAQ,MAAM;AAClB,eAAW,QAAQ,QAAQ;AACzB,YAAM,MAAM,KAAK,IAAI,iBAAiB;AACtC,UAAI,OAAO;AACX,UAAI,UAAU,QAAQ,OAAO;AAC7B,YAAM,IAAI,KAAK,IAAI,WAAW;AAC9B,QAAE,KAAK,QAAQ,MAAM,OAAO;AAC5B,UAAI,QAAQ,CAAC;AACb,QAAE,QAAQ,GAAG;AACb,UAAI,MAAM;AAAA,IACZ;AACA,QAAI,KAAK,gBAAgB,KAAK,KAAK,IAAI,aAAa,CAAC;AAAA,EACvD;AACF;AAGO,IAAM,QAAQ,IAAI,SAAS;;;AC7GlC,IAAI,SAA8B;AAElC,IAAM,WAAW;AACjB,IAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYZ,SAAS,cAAoB;AAC3B,MAAI,OAAO,aAAa,eAAe,SAAS,eAAe,QAAQ,EAAG;AAC1E,QAAM,IAAI,SAAS,cAAc,OAAO;AACxC,IAAE,KAAK;AACP,IAAE,cAAc;AAChB,WAAS,KAAK,YAAY,CAAC;AAC7B;AAEA,IAAI,OAA2B;AAExB,SAAS,eAAe,IAAuB;AACpD,SAAO;AACT;AAGO,SAAS,WAAW,MAAgC;AACzD,MAAI,OAAO,aAAa,aAAa;AACnC,WAAO,EAAE,QAAQ;AAAA,IAAC,GAAG,SAAS,KAA+B;AAAA,EAC/D;AACA,cAAY;AACZ,aAAW;AAEX,QAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,QAAM,YAAY,WAAW,KAAK,QAAQ,QAAQ,KAAK,MAAM,GAAG,KAAK,YAAY,MAAM,KAAK,YAAY,EAAE;AAC1G,QAAM,OAAO,SAAS,cAAc,KAAK;AACzC,OAAK,YAAY;AAEjB,MAAI,KAAK,OAAO;AACd,UAAM,IAAI,SAAS,cAAc,IAAI;AACrC,MAAE,cAAc,KAAK;AACrB,SAAK,YAAY,CAAC;AAAA,EACpB;AACA,MAAI,KAAK,MAAM;AACb,UAAM,IAAI,SAAS,cAAc,KAAK;AACtC,MAAE,YAAY;AACd,MAAE,YAAY,KAAK;AACnB,SAAK,YAAY,CAAC;AAAA,EACpB;AAEA,QAAM,UAAU,KAAK,WAAW,CAAC;AACjC,MAAI,MAAM,KAAK,IAAI,GAAG,QAAQ,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC;AACzD,MAAI,MAAM,EAAG,OAAM;AACnB,QAAM,QAA6B,CAAC;AACpC,MAAI,QAAQ,QAAQ;AAClB,UAAM,OAAO,SAAS,cAAc,KAAK;AACzC,SAAK,YAAY;AACjB,YAAQ,QAAQ,CAAC,GAAG,MAAM;AACxB,YAAM,MAAM,SAAS,cAAc,QAAQ;AAC3C,UAAI,YAAY,UAAU,EAAE,UAAU,aAAa,EAAE;AACrD,UAAI,cAAc,EAAE;AACpB,UAAI,iBAAiB,SAAS,MAAM,EAAE,SAAS,CAAC;AAChD,UAAI,iBAAiB,cAAc,MAAM,OAAO,CAAC,CAAC;AAClD,WAAK,YAAY,GAAG;AACpB,YAAM,KAAK,GAAG;AAAA,IAChB,CAAC;AACD,SAAK,YAAY,IAAI;AAAA,EACvB;AAEA,WAAS,OAAO,GAAiB;AAC/B,WAAO,IAAI,MAAM,UAAU,MAAM;AACjC,UAAM,QAAQ,CAAC,IAAI,MAAM,GAAG,UAAU,OAAO,OAAO,MAAM,GAAG,CAAC;AAAA,EAChE;AACA,MAAI,MAAM,OAAQ,QAAO,GAAG;AAE5B,QAAM,QAAQ,CAAC,MAAqB;AAClC,QAAI,CAAC,MAAM,OAAQ;AACnB,QAAI,EAAE,SAAS,aAAa;AAAE,aAAO,MAAM,CAAC;AAAG,QAAE,eAAe;AAAA,IAAG,WAC1D,EAAE,SAAS,WAAW;AAAE,aAAO,MAAM,CAAC;AAAG,QAAE,eAAe;AAAA,IAAG,WAC7D,EAAE,SAAS,WAAW,EAAE,SAAS,SAAS;AAAE,cAAQ,GAAG,GAAG,SAAS;AAAG,QAAE,eAAe;AAAA,IAAG;AAAA,EACrG;AACA,WAAS,iBAAiB,WAAW,KAAK;AAE1C,QAAM,YAAY,IAAI;AACtB,GAAC,QAAQ,SAAS,MAAM,YAAY,KAAK;AAEzC,QAAM,SAAuB;AAAA,IAC3B,SAAS;AAAA,IACT,QAAQ;AACN,eAAS,oBAAoB,WAAW,KAAK;AAC7C,YAAM,OAAO;AACb,UAAI,WAAW,OAAQ,UAAS;AAAA,IAClC;AAAA,EACF;AACA,WAAS;AACT,SAAO;AACT;AAEO,SAAS,aAAmB;AACjC,UAAQ,MAAM;AAChB;;;ACrHA,IAAM,MAAM;AACZ,IAAM,WAAqB,EAAE,QAAQ,KAAK,OAAO,KAAK,KAAK,KAAK,OAAO,OAAO,YAAY,OAAO,eAAe,MAAM;AAItH,IAAM,gBAAN,MAAoB;AAAA,EACV;AAAA,EACA,OAAO,oBAAI,IAAS;AAAA,EAE5B,cAAc;AACZ,SAAK,QAAQ,KAAK,KAAK;AACvB,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,MAAgB;AACd,WAAO,EAAE,GAAG,KAAK,MAAM;AAAA,EACzB;AAAA,EAEA,IAAI,OAAgC;AAClC,SAAK,QAAQ,EAAE,GAAG,KAAK,OAAO,GAAG,MAAM;AACvC,SAAK,KAAK;AACV,SAAK,YAAY;AACjB,eAAW,MAAM,KAAK,KAAM,IAAG,KAAK,IAAI,CAAC;AAAA,EAC3C;AAAA,EAEA,UAAU,IAAqB;AAC7B,SAAK,KAAK,IAAI,EAAE;AAChB,WAAO,MAAM,KAAK,KAAK,OAAO,EAAE;AAAA,EAClC;AAAA,EAEQ,cAAoB;AAC1B,UAAM,WAAW,EAAE,QAAQ,KAAK,MAAM,QAAQ,OAAO,KAAK,MAAM,OAAO,KAAK,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,MAAM,CAAC;AAAA,EACvH;AAAA,EAEQ,OAAiB;AACvB,QAAI;AACF,YAAM,MAAM,OAAO,iBAAiB,eAAe,aAAa,QAAQ,GAAG;AAC3E,UAAI,IAAK,QAAO,EAAE,GAAG,UAAU,GAAG,KAAK,MAAM,GAAG,EAAE;AAAA,IACpD,QAAQ;AAAA,IAER;AACA,WAAO,EAAE,GAAG,SAAS;AAAA,EACvB;AAAA,EACQ,OAAa;AACnB,QAAI;AACF,mBAAa,QAAQ,KAAK,KAAK,UAAU,KAAK,KAAK,CAAC;AAAA,IACtD,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAEO,IAAM,WAAW,IAAI,cAAc;AAGnC,SAAS,mBAAyB;AACvC,MAAI,OAAO,aAAa,YAAa;AACrC,QAAM,MAAM;AACZ,QAAM,KAAK,SAAS;AACpB,MAAI,SAAS,qBAAqB,IAAI,yBAAyB;AAC7D,KAAC,SAAS,kBAAkB,IAAI,uBAAuB,KAAK,QAAQ;AAAA,EACtE,OAAO;AACL,KAAC,GAAG,qBAAqB,GAAG,0BAA0B,KAAK,EAAE;AAAA,EAC/D;AACF;;;AC9DO,IAAM,QAAN,MAAY;AAAA,EACT,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EAER,YAAY,OAAqB,CAAC,GAAG;AACnC,SAAK,OAAO;AACZ,SAAK,aAAa,CAAC,MAAqB;AACtC,UAAI,EAAE,SAAS,UAAU;AACvB,UAAE,eAAe;AACjB,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AACA,QAAI,OAAO,aAAa,YAAa,UAAS,iBAAiB,WAAW,KAAK,UAAU;AAAA,EAC3F;AAAA,EAEA,IAAI,WAAoB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,SAAe;AACb,SAAK,SAAS,KAAK,OAAO,IAAI,KAAK,MAAM;AAAA,EAC3C;AAAA,EAEA,QAAc;AACZ,QAAI,KAAK,OAAQ;AACjB,SAAK,SAAS;AACd,UAAM,KAAK,GAAG;AACd,SAAK,KAAK,UAAU,IAAI;AACxB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,SAAe;AACb,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,SAAS;AACd,eAAW;AACX,SAAK,KAAK,UAAU,KAAK;AAAA,EAC3B;AAAA,EAEQ,SAAe;AACrB,UAAM,IAAI,SAAS,IAAI;AACvB,UAAM,MAAM,CAAC,OAAe,MAAc,GAAG,KAAK,KAAK,KAAK,MAAM,IAAI,GAAG,CAAC;AAC1E,eAAW;AAAA,MACT,OAAO,KAAK,KAAK,SAAS;AAAA,MAC1B,MACE,+DACG,IAAI,UAAU,EAAE,MAAM,CAAC,SAAM,IAAI,SAAS,EAAE,KAAK,CAAC,SAAM,IAAI,OAAO,EAAE,GAAG,CAAC;AAAA,MAE9E,SAAS;AAAA,QACP,EAAE,OAAO,UAAU,SAAS,MAAM,UAAU,MAAM,KAAK,OAAO,EAAE;AAAA,QAChE,EAAE,OAAO,EAAE,QAAQ,eAAe,YAAY,UAAU,MAAM;AAAE,mBAAS,IAAI,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE,MAAM,CAAC;AAAG,eAAK,OAAO;AAAA,QAAG,EAAE;AAAA,QACjI,EAAE,OAAO,kBAAa,UAAU,MAAM;AAAE,gBAAM,IAAI,KAAK,IAAI,GAAG,SAAS,IAAI,EAAE,QAAQ,GAAG,IAAI;AAAM,mBAAS,IAAI,EAAE,OAAO,IAAI,IAAI,IAAI,EAAE,CAAC;AAAG,eAAK,OAAO;AAAA,QAAG,EAAE;AAAA,QAC3J,EAAE,OAAO,kBAAkB,UAAU,MAAM,iBAAiB,EAAE;AAAA,QAC9D,GAAI,KAAK,KAAK,YAAY,CAAC,EAAE,OAAO,WAAW,UAAU,MAAM;AAAE,eAAK,OAAO;AAAG,eAAK,KAAK,UAAW;AAAA,QAAG,EAAE,CAAC,IAAI,CAAC;AAAA,QAChH,GAAI,KAAK,KAAK,SAAS,CAAC,EAAE,OAAO,QAAQ,UAAU,MAAM;AAAE,eAAK,OAAO;AAAG,eAAK,KAAK,OAAQ;AAAA,QAAG,EAAE,CAAC,IAAI,CAAC;AAAA,MACzG;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,UAAgB;AACd,QAAI,OAAO,aAAa,YAAa,UAAS,oBAAoB,WAAW,KAAK,UAAU;AAC5F,eAAW;AAAA,EACb;AACF;;;ACrCO,SAAS,MACd,QACA,UAAwB,CAAC,GACN;AACnB,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,QAAQ,OAAO,QAAQ,QAAQ,KAAK;AAE1C,MAAI,OAAO,MAAM,KAAK,EAAG,QAAO,EAAE,UAAU,MAAM,MAAM,CAAC,GAAG,OAAO,GAAG,OAAO,GAAG,WAAW,MAAM;AAMjG,MAAI,WAAoB,CAAC,EAAE,OAAO,OAAO,MAAM,CAAC,EAAE,CAAC;AACnD,QAAM,OAAO,oBAAI,IAAY,CAAC,OAAO,IAAI,KAAK,CAAC,CAAC;AAChD,MAAI,QAAQ;AAEZ,WAAS,QAAQ,GAAG,QAAQ,YAAY,SAAS,SAAS,GAAG,SAAS;AACpE,UAAM,OAAgB,CAAC;AACvB,eAAW,EAAE,OAAO,KAAK,KAAK,UAAU;AACtC,iBAAW,QAAQ,OAAO,MAAM,KAAK,GAAG;AACtC,YAAI,SAAS,QAAS,QAAO,EAAE,UAAU,OAAO,OAAO,WAAW,KAAK;AACvE;AACA,cAAM,QAAQ,OAAO,MAAM,OAAO,IAAI;AACtC,YAAI,OAAO,SAAS,KAAK,EAAG;AAC5B,YAAI,OAAO,MAAM,KAAK,GAAG;AACvB,iBAAO,EAAE,UAAU,MAAM,MAAM,CAAC,GAAG,MAAM,IAAI,GAAG,OAAO,QAAQ,GAAG,OAAO,WAAW,MAAM;AAAA,QAC5F;AACA,cAAM,IAAI,OAAO,IAAI,KAAK;AAC1B,YAAI,CAAC,KAAK,IAAI,CAAC,GAAG;AAChB,eAAK,IAAI,CAAC;AACV,eAAK,KAAK,EAAE,OAAO,OAAO,MAAM,CAAC,GAAG,MAAM,IAAI,EAAE,CAAC;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AACA,eAAW;AAAA,EACb;AACA,SAAO,EAAE,UAAU,OAAO,OAAO,WAAW,SAAS,SAAS,EAAE;AAClE;AAMO,SAAS,eACd,QACA,UAAwB,CAAC,GACN;AACnB,QAAM,SAAS,MAAM,QAAQ,OAAO;AACpC,MAAI,CAAC,OAAO,UAAU;AACpB,UAAM,IAAI;AAAA,MACR,gBAAgB,QAAQ,SAAS,CAAC,8BACnB,OAAO,KAAK,SAAS,OAAO,YAAY,kDAA6C,EAAE;AAAA,IACxG;AAAA,EACF;AACA,SAAO;AACT;;;ACvFO,SAAS,OAAO,WAAyB,KAAwD;AACtG,QAAM,QAAQ,UAAU;AACxB,QAAM,SAAmB,CAAC;AAC1B,WAAS,IAAI,GAAG,IAAI,IAAI,OAAO,QAAQ,KAAK;AAC1C,UAAM,KAAK,aAAa,KAAK,CAAC,CAAC;AAC/B,WAAO,KAAK,MAAM,KAAK,CAAC;AAAA,EAC1B;AACA,SAAO,EAAE,WAAW,MAAM,KAAK,GAAG,OAAO;AAC3C;AAWO,SAAS,mBAAmB,WAAyB,KAAkC;AAC5F,QAAM,IAAI,OAAO,WAAW,GAAG;AAC/B,QAAM,IAAI,OAAO,WAAW,GAAG;AAC/B,MAAI,aAAa;AACjB,WAAS,IAAI,GAAG,IAAI,EAAE,OAAO,QAAQ,KAAK;AACxC,QAAI,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;AAC/B,mBAAa;AACb;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,IAAI,eAAe,MAAM,EAAE,cAAc,EAAE;AAAA,IAC3C,QAAQ,IAAI,OAAO;AAAA,IACnB;AAAA,IACA,WAAW,EAAE;AAAA,EACf;AACF;AAGO,SAAS,oBAAoB,WAAyB,KAAkC;AAC7F,QAAM,SAAS,mBAAmB,WAAW,GAAG;AAChD,MAAI,CAAC,OAAO,IAAI;AACd,UAAM,IAAI;AAAA,MACR,iEAA4D,OAAO,UAAU,OACrE,OAAO,MAAM;AAAA,IACvB;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,qBACd,WACA,KACA,QAC+C;AAC/C,QAAM,WAAW,UAAU;AAC3B,WAAS,IAAI,GAAG,IAAI,QAAQ,IAAK,UAAS,KAAK,aAAa,KAAK,CAAC,CAAC;AACnE,QAAM,OAAO,SAAS,SAAS;AAE/B,QAAM,WAAW,UAAU;AAC3B,WAAS,QAAQ,IAAI;AAErB,WAAS,IAAI,QAAQ,IAAI,IAAI,OAAO,QAAQ,KAAK;AAC/C,aAAS,KAAK,aAAa,KAAK,CAAC,CAAC;AAClC,aAAS,KAAK,aAAa,KAAK,CAAC,CAAC;AAAA,EACpC;AACA,QAAM,QAAQ,SAAS,KAAK;AAC5B,QAAM,QAAQ,SAAS,KAAK;AAC5B,SAAO,EAAE,IAAI,UAAU,OAAO,OAAO,MAAM;AAC7C;;;ACtEO,SAAS,KAAK,SAAmB,QAAyB;AAC/D,SAAO,EAAE,SAAS,OAAO;AAC3B;AAEO,SAAS,KAAK,QAAyB;AAC5C,SAAO,EAAE,SAAS,CAAC,GAAG,OAAO;AAC/B;AAUO,SAAS,oBAAoB,OAAc,QAAsC;AACtF,QAAM,SAAoC,CAAC;AAC3C,MAAI,QAAQ;AACZ,aAAW,OAAO,QAAQ;AACxB,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,IAAK,OAAM,KAAK,IAAI,WAAW,CAAC,CAAC;AACjE,aAAS,IAAI;AACb,WAAO,KAAK,MAAM,MAAM,CAAC;AAAA,EAC3B;AACA,SAAO,EAAE,aAAa,OAAO,WAAW,MAAM,KAAK,GAAG,OAAO;AAC/D;AAGO,SAAS,KAAK,OAAc,QAAgB,UAAoB,CAAC,GAAS;AAC/E,WAAS,IAAI,GAAG,IAAI,QAAQ,IAAK,OAAM,KAAK,OAAO;AACrD;;;ACnBO,SAAS,gBAAyB;AACvC,SAAO,OAAO,aAAa,eAAe,IAAI,gBAAgB,SAAS,MAAM,EAAE,IAAI,SAAS;AAC9F;AAGO,SAAS,eAAe,QAAqC;AAClE,QAAM,MAAoB;AAAA,IACxB,KAAK,QAAQ,UAAU,CAAC,GAAG;AACzB,aAAO,UAAU,IAAI;AACrB,eAAS,IAAI,GAAG,IAAI,QAAQ,IAAK,QAAO,SAAS,OAAO;AACxD,aAAO,OAAO,MAAM,MAAM;AAAA,IAC5B;AAAA,IACA,OAAO,MAAM,OAAO,MAAM,MAAM;AAAA,IAChC,MAAM,MAAM,OAAO,MAAM,KAAK;AAAA,IAC9B,MAAM,MAAM,OAAO,UAAU;AAAA,IAC7B,MAAM,KAAK,MAAM;AACf,YAAM,MAAM,OAAO,UAAU;AAC7B,UAAI;AACF,cAAM,MAAM,MAAM,MAAM,WAAW;AAAA,UACjC,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,UAC9C,MAAM,KAAK,UAAU,EAAE,MAAM,IAAI,CAAC;AAAA,QACpC,CAAC;AACD,eAAO,IAAI;AAAA,MACb,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,IAAI,MAAM,MAAM;AACd,eAAS,cAAc,IAAI,cAAc,MAAM,EAAE,MAAM,SAAS,KAAK,CAAC,CAAC;AAAA,IACzE;AAAA,IACA,IAAI,QAAQ;AACV,aAAO,OAAO;AAAA,IAChB;AAAA,EACF;AACA,EAAC,WAAoD,UAAU;AAC/D,SAAO;AACT;;;AC5CO,SAAS,eAAe,QAAiC;AAC9D,QAAM,MAAkB,CAAC;AACzB,aAAW,OAAO,QAAQ;AACxB,UAAMC,KAAI,IAAI,UAAU;AACxB,UAAMC,QAAO,IAAI,QAAQ,CAAC;AAC1B,aAAS,IAAI,GAAG,IAAID,IAAG,IAAK,KAAI,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,GAAGC,OAAM,GAAG,IAAI,KAAK,IAAI,CAAC,GAAGA,KAAI,CAAC;AAAA,EACjG;AACA,SAAO;AACT;AAaO,SAAS,MAAM,OAAc,QAAqB,OAAkE;AACzH,MAAI,SAAS;AACb,aAAW,KAAK,eAAe,MAAM,GAAG;AACtC,QAAI,SAAS,MAAM,MAAM,MAAM,CAAC,EAAG,QAAO,EAAE,QAAQ,SAAS,KAAK;AAClE,UAAM,KAAK,CAAC;AACZ;AAAA,EACF;AACA,SAAO,EAAE,QAAQ,SAAS,QAAQ,MAAM,MAAM,MAAM,CAAC,IAAI,MAAM;AACjE;;;AClBO,SAAS,cAAoD,MAAc,OAA8D;AAC9I,MAAI,IAAI;AACR,MAAI,SAAS;AACb,MAAI,MAA+B,CAAC;AAEpC,QAAM,KAAK,CAAC,UAA2B;AACrC,UAAM,MAAgB,CAAC;AACvB,UAAM,OAAO,KAAK,CAAC;AACnB,QAAI,CAAC,KAAM,QAAO;AAClB;AACA,UAAM,MAAc;AAAA,MAClB,IAAI,SAAS;AACX,eAAO;AAAA,MACT;AAAA,MACA;AAAA,MACA,OAAO;AACL;AACA,iBAAS;AACT,cAAM,CAAC;AAAA,MACT;AAAA,MACA,QAAQ;AACN,iBAAS;AACT,cAAM,CAAC;AAAA,MACT;AAAA,IACF;AACA,UAAM,OAAO,MAAM,KAAK,IAAI;AAC5B,QAAI,CAAC,KAAM,OAAM,IAAI,MAAM,wCAAwC,KAAK,IAAI,GAAG;AAC/E,SAAK,MAAM,OAAO,KAAK,GAAG;AAC1B,WAAO;AAAA,EACT;AACA,QAAM,MAAM;AACZ,MAAI,YAAY,MAAM;AACtB,MAAI,OAAO,MAAM,KAAK,KAAK;AAC3B,SAAO;AACT;AAGO,SAAS,QAAQ,IAAY,IAAY,IAAY,IAAY,KAAe,OAAO,GAAS;AACrG,MAAI,KAAK,KAAK,KAAM,KAAI,KAAK,OAAO;AAAA,WAC3B,KAAK,KAAK,KAAM,KAAI,KAAK,MAAM;AACxC,MAAI,KAAK,KAAK,KAAM,KAAI,KAAK,MAAM;AAAA,WAC1B,KAAK,KAAK,KAAM,KAAI,KAAK,IAAI;AACxC;;;ACvDO,SAAS,eAAe,OAAc,QAAkC;AAC7E,QAAM,MAAoB,CAAC,MAAM,MAAM,CAAC;AACxC,aAAW,KAAK,QAAQ;AACtB,UAAM,KAAK,CAAC;AACZ,QAAI,KAAK,MAAM,MAAM,CAAC;AAAA,EACxB;AACA,SAAO;AACT;AAGO,SAAS,WAAW,UAAwB,MAA0C;AAC3F,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,IAAK,KAAI,KAAK,SAAS,CAAC,CAAC,EAAG,QAAO;AACxE,SAAO;AACT;AAGO,SAAS,OAAO,UAAwB,KAAwB;AACrE,SAAO,SAAS,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;AACnC;AAGO,SAAS,aAAa,UAAwB,KAAuB;AAC1E,QAAM,MAAgB,CAAC;AACvB,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,IAAK,KAAI,SAAS,CAAC,EAAE,GAAG,MAAM,SAAS,IAAI,CAAC,EAAE,GAAG,EAAG,KAAI,KAAK,CAAC;AACnG,SAAO;AACT;AAGO,SAAS,YAAY,QAAkB,KAAoB,QAAQ,GAAY;AACpF,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,QAAI,QAAQ,OAAO,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,IAAI,QAAQ,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,IAAI,MAAO,QAAO;AAAA,EACnG;AACA,SAAO;AACT;AAOO,SAAS,aAAa,QAA4B;AACvD,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,SAAO,OAAO,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,SAAS,OAAO;AAC5D;AAGO,SAAS,YAAY,aAAuB,aAA6B;AAC9E,QAAM,MAAM,CAAC,GAAG,GAAG,aAAa,WAAW;AAC3C,MAAI,QAAQ;AACZ,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,IAAK,SAAQ,KAAK,IAAI,OAAO,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;AAChF,SAAO;AACT;;;AC1CO,SAAS,gBAAgB,OAAc,QAAoB,MAAgC;AAChG,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,UAAU,EAAE;AAC5C,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,KAAK,OAAO,UAAU,SAAS,EAAE,CAAC;AACjE,QAAM,QAA4C,CAAC,EAAE,OAAO,GAAG,OAAO,mBAAmB,MAAM,OAAO,CAAC,EAAE,CAAC;AAC1G,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,KAAK,OAAO,CAAC,CAAC;AACpB,SAAK,IAAI,KAAK,UAAU,KAAK,MAAM,OAAO,SAAS,GAAG;AACpD,YAAM,KAAK,EAAE,OAAO,IAAI,GAAG,OAAO,mBAAmB,MAAM,OAAO,CAAC,EAAE,CAAC;AAAA,IACxE;AAAA,EACF;AAEA,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,QAAQ,CAAC;AACvC,QAAM,KAAK,KAAK,cAAc;AAC9B,QAAM,KAAK,KAAK,MAAO,KAAK,KAAK,SAAU,KAAK,KAAK;AACrD,QAAM,SAAS;AACf,QAAM,MAAM;AACZ,QAAM,QAAQ,KAAK;AACnB,QAAM,QAAQ,KAAK,SAAS;AAC5B,QAAM,OAAO,KAAK,KAAK,MAAM,SAAS,IAAI;AAC1C,QAAM,SAAS,OAAO,QAAQ;AAC9B,QAAM,SAAS,OAAO,QAAQ;AAC9B,QAAM,KAAK,KAAK,cAAc;AAE9B,QAAM,QAAQ,MACX,IAAI,CAAC,GAAG,MAAM;AACb,UAAM,IAAI,MAAO,IAAI,OAAQ;AAC7B,UAAM,IAAI,MAAM,KAAK,MAAM,IAAI,IAAI,IAAI;AACvC,WACE,2BAA2B,CAAC,IAAI,CAAC,kBAClB,EAAE,aAAa,EAAE,kBAAkB,KAAK,KAAK,IAAI,KAAK,MAAM,8BAC/C,KAAK,KAAK,aAAa,KAAK,MAAM,WAAW,EAAE,QAC3E,EAAE,QACF,kCAC4B,EAAE,aAAa,EAAE,0DACjC,KAAK,CAAC,QAAQ,KAAK,EAAE,+EAC5B,EAAE,KAAK,UAAO,EAAE,QAAQ,IAAI,QAAQ,CAAC,CAAC;AAAA,EAG/C,CAAC,EACA,KAAK,EAAE;AAEV,SACE,wDAAwD,MAAM,IAAI,MAAM,YAAY,MAAM,aAAa,MAAM,8BACjF,MAAM,aAAa,MAAM,uBACrD,QACA;AAEJ;;;AC7CO,IAAM,QAAN,MAAoC;AAAA,EAChC;AAAA,EACA;AAAA,EACA,QAAQ,IAAI,WAAW;AAAA,EACvB,SAAS,IAAI,SAAqB;AAAA,EAClC,YAAY,oBAAI,IAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO9C,QAAiC,CAAC;AAAA,EACzB;AAAA,EACA;AAAA,EAET;AAAA,EACA,eAAgC;AAAA,EAExB;AAAA,EACA,YAAoB,CAAC;AAAA,EACrB,UAAU;AAAA,EAElB,YAAY,SAAsB,CAAC,GAAG;AACpC,SAAK,OAAO,OAAO,QAAQ;AAC3B,SAAK,MAAM,IAAI,IAAI,KAAK,IAAI;AAC5B,SAAK,QAAQ,IAAI,MAAM,OAAO,KAAK;AACnC,SAAK,QAAQ,OAAO,SAAS;AAC7B,SAAK,SAAS,OAAO,UAAU;AAC/B,SAAK,OAAO,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC;AAAA,EACvC;AAAA,EAEA,IAAI,OAAe;AACjB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EACA,IAAI,QAAgB;AAClB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA,EAGA,QAAQ,MAAkB;AACxB,QAAI,KAAK,KAAM,MAAK,KAAK,SAAS;AAClC,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,YAAY,MAAkB;AAC5B,SAAK,UAAU,KAAK,IAAI;AAAA,EAC1B;AAAA,EAEQ,gBAAsB;AAC5B,QAAI,CAAC,KAAK,SAAS;AACjB,WAAK,KAAK,UAAU,IAAI;AACxB,WAAK,UAAU;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,cAAgC,CAAC,GAAS;AAC7C,SAAK,cAAc;AACnB,SAAK,MAAM,WAAW,WAAW;AACjC,SAAK,KAAK,WAAW,KAAK,MAAM,EAAE;AAClC,SAAK,UAAU;AACf,SAAK,MAAM,KAAK;AAAA,EAClB;AAAA;AAAA,EAGA,QAAQ,QAAgB,cAAgC,CAAC,GAAW;AAClE,UAAM,QAAQ,KAAK,MAAM,QAAQ,MAAM;AACvC,aAAS,IAAI,GAAG,IAAI,OAAO,IAAK,MAAK,KAAK,WAAW;AACrD,WAAO;AAAA,EACT;AAAA,EAEQ,YAAkB;AACxB,QAAI,KAAK,UAAU,WAAW,EAAG;AACjC,UAAM,IAAI,KAAK;AACf,SAAK,YAAY,CAAC;AAClB,eAAW,QAAQ,GAAG;AACpB,WAAK,SAAS;AACd,WAAK,QAAQ,YAAY,IAAI;AAC7B,UAAI,KAAK,iBAAiB,KAAM,MAAK,eAAe;AAAA,IACtD;AAAA,EACF;AAAA;AAAA;AAAA,EAIA,gBAA2B;AACzB,QAAI,CAAC,KAAK,aAAc,QAAO;AAC/B,UAAM,MAAM,KAAK;AAEjB,UAAM,WAAW,IAAI,eAAe;AACpC,UAAM,WAAW,iBAAiB,cAAc,EAAE,GAAG,KAAK,QAAQ,GAAG,GAAG,KAAK,SAAS,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,MAAM,GAAG,IAAI,KAAK,CAAC,GAAG,gBAAgB,QAAQ,CAAC;AACtJ,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,SAAwB;AACtB,SAAK,cAAc;AACnB,UAAM,MAAqB,CAAC;AAC5B,SAAK,KAAK,YAAY,KAAK,KAAK,cAAc,CAAC;AAC/C,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIA,OAAe;AACb,WAAO,UAAU;AAAA,MACf,MAAM,KAAK;AAAA,MACX,KAAK,KAAK,IAAI,SAAS;AAAA,MACvB,OAAO,KAAK,MAAM,SAAS;AAAA,MAC3B,OAAO,KAAK,MAAM,SAAS;AAAA,MAC3B,OAAO,KAAK;AAAA,MACZ,MAAM,KAAK,KAAK,UAAU;AAAA,IAC5B,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,WAA0B;AACxB,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,KAAK,KAAK,IAAI,SAAS;AAAA,MACvB,OAAO,KAAK,MAAM,SAAS;AAAA,MAC3B,OAAO,KAAK,MAAM,SAAS;AAAA,MAC3B,OAAO,gBAAgB,KAAK,KAAK;AAAA,MACjC,MAAM,KAAK,KAAK,UAAU;AAAA,IAC5B;AAAA,EACF;AAAA;AAAA,EAGA,QAAQ,MAA2B;AACjC,SAAK,OAAO,KAAK;AACjB,SAAK,IAAI,SAAS,KAAK,GAAG;AAC1B,SAAK,MAAM,SAAS,KAAK,KAAK;AAC9B,SAAK,MAAM,SAAS,KAAK,KAAK;AAC9B,SAAK,QAAQ,gBAAgB,KAAK,KAAK;AACvC,iBAAa,GAAS;AACtB,SAAK,QAAQ,gBAAgB,KAAK,IAAI,CAAC;AACvC,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA,EAGA,QAAiC;AAC/B,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,MAAM,KAAK;AAAA,MACX,MAAM,KAAK,KAAK;AAAA,MAChB,OAAO,KAAK,KAAK,MAAM,QAAQ,EAAE,SAAS,KAAK,KAAK,MAAM,MAAM,EAAE;AAAA,IACpE;AAAA,EACF;AACF;;;AC3JO,SAAS,WAAW,KAA+H;AACxJ,SAAO;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,GAAG;AAAA,EACL;AACF;AAGO,SAAS,YAAY,KAAqB,cAA8B;AAC7E,QAAM,QAAQ,IAAI,MAAM;AAAA,IACtB,MAAM,gBAAgB,IAAI,QAAQ;AAAA,IAClC,OAAO,IAAI,SAAS;AAAA,IACpB,QAAQ,IAAI,UAAU;AAAA,IACtB,OAAO,IAAI;AAAA,EACb,CAAC;AACD,QAAM,QAAQ,IAAI,MAAM,KAAK,CAAC;AAC9B,MAAI,IAAI,OAAO;AAEb,IAAC,MAA8D,QAAQ,MAAM,IAAI,MAAO,KAAK;AAAA,EAC/F;AACA,SAAO;AACT;AAGO,SAAS,aAAa,KAA+B;AAC1D,SAAO,IAAI,YAAY;AACzB;AAaO,SAAS,YAAY,KAAqB,UAAqC;AACpF,QAAM,QAAQ,YAAY,GAAG;AAC7B,QAAM,SAAS,UAAU,UAAU,CAAC;AACpC,aAAW,KAAK,OAAQ,OAAM,KAAK,CAAC;AACpC,SAAO,EAAE,OAAO,MAAM,MAAM,KAAK,GAAG,OAAO,OAAO,OAAO;AAC3D;;;ACtCO,SAAS,WAAW,KAAqB,OAAoB,OAAmB,CAAC,GAAe;AACrG,QAAM,QAAQ,IAAI,SAAS;AAC3B,QAAM,SAAS,IAAI,UAAU;AAC7B,QAAM,aAAa,IAAI,cAAc;AAErC,MAAI,QAAQ,YAAY,GAAG;AAC3B,QAAM,WACJ,KAAK,aAAa,WACd,IAAI,iBAAiB,EAAE,OAAO,QAAQ,WAAW,CAAC,IAClD,IAAI,YAAY,EAAE,OAAO,QAAQ,WAAW,CAAC;AAEnD,QAAM,MAAM,WAAW,MAAM,MAAM,YAAY;AAC/C,WAAS,QAAQ,KAAK;AACtB,iBAAe,KAAK;AAEpB,QAAM,QAAQ,IAAI,eAAe,IAAI,YAAY,CAAC,GAAG,QAAQ;AAC7D,QAAM,UAAU,cAAc;AAG9B,QAAM,aAAa,MAAM;AACvB,UAAM,MAAM;AACZ,UAAM,IAAI,SAAS,IAAI;AACvB,UAAM,WAAW,CAAC;AAClB,WAAO,oBAAoB,eAAe,UAAU;AACpD,WAAO,oBAAoB,WAAW,UAAU;AAAA,EAClD;AACA,SAAO,iBAAiB,eAAe,UAAU;AACjD,SAAO,iBAAiB,WAAW,UAAU;AAE7C,QAAM,cAAc,MAAM,SAAS,KAAK,MAAM,OAAO,CAAC;AACtD,QAAM,UAAU,MAAM;AACpB,YAAQ,YAAY,GAAG;AACvB,gBAAY;AAAA,EACd;AAEA,QAAM,QACJ,KAAK,UAAU,QACX,OACA,IAAI,MAAM;AAAA,IACR,OAAO,IAAI;AAAA,IACX,WAAW,KAAK,aAAa;AAAA,IAC7B,SAAS,MAAM;AAAA,IAAC;AAAA,EAClB,CAAC;AAEP,MAAI,MAAM;AACV,MAAI,OAAO,YAAY,IAAI;AAC3B,QAAM,OAAO,CAAC,QAAgB;AAC5B,UAAM,KAAK,MAAM;AACjB,WAAO;AACP,QAAI,CAAC,WAAW,CAAE,OAAO,UAAW;AAClC,YAAM,QAAQ,MAAM,QAAQ,IAAI,MAAM,eAAe,CAAC;AACtD,UAAI,QAAQ,EAAG,OAAM,aAAa;AAAA,IACpC;AACA,gBAAY;AACZ,UAAM,sBAAsB,IAAI;AAAA,EAClC;AACA,QAAM,sBAAsB,IAAI;AAEhC,QAAM,SAAqB;AAAA,IACzB,IAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AACL,2BAAqB,GAAG;AACxB,YAAM,QAAQ;AACd,aAAO,QAAQ;AACf,eAAS,UAAU;AAAA,IACrB;AAAA,IACA;AAAA,EACF;AAEA,MAAI,SAAS;AACX,mBAAe;AAAA,MACb,IAAI,QAAQ;AACV,eAAO;AAAA,MACT;AAAA,MACA,UAAU,CAAC,UAAU,CAAC,MAAM;AAC1B,cAAM,KAAK,OAAO;AAClB,oBAAY;AAAA,MACd;AAAA,MACA,WAAW,MAAM,kBAAkB,MAAM,OAAO,GAAG,OAAO,QAAQ,UAAU;AAAA,MAC5E,WAAW,MAAM;AAAA,MAAC;AAAA,IACpB,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;ACxDO,IAAM,UAAU;",
6
+ "names": ["n", "n", "mix", "n", "dx", "dy", "n", "n", "n", "hold"]
7
+ }
@@ -0,0 +1,40 @@
1
+ /** action name → physical key codes (KeyboardEvent.code strings). */
2
+ export type InputMap = Record<string, string[]>;
3
+ export declare class InputState {
4
+ private down;
5
+ private prev;
6
+ /** Analog axes (e.g. from gamepad or pointer), sampled per step. */
7
+ readonly axes: Map<string, number>;
8
+ /** Engine: set which actions are down this step (from live input or replay). */
9
+ beginFrame(actionsDown: Iterable<string>): void;
10
+ isDown(action: string): boolean;
11
+ justPressed(action: string): boolean;
12
+ justReleased(action: string): boolean;
13
+ axis(name: string): number;
14
+ /** The current down-set as a stable sorted array (for recording). */
15
+ snapshot(): string[];
16
+ getState(): {
17
+ down: string[];
18
+ prev: string[];
19
+ };
20
+ setState(s: {
21
+ down: string[];
22
+ prev: string[];
23
+ }): void;
24
+ }
25
+ /** Map a set of raw key codes to the set of actions they trigger. */
26
+ export declare function keysToActions(map: InputMap, keysDown: Set<string>): string[];
27
+ /** Records the per-frame action-down sets → a compact, replayable input log. */
28
+ export declare class InputRecorder {
29
+ private frames;
30
+ record(actionsDown: string[]): void;
31
+ get length(): number;
32
+ toLog(): InputLog;
33
+ }
34
+ export interface InputLog {
35
+ frames: string[][];
36
+ }
37
+ /** Replays a recorded log: returns the action set for frame index i. */
38
+ export declare function frameActions(log: InputLog, i: number): string[];
39
+ /** A default set of common bindings games can start from. */
40
+ export declare const DEFAULT_INPUT_MAP: InputMap;