@open-slot-ui/core 0.9.0 → 0.11.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.
- package/dist/index.cjs +251 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -1
- package/dist/index.d.ts +40 -1
- package/dist/index.js +246 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/signal.ts","../src/events.ts","../src/theme/tokens.ts","../src/layout/screen.ts","../src/layout/anchor.ts","../src/layout/defaultLayouts.ts","../src/transition/Transition.ts","../src/control/Control.ts","../src/controls/SpinControl.ts","../src/safe.ts","../src/format/currency.ts","../src/controls/ValueDisplay.ts","../src/controls/ButtonControl.ts","../src/controls/SliderControl.ts","../src/controls/PanelControl.ts","../src/controls/ToggleControl.ts","../src/controls/TurboControl.ts","../src/controls/StepperControl.ts","../src/controls/AutoplayControl.ts","../src/controls/ReadoutControl.ts","../src/controls/CardControl.ts","../src/controls/SelectControl.ts","../src/theme/presets.ts","../src/registry/ControlRegistry.ts","../src/spec/types.ts","../src/spec/validateSpec.ts","../src/spec/buildPanel.ts","../src/spec/jurisdiction.ts","../src/notice.ts","../src/i18n/translator.ts","../src/spec/facts.ts","../src/OpenUI.ts","../src/spec/responsive.ts","../src/spec/socialPhrases.ts","../src/spec/createUI.ts","../src/spec/menu.ts","../src/spec/rulesDoc.ts","../src/spec/defaultHudSpec.ts","../src/EventLog.ts","../src/bet.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Zero-dependency reactive primitives — the \"M\" substrate.\n * Deliberately tiny: a value box you can subscribe to, plus an effect helper.\n * No framework, no global graph, no magic. This is the whole reactivity story.\n */\n\nexport type Dispose = () => void;\n\nexport interface Subscribable {\n subscribe(fn: (value: never) => void): Dispose;\n}\n\nexport class Signal<T> {\n private _value: T;\n private readonly subs = new Set<(value: T) => void>();\n\n constructor(initial: T) {\n this._value = initial;\n }\n\n get(): T {\n return this._value;\n }\n\n set(next: T): void {\n if (Object.is(next, this._value)) return;\n this._value = next;\n // copy to tolerate (un)subscribe during emit\n for (const fn of [...this.subs]) fn(next);\n }\n\n /** Mutate-in-place then notify (for objects whose identity is stable). */\n update(mutate: (value: T) => void): void {\n mutate(this._value);\n for (const fn of [...this.subs]) fn(this._value);\n }\n\n subscribe(fn: (value: T) => void): Dispose {\n this.subs.add(fn);\n return () => {\n this.subs.delete(fn);\n };\n }\n\n get size(): number {\n return this.subs.size;\n }\n}\n\n/**\n * Run `fn` once now and again whenever any dependency changes.\n * Dependencies are explicit (no auto-tracking) — keeps the model trivial and predictable.\n */\nexport function effect(fn: () => void, deps: Subscribable[]): Dispose {\n const run = (): void => fn();\n const disposers = deps.map((d) => d.subscribe(run as (value: never) => void));\n run();\n return () => {\n for (const d of disposers) d();\n };\n}\n","import type { Dispose } from './signal';\n\n/** A typed event map: event name -> payload type. */\nexport type EventMap = Record<string, unknown>;\n\n/**\n * One typed event bus. Period. (Charter B1.)\n * No magic strings sprinkled around the codebase; payloads are checked.\n */\nexport class EventBus<E extends EventMap> {\n private readonly map = new Map<keyof E, Set<(payload: unknown) => void>>();\n\n on<K extends keyof E>(type: K, fn: (payload: E[K]) => void): Dispose {\n let set = this.map.get(type);\n if (!set) {\n set = new Set();\n this.map.set(type, set);\n }\n const wrapped = fn as (payload: unknown) => void;\n set.add(wrapped);\n return () => {\n set?.delete(wrapped);\n };\n }\n\n emit<K extends keyof E>(type: K, payload: E[K]): void {\n const set = this.map.get(type);\n if (!set) return;\n for (const fn of [...set]) fn(payload);\n }\n}\n","/**\n * Theming = data. Semantic tokens with safe fallbacks (Charter P8).\n * A game theme is a small override map; nothing renders un-themed because\n * the renderer always has these defaults to fall back on.\n */\n\nexport interface Theme {\n color: {\n accent: string;\n accentText: string;\n surface: string;\n surfaceAlt: string;\n text: string;\n textDim: string;\n disabled: string;\n };\n radius: { pill: number; card: number };\n space: { sm: number; md: number; lg: number };\n type: { family: string; size: { sm: number; md: number; lg: number } };\n /** Motion durations in ms. */\n motion: { fast: number; base: number; slow: number };\n}\n\n/** Neutral reference theme. The real game theme is built on top of this. */\nexport const defaultTheme: Theme = {\n color: {\n accent: '#ffc935',\n accentText: '#1a1a1a',\n surface: '#161b22',\n surfaceAlt: '#0b0e13',\n text: '#ffffff',\n textDim: '#7a8290',\n disabled: '#3a3f47',\n },\n radius: { pill: 999, card: 16 },\n space: { sm: 8, md: 16, lg: 24 },\n type: { family: 'system-ui, sans-serif', size: { sm: 14, md: 18, lg: 28 } },\n motion: { fast: 120, base: 200, slow: 360 },\n};\n\nexport type DeepPartial<T> = {\n [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];\n};\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\nfunction merge<T>(base: T, patch: DeepPartial<T>): T {\n const out = { ...base } as Record<string, unknown>;\n for (const key of Object.keys(patch)) {\n const pv = (patch as Record<string, unknown>)[key];\n const bv = (base as Record<string, unknown>)[key];\n out[key] = isObject(pv) && isObject(bv) ? merge(bv, pv as DeepPartial<typeof bv>) : pv;\n }\n return out as T;\n}\n\n/** Produce a new theme from the default (or any base) plus an override patch. */\nexport function extendTheme(base: Theme, patch: DeepPartial<Theme>): Theme {\n return merge(base, patch);\n}\n","/** Responsive screen model: orientation, a named breakpoint, and a fit scale. */\n\nexport type Orientation = 'landscape' | 'portrait';\n\n/** A named device bucket. Config can target these to restyle per device. */\nexport type Breakpoint = 'mobile' | 'tablet' | 'desktop';\n\n/** The uniformly-scaled DESIGN FRAME (\"stage\") rect, in screen pixels. */\nexport interface StageRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface ScreenState {\n width: number;\n height: number;\n orientation: Orientation;\n /** Named device bucket, derived from the shorter screen edge (see LayoutConfig). */\n breakpoint: Breakpoint;\n /** Multiply reference-px sizes by this to fit the current screen. */\n scale: number;\n /**\n * The reference design frame, scaled UNIFORMLY by `scale` and placed in the viewport\n * (letterboxed by `stageAnchor` when the aspect ratio differs). Every control anchors\n * to THIS rect — not the raw screen — so the whole HUD scales as one homogeneous unit\n * and the relative gaps between controls never change with aspect ratio. At the\n * reference resolution `stage` exactly equals the screen, so authored layouts are\n * pixel-identical there.\n */\n stage: StageRect;\n}\n\nexport interface LayoutConfig {\n /** Reference design resolution for landscape / portrait. */\n refLandscape: [number, number];\n refPortrait: [number, number];\n /** Aspect ratio (w/h) below which we switch to the portrait layout. */\n portraitBelowAspect: number;\n /**\n * Breakpoint thresholds on the SHORTER screen edge (px). A phone is \"mobile\" in\n * both orientations because its short edge stays small — the right intuition for\n * \"what device is this\". `<= mobile` → mobile, `<= tablet` → tablet, else desktop.\n */\n breakpoints: { mobile: number; tablet: number };\n /**\n * Where the uniformly-scaled design frame sits in the viewport when the aspect ratio\n * doesn't match the reference (i.e. how the letterbox margins are distributed), as\n * `[x, y]` factors in `0..1`. `[0.5, 1]` (default) = bottom-centre: the bottom bar\n * always hugs the screen bottom and any extra vertical room opens ABOVE (the reel\n * area, filled by the game); horizontal slack splits evenly. `[0.5, 0.5]` centres it.\n */\n stageAnchor: [number, number];\n}\n\nexport const defaultLayoutConfig: LayoutConfig = {\n // Reference design frames, matching the Figma \"DEF\" frames 1:1 so offsets map\n // directly: desktop 1920×1080, mobile 360×779 (×3 = 1080×2337). The portrait\n // aspect matches real phones (~0.46), so scaling no longer squashes vertically.\n refLandscape: [1920, 1080],\n refPortrait: [1080, 2337],\n portraitBelowAspect: 0.85,\n breakpoints: { mobile: 480, tablet: 840 },\n // Bottom bar hugs the screen bottom; extra height opens above (reel area).\n stageAnchor: [0.5, 1],\n};\n\n/** Classify the shorter edge into a named device bucket. Pure, total. */\nexport function breakpointFor(width: number, height: number, cfg: LayoutConfig): Breakpoint {\n const short = Math.min(Math.max(width, 1), Math.max(height, 1));\n if (short <= cfg.breakpoints.mobile) return 'mobile';\n if (short <= cfg.breakpoints.tablet) return 'tablet';\n return 'desktop';\n}\n\nexport function computeScreen(width: number, height: number, cfg: LayoutConfig): ScreenState {\n const w = Math.max(width, 1);\n const h = Math.max(height, 1);\n const orientation: Orientation = w / h < cfg.portraitBelowAspect ? 'portrait' : 'landscape';\n const [rw, rh] = orientation === 'portrait' ? cfg.refPortrait : cfg.refLandscape;\n const scale = Math.min(w / rw, h / rh);\n // The design frame, scaled uniformly and letterbox-positioned. At the reference\n // aspect it fills the screen exactly (stage == screen).\n const sw = rw * scale;\n const sh = rh * scale;\n const [ax, ay] = cfg.stageAnchor ?? [0.5, 1];\n const stage: StageRect = { x: (w - sw) * ax, y: (h - sh) * ay, width: sw, height: sh };\n return { width: w, height: h, orientation, breakpoint: breakpointFor(w, h, cfg), scale, stage };\n}\n","import type { ScreenState } from './screen';\n\n/** Explicit anchors — no magic numbers buried in components (Charter P9). */\nexport type Anchor =\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'center-left'\n | 'center'\n | 'center-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right';\n\nexport interface LayoutSpec {\n anchor: Anchor;\n /** Offset from the anchor, in reference px (scaled with the screen). */\n offset?: [number, number];\n /** Extra scale multiplier on top of the screen's fit scale. */\n scale?: number;\n /** Rotation in degrees, clockwise. Default 0. */\n rotation?: number;\n}\n\nexport interface Placement {\n x: number;\n y: number;\n scale: number;\n /** Rotation in radians (resolved from `LayoutSpec.rotation`, which is degrees). */\n rotation: number;\n}\n\nfunction anchorFactors(anchor: Anchor): [number, number] {\n const ax = anchor.includes('left') ? 0 : anchor.includes('right') ? 1 : 0.5;\n const ay = anchor.includes('top') ? 0 : anchor.includes('bottom') ? 1 : 0.5;\n return [ax, ay];\n}\n\n/**\n * Resolve a control's layout against the current screen. Pure math.\n *\n * Anchors to the uniformly-scaled `screen.stage` frame — NOT the raw screen — so the\n * whole HUD scales as one homogeneous unit: the gap between two controls is always a\n * fixed fraction of the (uniformly-scaled) frame, never a function of the viewport's\n * aspect ratio. That's what stops a growing value or a narrow window from letting\n * controls drift into each other. At the reference resolution `stage` equals the\n * screen, so authored offsets land pixel-identically.\n */\nexport function resolvePlacement(spec: LayoutSpec, screen: ScreenState): Placement {\n const [ax, ay] = anchorFactors(spec.anchor);\n const [ox, oy] = spec.offset ?? [0, 0];\n const st = screen.stage;\n return {\n x: st.x + ax * st.width + ox * screen.scale,\n y: st.y + ay * st.height + oy * screen.scale,\n scale: screen.scale * (spec.scale ?? 1),\n rotation: ((spec.rotation ?? 0) * Math.PI) / 180,\n };\n}\n","import type { LayoutSpec } from './anchor';\n\n/**\n * The reference HUD arrangement, cloned 1:1 from the Figma design frames.\n *\n * Landscape (\"Desk DEF\", 1920×1080 = the landscape reference, so px map\n * directly): a bottom bar — balance · play · SPIN · turbo · bet (with the ±\n * steppers stacked to its right) — plus the ☰ menu on the lower-left rail and\n * the buy (bonus) button on the lower-right rail. Everything lives in the\n * bottom ~320 reference px so the reels area above stays clear.\n *\n * Portrait (\"Mobile DEF\", 360-wide × 3 = the 1080×2337 portrait reference):\n * a thumb-friendly stack — buy · play · SPIN · turbo · ☰ on one row, the bet ±\n * steppers below SPIN, balance/bet tilted into the corners, readouts larger.\n *\n * These are the LIBRARY defaults: `OpenUI` constructs controls with the\n * landscape values, and `createUI` installs the portrait set as a built-in\n * `responsive.portrait` bucket (layered UNDER host overrides — a host's static\n * `controls.{id}.layout` wins everywhere, and a host's own\n * `responsive.portrait` entry wins per-control).\n */\nexport const landscapeDefaultLayouts: Readonly<Record<string, LayoutSpec>> = Object.freeze({\n // Measured 1:1 from the Figma \"Desk DEF\" frame (1920×1080): spin ~0.95 of the base\n // 220px coin, dropped to −124, autoplay/turbo flanking at ±204. (The homogeneous\n // stage keeps this off the reels, so it no longer needs shrinking.)\n spin: { anchor: 'bottom-center', offset: [0, -124], scale: 0.95 },\n autoplay: { anchor: 'bottom-center', offset: [-204, -100] },\n turbo: { anchor: 'bottom-center', offset: [204, -100] },\n balance: { anchor: 'bottom-left', offset: [135, -104], rotation: -5 },\n bet: { anchor: 'bottom-right', offset: [-186, -104], rotation: 5 },\n 'bet-plus': { anchor: 'bottom-right', offset: [-120, -188], rotation: 5 },\n 'bet-minus': { anchor: 'bottom-right', offset: [-120, -104], rotation: 5 },\n bonus: { anchor: 'bottom-center', offset: [740, -320] },\n // Bonus \"total win\" readout — occupies the buy-feature corner; the renderer swaps\n // the two so only one shows at a time (buy in base play, total-win in a bonus round).\n // Right-anchored so a long localized caption grows LEFT and never clips the edge.\n 'total-win': { anchor: 'bottom-right', offset: [-150, -300] },\n settings: { anchor: 'bottom-center', offset: [-740, -320], rotation: -5 },\n mute: { anchor: 'top-right', offset: [-122, 46] },\n fullscreen: { anchor: 'top-right', offset: [-46, 46] },\n rtp: { anchor: 'top-left', offset: [20, 18] },\n 'session-timer': { anchor: 'top-left', offset: [20, 46] },\n 'net-position': { anchor: 'top-left', offset: [20, 74] },\n});\n\nexport const portraitDefaultLayouts: Readonly<Record<string, LayoutSpec>> = Object.freeze({\n // Mobile sizes run ~1.5× the desktop base (the Figma mobile frame draws the\n // controls larger relative to its width) so the buttons read well on a phone.\n spin: { anchor: 'bottom-center', offset: [0, -510], scale: 1.35 },\n autoplay: { anchor: 'bottom-center', offset: [-258, -510], scale: 1.5 },\n turbo: { anchor: 'bottom-center', offset: [258, -510], scale: 1.5 },\n bonus: { anchor: 'bottom-center', offset: [-438, -480], scale: 1.3 },\n // Figma \"Mobile FS\": the total-win sits on the LEFT at the spin's level (where the\n // buy coin lives in base play), left-aligned + tilted −10° — NOT centred over spin.\n 'total-win': { anchor: 'bottom-left', offset: [30, -520], rotation: -10 },\n settings: { anchor: 'bottom-center', offset: [438, -480], scale: 1.5, rotation: -5 },\n 'bet-minus': { anchor: 'bottom-center', offset: [-105, -267], scale: 1.5 },\n 'bet-plus': { anchor: 'bottom-center', offset: [105, -267], scale: 1.5 },\n mute: { anchor: 'top-right', offset: [-159, 57], scale: 1.5 },\n fullscreen: { anchor: 'top-right', offset: [-57, 57], scale: 1.5 },\n // Compliance readouts scale up ~2× on mobile with wider line spacing.\n rtp: { anchor: 'top-left', offset: [16, 16], scale: 2 },\n 'session-timer': { anchor: 'top-left', offset: [16, 66], scale: 2 },\n 'net-position': { anchor: 'top-left', offset: [16, 116], scale: 2 },\n balance: { anchor: 'bottom-left', offset: [36, -110], rotation: -5 },\n bet: { anchor: 'bottom-right', offset: [-36, -110], rotation: 5 },\n});\n\n/** A control's default layout for the landscape reference frame (cloned — safe to mutate). */\nexport function defaultLayout(id: string): LayoutSpec {\n const l = landscapeDefaultLayouts[id];\n if (!l) return { anchor: 'center' };\n return { anchor: l.anchor, offset: l.offset ? [l.offset[0], l.offset[1]] : undefined, scale: l.scale, rotation: l.rotation };\n}\n","/**\n * Transitions are composable OOP descriptors (Charter B6) — pure data, renderer-agnostic.\n * The renderer interprets the `kind`; the core never animates anything itself.\n * Some controls turn, some squish, some tick up, some emit particles — all from these.\n */\n\nexport class Squish {\n readonly kind = 'squish' as const;\n constructor(public scale = 0.92, public ms = 120) {}\n}\n\nexport class Pulse {\n readonly kind = 'pulse' as const;\n constructor(public scale = 1.06, public ms = 160) {}\n}\n\nexport class Turn {\n readonly kind = 'turn' as const;\n /** Rotations per second; loops until the state changes. */\n constructor(public rps = 1, public loop = true) {}\n}\n\nexport class Fade {\n readonly kind = 'fade' as const;\n constructor(public alpha = 0.4, public ms = 160) {}\n}\n\nexport class Sequence {\n readonly kind = 'sequence' as const;\n constructor(public steps: Transition[]) {}\n}\n\nexport class Parallel {\n readonly kind = 'parallel' as const;\n constructor(public steps: Transition[]) {}\n}\n\nexport type Transition = Squish | Pulse | Turn | Fade | Sequence | Parallel;\n","import { Signal, type Dispose } from '../signal';\nimport type { Transition } from '../transition/Transition';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { Rect } from '../types';\n\n/** One state of a control: is it interactable, and what plays on entry. */\nexport interface StateDef {\n interactable: boolean;\n transition?: Transition;\n}\n\nexport type StateMap = Record<string, StateDef>;\n\nexport interface ControlOptions {\n id: string;\n role: string;\n layout: LayoutSpec;\n}\n\n/** What a view reports back for introspection. Set by the renderer's view. */\nexport type ViewInspect = () => { bounds: Rect | null; animating: boolean };\n\n/**\n * Base of every control: a finite state machine that is the single source of\n * truth for look, interactivity, AND tests (Charter P5/P6/P12).\n * Renderer-agnostic — it knows nothing about Pixi or the DOM.\n */\nexport abstract class Control {\n readonly id: string;\n readonly role: string;\n layout: LayoutSpec;\n\n /** Declared by the subclass: the legal states and their transitions. */\n abstract readonly states: StateMap;\n\n /** Current state name, observable. */\n readonly state: Signal<string>;\n\n /** The renderer sets this so `inspect()` can report bounds/animation. */\n viewInspect?: ViewInspect;\n\n /**\n * Optional host gate (e.g. a ref-counted input lock). When set, the control is\n * interactable only if its state allows it AND the gate returns true. Set per\n * instance — by OpenUI on register — so multiple HUDs on one page never share\n * lock state. Interactability stays *derived*, never stored (Charter P6).\n */\n gate?: () => boolean;\n\n protected readonly disposers: Dispose[] = [];\n private readonly transitionSubs = new Set<(t: Transition | undefined, to: string, from: string) => void>();\n\n constructor(opts: ControlOptions, initial: string) {\n this.id = opts.id;\n this.role = opts.role;\n this.layout = opts.layout;\n this.state = new Signal<string>(initial);\n }\n\n get current(): string {\n return this.state.get();\n }\n\n /** Derived, never stored (Charter P6). Folds in the optional host gate. */\n get interactable(): boolean {\n const base = this.states[this.current]?.interactable ?? false;\n return base && (this.gate?.() ?? true);\n }\n\n /** Transition to a new state. Throws on unknown states (illegal states unrepresentable). */\n setState(to: string): void {\n if (!(to in this.states)) {\n throw new Error(`[open-ui] control \"${this.id}\": unknown state \"${to}\"`);\n }\n const from = this.current;\n if (to === from) return;\n this.state.set(to);\n const t = this.states[to]?.transition;\n for (const fn of [...this.transitionSubs]) fn(t, to, from);\n }\n\n /** The renderer subscribes to play the entry transition for each state change. */\n onTransition(fn: (t: Transition | undefined, to: string, from: string) => void): Dispose {\n this.transitionSubs.add(fn);\n return () => {\n this.transitionSubs.delete(fn);\n };\n }\n\n inspect(): { bounds: Rect | null; animating: boolean } {\n return this.viewInspect?.() ?? { bounds: null, animating: false };\n }\n\n /** Leak-free teardown (Charter P12). */\n dispose(): void {\n for (const d of this.disposers) d();\n this.disposers.length = 0;\n this.transitionSubs.clear();\n this.viewInspect = undefined;\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Signal } from '../signal';\nimport { Squish, Pulse, Fade } from '../transition/Transition';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\n/**\n * The spin control — the vertical-spine exemplar.\n * A full state machine: each state declares interactability + an entry transition.\n * The game drives it via the façade (`busy/idle/stop/disable`); the view drives\n * the transient input states (`hover/pressed`) and calls `activate()` on release.\n */\nexport class SpinControl extends Control {\n readonly states: StateMap = {\n idle: { interactable: true, transition: new Squish(0.94, 120) },\n hover: { interactable: true, transition: new Pulse(1.06, 160) },\n pressed: { interactable: true, transition: new Squish(0.86, 70) },\n // Spinning no longer rotates — the button just squishes on press and sits.\n spinning: { interactable: false, transition: new Squish(0.94, 120) },\n stop: { interactable: true, transition: new Pulse(1.08, 140) },\n auto: { interactable: true, transition: new Pulse(1.06, 160) },\n disabled: { interactable: false, transition: new Fade(0.4, 160) },\n };\n\n /**\n * When true, the view arms press-and-hold: holding the spin button fires a\n * `holdSpinStarted` and the host turbo-spins until release (`holdSpinStopped`).\n * A quick tap still spins once. Toggleable via the `spin.press` config.\n */\n holdToSpin = false;\n\n /**\n * Whether tapping mid-spin slam-stops/skips the reels. Stake Engine's\n * `disabledSlamstop` jurisdiction flag sets this false → the button then LOCKS\n * (dims, no tap) during a spin instead of skipping. Observable so the view can\n * re-dim if it flips at runtime (e.g. on `applyJurisdiction`).\n */\n readonly allowSlamStop = new Signal<boolean>(true);\n\n /**\n * Whether the keyboard (Space / Enter) can trigger a spin. Stake's\n * `disabledSpacebar` sets this false (and turns off hold-to-spin). The renderer\n * reads it; RTS 14D requires a fresh press per cycle (no auto-repeat).\n */\n readonly allowKeyboard = new Signal<boolean>(true);\n\n /**\n * Remaining free spins (0 = normal play). Set it > 0 and the spin button switches\n * to its free-spins face — a big remaining count over an \"FS\" label — via the view;\n * back to 0 returns the normal play button. The host drives the loop; this is just\n * the display. Set with {@link setFreeSpins}.\n */\n readonly freeSpins = new Signal<number>(0);\n\n constructor(\n opts: { id?: string; layout: LayoutSpec; holdToSpin?: boolean },\n private readonly bus: EventBus<OpenUIEvents>,\n ) {\n super({ id: opts.id ?? 'spin', role: 'button', layout: opts.layout }, 'idle');\n this.holdToSpin = opts.holdToSpin ?? false;\n }\n\n /**\n * Derived (Charter P6), with the slam-stop guard folded in: when slam-stop is\n * disabled, the in-spin `stop`/`auto` affordance is locked — the button can't be\n * tapped to skip; it just dims.\n */\n override get interactable(): boolean {\n if (!this.allowSlamStop.get() && (this.current === 'auto' || this.current === 'stop')) return false;\n return super.interactable;\n }\n\n // ---- façade (the game talks to these) ----\n busy(): void {\n this.setState('spinning');\n }\n idle(): void {\n this.setState('idle');\n }\n stopState(): void {\n this.setState('stop');\n }\n /** Show the autoplay-engaged look (press to stop). */\n auto(): void {\n this.setState('auto');\n }\n enable(): void {\n if (this.current === 'disabled') this.setState('idle');\n }\n disable(): void {\n this.setState('disabled');\n }\n\n // ---- input (the view calls this on a valid press-release) ----\n activate(): void {\n if (this.current === 'auto') {\n // autoplay-engaged: tapping slam-stops / skips the reels — it does NOT stop\n // autoplay. Suppressed when slam-stop is disabled by jurisdiction.\n if (this.allowSlamStop.get()) this.bus.emit('skipRequested', undefined);\n return;\n }\n if (this.interactable) this.bus.emit('spinRequested', undefined);\n }\n\n /** View calls this when a press is held past the hold threshold. Returns whether\n * hold-to-spin engaged (so the view knows to wait for release). */\n holdBegin(): boolean {\n if (!this.holdToSpin || !this.interactable) return false;\n this.bus.emit('holdSpinStarted', undefined);\n return true;\n }\n /** View calls this on release after a hold — the host stops the turbo loop. */\n holdEnd(): void {\n this.bus.emit('holdSpinStopped', undefined);\n }\n\n /** Switch the button to / from its free-spins face. `n > 0` shows \"n FS\"; `0`\n * restores the normal play button. Non-number/negative is clamped to 0 (P11). */\n setFreeSpins(n: number): void {\n this.freeSpins.set(typeof n === 'number' && Number.isFinite(n) && n > 0 ? Math.floor(n) : 0);\n }\n}\n","/**\n * Never-reject inbound boundary helpers (Charter P11). The UI *displays* values\n * the host sets and computes no money — so malformed host data must degrade to a\n * no-op, never throw into the render loop.\n */\n\n/** Return `n` if it is a finite number, else fall back to the last good value. */\nexport function safeAmount(n: number, lastGood: number): number {\n return typeof n === 'number' && Number.isFinite(n) ? n : lastGood;\n}\n\n/** Clamp a currency's fractional digits to a sane 0..8 integer (default 2). */\nexport function clampDecimals(d: number): number {\n if (typeof d !== 'number' || !Number.isFinite(d)) return 2;\n return Math.max(0, Math.min(8, Math.trunc(d)));\n}\n\n/** Clamp the value counter's fit WIDTH budget to a sane 1..18 column count (default 9). */\nexport function clampDigits(n: number): number {\n if (typeof n !== 'number' || !Number.isFinite(n)) return 9;\n return Math.max(1, Math.min(18, Math.trunc(n)));\n}\n\n/** Clamp a value-display's MINIMUM column width: 0..18, where 0 means \"auto\" — size\n * the odometer tightly to the value. Garbage → 0 (auto). */\nexport function clampMinDigits(n: number): number {\n if (typeof n !== 'number' || !Number.isFinite(n)) return 0;\n return Math.max(0, Math.min(18, Math.trunc(n)));\n}\n\n/** How many integer (whole-part) digits a value needs, minimum 1 (so `0.x` shows a\n * leading `0`). Uses string length, not log10, to dodge the `log10(1000)=2.999…` trap. */\nexport function integerDigits(value: number): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) return 1;\n return String(Math.floor(Math.abs(value))).length;\n}\n\n/**\n * Total odometer columns to show `value` at `decimals` precision TIGHTLY — exactly\n * the integer digits the value needs plus the fraction columns, so there are no\n * hidden leading-zero columns padding the number (a fixed reserve would either gap\n * small values like `$1.00` or clamp large ones like `12.34 BTC` on a 9-col budget).\n * Never below `minTotal` (a host-set stable width) nor `decimals + 1` (the counter\n * needs `decimals < digits`); capped at 18. The renderer grows the counter as the\n * value grows, so the magnitude is never clamped.\n */\nexport function displayDigits(value: number, minTotal: number, decimals: number): number {\n const d = clampDecimals(decimals);\n const min = clampMinDigits(minTotal);\n return Math.min(18, Math.max(min, integerDigits(value) + d, d + 1));\n}\n\n/**\n * On-screen width budget (px) the value counter is allowed before `fit` scales it\n * down. Keyed to a fixed display budget (≥ 9 columns, or the host's wider `digits`)\n * so a normal-magnitude readout renders full-size while a very large value scales to\n * fit (\"won't go too far\"). `+64` leaves room for the currency affix.\n */\nexport function valueFitMaxWidth(digits: number, columnWidth: number): number {\n return clampDigits(digits) * columnWidth + 64;\n}\n","/**\n * Currency display metadata + a pure formatter (Charter P11: data, not code).\n *\n * This is the **Stake Engine currency table**: every code Stake supports, mapped to\n * its display SYMBOL, minor-unit decimals, and symbol side (before/after the number).\n * A game shouldn't hand-tune any of this — it either passes a full `CurrencySpec`, or\n * just the CODE (`currency: 'CNY'`) and gets the Stake formatting for free\n * (\"I use the Stake currency formatter\"). Unknown codes fall back to a 2-decimal,\n * code-suffix spec so nothing ever breaks. The UI computes no money — it only formats\n * what the game sets.\n */\nimport type { CurrencySpec } from '../controls/ValueDisplay';\nimport { clampDecimals } from '../safe';\n\nexport interface CurrencyInfo {\n /** The glyph shown to the player (\"$\", \"CN¥\", \"GC\"). */\n symbol: string;\n /** Fractional digits to show (JPY/KRW/IDR = 0, USD = 2, BTC = 8). */\n decimals: number;\n /** Symbol AFTER the number (\"10,00 zł\") rather than before (\"$10.00\"). Default before. */\n symbolAfter?: boolean;\n /** A social / sweepstakes coin (Gold Coins / Stake Cash) — never fiat wording. */\n social?: boolean;\n}\n\n/**\n * The Stake Engine supported-currency matrix (symbol · decimals · placement), 1:1 with\n * the platform's `CurrencyMeta`. Symbol placement: prefix by default, SUFFIX for the\n * few that render after the amount (DKK/NOK/PLN/VND/CLP/ARS/PEN). Decimals follow the\n * ISO minor units — 0 for JPY/KRW/IDR/VND/CLP, 3 for the KWD/JOD/BHD dinars (1000 fils),\n * 2 otherwise. Crypto is included (8-dp) so high-precision balances also format right.\n */\nexport const CURRENCY_TABLE: Readonly<Record<string, CurrencyInfo>> = Object.freeze({\n // ── fiat — symbol BEFORE the amount ──────────────────────────────────────────\n USD: { symbol: '$', decimals: 2 },\n CAD: { symbol: 'CA$', decimals: 2 },\n JPY: { symbol: '¥', decimals: 0 },\n EUR: { symbol: '€', decimals: 2 },\n RUB: { symbol: '₽', decimals: 2 },\n CNY: { symbol: 'CN¥', decimals: 2 },\n PHP: { symbol: '₱', decimals: 2 },\n INR: { symbol: '₹', decimals: 2 },\n IDR: { symbol: 'Rp', decimals: 0 },\n KRW: { symbol: '₩', decimals: 0 },\n BRL: { symbol: 'R$', decimals: 2 },\n MXN: { symbol: 'MX$', decimals: 2 },\n TRY: { symbol: '₺', decimals: 2 },\n GBP: { symbol: '£', decimals: 2 },\n NGN: { symbol: '₦', decimals: 2 },\n TWD: { symbol: 'NT$', decimals: 2 },\n SGD: { symbol: 'SG$', decimals: 2 },\n MYR: { symbol: 'RM', decimals: 2 },\n CRC: { symbol: '₡', decimals: 2 },\n // three-decimal dinars/rials (1 unit = 1000 fils) — the >2-decimal path must format these\n KWD: { symbol: 'KD', decimals: 3 },\n JOD: { symbol: 'JD', decimals: 3 },\n BHD: { symbol: 'BD', decimals: 3 },\n OMR: { symbol: 'OMR', decimals: 3 },\n TND: { symbol: 'DT', decimals: 3 },\n LYD: { symbol: 'LD', decimals: 3 },\n IQD: { symbol: 'IQD', decimals: 3 },\n // ── fiat — symbol AFTER the amount ───────────────────────────────────────────\n DKK: { symbol: 'kr', decimals: 2, symbolAfter: true },\n NOK: { symbol: 'kr', decimals: 2, symbolAfter: true },\n PLN: { symbol: 'zł', decimals: 2, symbolAfter: true },\n VND: { symbol: '₫', decimals: 0, symbolAfter: true },\n CLP: { symbol: 'CLP', decimals: 0, symbolAfter: true },\n ARS: { symbol: 'ARS', decimals: 2, symbolAfter: true },\n PEN: { symbol: 'S/', decimals: 2, symbolAfter: true },\n // ── crypto (8-dp, so sub-cent + high precision format correctly) ─────────────\n BTC: { symbol: '₿', decimals: 8 },\n ETH: { symbol: 'Ξ', decimals: 8 },\n LTC: { symbol: 'Ł', decimals: 8 },\n BCH: { symbol: 'BCH', decimals: 8 },\n DOGE: { symbol: 'Ð', decimals: 8 },\n USDT: { symbol: '₮', decimals: 2 },\n USDC: { symbol: 'USDC', decimals: 2 },\n // ── Stake social coins — Gold Coins / Stake Cash (shown as GC / SC) ───────────\n XGC: { symbol: 'GC', decimals: 2, social: true },\n XSC: { symbol: 'SC', decimals: 2, social: true },\n GC: { symbol: 'GC', decimals: 2, social: true },\n SC: { symbol: 'SC', decimals: 2, social: true },\n});\n\nconst upper = (code: string): string => (typeof code === 'string' ? code.toUpperCase() : '');\n\n/** True if `code` is a Stake social/sweepstakes coin (displayed \"GC\"/\"SC\"). */\nexport function isSocialCurrency(code: string): boolean {\n return CURRENCY_TABLE[upper(code)]?.social === true;\n}\n\n/**\n * Resolve a currency code to a complete, display-ready {@link CurrencySpec} using the\n * Stake table: fills the SYMBOL (rendered tight, `display:'symbol'`), its side\n * (`position`), and the minor-unit `decimals`. Anything in `overrides` wins so a game\n * can still hand-tune (e.g. force more decimals for sub-cent payouts). An unknown code\n * degrades to a 2-decimal code-suffix spec. Never throws.\n */\nexport function resolveCurrency(code: string, overrides: Partial<CurrencySpec> = {}): CurrencySpec {\n const info = CURRENCY_TABLE[upper(code)];\n if (!info) {\n // Unknown code → show the raw code as a suffix (safe default).\n return {\n code: overrides.code ?? code,\n decimals: clampDecimals(overrides.decimals ?? 2),\n position: overrides.position ?? 'suffix',\n separator: overrides.separator ?? ',',\n decimalChar: overrides.decimalChar ?? '.',\n ...(overrides.symbol ? { symbol: overrides.symbol, display: overrides.display ?? 'symbol' } : {}),\n };\n }\n return {\n // Social coins carry their DISPLAY code (XGC → \"GC\", XSC → \"SC\"); fiat/crypto keep\n // their ISO code (the symbol is what's actually rendered under `display:'symbol'`).\n code: overrides.code ?? (info.social ? info.symbol : code),\n symbol: overrides.symbol ?? info.symbol,\n display: overrides.display ?? 'symbol',\n position: overrides.position ?? (info.symbolAfter ? 'suffix' : 'prefix'),\n decimals: clampDecimals(overrides.decimals ?? info.decimals),\n separator: overrides.separator ?? ',',\n decimalChar: overrides.decimalChar ?? '.',\n };\n}\n\n/**\n * Format an amount (major units) per a {@link CurrencySpec}: grouped integer part,\n * fixed decimals, and the affix on the configured side. When `display:'symbol'` (and a\n * symbol is set) the SYMBOL sits tight against the number (`CN¥1,234.56` · `1.234,56 zł`);\n * otherwise the ISO code is spaced (`1,234.56 USD`). `signed` adds an explicit \"+\" for\n * non-negative values (used by the net-position readout). Pure + total: a malformed\n * number renders as \"0\".\n */\n/**\n * How many fraction digits a value ACTUALLY uses — never fewer than the currency's\n * native `base` precision, never more than the 8-decimal ceiling. Snaps float noise\n * (0.1+0.2) by measuring at 8 dp, then strips trailing zeros back down to `base`.\n *\n * Why: Stake requires a currency's FULL bet ladder verbatim from authenticate —\n * including its true minimum (USD 0.01) — so a win (0.01 bet × a ×0.2 face = 0.002)\n * or a running balance (999.982) can carry sub-unit precision the currency's fixed\n * decimals would CROP to \"0.00\". This tells the display exactly how many digits that\n * value needs; a clean value keeps the ordinary native look (5.00, 1,000.00).\n */\nexport function neededDecimals(value: number, base: number): number {\n const b = clampDecimals(base);\n if (!Number.isFinite(value) || value === 0) return b;\n let scaled = Math.round(Math.abs(value) * 1e8); // integer minor units at 8 dp\n let d = 8;\n while (d > b && scaled % 10 === 0) {\n scaled /= 10;\n d--;\n }\n return d;\n}\n\n/**\n * Format an amount at the precision it actually needs (see {@link neededDecimals}),\n * so a sub-unit win renders in full (\"$0.002\") instead of rounding to \"$0.00\".\n * Values within the currency's native precision format exactly like {@link formatAmount}.\n */\nexport function formatAmountPrecise(value: number, spec: CurrencySpec, opts: { signed?: boolean } = {}): string {\n const base = clampDecimals(spec.decimals ?? 2);\n const d = neededDecimals(value, base);\n return d === base ? formatAmount(value, spec, opts) : formatAmount(value, { ...spec, decimals: d }, opts);\n}\n\nexport function formatAmount(value: number, spec: CurrencySpec, opts: { signed?: boolean } = {}): string {\n const decimals = clampDecimals(spec.decimals);\n const sep = spec.separator ?? ',';\n const dot = spec.decimalChar ?? '.';\n const n = Number.isFinite(value) ? value : 0;\n const fixed = Math.abs(n).toFixed(decimals);\n const [int = '0', frac] = fixed.split('.');\n const grouped = int.replace(/\\B(?=(\\d{3})+(?!\\d))/g, sep);\n const body = frac ? `${grouped}${dot}${frac}` : grouped;\n const sign = n < 0 ? '-' : opts.signed ? '+' : '';\n const number = `${sign}${body}`;\n const symbolMode = spec.display === 'symbol' && !!spec.symbol;\n const affix = symbolMode ? (spec.symbol as string) : spec.code;\n const prefix = (spec.position ?? 'suffix') === 'prefix';\n // Stake DisplayBalance: a PREFIX symbol hugs the number (\"CN¥10.00\"); a SUFFIX symbol\n // is spaced (\"10.00 zł\"); the ISO code is always spaced.\n const gap = symbolMode && prefix ? '' : ' ';\n return prefix ? `${affix}${gap}${number}` : `${number}${gap}${affix}`;\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Signal } from '../signal';\nimport { safeAmount, clampDecimals, clampMinDigits } from '../safe';\nimport { neededDecimals } from '../format/currency';\nimport type { LayoutSpec } from '../layout/anchor';\n\n/** Currency / crypto descriptor — the code/symbol + how to format it. */\nexport interface CurrencySpec {\n /** ISO code or crypto name: \"USD\", \"EUR\", \"BTC\", \"mBTC\", \"SATS\". */\n code: string;\n /**\n * The minimal-unit precision — how many fractional digits show after the `.`:\n * 2 (USD/EUR cents), 0 (JPY/SATS), 5 (mBTC), 8 (BTC). Values are held + rolled as\n * integer minor units (no float drift). Clamped to 0..8.\n */\n decimals: number;\n /** Symbol for `display: 'symbol'` (e.g. \"$\", \"€\", \"₿\"). */\n symbol?: string;\n /** Show the ISO/crypto `code` (default) or the `symbol` (when one is set). */\n display?: 'code' | 'symbol';\n /** Affix on the left or right of the number. Default 'suffix'. */\n position?: 'prefix' | 'suffix';\n /** Thousands separator char. Default ','. */\n separator?: string;\n /** Decimal point char. Default '.'. */\n decimalChar?: string;\n}\n\nexport interface ValueDisplayOptions {\n id: string;\n layout: LayoutSpec;\n currency: CurrencySpec;\n /** Optional caption (\"Balance\" / \"Bet\"). */\n label?: string;\n /** Initial value, in major units (e.g. 1234.56). */\n initial?: number;\n /** Optional MINIMUM total column width for the rolling counter (integer + fraction).\n * `0`/unset = auto: the odometer is sized tightly to the value and grows as it does,\n * so the currency symbol hugs the number and large balances never clamp. Set it only\n * to reserve a stable, wider odometer. Clamped 0..18. Default 0 (auto). */\n digits?: number;\n}\n\n/**\n * A value display: a number plus a currency/crypto code. Not interactive — the\n * host sets the value (`ui.balance.set(...)`) and the renderer animates it.\n * Value is held in major units; `minorUnits` is the integer the counter rolls.\n */\nexport class ValueDisplay extends Control {\n readonly states: StateMap = { idle: { interactable: false } };\n readonly value = new Signal<number>(0);\n readonly currency: Signal<CurrencySpec>;\n readonly label?: string;\n /**\n * Show a value at the precision it ACTUALLY carries (default on): when the value has\n * more fraction digits than the currency's native precision — a sub-unit win like a\n * USD 0.01 bet × a ×0.2 face = 0.002, or the 999.982 balance it leaves behind — the\n * display decimals bump just enough to reveal them ($0.002), and drop back to the\n * native look (5.00) once the value is clean again. Set `false` for hard-fixed decimals.\n */\n autoPrecision = true;\n /** The currency's NATIVE precision — what `autoPrecision` returns to on clean values. */\n private baseDecimals: number;\n /** Minimum odometer column width (0 = auto: sized tightly to the value, grows as it\n * does). Read by the renderer at build time, so set it before mount (or declaratively\n * via `controls.{id}.digits`). */\n digits: number;\n\n constructor(opts: ValueDisplayOptions) {\n super({ id: opts.id, role: 'status', layout: opts.layout }, 'idle');\n // Clamp at construction too (not just setCurrency) so the stored spec is the\n // single source of truth — `minorUnits` and the counter never see decimals > 8.\n const c = opts.currency;\n this.currency = new Signal<CurrencySpec>(\n c && typeof c.code === 'string' ? { ...c, decimals: clampDecimals(c.decimals) } : { code: 'USD', decimals: 2 },\n );\n this.baseDecimals = this.currency.get().decimals;\n this.label = opts.label;\n this.digits = clampMinDigits(opts.digits ?? 0);\n if (opts.initial != null) this.value.set(opts.initial);\n this.applyPrecision();\n }\n\n /** Set the minimum odometer column width (clamped 0..18; 0 = auto). Read by the\n * renderer at build time, so set it before mount (or via `controls.{id}.digits`). */\n setDigits(n: number): void {\n this.digits = clampMinDigits(n);\n }\n\n /** Never-reject: NaN/Infinity/non-number degrade to a no-op, keeping the last\n * good value — malformed host data never throws into the render loop (P11). */\n set(amount: number): void {\n this.value.set(safeAmount(amount, this.value.get()));\n this.applyPrecision();\n }\n\n get(): number {\n return this.value.get();\n }\n\n /** Keep the prior spec on malformed input; clamp decimals to 0..8 (P11). The given\n * decimals become the NATIVE precision (`autoPrecision` bumps above it as needed). */\n setCurrency(spec: CurrencySpec): void {\n if (!spec || typeof spec.code !== 'string') return;\n this.baseDecimals = clampDecimals(spec.decimals);\n this.currency.set({ ...spec, decimals: this.baseDecimals });\n this.applyPrecision();\n }\n\n /** Bump the display decimals to what the current value needs — never below the\n * currency's native precision — and drop back once the value is clean again.\n * No-op (and no signal churn) when the shown precision is already right. */\n private applyPrecision(): void {\n if (!this.autoPrecision) return;\n const want = neededDecimals(this.value.get(), this.baseDecimals);\n const cur = this.currency.get();\n if (cur.decimals !== want) this.currency.set({ ...cur, decimals: want });\n }\n\n /** Accent emphasis: the renderer tints the value in the theme accent while on.\n * For \"this number is modified\" moments — e.g. a bet display showing the\n * EFFECTIVE stake while an ante/boost multiplies it. */\n readonly emphasized = new Signal<boolean>(false);\n\n setEmphasis(on: boolean): void {\n this.emphasized.set(on === true);\n }\n\n /** Integer minor units for the counter (no float drift). */\n get minorUnits(): number {\n return Math.round(this.value.get() * Math.pow(10, this.currency.get().decimals));\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Squish, Pulse, Fade } from '../transition/Transition';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\nexport interface ButtonOptions {\n id: string;\n layout: LayoutSpec;\n /** Optional text label (e.g. \"Rules\"). */\n label?: string;\n /** ARIA-ish role; default 'button'. */\n role?: string;\n}\n\n/**\n * A generic tap button: idle / hover / pressed / disabled, emitting\n * `buttonActivated` on a valid press-release. Used for settings, rules, close, …\n */\nexport class ButtonControl extends Control {\n readonly states: StateMap = {\n idle: { interactable: true, transition: new Squish(0.94, 110) },\n hover: { interactable: true, transition: new Pulse(1.05, 140) },\n pressed: { interactable: true, transition: new Squish(0.88, 70) },\n disabled: { interactable: false, transition: new Fade(0.4, 150) },\n };\n readonly label?: string;\n\n constructor(opts: ButtonOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n super({ id: opts.id, role: opts.role ?? 'button', layout: opts.layout }, 'idle');\n this.label = opts.label;\n }\n\n enable(): void {\n if (this.current === 'disabled') this.setState('idle');\n }\n disable(): void {\n this.setState('disabled');\n }\n\n /** The view calls this on a valid press-release. */\n activate(): void {\n if (this.interactable) this.bus?.emit('buttonActivated', { id: this.id });\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Signal } from '../signal';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\nconst clamp01 = (v: number): number => Math.min(1, Math.max(0, v));\n\nexport interface SliderOptions {\n id: string;\n layout: LayoutSpec;\n /** Initial value, 0..1. Default 0.5. */\n initial?: number;\n label?: string;\n}\n\n/**\n * A 0..1 slider (sound volume, etc.). The view drives `setNormalized` while\n * dragging; the lib holds the value and emits `valueChanged`. The host applies\n * the actual effect (e.g. sets audio volume).\n */\nexport class SliderControl extends Control {\n readonly states: StateMap = {\n idle: { interactable: true },\n dragging: { interactable: true },\n };\n readonly value = new Signal<number>(0.5);\n readonly label?: string;\n\n constructor(opts: SliderOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n super({ id: opts.id, role: 'slider', layout: opts.layout }, 'idle');\n this.label = opts.label;\n if (opts.initial != null) this.value.set(clamp01(opts.initial));\n }\n\n /** Set the normalized value (0..1) and notify. */\n setNormalized(v: number): void {\n const c = clamp01(v);\n if (c === this.value.get()) return;\n this.value.set(c);\n this.bus?.emit('valueChanged', { id: this.id, value: c });\n }\n\n beginDrag(): void {\n this.setState('dragging');\n }\n endDrag(): void {\n this.setState('idle');\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\nexport type PanelVariant = 'modal' | 'popover';\n\nexport interface PanelOptions {\n id: string;\n variant: PanelVariant;\n layout?: LayoutSpec;\n /** Title shown at the top of a modal. */\n title?: string;\n}\n\n/**\n * A panel that opens/closes. `modal` = full-screen backdrop + scrollable content\n * + close button; `popover` = small anchored cluster (e.g. the settings flyout).\n * State is the single source of truth (open|closed); the view animates it.\n */\nexport class PanelControl extends Control {\n readonly states: StateMap = {\n closed: { interactable: false },\n open: { interactable: true },\n };\n readonly variant: PanelVariant;\n readonly title?: string;\n\n constructor(opts: PanelOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n super({ id: opts.id, role: 'dialog', layout: opts.layout ?? { anchor: 'center' } }, 'closed');\n this.variant = opts.variant;\n this.title = opts.title;\n }\n\n get isOpen(): boolean {\n return this.current === 'open';\n }\n\n openPanel(): void {\n if (this.isOpen) return;\n this.setState('open');\n this.bus?.emit('panelToggled', { id: this.id, open: true });\n }\n closePanel(): void {\n if (!this.isOpen) return;\n this.setState('closed');\n this.bus?.emit('panelToggled', { id: this.id, open: false });\n }\n toggle(): void {\n if (this.isOpen) this.closePanel();\n else this.openPanel();\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Squish, Pulse, Fade } from '../transition/Transition';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\nexport interface ToggleOptions {\n id: string;\n layout: LayoutSpec;\n /** Initial on/off. Default false. */\n on?: boolean;\n}\n\n/**\n * An on/off toggle (e.g. Turbo). State IS the value: `off` | `on`. Emits `toggled`.\n * The view skins each state (e.g. the Turbo off/on frames).\n */\nexport class ToggleControl extends Control {\n readonly states: StateMap = {\n off: { interactable: true, transition: new Squish(0.92, 110) },\n on: { interactable: true, transition: new Pulse(1.08, 150) },\n disabled: { interactable: false, transition: new Fade(0.4, 150) },\n };\n\n constructor(opts: ToggleOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n super({ id: opts.id, role: 'switch', layout: opts.layout }, opts.on ? 'on' : 'off');\n }\n\n get isOn(): boolean {\n return this.current === 'on';\n }\n\n set(on: boolean): void {\n const next = on ? 'on' : 'off';\n if (next === this.current) return;\n this.setState(next);\n this.bus?.emit('toggled', { id: this.id, on });\n }\n\n /** Called by the view on a valid press-release. */\n toggle(): void {\n if (this.current === 'disabled') return;\n this.set(!this.isOn);\n }\n\n enable(): void {\n if (this.current === 'disabled') this.setState('off');\n }\n disable(): void {\n this.setState('disabled');\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Signal } from '../signal';\nimport { Squish, Pulse, Fade } from '../transition/Transition';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\nexport interface TurboOptions {\n id: string;\n layout: LayoutSpec;\n /**\n * The ordered modes this switcher cycles through. The FIRST mode is \"off\".\n * Two modes (`['off','on']`) behave exactly like a plain on/off toggle; three\n * (`['off','turbo','super']`) make a 3-mode switcher. Default `['off','on']`.\n */\n modes?: string[];\n /** Initial mode index. Default 0 (off). */\n index?: number;\n}\n\n/**\n * Turbo switcher. Each press advances to the next mode and wraps back to \"off\"\n * — so the SAME control is a 2-mode toggle or a 3-mode (off / turbo / super)\n * switcher purely by configuration. The current FSM state IS the current mode,\n * so look + interactivity + tests all read from one place (Charter P5).\n *\n * Emits both `turboChanged` (mode + index, the full story) and `toggled`\n * (`on` = \"any mode past off\") so existing 2-mode listeners keep working.\n */\nexport class TurboControl extends Control {\n states: StateMap;\n private _modes: string[];\n /** Current mode index, observable (0 = off). */\n readonly index: Signal<number>;\n\n constructor(opts: TurboOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n const modes = opts.modes?.length ? opts.modes.slice() : ['off', 'on'];\n const start = clampIndex(opts.index ?? 0, modes.length);\n super({ id: opts.id, role: 'switch', layout: opts.layout }, modes[start]!);\n this._modes = modes;\n this.states = TurboControl.buildStates(modes);\n this.index = new Signal<number>(start);\n }\n\n private static buildStates(modes: string[]): StateMap {\n const states: StateMap = {};\n modes.forEach((m, i) => {\n // \"off\" squishes in; engaged modes pulse, brighter further up the ladder.\n states[m] = { interactable: true, transition: i === 0 ? new Squish(0.92, 110) : new Pulse(1.06 + i * 0.02, 150) };\n });\n states.disabled = { interactable: false, transition: new Fade(0.4, 150) };\n return states;\n }\n\n /** The ordered modes (the first is \"off\"). */\n get modes(): string[] {\n return this._modes;\n }\n /** Number of modes (2 = toggle, 3 = three-mode switcher). */\n get modeCount(): number {\n return this._modes.length;\n }\n /** The current mode name. */\n get mode(): string {\n return this.current;\n }\n /** True for any mode past \"off\" — the 2-mode `isOn` semantics, preserved. */\n get isOn(): boolean {\n return this.current !== 'disabled' && this.index.get() > 0;\n }\n\n /** Replace the mode ladder (e.g. switch a game from 2-mode to 3-mode at runtime). */\n setModes(modes: string[]): void {\n if (!modes.length) return;\n this._modes = modes.slice();\n this.states = TurboControl.buildStates(this._modes);\n this.goTo(clampIndex(this.index.get(), this._modes.length), false);\n }\n\n /** Advance to the next mode, wrapping back to \"off\". The view's tap handler. */\n cycle(): void {\n if (this.current === 'disabled') return;\n this.goTo((this.index.get() + 1) % this._modes.length);\n }\n\n /** Jump to a specific mode index (clamped). */\n setIndex(i: number): void {\n if (this.current === 'disabled') return;\n this.goTo(clampIndex(i, this._modes.length));\n }\n\n /** 2-mode convenience: off (index 0) or on (index 1). */\n set(on: boolean): void {\n this.goTo(on ? Math.min(1, this._modes.length - 1) : 0);\n }\n /** Alias kept so old `toggle()` callers compile — same as `cycle()`. */\n toggle(): void {\n this.cycle();\n }\n\n private goTo(i: number, emit = true): void {\n const next = this._modes[i]!;\n const changed = next !== this.current || i !== this.index.get();\n this.index.set(i);\n this.setState(next); // no-op transition if same state name, but index already synced\n if (emit && changed) {\n this.bus?.emit('turboChanged', { id: this.id, mode: next, index: i });\n this.bus?.emit('toggled', { id: this.id, on: i > 0 });\n }\n }\n\n enable(): void {\n if (this.current === 'disabled') this.goTo(this.index.get(), false);\n }\n disable(): void {\n this.setState('disabled');\n }\n}\n\nfunction clampIndex(i: number, len: number): number {\n if (!Number.isFinite(i)) return 0;\n return Math.max(0, Math.min(Math.floor(i), len - 1));\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Signal } from '../signal';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\nexport interface StepperOptions {\n id: string;\n layout: LayoutSpec;\n /** Ordered list of allowed values (e.g. bet levels). */\n levels: number[];\n /** Starting index into `levels`. Default 0. */\n index?: number;\n /** Optional caption (e.g. \"Bet\"). */\n label?: string;\n}\n\n/**\n * Steps through a host-provided ordered list of values (bet levels). `inc`/`dec`\n * move the index and clamp at the ends; `canInc`/`canDec` drive the +/- buttons'\n * enabled state. Emits `valueChanged` with the resolved value.\n */\nexport class StepperControl extends Control {\n readonly states: StateMap = { idle: { interactable: true } };\n readonly index: Signal<number>;\n /** Optional caption (e.g. \"Bet\"). */\n readonly label?: string;\n private levels: number[];\n\n constructor(opts: StepperOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n super({ id: opts.id, role: 'spinbutton', layout: opts.layout }, 'idle');\n this.levels = opts.levels.length ? opts.levels : [0];\n this.index = new Signal<number>(this.clampIndex(opts.index ?? 0));\n this.label = opts.label;\n }\n\n private clampIndex(i: number): number {\n return Math.max(0, Math.min(this.levels.length - 1, i));\n }\n\n get value(): number {\n return this.levels[this.index.get()] ?? 0;\n }\n get canInc(): boolean {\n return this.index.get() < this.levels.length - 1;\n }\n get canDec(): boolean {\n return this.index.get() > 0;\n }\n\n inc(): void {\n if (this.canInc) this.setIndex(this.index.get() + 1);\n }\n dec(): void {\n if (this.canDec) this.setIndex(this.index.get() - 1);\n }\n\n setIndex(i: number): void {\n const next = this.clampIndex(i);\n if (next === this.index.get()) return;\n this.index.set(next);\n this.bus?.emit('valueChanged', { id: this.id, value: this.value });\n }\n\n /** Replace the level list (e.g. when the currency/limits change). */\n setLevels(levels: number[], index = 0): void {\n const prior = this.value;\n if (levels.length) this.levels = levels;\n this.index.set(this.clampIndex(index));\n // Emit only when the resolved value actually changed (mirrors setIndex) —\n // a no-op setLevels must not fire a spurious public valueChanged / log entry.\n if (this.value !== prior) this.bus?.emit('valueChanged', { id: this.id, value: this.value });\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Signal } from '../signal';\nimport { Squish, Pulse, Fade } from '../transition/Transition';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\n/**\n * How tapping autoplay behaves:\n * - `'options'` — tap opens a picker (a bottom drawer) to choose a spin count, then Start.\n * - `'infinite'` — tap starts infinite autoplay immediately; tap again stops. No picker.\n */\nexport type AutoplayMode = 'options' | 'infinite';\n\n/** Responsible-gambling stop limits for an autoplay session (multiples of bet). */\nexport interface AutoplayLimits {\n /** Stop when cumulative net loss reaches `lossLimit × bet`. Infinity = no limit. */\n lossLimit?: number;\n /** Stop on a single win ≥ `singleWinLimit × bet`. Infinity = no limit. */\n singleWinLimit?: number;\n}\n\nexport interface AutoplayOptions {\n id: string;\n layout: LayoutSpec;\n /** Count choices shown in the picker. Use Infinity for \"∞\". */\n options?: number[];\n /** Tap behavior. Default `'options'`. */\n mode?: AutoplayMode;\n /**\n * Optional responsible-gambling limit choices offered in the picker (multiples\n * of the bet; Infinity = \"no limit\"). When present, the picker shows a\n * \"stop if total loss reaches N×\" / \"stop on a single win ≥ N×\" row, and the\n * host must feed each round's outcome via {@link AutoplayControl.reportResult}.\n */\n lossLimitOptions?: number[];\n winLimitOptions?: number[];\n}\n\n/**\n * Autoplay button. In `'options'` mode, tapping (idle) opens a count picker;\n * choosing a count starts autoplay. In `'infinite'` mode, tapping starts infinite\n * autoplay straight away. While active it shows the live remaining count (fed by\n * the host via `setCount`); tapping stops. open-ui owns the picker UI + the\n * displayed count; the host runs the actual spin loop.\n */\nexport class AutoplayControl extends Control {\n readonly states: StateMap = {\n idle: { interactable: true, transition: new Squish(0.94, 110) },\n picking: { interactable: true },\n active: { interactable: true, transition: new Pulse(1.06, 150) },\n disabled: { interactable: false, transition: new Fade(0.4, 150) },\n };\n /** Remaining spins while active (Infinity = ∞). 0 when not active. */\n readonly count: Signal<number>;\n private _options: number[];\n private _lossLimitOptions: number[];\n private _winLimitOptions: number[];\n /** Active stop-on-total-loss (multiples of bet; Infinity = no limit). */\n lossLimit = Infinity;\n /** Active stop-on-single-win (multiples of bet; Infinity = no limit). */\n singleWinLimit = Infinity;\n /** Running net loss this autoplay session (bet − win, summed). */\n private netLoss = 0;\n /** Tap behavior (`'options'` opens the picker, `'infinite'` starts immediately). */\n mode: AutoplayMode;\n\n constructor(opts: AutoplayOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n super({ id: opts.id, role: 'button', layout: opts.layout }, 'idle');\n this._options = opts.options ?? [10, 25, 50, 100, Infinity];\n this._lossLimitOptions = opts.lossLimitOptions ?? [];\n this._winLimitOptions = opts.winLimitOptions ?? [];\n this.mode = opts.mode ?? 'options';\n this.count = new Signal<number>(0);\n }\n\n /** Count choices shown in the picker (Infinity allowed = ∞). */\n get options(): number[] {\n return this._options;\n }\n /** Loss-limit choices for the picker (multiples of bet; Infinity = no limit). */\n get lossLimitOptions(): number[] {\n return this._lossLimitOptions;\n }\n /** Single-win-stop choices for the picker (multiples of bet; Infinity = no limit). */\n get winLimitOptions(): number[] {\n return this._winLimitOptions;\n }\n\n /** Replace the picker's count choices (e.g. when limits change). */\n setOptions(options: number[]): void {\n if (options.length) this._options = options.slice();\n }\n /** Replace the picker's loss-limit / single-win-stop choices. */\n setLossLimitOptions(options: number[]): void {\n this._lossLimitOptions = Array.isArray(options) ? options.slice() : [];\n }\n setWinLimitOptions(options: number[]): void {\n this._winLimitOptions = Array.isArray(options) ? options.slice() : [];\n }\n\n get isActive(): boolean {\n return this.current === 'active';\n }\n\n openPicker(): void {\n if (this.current === 'idle') this.setState('picking');\n }\n cancelPicker(): void {\n if (this.current === 'picking') this.setState('idle');\n }\n\n /** Choose a count (+ optional RG limits) from the picker → start autoplay. */\n pick(count: number, limits: AutoplayLimits = {}): void {\n if (this.current !== 'picking') return;\n this.begin(count, limits);\n }\n\n /** Start autoplay with a count (Infinity = ∞) + optional RG limits, from idle or\n * the picker. The limits are enforced as the host reports each round's outcome\n * via {@link reportResult}. */\n begin(count: number, limits: AutoplayLimits = {}): void {\n if (this.current !== 'idle' && this.current !== 'picking') return;\n this.lossLimit = limits.lossLimit ?? Infinity;\n this.singleWinLimit = limits.singleWinLimit ?? Infinity;\n this.netLoss = 0;\n this.count.set(count);\n this.setState('active');\n this.bus?.emit('autoplayStarted', { count, lossLimit: this.lossLimit, singleWinLimit: this.singleWinLimit });\n }\n\n /**\n * The host reports one completed autoplay round's outcome (major units) — this is\n * the responsible-gambling guardrail. It advances the remaining count and stops\n * autoplay if: the count is exhausted, the cumulative net loss reaches the\n * loss-limit, or this single win reaches the single-win-stop. No-op when autoplay\n * isn't active or the inputs are malformed (Charter P11).\n */\n reportResult(win: number, bet: number): void {\n if (this.current !== 'active') return;\n if (!Number.isFinite(win) || !Number.isFinite(bet)) return;\n this.netLoss += bet - win;\n const c = this.count.get();\n if (Number.isFinite(c)) this.count.set(Math.max(0, c - 1));\n const winHit = Number.isFinite(this.singleWinLimit) && win >= this.singleWinLimit * bet;\n const lossHit = Number.isFinite(this.lossLimit) && this.netLoss >= this.lossLimit * bet;\n if (this.count.get() <= 0 || winHit || lossHit) this.stop();\n }\n\n stop(): void {\n if (this.current !== 'active') return;\n this.count.set(0);\n this.setState('idle');\n this.bus?.emit('autoplayStopped', undefined);\n }\n\n /** Host updates the remaining count during play. Infinity is valid (∞); only\n * NaN/non-number is rejected, so bad host data never corrupts the badge (P11). */\n setCount(n: number): void {\n if (typeof n !== 'number' || Number.isNaN(n)) return;\n this.count.set(n);\n }\n\n /** The view's tap handler. In `'infinite'` mode, idle starts straight away;\n * in `'options'` mode, idle opens the picker. Active always stops. */\n press(): void {\n if (this.current === 'idle') {\n if (this.mode === 'infinite') this.begin(Infinity);\n else this.openPicker();\n } else if (this.current === 'active') this.stop();\n else if (this.current === 'picking') this.cancelPicker();\n }\n\n disable(): void {\n this.setState('disabled');\n }\n enable(): void {\n if (this.current === 'disabled') this.setState('idle');\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Signal } from '../signal';\nimport { safeAmount } from '../safe';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { CurrencySpec } from './ValueDisplay';\n\n/**\n * What a readout shows:\n * - `'percent'` → a number + \"%\" (RTP disclosure — `displayRTP`)\n * - `'currency'` → a signed currency amount (net position — `displayNetPosition`)\n * - `'duration'` → an elapsed clock the view ticks (session timer — `displaySessionTimer`)\n * - `'plain'` → the grouped number\n */\nexport type ReadoutKind = 'percent' | 'currency' | 'duration' | 'plain';\n\nexport interface ReadoutOptions {\n id: string;\n layout: LayoutSpec;\n kind?: ReadoutKind;\n label?: string;\n /** Initial value (percent: 96, currency: major units, duration: seconds). */\n value?: number;\n /** Decimals for `percent`/`plain`. Default 1 for percent, 0 otherwise. */\n decimals?: number;\n /** Currency descriptor for the `currency` kind. */\n currency?: CurrencySpec;\n /** Whether a `currency` readout shows an explicit +/- sign. Default true. */\n signed?: boolean;\n}\n\n/**\n * A small, non-interactive text readout for the compliance display elements Stake\n * Engine's jurisdiction config can mandate: RTP (`displayRTP`), net position\n * (`displayNetPosition`), and the session timer (`displaySessionTimer`). It is the\n * single source of truth for the value; the renderer formats it (and, for\n * `'duration'`, ticks it). Hidden by default — `applyJurisdiction` reveals the ones\n * a jurisdiction requires. Never-reject inbound boundary (Charter P11).\n */\nexport class ReadoutControl extends Control {\n readonly states: StateMap = { idle: { interactable: false } };\n readonly value = new Signal<number>(0);\n /** Whether a `'duration'` readout is currently advancing. */\n readonly running = new Signal<boolean>(false);\n /** Accent emphasis: the renderer tints the value in the theme accent while on — for\n * a MODIFIED readout (e.g. net position while a bet boost is active). Mirrors\n * {@link ValueDisplay.emphasized}. */\n readonly emphasized = new Signal<boolean>(false);\n readonly kind: ReadoutKind;\n readonly label?: string;\n readonly decimals: number;\n readonly signed: boolean;\n /** Present for the `'currency'` kind so the view can format + react to changes. */\n readonly currency?: Signal<CurrencySpec>;\n\n constructor(opts: ReadoutOptions) {\n super({ id: opts.id, role: 'status', layout: opts.layout }, 'idle');\n this.kind = opts.kind ?? 'plain';\n this.label = opts.label;\n this.decimals = opts.decimals ?? (this.kind === 'percent' ? 1 : 0);\n this.signed = opts.signed ?? true;\n if (opts.currency) this.currency = new Signal<CurrencySpec>(opts.currency);\n if (opts.value != null) this.value.set(safeAmount(opts.value, 0));\n }\n\n /** Never-reject: malformed input keeps the last good value (P11). */\n set(v: number): void {\n this.value.set(safeAmount(v, this.value.get()));\n }\n /** Accent-tint the value (\"this readout is modified\"). Strict boolean. */\n setEmphasis(on: boolean): void {\n this.emphasized.set(on === true);\n }\n get(): number {\n return this.value.get();\n }\n setCurrency(spec: CurrencySpec): void {\n if (this.currency && spec && typeof spec.code === 'string') this.currency.set(spec);\n }\n\n // ── duration / session timer ────────────────────────────────────────────────\n /** Advance an elapsed-time readout by `deltaSec` (the renderer calls this each frame). */\n tick(deltaSec: number): void {\n if (this.kind !== 'duration' || !this.running.get()) return;\n if (!Number.isFinite(deltaSec) || deltaSec <= 0) return;\n this.value.set(this.value.get() + deltaSec);\n }\n start(): void {\n this.running.set(true);\n }\n stop(): void {\n this.running.set(false);\n }\n reset(): void {\n this.value.set(0);\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Squish, Pulse, Fade } from '../transition/Transition';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\nexport interface CardOptions {\n id: string;\n layout: LayoutSpec;\n /** Card title (e.g. the feature name). */\n title?: string;\n /** Price / cost shown on the card (formatted string or number). */\n price?: string;\n /** Asset id/key for the card image (resolved by the view/host). */\n image?: string;\n}\n\n/**\n * A selectable buy-feature card: image + title + price + a buy action.\n * Emits `cardActivated` on a valid press-release. Lives inside a buy-feature panel.\n */\nexport class CardControl extends Control {\n readonly states: StateMap = {\n idle: { interactable: true, transition: new Squish(0.96, 110) },\n hover: { interactable: true, transition: new Pulse(1.04, 140) },\n pressed: { interactable: true, transition: new Squish(0.9, 70) },\n disabled: { interactable: false, transition: new Fade(0.4, 150) },\n };\n title?: string;\n price?: string;\n image?: string;\n\n constructor(opts: CardOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n super({ id: opts.id, role: 'button', layout: opts.layout }, 'idle');\n this.title = opts.title;\n this.price = opts.price;\n this.image = opts.image;\n }\n\n enable(): void {\n if (this.current === 'disabled') this.setState('idle');\n }\n disable(): void {\n this.setState('disabled');\n }\n\n /** The view calls this on a valid press-release. */\n activate(): void {\n if (this.interactable) this.bus?.emit('cardActivated', { id: this.id });\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Signal } from '../signal';\nimport { Squish, Pulse, Fade } from '../transition/Transition';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\nexport interface SelectOption {\n value: string;\n label: string;\n}\n\nexport interface SelectControlOptions {\n id: string;\n layout: LayoutSpec;\n options: SelectOption[];\n index?: number;\n /** Caption shown beside the control (e.g. \"Language\"). */\n label?: string;\n role?: string;\n}\n\n/**\n * A single-choice select (language, quality, …). FSM peer of StepperControl:\n * `closed | open | disabled`. Tapping cycles or opens a list; all logic is\n * headless and the renderer just draws it. Emits its OWN typed `optionSelected`\n * event rather than overloading the numeric `valueChanged` (Charter B1, P5).\n */\nexport class SelectControl extends Control {\n readonly states: StateMap = {\n closed: { interactable: true, transition: new Squish(0.96, 100) },\n open: { interactable: true, transition: new Pulse(1.04, 140) },\n disabled: { interactable: false, transition: new Fade(0.4, 150) },\n };\n readonly index: Signal<number>;\n /** Caption (e.g. \"Language\") — distinct from the selected option's label. */\n readonly caption?: string;\n private _options: SelectOption[];\n\n constructor(opts: SelectControlOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n if (!opts.options || opts.options.length === 0) {\n throw new Error(`[open-ui] select \"${opts.id}\": needs at least one option`);\n }\n super({ id: opts.id, role: opts.role ?? 'listbox', layout: opts.layout }, 'closed');\n this._options = opts.options.slice();\n this.caption = opts.label;\n this.index = new Signal<number>(this.clamp(opts.index ?? 0));\n }\n\n private clamp(i: number): number {\n if (!Number.isFinite(i)) return 0;\n return Math.max(0, Math.min(this._options.length - 1, Math.trunc(i)));\n }\n\n get options(): ReadonlyArray<SelectOption> {\n return this._options;\n }\n get value(): string {\n return this._options[this.index.get()]?.value ?? '';\n }\n get optionLabel(): string {\n return this._options[this.index.get()]?.label ?? '';\n }\n get isOpen(): boolean {\n return this.current === 'open';\n }\n\n openList(): void {\n if (this.current === 'closed') this.setState('open');\n }\n closeList(): void {\n if (this.current === 'open') this.setState('closed');\n }\n\n /** Choose by value (the view's list-item handler). Closes the list. */\n choose(value: string): void {\n const i = this._options.findIndex((o) => o.value === value);\n if (i < 0) return;\n if (i !== this.index.get()) {\n this.index.set(i);\n this.bus?.emit('optionSelected', { id: this.id, value: this.value, index: i });\n }\n if (this.current === 'open') this.setState('closed');\n }\n\n /** Jump to an index (clamped). Emits only if it changed. */\n setIndex(i: number): void {\n const next = this.clamp(i);\n if (next === this.index.get()) return;\n this.index.set(next);\n this.bus?.emit('optionSelected', { id: this.id, value: this.value, index: next });\n }\n\n /** Advance to the next option, wrapping (the view's cycle-on-tap handler). */\n cycle(): void {\n if (this._options.length < 2) return;\n this.setIndex((this.index.get() + 1) % this._options.length);\n }\n\n /** Replace the option list (e.g. when limits or locale change). */\n setOptions(options: SelectOption[], index = 0): void {\n if (!options.length) return;\n this._options = options.slice();\n this.index.set(this.clamp(index));\n this.bus?.emit('optionSelected', { id: this.id, value: this.value, index: this.index.get() });\n }\n\n enable(): void {\n if (this.current === 'disabled') this.setState('closed');\n }\n disable(): void {\n this.setState('disabled');\n }\n}\n","import { defaultTheme, extendTheme, type Theme, type DeepPartial } from './tokens';\n\n/** Built-in presets. open-ui ships a SINGLE canonical look — black & white with a\n * yellow accent (the `default` token theme). Hosts restyle via `ThemeOverrides`\n * (sanitized colours/radius/font), so the library stays themeable without shipping\n * a palette zoo. Unknown preset names resolve to `default`. */\nexport type ThemePreset = 'default';\n\n/**\n * The SAFE, curated surface a host may override (Charter P8 + \"configure, don't\n * break\"). Deliberately a subset of the full `Theme`: colours, corner radii, and\n * the font family — the look knobs. Structural tokens (spacing, motion timing,\n * font sizes) are NOT exposed, so a theme can restyle the HUD but cannot break its\n * layout or timing. Every value is validated/clamped at runtime too (see below).\n */\nexport interface ThemeOverrides {\n color?: Partial<Theme['color']>;\n radius?: Partial<Theme['radius']>;\n type?: { family?: string };\n}\n\n/** A reportable theme problem (structurally a `SpecIssue`, kept dependency-free). */\nexport interface ThemeIssue {\n level: 'warn' | 'error';\n path: string;\n code: string;\n message: string;\n}\n\n/**\n * What a host can pass for `theme`: a preset name, a safe override (layered on the\n * default), or `{ preset, overrides }` to layer a safe override on a chosen preset.\n */\nexport type ThemeChoice =\n | ThemePreset\n | ThemeOverrides\n | { preset?: ThemePreset; overrides?: ThemeOverrides };\n\n/** The one ready-to-use theme: black & white with a yellow accent (`defaultTheme`). */\nexport const themePresets: Readonly<Record<ThemePreset, Theme>> = Object.freeze({\n default: defaultTheme,\n}) as Readonly<Record<ThemePreset, Theme>>;\n\n// A pragmatic CSS-colour check: hex (#rgb/#rgba/#rrggbb/#rrggbbaa) or rgb()/rgba().\nconst HEX = /^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;\nconst RGB = /^rgba?\\(\\s*[0-9.\\s,%/]+\\)$/i;\n\n/** True for a colour string the renderer can safely use. */\nexport function isSafeColor(v: unknown): v is string {\n return typeof v === 'string' && (HEX.test(v.trim()) || RGB.test(v.trim()));\n}\n\nconst clamp = (n: number, lo: number, hi: number): number => Math.max(lo, Math.min(hi, n));\n\n/**\n * Turn host overrides into a guaranteed-safe `DeepPartial<Theme>`: invalid colours\n * are dropped (the base token shows through), radii are clamped to a sane range,\n * and a non-string font family is ignored. Each rejection is reported, never fatal.\n */\nexport function sanitizeThemeOverrides(ov: ThemeOverrides, onIssue?: (i: ThemeIssue) => void): DeepPartial<Theme> {\n const out: DeepPartial<Theme> = {};\n if (ov.color) {\n const color: Partial<Theme['color']> = {};\n for (const [k, v] of Object.entries(ov.color)) {\n if (isSafeColor(v)) color[k as keyof Theme['color']] = v.trim();\n else onIssue?.({ level: 'warn', path: `theme.color.${k}`, code: 'bad-color', message: `\"${String(v)}\" is not a valid colour — kept the theme default` });\n }\n if (Object.keys(color).length) out.color = color;\n }\n if (ov.radius) {\n const radius: Partial<Theme['radius']> = {};\n for (const [k, v] of Object.entries(ov.radius)) {\n if (typeof v === 'number' && Number.isFinite(v)) radius[k as keyof Theme['radius']] = clamp(v, 0, 999);\n else onIssue?.({ level: 'warn', path: `theme.radius.${k}`, code: 'bad-radius', message: `radius \"${String(v)}\" must be a finite number — ignored` });\n }\n if (Object.keys(radius).length) out.radius = radius;\n }\n if (ov.type?.family != null) {\n if (typeof ov.type.family === 'string' && ov.type.family.trim()) out.type = { family: ov.type.family };\n else onIssue?.({ level: 'warn', path: 'theme.type.family', code: 'bad-family', message: 'font family must be a non-empty string — ignored' });\n }\n return out;\n}\n\nfunction isPresetChoice(c: ThemeChoice): c is { preset?: ThemePreset; overrides?: ThemeOverrides } {\n return typeof c === 'object' && c !== null && ('preset' in c || 'overrides' in c);\n}\n\n/**\n * Resolve any `ThemeChoice` into a concrete, frozen Theme. Overrides are\n * sanitized first, so a host can restyle the HUD but never break it: bad values\n * fall back to the safe token (Charter P8/G5/P11). Pass `onIssue` to surface\n * rejections (createUI forwards these to `HostHooks.onDataIssue`).\n */\nexport function resolveTheme(choice?: ThemeChoice, onIssue?: (i: ThemeIssue) => void): Theme {\n if (!choice) return defaultTheme;\n if (typeof choice === 'string') return themePresets[choice] ?? defaultTheme;\n if (isPresetChoice(choice)) {\n const base = choice.preset ? themePresets[choice.preset] ?? defaultTheme : defaultTheme;\n if (!choice.overrides) return base;\n return Object.freeze(extendTheme(base, sanitizeThemeOverrides(choice.overrides, onIssue)));\n }\n return Object.freeze(extendTheme(defaultTheme, sanitizeThemeOverrides(choice as ThemeOverrides, onIssue)));\n}\n","/**\n * Resolves a declarative BlockSpec into a real Control. This is the swap-by-class\n * seam (Charter P7): the defaults can be overridden per kind, so a game can drop\n * in its own control class without forking. Keyed by block `kind`.\n */\nimport type { Control } from '../control/Control';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\nimport type { BlockSpec } from '../spec/types';\nimport { SliderControl } from '../controls/SliderControl';\nimport { ToggleControl } from '../controls/ToggleControl';\nimport { ButtonControl } from '../controls/ButtonControl';\nimport { SelectControl } from '../controls/SelectControl';\nimport { StepperControl } from '../controls/StepperControl';\nimport { ValueDisplay } from '../controls/ValueDisplay';\n\nexport type BlockFactory = (block: BlockSpec, bus: EventBus<OpenUIEvents>) => Control | null;\n\n/** Leaf controls are laid out by the panel body, so they anchor at center here. */\nconst CENTER = { anchor: 'center' } as const;\n\nexport class ControlRegistry {\n private readonly factories = new Map<string, BlockFactory>();\n\n register(kind: string, factory: BlockFactory): void {\n this.factories.set(kind, factory);\n }\n\n has(kind: string): boolean {\n return this.factories.has(kind);\n }\n\n /** Build the Control for a block, or null for non-control blocks / unknown kinds. */\n resolve(block: BlockSpec, bus: EventBus<OpenUIEvents>): Control | null {\n return this.factories.get(block.kind)?.(block, bus) ?? null;\n }\n\n /** A registry with every built-in block kind wired to its reference control. */\n static defaults(): ControlRegistry {\n const r = new ControlRegistry();\n r.register('slider', (b, bus) =>\n b.kind === 'slider' ? new SliderControl({ id: b.id, layout: CENTER, label: b.label, initial: b.initial }, bus) : null);\n r.register('toggle', (b, bus) =>\n b.kind === 'toggle' ? new ToggleControl({ id: b.id, layout: CENTER, on: b.on }, bus) : null);\n r.register('button', (b, bus) =>\n b.kind === 'button' ? new ButtonControl({ id: b.id, layout: CENTER, label: b.label, role: b.role }, bus) : null);\n r.register('select', (b, bus) =>\n b.kind === 'select' ? new SelectControl({ id: b.id, layout: CENTER, options: b.options, index: b.index, label: b.label }, bus) : null);\n r.register('stepper', (b, bus) =>\n b.kind === 'stepper' ? new StepperControl({ id: b.id, layout: CENTER, levels: b.levels, index: b.index, label: b.label }, bus) : null);\n r.register('value', (b) =>\n b.kind === 'value' ? new ValueDisplay({ id: b.id, layout: CENTER, label: b.label, currency: b.currency ?? { code: 'USD', decimals: 2 }, initial: b.initial }) : null);\n // 'text' and 'group' carry no control — buildPanel handles them directly.\n return r;\n }\n}\n","/**\n * The JSON-serializable UISpec — the single source of truth that builds the\n * control tree, drives e2e, and powers the docs panel editor (the \"SpecKit\"\n * design). Authoring it is type-checked; `validateSpec` guards it at runtime;\n * `createUI` assembles it over the existing OpenUI machinery.\n */\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { LayoutConfig, Breakpoint, Orientation } from '../layout/screen';\nimport type { ThemeChoice } from '../theme/presets';\nimport type { CurrencySpec } from '../controls/ValueDisplay';\nimport type { SelectOption } from '../controls/SelectControl';\nimport type { AutoplayMode } from '../controls/AutoplayControl';\nimport type { PanelVariant, PanelControl } from '../controls/PanelControl';\nimport type { Control } from '../control/Control';\nimport type { OpenUIEvents } from '../types';\nimport type { MenuSpec } from './menu';\nimport type { JurisdictionConfig } from './jurisdiction';\nimport type { GameFacts } from './facts';\n\n/** The reference-HUD control ids — typed so a typo is a compile error. */\nexport type KnownControlId =\n | 'spin'\n | 'balance'\n | 'bet'\n | 'settings'\n | 'settings-panel'\n | 'music'\n | 'sfx'\n | 'rules'\n | 'info-panel'\n | 'info-close'\n | 'turbo'\n | 'autoplay'\n | 'bonus'\n | 'bet-stepper'\n | 'bet-plus'\n | 'bet-minus'\n | 'fullscreen'\n | 'mute'\n | 'rtp'\n | 'net-position'\n | 'session-timer'\n | 'notice-panel';\n\n/** One issue from the never-throw validator. */\nexport interface SpecIssue {\n level: 'error' | 'warn';\n path: string;\n code: string;\n message: string;\n}\n\n/** Host-owned side effects, injected (the lib performs none itself — Charter B8). */\nexport interface HostHooks {\n onDataIssue?(issue: SpecIssue): void;\n onAnalyticsEvent?: <K extends keyof OpenUIEvents>(type: K, payload: OpenUIEvents[K]) => void;\n}\n\n/** A targeted override for one shipped control. Anything omitted keeps the default. */\nexport interface ControlOverride {\n layout?: LayoutSpec;\n label?: string;\n hidden?: boolean;\n disabled?: boolean;\n currency?: CurrencySpec;\n initial?: number;\n /** Value-display only: MINIMUM odometer column width. `0`/unset = auto — the counter\n * is sized tightly to the value (symbol hugs the number) and grows as it does, so\n * balances never clamp. Set it only to reserve a stable, wider readout. Clamped\n * 0..18; ignored by non-value controls. Default 0 (auto). */\n digits?: number;\n}\n\n/**\n * Turbo switcher config. Choose how many modes the one Turbo control cycles\n * through — `2` (off/on) or `3` (off/turbo/super) — or pass explicit mode names.\n */\nexport interface TurboSpec {\n /** `2` → off/on · `3` → off/turbo/super · or a custom ordered ladder (first = off). */\n modes?: 2 | 3 | string[];\n /** Initial mode index (0 = off). */\n index?: number;\n}\n\n/** How pressing the spin button behaves. */\nexport type SpinPress = 'tap' | 'hold-to-spin';\n\nexport interface SpinSpec {\n /** `'tap'` = one spin per tap · `'hold-to-spin'` = turbo-spin while held. Default `'tap'`. */\n press?: SpinPress;\n}\n\n/** A responsive bucket the config can target: a device size OR an orientation. */\nexport type ResponsiveKey = Breakpoint | Orientation;\n\n/** What a responsive bucket may change. Layout + visibility, per control. */\nexport interface ResponsiveOverride {\n controls?: Record<string, Pick<ControlOverride, 'layout' | 'hidden'>>;\n}\n\n/**\n * A declarative menu/panel content block. Discriminated by `kind` so a \"shown but\n * no payload\" bug is uncompilable (Charter B10): a `select` cannot omit options,\n * a `slider` cannot carry them.\n *\n * Every block may carry `covers` — rules-audit topic tags (e.g. `'rtp:bonus'`,\n * `'freespins'`) marking that this block's hand-written prose covers a declaration\n * the audit's text heuristics can't see. See `auditRules` in `spec/facts`.\n */\nexport type BlockSpec = {\n /** Rules-audit topics this block covers (see `auditRules`). */\n covers?: string[];\n} & (\n // `hint` is a short description of what the control does, shown dim UNDER it — so\n // every interactive control in the Info/settings menu explains its own function.\n | { kind: 'slider'; id: string; label?: string; initial?: number; hint?: string }\n | { kind: 'toggle'; id: string; label?: string; on?: boolean; hint?: string }\n | { kind: 'button'; id: string; label: string; action?: 'closePanel' | 'openPanel' | 'emit'; target?: string; role?: string; hint?: string }\n | { kind: 'select'; id: string; label?: string; options: SelectOption[]; index?: number; hint?: string }\n | { kind: 'stepper'; id: string; label?: string; levels: number[]; index?: number; hint?: string }\n | { kind: 'value'; id: string; label?: string; currency?: CurrencySpec; initial?: number }\n | { kind: 'text'; id: string; text: string }\n // ── static \"rules\"/info content (no control; every text run through `ui.t`) ──\n | { kind: 'heading'; id: string; text: string }\n | { kind: 'subheading'; id: string; text: string }\n | { kind: 'callout'; id: string; tone?: 'info' | 'bonus' | 'warning'; title?: string; text: string }\n | { kind: 'stat-grid'; id: string; items: Array<{ label: string; value: string }> }\n // AUTO-GENERATED per-mode RTP / Max-win grid, rendered straight from `UISpec.facts`\n // (+ `ui.declareFacts`) — declared once, so the table can never drift from the config.\n | { kind: 'mode-stats'; id: string; extras?: Array<{ label: string; value: string }> }\n | { kind: 'steps'; id: string; ordered?: boolean; items: string[] }\n | { kind: 'table'; id: string; columns?: string[]; rows: string[][] }\n | { kind: 'paytable'; id: string; columns?: number; rows: Array<{ symbol?: string; payouts: string; icon?: string }> }\n | { kind: 'image'; id: string; src: string; alt?: string; width?: number; height?: number }\n | { kind: 'media'; id: string; src: string; alt?: string; side?: 'left' | 'right'; title?: string; text: string; width?: number; height?: number }\n | { kind: 'cards'; id: string; items: Array<{ icon?: string; title: string; text?: string }> }\n | { kind: 'legal'; id: string; text: string }\n | { kind: 'divider'; id: string }\n | { kind: 'group'; id: string; title?: string; children: BlockSpec[] }\n);\n\n/** All block kinds, for runtime validation of untyped host data. */\nexport const BLOCK_KINDS = [\n 'slider',\n 'toggle',\n 'button',\n 'select',\n 'stepper',\n 'value',\n 'text',\n 'heading',\n 'subheading',\n 'callout',\n 'stat-grid',\n 'mode-stats',\n 'steps',\n 'table',\n 'paytable',\n 'image',\n 'media',\n 'cards',\n 'legal',\n 'divider',\n 'group',\n] as const;\n\nexport interface PanelSpec {\n id: string;\n variant: PanelVariant;\n title?: string;\n layout?: LayoutSpec;\n blocks: BlockSpec[];\n}\n\n/** The whole UI as one optional, JSON-serializable object. Omit any field → default. */\nexport interface UISpec {\n meta?: { id: string; version: number };\n theme?: ThemeChoice;\n layout?: LayoutConfig;\n /** Balance + bet currency: a full spec, or a code string (e.g. `'JPY'`, `'XGC'`)\n * auto-resolved (decimals, social coins) via the built-in currency table. */\n currency?: CurrencySpec | string;\n betLadder?: { levels: number[]; index?: number };\n /**\n * Autoplay count choices + tap behavior (`'options'` drawer or `'infinite'`), plus\n * optional responsible-gambling limit choices (multiples of bet; Infinity = none).\n * When `lossLimits`/`winLimits` are set, the picker offers them and the host must\n * feed each round to `hud.reportRound(win, bet)` so they're enforced.\n * `insufficientFundsNotice` (default true): when autoplay stops with the balance\n * unable to cover the next round, show the same insufficient-funds modal a manual\n * spin shows (ERR_IPB) instead of ending silently.\n */\n autoplay?: { options?: number[]; mode?: AutoplayMode; lossLimits?: number[]; winLimits?: number[]; insufficientFundsNotice?: boolean };\n /** Turbo switcher: 2-mode (off/on) or 3-mode (off/turbo/super). */\n turbo?: TurboSpec;\n /** Spin button behavior: single `'tap'` or `'hold-to-spin'` turbo. */\n spin?: SpinSpec;\n /**\n * Per-device / per-orientation overrides, layered on top of `controls`. Keys are\n * `'mobile' | 'tablet' | 'desktop'` (device size) and `'portrait' | 'landscape'`\n * (orientation); on each resize the matching buckets re-apply, so the HUD can\n * reflow or drop controls per screen. Order: base → orientation → size.\n */\n responsive?: Partial<Record<ResponsiveKey, ResponsiveOverride>>;\n controls?: Partial<Record<KnownControlId, ControlOverride>> & Record<string, ControlOverride>;\n /** The unified scrollable MENU opened by ☰: Settings → Paytable → Rules. */\n menu?: MenuSpec;\n /** Back-compat: rules blocks, folded into the menu's Rules section if `menu.rules` is absent. */\n rules?: BlockSpec[];\n /** Additional declarative panels. */\n panels?: PanelSpec[];\n /** i18n dictionary + starting locale (built into a DictionaryTranslator). */\n locale?: {\n messages: Record<string, Record<string, string>>;\n locale: string;\n /** SEPARATE social/sweepstakes wording dictionary (same keys as `messages`),\n * used only in social mode — kept apart so the two can't be mixed up. */\n socialMessages?: Record<string, Record<string, string>>;\n };\n /** Block/control id whose `optionSelected` switches the locale. Default 'lang'. */\n localeSelectId?: string;\n /** Auto-lock the whole HUD while the spin control is spinning. Default true. */\n lockDuringSpin?: boolean;\n /**\n * Stake Engine per-player jurisdiction config — the compliance switchboard. Usually\n * known only after the game authenticates, so prefer the runtime\n * `hud.applyJurisdiction(jur)`; set it here when known up front (createUI applies it\n * before the responsive layer so `disabled*` hides survive resizes).\n */\n jurisdiction?: JurisdictionConfig;\n /** Initial RTP percentage for the RTP readout (e.g. 96 → \"96.0%\"). */\n rtp?: number;\n /** Game name + version — shown in the menu footer (support / certification). */\n game?: { name?: string; version?: string };\n /**\n * Structured GAME FACTS — what the game HAS: its math modes (base / buy features /\n * boosts) with RTP + max win, its free-spins behavior, volatility and cap. Drives\n * the auto `mode-stats` rules block AND the rules-completeness audit: a configured\n * mode whose RTP / max win / description is missing from the rules is called out\n * explicitly in the info menu (see `auditRules`). The buy-feature modal declares\n * its configured features into this automatically (`ui.declareFacts`).\n */\n facts?: GameFacts;\n /** Buy-feature / bet-mode confirmation. `confirmAboveCost` (× base bet) makes any\n * play costing MORE than that require a confirm step before it commits — Stake\n * requires bet modes above 2× to never activate on a single click, so set `2`.\n * The game routes a purchase/activation through `hud.requestBuyFeature(...)`, which\n * shows the confirm popup itself when the cost exceeds the threshold. A jurisdiction\n * can set the same threshold (`JurisdictionConfig.confirmBuyAboveCost`). */\n buyFeature?: { confirmAboveCost?: number };\n /** Reality-check reminder (RTS 13): open-ui runs a wall-clock timer, emits a\n * `realityCheck` event, stops autoplay, and (unless `showModal:false`) shows an\n * acknowledge modal. You supply only the cadence + text. `title`/`message` are\n * literal-or-key with `{{minutes}}`/`{{spent}}`/`{{won}}` interpolation. */\n realityCheck?: { everyMinutes: number; title?: string; message?: string; showModal?: boolean };\n /** Social / sweepstakes mode: `true` swaps gambling wording (Bet/Buy → social\n * terms); `{ coin }` also shows balance/bet/net in that coin (e.g. `'GC'`/`'SC'`). */\n social?: boolean | { coin?: string };\n /** Audio start state. `startMuted` boots muted (the mute icon reflects it; unmuting\n * restores the configured volumes). */\n audio?: { startMuted?: boolean };\n}\n\n/** The result of building a PanelSpec: the panel + every leaf control, in render order. */\nexport interface BuiltPanel {\n panel: PanelControl;\n controls: Control[];\n blocks: BlockSpec[];\n}\n","/**\n * Never-throw spec validator (Charter P11/B9). Returns a report; callers\n * (createUI) drop only the offending pieces and degrade — a malformed HUD still\n * boots. Every guardrail check lives here; it is pure and unit-tested.\n */\nimport type { UISpec, BlockSpec, SpecIssue } from './types';\nimport { BLOCK_KINDS } from './types';\n\nconst ANCHORS = new Set([\n 'top-left', 'top-center', 'top-right',\n 'center-left', 'center', 'center-right',\n 'bottom-left', 'bottom-center', 'bottom-right',\n]);\n\nconst AUTOPLAY_MODES = new Set(['options', 'infinite']);\nconst SPIN_PRESS = new Set(['tap', 'hold-to-spin']);\nconst RESPONSIVE_KEYS = new Set(['mobile', 'tablet', 'desktop', 'portrait', 'landscape']);\n\nexport function validateSpec(spec: UISpec): { ok: boolean; issues: SpecIssue[] } {\n const issues: SpecIssue[] = [];\n const add = (level: SpecIssue['level'], path: string, code: string, message: string): void => {\n issues.push({ level, path, code, message });\n };\n const ids = new Set<string>();\n const seeId = (id: string | undefined, path: string): void => {\n if (!id || !id.trim()) add('error', path, 'blank-id', 'control id must be a non-empty string');\n else if (ids.has(id)) add('error', path, 'dup-id', `duplicate control id \"${id}\"`);\n else ids.add(id);\n };\n const checkLayout = (anchor: string | undefined, path: string): void => {\n if (anchor && !ANCHORS.has(anchor)) add('error', path, 'bad-anchor', `unknown anchor \"${anchor}\"`);\n };\n\n try {\n if (spec.betLadder) {\n const lv = spec.betLadder.levels;\n if (!Array.isArray(lv) || lv.length === 0) {\n add('error', 'betLadder.levels', 'empty-levels', 'bet ladder needs at least one level');\n } else if (spec.betLadder.index != null && (spec.betLadder.index < 0 || spec.betLadder.index >= lv.length)) {\n add('error', 'betLadder.index', 'index-oor', `index ${spec.betLadder.index} is out of range 0..${lv.length - 1}`);\n }\n }\n\n if (spec.autoplay?.options) {\n spec.autoplay.options.forEach((o, i) => {\n if (!(typeof o === 'number' && o > 0)) {\n add('error', `autoplay.options[${i}]`, 'bad-option', `autoplay option must be > 0 (Infinity allowed), got ${String(o)}`);\n }\n });\n }\n if (spec.autoplay?.mode && !AUTOPLAY_MODES.has(spec.autoplay.mode)) {\n add('error', 'autoplay.mode', 'bad-mode', `autoplay.mode must be 'options' or 'infinite', got \"${String(spec.autoplay.mode)}\"`);\n }\n for (const key of ['lossLimits', 'winLimits'] as const) {\n const arr = spec.autoplay?.[key];\n if (arr) {\n arr.forEach((o, i) => {\n if (!(typeof o === 'number' && o > 0)) add('error', `autoplay.${key}[${i}]`, 'bad-limit', `autoplay ${key} must be > 0 (Infinity allowed), got ${String(o)}`);\n });\n }\n }\n\n if (spec.turbo) {\n const m = spec.turbo.modes;\n if (Array.isArray(m)) {\n if (m.length < 2) add('error', 'turbo.modes', 'turbo-too-few', 'a turbo ladder needs at least 2 modes (first = off)');\n if (m.some((x) => typeof x !== 'string' || !x.trim())) add('error', 'turbo.modes', 'turbo-bad-mode', 'turbo mode names must be non-empty strings');\n if (new Set(m).size !== m.length) add('error', 'turbo.modes', 'turbo-dup-mode', 'turbo mode names must be unique');\n } else if (m != null && m !== 2 && m !== 3) {\n add('error', 'turbo.modes', 'turbo-bad-count', `turbo.modes preset must be 2 or 3, got ${String(m)}`);\n }\n const len = Array.isArray(m) ? m.length : (m ?? 2);\n if (spec.turbo.index != null && (spec.turbo.index < 0 || spec.turbo.index >= len)) {\n add('error', 'turbo.index', 'index-oor', `turbo.index ${spec.turbo.index} is out of range 0..${len - 1}`);\n }\n }\n\n if (spec.spin?.press && !SPIN_PRESS.has(spec.spin.press)) {\n add('error', 'spin.press', 'bad-press', `spin.press must be 'tap' or 'hold-to-spin', got \"${String(spec.spin.press)}\"`);\n }\n\n if (spec.responsive) {\n for (const [key, ov] of Object.entries(spec.responsive)) {\n if (!RESPONSIVE_KEYS.has(key)) {\n add('error', `responsive.${key}`, 'bad-bucket', `unknown responsive bucket \"${key}\" (expected ${[...RESPONSIVE_KEYS].join(', ')})`);\n }\n if (ov?.controls) {\n for (const [id, co] of Object.entries(ov.controls)) {\n checkLayout(co.layout?.anchor, `responsive.${key}.controls.${id}.layout.anchor`);\n }\n }\n }\n }\n\n if (spec.currency && typeof spec.currency === 'object' && typeof spec.currency.decimals === 'number') {\n const d = spec.currency.decimals;\n if (d < 0 || d > 8) add('warn', 'currency.decimals', 'decimals-range', `decimals ${d} clamped to 0..8`);\n }\n\n if (spec.jurisdiction) {\n for (const [k, v] of Object.entries(spec.jurisdiction)) {\n if (k === 'minimumRoundDuration') {\n if (v != null && !(typeof v === 'number' && Number.isFinite(v) && v >= 0)) {\n add('error', `jurisdiction.${k}`, 'bad-duration', `minimumRoundDuration must be a non-negative number, got ${String(v)}`);\n }\n } else if (v != null && typeof v !== 'boolean') {\n add('error', `jurisdiction.${k}`, 'bad-flag', `jurisdiction.${k} must be a boolean, got ${String(v)}`);\n }\n }\n }\n if (spec.rtp != null && !(typeof spec.rtp === 'number' && Number.isFinite(spec.rtp))) {\n add('error', 'rtp', 'bad-rtp', `rtp must be a number, got ${String(spec.rtp)}`);\n }\n if (spec.realityCheck != null && !(typeof spec.realityCheck.everyMinutes === 'number' && spec.realityCheck.everyMinutes > 0)) {\n add('error', 'realityCheck.everyMinutes', 'bad-interval', 'realityCheck.everyMinutes must be a number > 0');\n }\n if (spec.buyFeature?.confirmAboveCost != null && !(typeof spec.buyFeature.confirmAboveCost === 'number' && Number.isFinite(spec.buyFeature.confirmAboveCost) && spec.buyFeature.confirmAboveCost >= 0)) {\n add('error', 'buyFeature.confirmAboveCost', 'bad-threshold', 'buyFeature.confirmAboveCost must be a finite number >= 0');\n }\n\n if (spec.controls) {\n for (const [id, ov] of Object.entries(spec.controls)) {\n checkLayout(ov.layout?.anchor, `controls.${id}.layout.anchor`);\n if (ov.digits != null) {\n if (!(typeof ov.digits === 'number' && Number.isFinite(ov.digits))) {\n add('error', `controls.${id}.digits`, 'bad-digits', `digits must be a number, got ${String(ov.digits)}`);\n } else if (ov.digits < 0 || ov.digits > 18) {\n add('warn', `controls.${id}.digits`, 'digits-range', `digits ${ov.digits} clamped to 0..18 (0 = auto)`);\n }\n }\n }\n }\n\n const walkBlocks = (blocks: BlockSpec[] | undefined, base: string): void => {\n blocks?.forEach((b, i) => {\n const p = `${base}[${i}]`;\n if (!BLOCK_KINDS.includes(b.kind as (typeof BLOCK_KINDS)[number])) {\n add('error', `${p}.kind`, 'unknown-kind', `unknown block kind \"${String(b.kind)}\"`);\n return;\n }\n seeId(b.id, `${p}.id`);\n if (b.kind === 'select' && (!b.options || b.options.length === 0)) {\n add('error', `${p}.options`, 'select-empty', 'a select block needs at least one option');\n }\n if (b.kind === 'slider' && b.initial != null && (b.initial < 0 || b.initial > 1)) {\n add('error', `${p}.initial`, 'slider-range', `slider initial ${b.initial} must be 0..1`);\n }\n if (b.kind === 'stepper' && (!b.levels || b.levels.length === 0)) {\n add('error', `${p}.levels`, 'empty-levels', 'a stepper block needs at least one level');\n }\n if (b.kind === 'stat-grid' && (!b.items || b.items.length === 0)) {\n add('warn', `${p}.items`, 'empty-grid', 'a stat-grid block has no items');\n }\n if (b.kind === 'mode-stats' && !spec.facts?.modes?.length) {\n add('warn', `${p}`, 'mode-stats-no-facts', 'a mode-stats block renders from spec.facts.modes, but no modes are declared');\n }\n if (b.kind === 'steps' && (!b.items || b.items.length === 0)) {\n add('warn', `${p}.items`, 'empty-steps', 'a steps block has no items');\n }\n if (b.kind === 'paytable' && (!b.rows || b.rows.length === 0)) {\n add('warn', `${p}.rows`, 'empty-paytable', 'a paytable block has no rows');\n }\n if (b.kind === 'image' && (!b.src || !b.src.trim())) {\n add('error', `${p}.src`, 'image-src', 'an image block needs a src');\n }\n if (b.kind === 'image' && ((b.width != null && b.width <= 0) || (b.height != null && b.height <= 0))) {\n add('error', `${p}.width`, 'image-dims', 'image width/height must be > 0 when set');\n }\n if (b.kind === 'media' && (!b.src || !b.src.trim())) {\n add('error', `${p}.src`, 'image-src', 'a media block needs an image src');\n }\n if (b.kind === 'media' && ((b.width != null && b.width <= 0) || (b.height != null && b.height <= 0))) {\n add('error', `${p}.width`, 'image-dims', 'media width/height must be > 0 when set');\n }\n if (b.kind === 'cards' && (!b.items || b.items.length === 0)) {\n add('warn', `${p}.items`, 'empty-cards', 'a cards block has no items');\n }\n if (b.kind === 'table' && (!b.rows || b.rows.length === 0)) {\n add('warn', `${p}.rows`, 'empty-table', 'a table block has no rows');\n }\n if (b.kind === 'group') walkBlocks(b.children, `${p}.children`);\n });\n };\n\n if (spec.menu?.banner && (!spec.menu.banner.src || !spec.menu.banner.src.trim())) {\n add('error', 'menu.banner.src', 'image-src', 'a menu banner needs a src');\n }\n walkBlocks(spec.menu?.settings, 'menu.settings');\n walkBlocks(spec.menu?.paytable, 'menu.paytable');\n walkBlocks(spec.menu?.rules, 'menu.rules');\n walkBlocks(spec.rules, 'rules');\n spec.panels?.forEach((pn, i) => {\n seeId(pn.id, `panels[${i}].id`);\n checkLayout(pn.layout?.anchor, `panels[${i}].layout.anchor`);\n walkBlocks(pn.blocks, `panels[${i}].blocks`);\n });\n } catch (e) {\n // The validator must never throw — a crash here is itself a reportable issue.\n add('error', '', 'validator-crash', e instanceof Error ? e.message : String(e));\n }\n\n return { ok: !issues.some((i) => i.level === 'error'), issues };\n}\n","/**\n * Turns a declarative PanelSpec into a PanelControl plus one Control per leaf\n * block (resolved through the registry, so blocks are swappable too — Charter P7).\n * Pure assembly: it instantiates and returns; action wiring + registration is the\n * caller's job (createUI / OpenUIPixi), so buildPanel stays leak-free and testable.\n */\nimport { PanelControl } from '../controls/PanelControl';\nimport type { Control } from '../control/Control';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\nimport type { BlockSpec, PanelSpec, BuiltPanel } from './types';\nimport { ControlRegistry } from '../registry/ControlRegistry';\n\n/** Resolve a block tree to its flat leaf controls, in render order. text/group carry none. */\nexport function buildBlocks(\n blocks: BlockSpec[],\n bus: EventBus<OpenUIEvents>,\n registry: ControlRegistry = ControlRegistry.defaults(),\n /** If a block id already resolves to a control (e.g. a built-in like 'music'),\n * reuse it instead of building a shadow copy that would overwrite it. */\n reuse?: (id: string) => Control | undefined,\n): Control[] {\n const controls: Control[] = [];\n const walk = (bs: BlockSpec[]): void => {\n for (const b of bs) {\n if (b.kind === 'group') {\n walk(b.children);\n continue;\n }\n if (b.kind === 'text') continue;\n const existing = reuse?.(b.id);\n if (existing) {\n controls.push(existing);\n continue;\n }\n const c = registry.resolve(b, bus);\n if (c) controls.push(c);\n }\n };\n walk(blocks);\n return controls;\n}\n\nexport function buildPanel(\n spec: PanelSpec,\n bus: EventBus<OpenUIEvents>,\n registry: ControlRegistry = ControlRegistry.defaults(),\n): BuiltPanel {\n const panel = new PanelControl(\n { id: spec.id, variant: spec.variant, title: spec.title, layout: spec.layout },\n bus,\n );\n const controls = buildBlocks(spec.blocks, bus, registry);\n return { panel, controls, blocks: spec.blocks };\n}\n\n/** Flatten a block tree to its button blocks (used to wire panel actions). */\nexport function buttonBlocks(blocks: BlockSpec[]): Array<Extract<BlockSpec, { kind: 'button' }>> {\n const out: Array<Extract<BlockSpec, { kind: 'button' }>> = [];\n const walk = (bs: BlockSpec[]): void => {\n for (const b of bs) {\n if (b.kind === 'button') out.push(b);\n else if (b.kind === 'group') walk(b.children);\n }\n };\n walk(blocks);\n return out;\n}\n","import type { OpenUI } from '../OpenUI';\n\n/**\n * Stake Engine's per-player jurisdiction config — the object the RGS returns at\n * `/wallet/authenticate` as `config.jurisdiction`. It is the platform's regulatory\n * switchboard: each `disabled*` flag must HIDE/limit a feature, each `display*`\n * flag must SHOW a readout, and `minimumRoundDuration` is a hint the GAME enforces\n * (open-ui never throttles the round). Every field is optional — an omitted flag\n * leaves the HUD's configured default untouched.\n *\n * @see https://github.com/StakeEngine/web-sdk — packages/rgs-fetcher/src/schema.ts\n */\nexport interface JurisdictionConfig {\n /** Social / sweepstakes mode (coins shown as GC/SC). */\n socialCasino?: boolean;\n disabledFullscreen?: boolean;\n disabledTurbo?: boolean;\n disabledAutoplay?: boolean;\n disabledSlamstop?: boolean;\n disabledSpacebar?: boolean;\n disabledBuyFeature?: boolean;\n displayNetPosition?: boolean;\n displayRTP?: boolean;\n displaySessionTimer?: boolean;\n /** Minimum ms a round must take — stored on the HUD for the GAME to enforce. */\n minimumRoundDuration?: number;\n /** Buy-feature confirm threshold (× base bet). A play costing more than this must\n * be confirmed before it commits — Stake requires that bet modes above 2× never\n * activate on a single click, so a Stake preset sets this to `2`. Not part of the\n * wallet schema; a convenience so a jurisdiction can require the confirm step. */\n confirmBuyAboveCost?: number;\n}\n\n/**\n * Apply a Stake Engine `jurisdiction` config to a live HUD — the whole switchboard\n * in one call. Safe to run at any time (typically right after the game\n * authenticates and learns the player's jurisdiction): it only acts on the flags\n * that are set, so it composes with the game's own `controls`/`responsive` config\n * and is idempotent. `disabled*` hides are made permanent (resize-proof) via\n * `ui.forceHidden`; `display*` flags reveal/hide the mandated readouts. It reuses\n * the primitives open-ui already has, so honoring the platform is one line.\n */\nexport function applyJurisdiction(ui: OpenUI, jur: JurisdictionConfig | undefined): void {\n if (!jur) return;\n\n const lockHidden = (id: string): void => {\n ui.forceHidden.add(id); // can never be re-shown by responsive (compliance)\n ui.setHidden(id, true);\n };\n\n // ── \"disable X\" → hide AND really disable the feature (not just visual) ───────\n if (jur.disabledFullscreen) lockHidden('fullscreen');\n if (jur.disabledTurbo) lockHidden('turbo');\n if (jur.disabledAutoplay) {\n lockHidden('autoplay');\n ui.autoplay.disable(); // a real guard: begin()/press() now no-op (state 'disabled')\n }\n if (jur.disabledBuyFeature) {\n lockHidden('bonus');\n ui.bonusButton.disable(); // the buy button can't be tapped; confirmBuy() also no-ops\n }\n // Slam-stop off → the spin button locks (dims) during the spin; no tap-to-stop.\n if (jur.disabledSlamstop) ui.spin.allowSlamStop.set(false);\n // Spacebar / hold-to-spin off → no keyboard spin + each cycle needs a fresh press.\n if (jur.disabledSpacebar) {\n ui.spin.holdToSpin = false;\n ui.spin.allowKeyboard.set(false);\n }\n\n // ── \"display X\" → reveal the mandated readout (jurisdiction owns these) ───────\n if (jur.displayRTP != null) ui.setHidden('rtp', !jur.displayRTP);\n if (jur.displayNetPosition != null) ui.setHidden('net-position', !jur.displayNetPosition);\n if (jur.displaySessionTimer != null) {\n ui.setHidden('session-timer', !jur.displaySessionTimer);\n if (jur.displaySessionTimer) ui.sessionTimer.start();\n else ui.sessionTimer.stop();\n }\n\n // Social / sweepstakes mode — swaps gambling wording (and shows GC/SC when the\n // game has set a social coin). The round-duration hint stays GAME-enforced.\n if (jur.socialCasino != null) ui.setSocial(jur.socialCasino);\n if (typeof jur.minimumRoundDuration === 'number' && Number.isFinite(jur.minimumRoundDuration)) {\n ui.minimumRoundDuration = Math.max(0, jur.minimumRoundDuration);\n }\n if (typeof jur.confirmBuyAboveCost === 'number' && Number.isFinite(jur.confirmBuyAboveCost)) {\n ui.confirmBuyAboveCost = Math.max(0, jur.confirmBuyAboveCost);\n }\n}\n","/**\n * The notice / error modal model.\n *\n * The HUD shows a menu-style modal built from declarative {@link BlockSpec} content\n * plus a row of action buttons. EVERY string — title, message, and each button\n * label — is passed through the translator (`ui.t`), so the host can either pass the\n * EXACT literal text they want, or a translation key they localize themselves (their\n * `locale.messages` dict overrides the built-in English defaults). Nothing is\n * hard-coded in the renderer, and every default is overridable per call.\n */\nimport type { BlockSpec } from './spec/types';\n\nexport interface NoticeAction {\n /** Button label — a literal string OR an i18n key (resolved via the translator). */\n label: string;\n /** Called when the button is pressed. */\n onSelect?: () => void;\n /** Also emit a `buttonActivated` event with this id (for analytics / host wiring). */\n emit?: string;\n /** Visual weight (default: first action `primary`, the rest `secondary`). */\n variant?: 'primary' | 'secondary';\n /** Keep the modal open after pressing (default: dismiss it). */\n keepOpen?: boolean;\n}\n\nexport interface NoticeOptions {\n /** Title — literal or i18n key. Default `'openui.error'` for errors. */\n title?: string;\n /** Callout tone. Default `'warning'` for errors. */\n tone?: 'info' | 'warning' | 'bonus';\n /** Action buttons. Omitted → a single dismiss button (`openui.ok`), or NONE when\n * `blocking` (so a fatal modal is dismissable only in code). */\n actions?: NoticeAction[];\n /** FATAL/blocking modal: locks the HUD, no backdrop/✕ dismiss; remove via `hideNotice`. */\n blocking?: boolean;\n}\n\n/** Reality-check reminder config (RTS 13). You supply the cadence + text; open-ui\n * owns the (wall-clock) timer, the event, and the modal. */\nexport interface RealityCheckOptions {\n /** Reminder interval in minutes (wall-clock). */\n everyMinutes: number;\n /** Modal title — literal or i18n key. `{{minutes}}`/`{{spent}}`/`{{won}}` interpolate. */\n title?: string;\n /** Modal message — literal or i18n key. Same interpolation tokens. */\n message?: string;\n /** Show the built-in acknowledge modal (default true). `false` → only the event fires. */\n showModal?: boolean;\n /** Custom action buttons (default a single \"Continue\"). */\n actions?: NoticeAction[];\n}\n\n/** What `showRgsError` accepts: notice options plus an exact message override. */\nexport interface RgsErrorOptions extends NoticeOptions {\n /** Override the default message for this code with exact text (or your own key). */\n message?: string;\n /** Stop an in-progress autoplay session (default true — most RGS errors should). */\n stopAutoplay?: boolean;\n}\n\n/** RGS status codes open-ui ships a default message for (the TS enum + the HTTP groups). */\nexport type RgsErrorCode =\n | 'ERR_IPB'\n | 'ERR_IS'\n | 'ERR_ATE'\n | 'ERR_GLE'\n | 'ERR_BE'\n | 'ERR_BNF'\n | 'ERR_LOC'\n | 'ERR_MAINTENANCE'\n | 'ERR_VAL'\n | 'ERR_GEN'\n | 'ERR_UE'\n | 'ERR_TIMEOUT';\n\n/**\n * Code → default title/message i18n KEYS. The English text for these keys lives in\n * the translator defaults (`openuiDefaults`), so a host localizes errors by adding\n * those keys to their `messages` dict — or overrides any single one per call via\n * `showRgsError(code, { title, message })`. Unknown codes fall back to generic.\n */\nexport const RGS_ERROR_KEYS: Readonly<Record<string, { title: string; message: string }>> = Object.freeze({\n ERR_IPB: { title: 'openui.err.insufficient.title', message: 'openui.err.insufficient.message' },\n ERR_IS: { title: 'openui.err.session.title', message: 'openui.err.session.message' },\n ERR_ATE: { title: 'openui.err.session.title', message: 'openui.err.session.message' },\n ERR_GLE: { title: 'openui.err.limit.title', message: 'openui.err.limit.message' },\n ERR_BE: { title: 'openui.err.activebet.title', message: 'openui.err.activebet.message' },\n ERR_BNF: { title: 'openui.err.generic.title', message: 'openui.err.generic.message' },\n ERR_LOC: { title: 'openui.err.location.title', message: 'openui.err.location.message' },\n ERR_MAINTENANCE: { title: 'openui.err.maintenance.title', message: 'openui.err.maintenance.message' },\n ERR_VAL: { title: 'openui.err.generic.title', message: 'openui.err.generic.message' },\n ERR_GEN: { title: 'openui.err.generic.title', message: 'openui.err.generic.message' },\n ERR_UE: { title: 'openui.err.generic.title', message: 'openui.err.generic.message' },\n ERR_TIMEOUT: { title: 'openui.err.connection.title', message: 'openui.err.connection.message' },\n});\n\n/** The default dismiss action used when a notice supplies none. */\nexport const DEFAULT_NOTICE_ACTION: NoticeAction = { label: 'openui.ok', variant: 'primary' };\n\n/** Build the title + message blocks for an error/notice (used by `showError`).\n * The Figma \"default\" modal is plain: a heading + body text (no tinted callout).\n * `tone` is kept for API compatibility but no longer changes the rendering. */\nexport function errorBlocks(message: string, title: string, _tone: NonNullable<NoticeOptions['tone']>): BlockSpec[] {\n return [\n { kind: 'heading', id: 'notice-title', text: title },\n { kind: 'text', id: 'notice-body', text: message },\n ];\n}\n","import type { Dispose } from '../signal';\n\n/**\n * i18n port (Charter B5/B8): the core depends on this tiny interface, NOT on i18next.\n * Ship adapters (`@open-slot-ui/i18n-i18next`, the built-in `dictionary()`), never a hard dep.\n */\nexport interface Translator {\n t(key: string, vars?: Record<string, string | number>): string;\n readonly locale: string;\n /** Switch the active locale (a no-op for the same locale); fires onChange. */\n setLocale(next: string): void;\n onChange(cb: (locale: string) => void): Dispose;\n /** Switch social/sweepstakes wording on/off. In social mode `t` resolves from a\n * SEPARATE social dictionary first, so social copy can never be mixed into the\n * normal keys by accident (by design). No-op if unsupported. */\n setSocial?(on: boolean): void;\n}\n\n/** open-ui owns this namespace; the host's translator may override any key. */\nexport const openuiDefaults: Record<string, string> = {\n 'openui.spin': 'Spin',\n 'openui.stop': 'Stop',\n 'openui.autoplay': 'Autoplay',\n 'openui.bet': 'Bet',\n 'openui.balance': 'Balance',\n 'openui.win': 'Win',\n 'openui.totalWin': 'Total Win',\n 'openui.menu': 'Menu',\n 'openui.rules': 'Rules',\n 'openui.paytable': 'Paytable',\n 'openui.settings': 'Settings',\n 'openui.close': 'Close',\n 'openui.language': 'Language',\n // compliance readouts + autoplay limit headings\n 'openui.rtp': 'RTP',\n 'openui.net': 'Net',\n 'openui.session': 'Session',\n 'openui.lossLimit': 'Stop on loss',\n 'openui.winLimit': 'Stop on single win',\n // notice / error modal\n 'openui.ok': 'OK',\n 'openui.cancel': 'Cancel',\n 'openui.confirm': 'Confirm',\n 'openui.continue': 'Continue',\n 'openui.reload': 'Reload',\n 'openui.error': 'Error',\n 'openui.notice': 'Notice',\n 'openui.replay': 'Replay',\n // Replay panel (Stake \"Replay Support\"): the round's cost + worth is shown at the\n // start; a Replay button re-runs it at the end.\n 'openui.replay.title': 'Replay',\n 'openui.replay.baseBet': 'Base Bet',\n 'openui.replay.costMultiplier': 'Cost Multiplier',\n 'openui.replay.payoutMultiplier': 'Payout Multiplier',\n 'openui.replay.amount': 'Final amount',\n 'openui.replay.play': 'Play',\n 'openui.replay.again': 'Replay',\n 'openui.buyFeature.title': 'Buy feature',\n 'openui.buyFeature.message': 'Buy this feature now?',\n // Confirm step for a higher-cost play — {{name}} / {{price}} are interpolated.\n 'openui.buyFeature.confirm': 'Buy {{name}} for {{price}}?',\n 'openui.freeSpins': 'FS',\n // reality check (RTS 13) — {{minutes}} is interpolated by open-ui's scheduler\n 'openui.realityCheck.title': 'Reality check',\n 'openui.realityCheck.message': \"You've been playing for {{minutes}} minutes. Take a moment before continuing.\",\n // Rules-completeness audit (the info menu's \"forgotten declarations\" card)\n 'openui.rulesAudit.title': 'Rules incomplete',\n 'openui.rulesAudit.required': 'Missing required information:',\n 'openui.rulesAudit.recommended': 'Highly recommended:',\n // RGS error defaults (override via your messages dict or per-call)\n 'openui.err.generic.title': 'Something went wrong',\n 'openui.err.generic.message': 'Sorry, something went wrong. Please try again.',\n 'openui.err.insufficient.title': 'Insufficient funds',\n 'openui.err.insufficient.message': \"You don't have enough balance to place this bet.\",\n 'openui.err.session.title': 'Session expired',\n 'openui.err.session.message': 'Your session has expired. Reload the game to continue.',\n 'openui.err.limit.title': 'Limit reached',\n 'openui.err.limit.message': 'A gambling limit has been reached. Please try again later.',\n 'openui.err.activebet.title': 'Round in progress',\n 'openui.err.activebet.message': 'You already have a round in progress. Reload to finish it.',\n 'openui.err.location.title': 'Unavailable here',\n 'openui.err.location.message': 'This game is not available in your location.',\n 'openui.err.maintenance.title': 'Under maintenance',\n 'openui.err.maintenance.message': 'The game is briefly down for maintenance. Please try again soon.',\n 'openui.err.connection.title': 'Connection lost',\n 'openui.err.connection.message': 'A stable connection is required. Reload to finish any open round.',\n};\n\n/**\n * Social / sweepstakes wording — a SEPARATE dictionary (same keys as the normal\n * ones). Kept apart on purpose so a host can never mix gambling and social copy in\n * one map: provide your social overrides under `locale.socialMessages`, not inline.\n */\nexport const openuiSocialDefaults: Record<string, string> = {\n 'openui.bet': 'Play',\n 'openui.balance': 'Balance',\n 'openui.win': 'Prize',\n 'openui.totalWin': 'Total Prize',\n // \"Paytable\" (contains \"pay\") and \"Insufficient funds\" (\"funds\") are restricted in\n // social mode → their compliant equivalents. The literal \"Paytable\" is overridden too\n // because the menu SECTION heading uses it as its key (DEFAULT_MENU_TITLES).\n 'openui.paytable': 'Prizes',\n Paytable: 'Prizes',\n 'openui.err.insufficient.title': 'Insufficient balance',\n 'openui.buyFeature.title': 'Play bonus',\n 'openui.buyFeature.message': 'Play this bonus now?',\n 'openui.buyFeature.confirm': 'Play {{name}} for {{price}}?',\n // Stake.us replay terms: Base Bet → Base Play, Cost Multiplier → Feature Multiplier,\n // Payout Multiplier → Final Multiplier.\n 'openui.replay.baseBet': 'Base Play',\n 'openui.replay.costMultiplier': 'Feature Multiplier',\n 'openui.replay.payoutMultiplier': 'Final Multiplier',\n 'openui.err.insufficient.message': \"You don't have enough balance for this play.\",\n 'openui.err.limit.message': 'A play limit has been reached. Please try again later.',\n // The auto mode-stats grid's label words (used as their own keys at render time).\n 'Max win': 'Max prize',\n};\n\nfunction interpolate(template: string, vars?: Record<string, string | number>): string {\n if (!vars) return template;\n // i18next-style {{token}}; dotted tokens ({{rtp.base}}, {{cost.free-spins}}) are the\n // facts-vars namespace (see `factsVars`) — flat lookup, same as i18next keySeparator:false.\n return template.replace(/\\{\\{([\\w.-]+)\\}\\}/g, (_m, k: string) => String(vars[k] ?? `{{${k}}}`));\n}\n\n/**\n * Zero-dep dictionary translator. Falls back to open-ui defaults, then to the\n * key itself only if nothing is found — but built-in keys always resolve, so the\n * library never renders a raw key (the text analog of \"never break un-themed\").\n */\nexport class DictionaryTranslator implements Translator {\n private _locale: string;\n private _social = false;\n private readonly subs = new Set<(locale: string) => void>();\n\n constructor(\n private readonly messages: Record<string, Record<string, string>>,\n locale: string,\n /** SEPARATE social/sweepstakes dictionary — consulted first in social mode. */\n private readonly socialMessages: Record<string, Record<string, string>> = {},\n ) {\n this._locale = locale;\n }\n\n get locale(): string {\n return this._locale;\n }\n\n setLocale(next: string): void {\n if (next === this._locale) return;\n this._locale = next;\n for (const cb of [...this.subs]) cb(next);\n }\n\n setSocial(on: boolean): void {\n this._social = on;\n }\n\n t(key: string, vars?: Record<string, string | number>): string {\n // Social mode resolves from the dedicated social dictionary FIRST (host social\n // overrides → built-in social defaults), then falls back to the normal chain —\n // so social and gambling copy are kept structurally separate.\n const social = this._social\n ? this.socialMessages[this._locale]?.[key] ?? openuiSocialDefaults[key]\n : undefined;\n const resolved = social ?? this.messages[this._locale]?.[key] ?? openuiDefaults[key] ?? key;\n return interpolate(resolved, vars);\n }\n\n onChange(cb: (locale: string) => void): Dispose {\n this.subs.add(cb);\n return () => {\n this.subs.delete(cb);\n };\n }\n}\n\n/** Convenience factory for a zero-dep dictionary translator. */\nexport function dictionary(\n messages: Record<string, Record<string, string>>,\n locale: string,\n socialMessages?: Record<string, Record<string, string>>,\n): DictionaryTranslator {\n return new DictionaryTranslator(messages, locale, socialMessages);\n}\n","/**\n * GAME FACTS + the rules-completeness AUDIT — the \"can't forget\" layer for the\n * Info/Rules menu (Charter P11: data, not prose).\n *\n * A game declares WHAT IT HAS as structured facts — its math modes (base game, buy\n * features, bet boosts) with their RTP and max win, its free-spins behavior, its\n * volatility/cap — via `UISpec.facts` and/or `ui.declareFacts` (the buy-feature modal\n * declares its configured features automatically). The rules content stays modular\n * blocks (the \"block builder\"), and two mechanisms tie the two together:\n *\n * 1. The `mode-stats` block AUTO-RENDERS the per-mode RTP / Max-win grid straight\n * from the facts — declared once, so the table can never drift from the config.\n * 2. `auditRules(facts, rules)` checks the rules blocks against the facts and\n * reports every REQUIRED declaration that is missing (a mode's RTP or max win,\n * an undescribed buy feature) plus the HIGHLY RECOMMENDED ones (free-spins count\n * + retrigger policy, the legal disclaimer, a controls guide). The info menu\n * renders these findings as an explicit warning card when the rules open — a\n * forgotten declaration is stated, never silent.\n *\n * Any block may carry `covers: ['rtp:bonus', 'freespins', …]` to mark a topic as\n * covered by hand-written prose the text heuristics can't see.\n */\nimport type { BlockSpec } from './types';\n\n/** One math mode / play mode the game exposes (base · buy feature · bet boost · ante). */\nexport interface GameModeFact {\n /** Stable id (matches the buy-feature card / RGS mode id), e.g. `'base'`, `'bonus'`. */\n id: string;\n /** Display name, e.g. `'Golden Rush'` — run through `ui.t` (social swaps apply). */\n name: string;\n /** What kind of mode this is. `'base'` is the plain game; everything else is a\n * configured feature that MUST be described in the rules. */\n kind?: 'base' | 'buy' | 'boost' | 'ante' | 'bonus';\n /** Cost as a multiple of the base bet (buy price / per-spin surcharge). */\n cost?: number;\n /** The mode's RTP in percent (e.g. 95.5). Required in the rules for every mode. */\n rtp?: number;\n /** The mode's maximum win as a multiple of the base bet (e.g. 5000). Required. */\n maxWinX?: number;\n}\n\n/** Free-spins behavior — HIGHLY RECOMMENDED to declare (or `false` = game has none). */\nexport interface FreeSpinsFact {\n /** How many free spins the bonus awards (e.g. exactly 3). */\n count?: number;\n /** Whether free spins can be retriggered during the bonus. */\n retrigger?: boolean;\n /** Free-form note (not audited). */\n note?: string;\n}\n\n/** Everything the game HAS, declared as data. Drives `mode-stats` + `auditRules`. */\nexport interface GameFacts {\n modes?: GameModeFact[];\n /** Free-spins facts, or `false` to state explicitly the game has none. */\n freeSpins?: FreeSpinsFact | false;\n /** Volatility label shown by `mode-stats` (e.g. `'Very high'`). */\n volatility?: string;\n /** The overall round win cap (× base bet) shown by `mode-stats` (e.g. 5000). */\n maxWinCapX?: number;\n}\n\n/** Merge two facts declarations: modes merge BY ID (defined incoming fields win);\n * scalar facts take the incoming value when defined. Pure — never mutates inputs. */\nexport function mergeFacts(base: GameFacts, add: GameFacts): GameFacts {\n const modes = [...(base.modes ?? [])];\n for (const m of add.modes ?? []) {\n const i = modes.findIndex((x) => x.id === m.id);\n if (i < 0) modes.push({ ...m });\n else {\n const merged = { ...modes[i] } as unknown as Record<string, unknown>;\n for (const [k, v] of Object.entries(m)) if (v !== undefined) merged[k] = v;\n modes[i] = merged as unknown as GameModeFact;\n }\n }\n return {\n ...(modes.length ? { modes } : {}),\n freeSpins: add.freeSpins !== undefined ? add.freeSpins : base.freeSpins,\n volatility: add.volatility ?? base.volatility,\n maxWinCapX: add.maxWinCapX ?? base.maxWinCapX,\n };\n}\n\n/** Format an RTP percent the Stake way: always two decimals (95.5 → \"95.50%\"). */\nexport function formatRtp(rtp: number): string {\n return `${rtp.toFixed(2)}%`;\n}\n\n/** Format a × multiple with thousands grouping (5000 → \"5,000×\"). */\nexport function formatTimes(x: number): string {\n return `${x.toLocaleString('en-US', { maximumFractionDigits: 2 })}×`;\n}\n\n/**\n * The auto-generated per-mode stat rows a `mode-stats` block renders: one\n * `RTP · <mode>` + `Max win · <mode>` pair per declared mode, then Volatility and\n * the round cap when declared. `tr` localizes the label words + mode names (social\n * mode swaps \"Max win\" → \"Max prize\" via the built-in social dictionary).\n */\nexport function modeStatsItems(\n facts: GameFacts | undefined,\n tr: (s: string) => string = (s) => s,\n): Array<{ label: string; value: string }> {\n const out: Array<{ label: string; value: string }> = [];\n for (const m of facts?.modes ?? []) {\n if (m.rtp != null) out.push({ label: `${tr('RTP')} · ${tr(m.name)}`, value: formatRtp(m.rtp) });\n if (m.maxWinX != null) out.push({ label: `${tr('Max win')} · ${tr(m.name)}`, value: formatTimes(m.maxWinX) });\n }\n if (facts?.volatility) out.push({ label: tr('Volatility'), value: tr(facts.volatility) });\n if (facts?.maxWinCapX != null) out.push({ label: tr('Round cap'), value: formatTimes(facts.maxWinCapX) });\n return out;\n}\n\n/**\n * The INTERPOLATION VARIABLES the declared facts expose to rules copy — the\n * \"universal interpolatable rules\" contract. Any rules text (inline blocks or a\n * {@link RulesDoc}) may use i18next-style tokens; the info menu resolves them from\n * the LIVE facts, so a stated RTP / max win / price can never drift from config:\n *\n * `{{rtp.<modeId>}}` → \"95.50%\" `{{maxWin.<modeId>}}` → \"5,000×\"\n * `{{cost.<modeId>}}` → \"185×\" `{{name.<modeId>}}` → the mode name\n * `{{freeSpins.count}}` → 3 `{{freeSpins.retrigger}}` → \"can\"/\"cannot\"\n * `{{volatility}}` → \"Very high\" `{{maxWinCap}}` → \"5,000×\"\n *\n * `extra` merges additional host vars (e.g. `game.name`) on top.\n */\nexport function factsVars(\n facts: GameFacts | undefined,\n extra?: Record<string, string | number>,\n): Record<string, string | number> {\n const vars: Record<string, string | number> = {};\n for (const m of facts?.modes ?? []) {\n if (!m.id) continue;\n vars[`name.${m.id}`] = m.name;\n if (m.rtp != null) vars[`rtp.${m.id}`] = formatRtp(m.rtp);\n if (m.maxWinX != null) vars[`maxWin.${m.id}`] = formatTimes(m.maxWinX);\n if (m.cost != null) vars[`cost.${m.id}`] = formatTimes(m.cost);\n }\n const fs = facts?.freeSpins;\n if (fs) {\n if (fs.count != null) vars['freeSpins.count'] = fs.count;\n if (fs.retrigger != null) vars['freeSpins.retrigger'] = fs.retrigger ? 'can' : 'cannot';\n }\n if (facts?.volatility) vars['volatility'] = facts.volatility;\n if (facts?.maxWinCapX != null) vars['maxWinCap'] = formatTimes(facts.maxWinCapX);\n return extra ? { ...vars, ...extra } : vars;\n}\n\n/** One finding from the rules audit. `required` findings are compliance gaps\n * (RTP / max win / an undescribed configured feature); `recommended` are the\n * strongly-advised ones (free-spins details, legal disclaimer, controls guide). */\nexport interface RulesAuditIssue {\n level: 'required' | 'recommended';\n /** Machine code, e.g. `'rules-missing-rtp'`, `'facts-missing-maxwin'`. */\n code: string;\n /** The coverage topic that would satisfy it, e.g. `'rtp:bonus'`, `'freespins'`. */\n topic: string;\n /** Human sentence shown in the info menu's warning card. */\n message: string;\n}\n\n/** Everything the audit extracts from the rules blocks in one pass. */\ninterface RulesScan {\n text: string;\n headings: string;\n covers: Set<string>;\n hasModeStats: boolean;\n hasLegal: boolean;\n}\n\nfunction scanBlocks(blocks: BlockSpec[] | undefined, resolve: (s: string) => string = (s) => s): RulesScan {\n const scan: RulesScan = { text: '', headings: '', covers: new Set(), hasModeStats: false, hasLegal: false };\n const addText = (t: unknown): void => {\n if (typeof t === 'string' && t) scan.text += `\\n${resolve(t)}`;\n };\n const walk = (list: BlockSpec[] | undefined): void => {\n for (const b of list ?? []) {\n for (const c of b.covers ?? []) scan.covers.add(c);\n const anyB = b as Record<string, unknown>;\n switch (b.kind) {\n case 'mode-stats':\n scan.hasModeStats = true;\n (b.extras ?? []).forEach((it) => {\n addText(it.label);\n addText(it.value);\n });\n break;\n case 'legal':\n scan.hasLegal = true;\n addText(b.text);\n break;\n case 'heading':\n case 'subheading':\n scan.headings += `\\n${resolve(b.text)}`;\n addText(b.text);\n break;\n case 'text':\n addText(b.text);\n break;\n case 'callout':\n addText(b.title);\n addText(b.text);\n break;\n case 'media':\n addText(b.title);\n addText(b.text);\n break;\n case 'steps':\n b.items.forEach(addText);\n break;\n case 'table':\n (b.columns ?? []).forEach(addText);\n b.rows.forEach((r) => r.forEach(addText));\n break;\n case 'paytable':\n b.rows.forEach((r) => {\n addText(r.symbol);\n addText(r.payouts);\n });\n break;\n case 'cards':\n b.items.forEach((it) => {\n addText(it.title);\n addText(it.text);\n });\n break;\n case 'stat-grid':\n b.items.forEach((it) => {\n addText(it.label);\n addText(it.value);\n });\n break;\n case 'group':\n addText(b.title);\n walk(b.children);\n break;\n default:\n addText(anyB.label);\n addText(anyB.hint);\n break;\n }\n }\n };\n walk(blocks);\n return scan;\n}\n\nconst escapeRe = (s: string): string => s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n/** Does the text state this RTP? Accepts \"95.5%\" / \"95.50%\" (and \"96%\" / \"96.00%\"). */\nfunction mentionsRtp(text: string, rtp: number): boolean {\n const s = String(rtp);\n const [int = '', frac = ''] = s.split('.');\n const body = frac ? `${escapeRe(int)}[.,]${escapeRe(frac)}0*` : `${escapeRe(int)}(?:[.,]0{1,2})?`;\n return new RegExp(`\\\\b${body}\\\\s*%`).test(text);\n}\n\n/** Does the text state this × multiple? Accepts \"5,000×\" / \"5000x\" / \"5 000 x\". */\nfunction mentionsTimes(text: string, x: number): boolean {\n const digits = String(Math.trunc(Math.abs(x)));\n let grouped = '';\n for (let i = 0; i < digits.length; i++) {\n if (i > 0 && (digits.length - i) % 3 === 0) grouped += '[,.\\\\s\\\\u00a0]?';\n grouped += digits[i];\n }\n const frac = Math.abs(x) % 1 !== 0 ? `[.,]\\\\d+` : `(?:[.,]\\\\d+)?`;\n return new RegExp(`\\\\b${grouped}${frac}\\\\s*[x×]`, 'i').test(text);\n}\n\nconst mentionsName = (text: string, name: string): boolean => text.toLowerCase().includes(name.toLowerCase());\n\n/**\n * Audit the rules blocks against the declared game facts. Pure + never-throw.\n * Findings come back most severe first (`required`, then `recommended`); an empty\n * array means the rules declare everything the game's configuration demands.\n *\n * `opts.resolve` maps each collected string BEFORE the text heuristics run — pass\n * the same translate-and-interpolate the renderer uses (`(s) => ui.t(s, factsVars(...))`)\n * so localized copy and `{{rtp.base}}`-style tokens are audited AS RENDERED: a rules\n * text that states its RTP via the token is, by construction, always correct.\n */\nexport function auditRules(\n facts: GameFacts | undefined,\n rules: BlockSpec[] | undefined,\n opts: { resolve?: (s: string) => string } = {},\n): RulesAuditIssue[] {\n const out: RulesAuditIssue[] = [];\n try {\n const scan = scanBlocks(rules, opts.resolve);\n const add = (level: RulesAuditIssue['level'], code: string, topic: string, message: string): void => {\n out.push({ level, code, topic, message });\n };\n const covered = (topic: string): boolean => scan.covers.has(topic);\n\n for (const m of facts?.modes ?? []) {\n const nameIn = mentionsName(scan.text, m.name);\n // RTP — required for every mode.\n if (m.rtp == null) {\n add('required', 'facts-missing-rtp', `rtp:${m.id}`, `“${m.name}” declares no RTP — set facts.modes[].rtp so the rules can state it.`);\n } else if (!(scan.hasModeStats || covered(`rtp:${m.id}`) || (nameIn && mentionsRtp(scan.text, m.rtp)))) {\n add('required', 'rules-missing-rtp', `rtp:${m.id}`, `The RTP of “${m.name}” (${formatRtp(m.rtp)}) is not stated in the rules.`);\n }\n // Max win — required for every mode.\n if (m.maxWinX == null) {\n add('required', 'facts-missing-maxwin', `maxwin:${m.id}`, `“${m.name}” declares no max win — set facts.modes[].maxWinX so the rules can state it.`);\n } else if (!(scan.hasModeStats || covered(`maxwin:${m.id}`) || (nameIn && mentionsTimes(scan.text, m.maxWinX)))) {\n add('required', 'rules-missing-maxwin', `maxwin:${m.id}`, `The max win of “${m.name}” (${formatTimes(m.maxWinX)}) is not stated in the rules.`);\n }\n // Every configured feature (anything that isn't the base game) must be described.\n if (m.kind && m.kind !== 'base' && !(covered(`feature:${m.id}`) || nameIn)) {\n add('required', 'rules-missing-feature', `feature:${m.id}`, `The configured feature “${m.name}” is not described in the rules.`);\n }\n }\n\n // Free spins — highly recommended (only nag games that opted into facts at all).\n const fs = facts?.freeSpins;\n if (fs === undefined) {\n if (facts?.modes?.length) {\n add('recommended', 'facts-missing-freespins', 'freespins', 'Free-spins info is highly recommended: declare facts.freeSpins { count, retrigger } — or freeSpins: false if the game has none.');\n }\n } else if (fs !== false) {\n const fsIn = covered('freespins') || /free\\s*spins?/i.test(scan.text);\n if (!fsIn) {\n add('recommended', 'rules-missing-freespins', 'freespins', 'The rules never mention the free spins this game declares.');\n } else {\n if (fs.count != null && !covered('freespins:count') && !new RegExp(`\\\\b${fs.count}\\\\b[\\\\s\\\\S]{0,60}?spins?|spins?[\\\\s\\\\S]{0,60}?\\\\b${fs.count}\\\\b`, 'i').test(scan.text)) {\n add('recommended', 'rules-missing-fs-count', 'freespins:count', `State that the bonus awards exactly ${fs.count} free spins.`);\n }\n if (fs.retrigger != null && !covered('freespins:retrigger') && !/re-?trigger/i.test(scan.text)) {\n add('recommended', 'rules-missing-fs-retrigger', 'freespins:retrigger', `State that free spins ${fs.retrigger ? 'CAN' : 'CANNOT'} be retriggered.`);\n }\n }\n }\n\n // Legal disclaimer + a controls guide — recommended for every game.\n if (rules?.length && !scan.hasLegal && !/malfunction/i.test(scan.text)) {\n add('recommended', 'rules-missing-legal', 'legal', 'Add the platform legal disclaimer (a `legal` block).');\n }\n if (rules?.length && !covered('controls') && !/\\bcontrols?\\b/i.test(scan.headings)) {\n add('recommended', 'rules-missing-controls', 'controls', 'Describe every interactive control (a “Controls” section or covers: [\"controls\"]).');\n }\n\n out.sort((a, b) => (a.level === b.level ? 0 : a.level === 'required' ? -1 : 1));\n } catch {\n /* the audit must never break the menu */\n }\n return out;\n}\n","import { Signal, type Dispose } from './signal';\nimport { EventBus } from './events';\nimport { Control } from './control/Control';\nimport { SpinControl } from './controls/SpinControl';\nimport { ValueDisplay } from './controls/ValueDisplay';\nimport { ButtonControl } from './controls/ButtonControl';\nimport { SliderControl } from './controls/SliderControl';\nimport { PanelControl } from './controls/PanelControl';\nimport { TurboControl } from './controls/TurboControl';\nimport { StepperControl } from './controls/StepperControl';\nimport { AutoplayControl } from './controls/AutoplayControl';\nimport { ReadoutControl } from './controls/ReadoutControl';\nimport { defaultTheme, type Theme } from './theme/tokens';\nimport {\n computeScreen,\n defaultLayoutConfig,\n type LayoutConfig,\n type ScreenState,\n} from './layout/screen';\nimport { defaultLayout } from './layout/defaultLayouts';\nimport type { ControlSnapshot, OpenUIEvents } from './types';\nimport type { UISpec, BlockSpec } from './spec/types';\nimport { applyJurisdiction as applyJurisdictionTo, type JurisdictionConfig } from './spec/jurisdiction';\nimport {\n type NoticeAction,\n type NoticeOptions,\n type RgsErrorOptions,\n type RealityCheckOptions,\n RGS_ERROR_KEYS,\n DEFAULT_NOTICE_ACTION,\n errorBlocks,\n} from './notice';\nimport { DictionaryTranslator, type Translator } from './i18n/translator';\nimport { resolveCurrency } from './format/currency';\nimport { mergeFacts, type GameFacts } from './spec/facts';\n\nexport interface OpenUIOptions {\n theme?: Theme;\n layout?: LayoutConfig;\n /** i18n port. Default: an empty dictionary on locale 'en' (keys fall through). */\n translator?: Translator;\n /** Start with audio muted (the icon reflects it). Unmute restores the volumes. */\n startMuted?: boolean;\n}\n\n/**\n * The headless root: owns the control tree, the active theme, the responsive\n * screen state, and the typed event bus. This is the object the game holds and\n * \"talks to\" (Charter P1/P4). Renderer-agnostic — a renderer binds to it.\n */\nexport class OpenUI {\n readonly theme: Theme;\n readonly layoutConfig: LayoutConfig;\n readonly bus = new EventBus<OpenUIEvents>();\n readonly screen: Signal<ScreenState>;\n\n /** i18n translator (the port — no hard i18next dep, Charter B5/B8). */\n readonly translator: Translator;\n /** Current locale, observable — views re-render their text when it changes. */\n readonly locale: Signal<string>;\n\n /**\n * Ref-counted input lock. While the count is above zero, `locked` is true and\n * EVERY registered control reports not-interactable through its derived getter\n * (Charter P6/G7) — no per-button bookkeeping, no desync. Instance-scoped: the\n * gate each control receives in `register` reads THIS ui's `locked`.\n */\n readonly locked = new Signal<boolean>(false);\n private lockCount = 0;\n\n /** Every subscription this ui owns, torn down by `dispose()` (Charter P12). */\n private readonly disposers: Dispose[] = [];\n\n /** Control ids the spec marked hidden — still registered (so they stay\n * introspectable in `snapshot()`) but skipped by the renderer (Charter P10). */\n readonly hidden = new Set<string>();\n /** Ids hidden UNCONDITIONALLY (e.g. a jurisdiction `disabled*` flag): `setHidden`\n * refuses to re-show these, so a responsive resize can't undo a compliance hide. */\n readonly forceHidden = new Set<string>();\n\n /** Master mute (music+sfx), observable so an icon can reflect it. */\n readonly muted = new Signal<boolean>(false);\n /** Social / sweepstakes mode: swaps gambling wording (Bet/Buy → social terms) and,\n * paired with a social coin, shows GC/SC. Toggle with {@link setSocial}. */\n readonly social = new Signal<boolean>(false);\n /** Declarative blocks backing the menu-style notice/error modal. */\n readonly noticeBlocks = new Signal<BlockSpec[]>([]);\n /** Action buttons for the notice/error modal (a single dismiss when empty). */\n readonly noticeActions = new Signal<NoticeAction[]>([]);\n /** Whether the open notice is a BLOCKING/fatal modal — no backdrop/✕ dismiss and\n * the HUD is locked; it can be removed only in code (`hideNotice`). */\n readonly noticeBlocking = new Signal<boolean>(false);\n private noticeLockHeld = false;\n /** Cumulative amount staked this session (major units) — RTS 12 \"money spent\". */\n readonly totalStaked = new Signal<number>(0);\n /** Cumulative amount won this session (major units). */\n readonly totalWon = new Signal<number>(0);\n /** The Stake jurisdiction config currently applied (read-back for guards/queries). */\n jurisdiction: Readonly<JurisdictionConfig> = {};\n /** Replay mode (Stake `replay=true`): the HUD locks + a REPLAY badge shows. */\n readonly replay = new Signal<boolean>(false);\n /** Game name + version (shown in the menu footer; for support / certification). */\n gameInfo: { name?: string; version?: string } = {};\n /** Declared GAME FACTS (modes + RTP/max win, free spins, volatility, cap) — seeded\n * from `spec.facts`, extended at runtime via {@link declareFacts} (the buy-feature\n * modal declares its configured features automatically). Drives the `mode-stats`\n * rules block + the rules-completeness audit in the info menu. */\n readonly facts = new Signal<GameFacts>({});\n /** Minimum round duration (ms) from jurisdiction — stored for the GAME to enforce. */\n minimumRoundDuration = 0;\n /** Buy-feature confirm threshold, as a multiple of the base bet. A play (buy or\n * bet-mode activation) that costs STRICTLY MORE than this must show a confirm step\n * — Stake requires that bet modes above 2× never activate on a single click. `0`\n * (the default) = off. Set via `spec.buyFeature.confirmAboveCost` or a jurisdiction. */\n confirmBuyAboveCost = 0;\n /** When autoplay stops while the balance can no longer cover the next round —\n * whether the built-in RG enforcement stopped it, the game's own pre-check did, or\n * the player pressed Stop already broke — pop the SAME insufficient-funds modal a\n * manual spin shows (ERR_IPB) instead of ending silently. A normal stop with funds\n * in hand shows nothing. Default on; `spec.autoplay.insufficientFundsNotice: false`\n * opts out. */\n autoplayInsufficientNotice = true;\n private sessionNet = 0;\n private prevVolumes: { music: number; sfx: number } | null = null;\n\n /** The frozen UISpec `createUI` built this from, if any — authored = run = tested. */\n spec?: Readonly<UISpec>;\n\n /** Typed convenience handles for the controls. */\n readonly spin: SpinControl;\n readonly balance: ValueDisplay;\n readonly bet: ValueDisplay;\n /** Bonus \"total win\" readout — shown in the buy-feature slot during a bonus/free-\n * spins round (the renderer swaps it for the buy button). Same money logic as `bet`. */\n readonly totalWin: ValueDisplay;\n readonly settingsButton: ButtonControl;\n readonly settingsPanel: PanelControl;\n readonly musicSlider: SliderControl;\n readonly sfxSlider: SliderControl;\n readonly turbo: TurboControl;\n readonly autoplay: AutoplayControl;\n readonly bonusButton: ButtonControl;\n readonly betStepper: StepperControl;\n readonly betPlus: ButtonControl;\n readonly betMinus: ButtonControl;\n readonly fullscreenButton: ButtonControl;\n readonly muteButton: ButtonControl;\n /** Compliance display readouts — hidden until a jurisdiction reveals them. */\n readonly rtp: ReadoutControl;\n readonly netPosition: ReadoutControl;\n readonly sessionTimer: ReadoutControl;\n /** Menu-style notice/error modal (content set via `showNotice`). */\n readonly noticePanel: PanelControl;\n\n private readonly controls = new Map<string, Control>();\n\n constructor(opts: OpenUIOptions = {}) {\n this.theme = opts.theme ?? defaultTheme;\n this.layoutConfig = opts.layout ?? defaultLayoutConfig;\n this.screen = new Signal<ScreenState>(computeScreen(1920, 1080, this.layoutConfig));\n\n this.translator = opts.translator ?? new DictionaryTranslator({}, 'en');\n this.locale = new Signal<string>(this.translator.locale);\n this.disposers.push(\n this.translator.onChange((loc) => {\n if (this.locale.get() === loc) return;\n this.locale.set(loc);\n this.bus.emit('localeChanged', loc);\n }),\n );\n\n this.spin = new SpinControl({ layout: defaultLayout('spin') }, this.bus);\n\n this.balance = new ValueDisplay({\n id: 'balance',\n label: 'openui.balance', // i18n key → localizes + swaps in social mode\n layout: defaultLayout('balance'),\n currency: { code: 'USD', decimals: 2 },\n initial: 1000,\n });\n this.bet = new ValueDisplay({\n id: 'bet',\n label: 'openui.bet',\n layout: defaultLayout('bet'),\n currency: { code: 'USD', decimals: 2 },\n initial: 1,\n });\n // Bonus total-win readout — same look/money logic as bet (caption pill + rolling\n // value), parked in the buy-feature slot; the renderer shows it only in a bonus.\n this.totalWin = new ValueDisplay({\n id: 'total-win',\n label: 'openui.totalWin',\n layout: defaultLayout('total-win'),\n currency: { code: 'USD', decimals: 2 },\n initial: 0,\n });\n\n // settings flyout: a button that toggles a popover with sound sliders + a Rules button\n this.settingsButton = new ButtonControl(\n { id: 'settings', layout: defaultLayout('settings') },\n this.bus,\n );\n this.settingsPanel = new PanelControl(\n { id: 'settings-panel', variant: 'popover', layout: { anchor: 'bottom-right', offset: [-24, -470] } },\n this.bus,\n );\n this.musicSlider = new SliderControl({ id: 'music', label: 'Music', layout: { anchor: 'center' }, initial: 0.7 }, this.bus);\n this.sfxSlider = new SliderControl({ id: 'sfx', label: 'Sound', layout: { anchor: 'center' }, initial: 0.5 }, this.bus);\n\n // bottom-bar controls\n this.bonusButton = new ButtonControl({ id: 'bonus', layout: defaultLayout('bonus') }, this.bus);\n this.autoplay = new AutoplayControl(\n { id: 'autoplay', layout: defaultLayout('autoplay'), options: [5, 10, 25, 50, 100, Infinity] },\n this.bus,\n );\n this.turbo = new TurboControl({ id: 'turbo', layout: defaultLayout('turbo') }, this.bus);\n this.betMinus = new ButtonControl({ id: 'bet-minus', layout: defaultLayout('bet-minus') }, this.bus);\n this.betPlus = new ButtonControl({ id: 'bet-plus', layout: defaultLayout('bet-plus') }, this.bus);\n this.betStepper = new StepperControl({ id: 'bet-stepper', layout: { anchor: 'center' }, levels: [0.5, 1, 2, 5, 10, 20], index: 1 }, this.bus);\n\n // edge controls: master mute + fullscreen (icon buttons at the screen corner)\n // Figma \"default\": two prominent b&w round buttons in the top-right corner with a\n // comfortable edge margin (sound on the left, fullscreen on the right).\n this.muteButton = new ButtonControl({ id: 'mute', layout: defaultLayout('mute') }, this.bus);\n this.fullscreenButton = new ButtonControl({ id: 'fullscreen', layout: defaultLayout('fullscreen') }, this.bus);\n\n // compliance readouts — created hidden; a jurisdiction's display* flag reveals them\n // Figma \"default\" compliance block: three plain `Label: value` lines stacked in\n // the top-left corner (RTP · Session Time · Net).\n this.rtp = new ReadoutControl({ id: 'rtp', kind: 'percent', label: 'RTP', layout: defaultLayout('rtp') });\n this.sessionTimer = new ReadoutControl({ id: 'session-timer', kind: 'duration', label: 'Session Time', layout: defaultLayout('session-timer') });\n this.netPosition = new ReadoutControl({ id: 'net-position', kind: 'currency', label: 'Net', currency: { code: 'USD', symbol: '$', display: 'symbol', position: 'prefix', decimals: 2 }, layout: defaultLayout('net-position') });\n\n // notice / error modal (rendered in the unified menu style)\n this.noticePanel = new PanelControl({ id: 'notice-panel', variant: 'modal', layout: { anchor: 'center' } }, this.bus);\n\n for (const c of [\n this.spin,\n this.balance,\n this.bet,\n this.totalWin,\n this.settingsButton,\n this.settingsPanel,\n this.musicSlider,\n this.sfxSlider,\n this.bonusButton,\n this.autoplay,\n this.turbo,\n this.betMinus,\n this.betPlus,\n this.betStepper,\n this.muteButton,\n this.fullscreenButton,\n this.rtp,\n this.netPosition,\n this.sessionTimer,\n this.noticePanel,\n ]) {\n this.register(c);\n }\n\n // compliance readouts start hidden — applyJurisdiction reveals the mandated ones\n this.hidden.add('rtp');\n this.hidden.add('net-position');\n this.hidden.add('session-timer');\n // The buy/bonus button is hidden until a host configures a buy feature (reveal it\n // with `controls.bonus.hidden = false` or `ui.setHidden('bonus', false)`) — so a\n // game with nothing to buy never shows a stray, purposeless button.\n this.hidden.add('bonus');\n\n // the library owns this navigation (a biased, stateful UI)\n this.bus.on('buttonActivated', ({ id }) => {\n if (id === 'settings') this.settingsPanel.toggle();\n else if (id === 'bet-plus') {\n this.betStepper.inc();\n } else if (id === 'bet-minus') {\n this.betStepper.dec();\n } else if (id === 'mute') {\n this.toggleMute();\n }\n });\n\n // bet stepper drives the bet value display + keeps +/- enabled within range\n this.bus.on('valueChanged', ({ id, value }) => {\n if (id === 'bet-stepper') this.bet.set(value);\n });\n const syncStepperButtons = (): void => {\n this.betStepper.canInc ? this.betPlus.enable() : this.betPlus.disable();\n this.betStepper.canDec ? this.betMinus.enable() : this.betMinus.disable();\n };\n this.disposers.push(this.betStepper.index.subscribe(syncStepperButtons));\n this.bet.set(this.betStepper.value);\n syncStepperButtons();\n\n // Autoplay that stops with the balance unable to cover the next round surfaces the\n // SAME insufficient-funds modal a manual spin shows — never a silent end. Guarded\n // against stomping a notice that is already open (e.g. `showRgsError` for another\n // code stops autoplay first, then presents its own message — that one must win).\n this.disposers.push(\n this.bus.on('autoplayStopped', () => {\n if (!this.autoplayInsufficientNotice || this.replay.get()) return;\n if (this.noticePanel.isOpen) return;\n if (this.balance.get() < this.bet.get()) this.showRgsError('ERR_IPB');\n }),\n );\n\n // When the notice/error modal closes, release a blocking lock + announce it.\n this.disposers.push(\n this.noticePanel.state.subscribe(() => {\n if (this.noticePanel.isOpen) return;\n if (this.noticeLockHeld) {\n this.unlock();\n this.noticeLockHeld = false;\n }\n if (this.noticeBlocking.get()) this.noticeBlocking.set(false);\n this.bus.emit('noticeDismissed', undefined);\n }),\n );\n\n if (opts.startMuted) this.setMuted(true);\n }\n\n register(control: Control): void {\n this.controls.set(control.id, control);\n control.gate = () => !this.locked.get();\n this.disposers.push(\n control.onTransition((_t, to, from) => {\n this.bus.emit('stateChanged', { id: control.id, from, to });\n }),\n );\n }\n\n control(id: string): Control | undefined {\n return this.controls.get(id);\n }\n\n all(): Control[] {\n return [...this.controls.values()];\n }\n\n /** Renderer calls this on resize; recomputes breakpoint + fit scale. */\n setScreen(width: number, height: number): void {\n this.screen.set(computeScreen(width, height, this.layoutConfig));\n }\n\n /**\n * Hide or show a control at runtime and tell the renderer (Charter P10). The\n * control stays registered — still in `snapshot()` — but the view is not drawn.\n * Used by the responsive layer to drop controls on small screens.\n */\n setHidden(id: string, hidden: boolean): void {\n if (!hidden && this.forceHidden.has(id)) return; // jurisdiction-locked: can't re-show\n const was = this.hidden.has(id);\n if (hidden === was) return;\n if (hidden) this.hidden.add(id);\n else this.hidden.delete(id);\n this.bus.emit('visibilityChanged', { id, hidden });\n }\n\n /** Push the ref-counted input lock (e.g. for the duration of a spin round). */\n lock(): void {\n this.lockCount += 1;\n if (this.lockCount === 1) this.locked.set(true);\n }\n\n /** Pop the lock; the HUD becomes interactable again only at zero. */\n unlock(): void {\n if (this.lockCount === 0) return;\n this.lockCount -= 1;\n if (this.lockCount === 0) this.locked.set(false);\n }\n\n /** Toggle master mute (music + sfx). */\n toggleMute(): void {\n this.setMuted(!this.muted.get());\n }\n\n /** Mute/unmute music+sfx, remembering the levels to restore on unmute. */\n setMuted(m: boolean): void {\n if (m === this.muted.get()) return;\n if (m) {\n this.prevVolumes = { music: this.musicSlider.value.get(), sfx: this.sfxSlider.value.get() };\n this.musicSlider.setNormalized(0);\n this.sfxSlider.setNormalized(0);\n } else if (this.prevVolumes) {\n this.musicSlider.setNormalized(this.prevVolumes.music);\n this.sfxSlider.setNormalized(this.prevVolumes.sfx);\n this.prevVolumes = null;\n }\n this.muted.set(m);\n }\n\n /**\n * Report one completed round (major units): updates the net-position readout and,\n * while autoplay is running, advances its count + enforces its RG loss/single-win\n * limits. One feed point powers both `displayNetPosition` and the autoplay stops.\n */\n reportRound(win: number, bet: number): void {\n if (!Number.isFinite(win) || !Number.isFinite(bet)) return;\n this.sessionNet += win - bet;\n this.netPosition.set(this.sessionNet);\n this.totalStaked.set(this.totalStaked.get() + bet);\n this.totalWon.set(this.totalWon.get() + win);\n if (this.autoplay.isActive) {\n this.autoplay.reportResult(win, bet);\n // auto-stop autoplay when the next round is no longer affordable (RG)\n if (this.autoplay.isActive && this.balance.get() < this.bet.get()) this.autoplay.stop();\n }\n }\n\n /** Merge more game facts into {@link facts} (modes merge by id; defined incoming\n * fields win). The info menu re-audits + re-renders its rules automatically. */\n declareFacts(add: GameFacts): void {\n if (!add || typeof add !== 'object') return;\n this.facts.set(mergeFacts(this.facts.get(), add));\n }\n\n /** Reset the running session net + aggregates + timer (e.g. on a fresh session). */\n resetSession(): void {\n this.sessionNet = 0;\n this.netPosition.set(0);\n this.totalStaked.set(0);\n this.totalWon.set(0);\n this.sessionTimer.reset();\n }\n\n /** Show the menu-style notice modal: declarative blocks + optional action buttons.\n * Every string (block text + button labels) runs through `ui.t`, so pass exact\n * literals OR your own i18n keys. Omit `actions` → a single dismiss button. */\n showNotice(blocks: BlockSpec[], actions?: NoticeAction[], opts: { blocking?: boolean } = {}): void {\n const blocking = !!opts.blocking;\n this.noticeBlocks.set(Array.isArray(blocks) ? blocks : []);\n // A blocking modal with no actions is dismissable ONLY in code (no default OK).\n this.noticeActions.set(actions && actions.length ? actions : blocking ? [] : [DEFAULT_NOTICE_ACTION]);\n this.noticeBlocking.set(blocking);\n // Keep the blocking lock in step even if one notice REPLACES another while open\n // (openPanel is idempotent, so the close-subscription wouldn't fire to release it).\n if (blocking && !this.noticeLockHeld) {\n this.lock();\n this.noticeLockHeld = true;\n } else if (!blocking && this.noticeLockHeld) {\n this.unlock();\n this.noticeLockHeld = false;\n }\n this.noticePanel.openPanel();\n this.bus.emit('noticeShown', { blocking });\n }\n\n /** Show a simple error/notice: a title + a tone-coloured message. `message` and\n * `opts.title` are literal-or-key (localized via `ui.t`); `opts.actions` adds\n * custom buttons (e.g. a \"Reload\"). `opts.blocking` → a fatal modal (locks the\n * HUD, no backdrop/✕ dismiss; removable only via `hideNotice`). */\n showError(message: string, opts: NoticeOptions = {}): void {\n this.showNotice(errorBlocks(message, opts.title ?? 'openui.error', opts.tone ?? 'warning'), opts.actions, {\n blocking: opts.blocking,\n });\n }\n\n /** Show a FATAL error: a blocking modal that locks the HUD and can be removed only\n * in code (`hideNotice`) — for unrecoverable RGS states. Pass `actions` (e.g. a\n * \"Reload\" that reloads the page) for the only way out. */\n showFatal(message: string, opts: NoticeOptions = {}): void {\n this.showError(message, { ...opts, blocking: true });\n }\n\n /** Show the default (localizable, overridable) message for an RGS status code.\n * Override the exact text per call via `opts.title` / `opts.message`. Stops an\n * active autoplay by default (`opts.stopAutoplay = false` to keep it). Pass\n * `opts.blocking` for unrecoverable codes (session expiry, maintenance). */\n showRgsError(code: string, opts: RgsErrorOptions = {}): void {\n const def = RGS_ERROR_KEYS[code] ?? RGS_ERROR_KEYS.ERR_GEN!;\n if (opts.stopAutoplay !== false && this.autoplay.isActive) this.autoplay.stop();\n this.showError(opts.message ?? def.message, {\n title: opts.title ?? def.title,\n tone: opts.tone ?? 'warning',\n actions: opts.actions,\n blocking: opts.blocking,\n });\n }\n\n /** Close the notice / error modal. */\n hideNotice(): void {\n this.noticePanel.closePanel();\n }\n\n /** Enter/leave replay mode (Stake `replay=true`) — locks the HUD so no real bet is\n * placed; the renderer shows a REPLAY badge while it's on. */\n setReplay(on: boolean): void {\n if (on === this.replay.get()) return;\n this.replay.set(on);\n if (on) this.lock();\n else this.unlock();\n }\n\n /** Apply a Stake Engine `jurisdiction` config to the live HUD (whole switchboard).\n * The merged config is stored for `isDisabled()` read-back. */\n applyJurisdiction(jur: JurisdictionConfig): void {\n this.jurisdiction = Object.freeze({ ...this.jurisdiction, ...jur });\n applyJurisdictionTo(this, jur);\n }\n\n /** Tear down every subscription and control this ui created (Charter P12). */\n dispose(): void {\n for (const d of this.disposers) d();\n this.disposers.length = 0;\n for (const c of this.controls.values()) c.dispose();\n this.controls.clear();\n }\n\n /**\n * Switch language. Drives the translator (if it can self-switch) and emits\n * `localeChanged`; controls' views, subscribed to `locale`, re-render their text.\n */\n setLocale(next: string): void {\n // The translator owns locale state; its onChange handler (wired in the\n // constructor) updates `locale` and emits localeChanged. No-op for same locale.\n this.translator.setLocale(next);\n }\n\n /** Translate a key (or pass plain text through) via the active translator. Social\n * wording is resolved by the translator from a SEPARATE social dictionary (see\n * `setSocial`), so gambling and social copy can never be mixed by accident. */\n t(key: string, vars?: Record<string, string | number>): string {\n return this.translator.t(key, vars);\n }\n\n /**\n * Turn social / sweepstakes mode on or off (one switch). Flips the translator to\n * its SEPARATE social dictionary (Bet→Play, Buy feature→Play bonus, etc.) and,\n * when a `coin` is given (e.g. `'GC'`/`'SC'`), shows balance/bet/net in that coin.\n * Wording re-renders live. Social copy lives in `locale.socialMessages` — kept\n * apart from your normal `locale.messages` by design.\n */\n setSocial(on: boolean, coin?: string): void {\n if (on !== this.social.get()) {\n this.social.set(on);\n this.translator.setSocial?.(on);\n this.locale.update(() => {}); // nudge text views (they subscribe to `locale`) to re-translate\n }\n if (coin) {\n const cur = resolveCurrency(coin);\n this.balance.setCurrency(cur);\n this.bet.setCurrency(cur);\n this.netPosition.setCurrency(cur);\n }\n }\n\n /** Read-back: did the applied jurisdiction disable this feature? (real guard, not\n * just a hide — `confirmBuy`/autoplay entry points consult this). */\n isDisabled(feature: 'autoplay' | 'buyFeature' | 'turbo' | 'fullscreen' | 'slamstop' | 'spacebar'): boolean {\n const j = this.jurisdiction;\n return (\n (feature === 'autoplay' && !!j.disabledAutoplay) ||\n (feature === 'buyFeature' && !!j.disabledBuyFeature) ||\n (feature === 'turbo' && !!j.disabledTurbo) ||\n (feature === 'fullscreen' && !!j.disabledFullscreen) ||\n (feature === 'slamstop' && !!j.disabledSlamstop) ||\n (feature === 'spacebar' && !!j.disabledSpacebar)\n );\n }\n\n /** True when a buy / bet-mode activation of `cost`× the base bet must be confirmed\n * before it commits (Stake: no one-click activation above `confirmBuyAboveCost`×).\n * Always false when the threshold is 0/unset or `cost` isn't a finite number. */\n shouldConfirmBuy(cost: number): boolean {\n const t = this.confirmBuyAboveCost;\n return t > 0 && Number.isFinite(cost) && cost > t;\n }\n\n /**\n * Start a reality-check reminder (RTS 13). Every `everyMinutes` (WALL-CLOCK, so a\n * backgrounded tab can't cheat it) it emits a `realityCheck` event, stops autoplay,\n * and — unless `showModal: false` — shows an acknowledge modal. You provide only\n * the interval + (optional) title/message text; `{{minutes}}`/`{{spent}}`/`{{won}}`\n * are interpolated. Returns a disposer (also torn down by `dispose()`).\n */\n startRealityCheck(opts: RealityCheckOptions): Dispose {\n const everyMs = Math.max(1, opts.everyMinutes) * 60_000;\n let last = Date.now();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const tick = (): void => {\n // don't stack on an already-open modal — re-check shortly\n if (this.noticePanel.isOpen) {\n timer = setTimeout(tick, 1000);\n return;\n }\n const elapsedMs = Date.now() - last;\n last = Date.now();\n this.fireRealityCheck(opts, elapsedMs);\n timer = setTimeout(tick, everyMs);\n };\n timer = setTimeout(tick, everyMs);\n const dispose = (): void => {\n if (timer) clearTimeout(timer);\n timer = undefined;\n };\n this.disposers.push(dispose);\n return dispose;\n }\n\n /** Fire one reality check now: emit the event (+ session totals), stop autoplay,\n * and show the modal unless `showModal:false`. Exposed for manual triggers / tests. */\n fireRealityCheck(opts: RealityCheckOptions, elapsedMs = 0): void {\n const minutes = Math.max(1, Math.round(opts.everyMinutes));\n const totalStaked = this.totalStaked.get();\n const totalWon = this.totalWon.get();\n this.bus.emit('realityCheck', { minutes, elapsedMs, totalStaked, totalWon });\n if (this.autoplay.isActive) this.autoplay.stop();\n if (opts.showModal === false) return;\n const vars = { minutes, spent: totalStaked, won: totalWon };\n this.showNotice(\n [\n { kind: 'heading', id: 'rc-title', text: this.t(opts.title ?? 'openui.realityCheck.title', vars) },\n { kind: 'text', id: 'rc-body', text: this.t(opts.message ?? 'openui.realityCheck.message', vars) },\n ],\n opts.actions ?? [{ label: 'openui.continue', variant: 'primary' }],\n );\n }\n\n on<K extends keyof OpenUIEvents>(type: K, fn: (payload: OpenUIEvents[K]) => void): Dispose {\n return this.bus.on(type, fn);\n }\n\n /** Serializable snapshot for the introspection / e2e API (Charter P10). */\n snapshot(): ControlSnapshot[] {\n return this.all().map((c) => {\n const { bounds, animating } = c.inspect();\n return {\n id: c.id,\n role: c.role,\n state: c.current,\n interactable: c.interactable,\n bounds,\n animating,\n };\n });\n }\n}\n","/**\n * The responsive layer: re-apply per-device / per-orientation control overrides\n * every time the screen bucket changes. Pure assembly over the existing layout\n * machinery — it only ever sets `control.layout` and toggles `ui.setHidden`, both\n * of which the views already react to (Charter P6/P10). No new rendering concepts.\n */\nimport type { OpenUI } from '../OpenUI';\nimport type { Dispose } from '../signal';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { ScreenState } from '../layout/screen';\nimport type { ResponsiveKey, ResponsiveOverride } from './types';\n\ntype Responsive = Partial<Record<ResponsiveKey, ResponsiveOverride>>;\n\ninterface Base {\n layout: LayoutSpec;\n hidden: boolean;\n}\n\nfunction cloneLayout(l: LayoutSpec): LayoutSpec {\n return { anchor: l.anchor, offset: l.offset ? [l.offset[0], l.offset[1]] : undefined, scale: l.scale, rotation: l.rotation };\n}\n\n/** The buckets that apply to a screen, least → most specific (size wins over orientation). */\nfunction activeKeys(screen: ScreenState): ResponsiveKey[] {\n return [screen.orientation, screen.breakpoint];\n}\n\n/**\n * Install responsive overrides. Snapshots each referenced control's CURRENT layout\n * + hidden state as the \"base\" (so callers must apply static `controls` overrides\n * first), then on every screen change re-derives base → orientation → size and\n * applies it. Returns a disposer. Runs once immediately for the current screen.\n */\nexport function installResponsive(ui: OpenUI, responsive: Responsive): Dispose {\n // Every control id mentioned in any bucket.\n const ids = new Set<string>();\n for (const key of Object.keys(responsive) as ResponsiveKey[]) {\n const ov = responsive[key];\n if (ov?.controls) for (const id of Object.keys(ov.controls)) ids.add(id);\n }\n if (!ids.size) return () => {};\n\n // Snapshot the base layout + visibility for each (the post-`controls` truth).\n const base = new Map<string, Base>();\n for (const id of ids) {\n const c = ui.control(id);\n if (!c) continue;\n base.set(id, { layout: cloneLayout(c.layout), hidden: ui.hidden.has(id) });\n }\n\n let applying = false;\n const apply = (screen: ScreenState): void => {\n applying = true;\n try {\n const keys = activeKeys(screen);\n for (const [id, b] of base) {\n const c = ui.control(id);\n if (!c) continue;\n let layout = b.layout;\n let hidden = b.hidden;\n for (const key of keys) {\n const ov = responsive[key]?.controls?.[id];\n if (!ov) continue;\n if (ov.layout) layout = ov.layout;\n if (ov.hidden != null) hidden = ov.hidden;\n }\n c.layout = cloneLayout(layout);\n ui.setHidden(id, hidden);\n }\n } finally {\n applying = false;\n }\n };\n\n // A visibility change we did NOT cause is the base truth moving at runtime —\n // e.g. `applyJurisdiction` revealing the RTP/session readouts after mount, or a\n // host calling `setHidden` — so fold it into the base instead of reverting it\n // on the next screen change.\n const offVis = ui.on('visibilityChanged', ({ id, hidden }) => {\n if (applying) return;\n const b = base.get(id);\n if (b) b.hidden = hidden;\n });\n\n // Subscribe in createUI (before the renderer mounts) so this runs BEFORE the\n // views' own screen subscribers — they then read the freshly-set layouts.\n const off = ui.screen.subscribe(apply);\n apply(ui.screen.get());\n return () => {\n off();\n offVis();\n };\n}\n","/**\n * Social-mode FORBIDDEN-PHRASE checker (Charter B8/P11). Stake US social/sweepstakes\n * jurisdiction restricts gambling wording; a game must not surface \"bet\", \"pay(table)\",\n * \"funds\", \"cash\", etc. anywhere in its copy. This scans the ENGLISH strings a game\n * ships (menu blocks, rules, section titles, control labels/hints, the `en` dictionary,\n * the game name) and reports every restricted phrase with a compliant replacement, so\n * the classic \"we shipped a *paytable* while `pay` is banned\" slips through no longer.\n *\n * It's a lint, not a gate — never throws; `createUI` runs it automatically in social\n * mode and forwards findings to `HostHooks.onDataIssue` (+ a console warning), and a\n * game's own test can call {@link checkSocialPhrases} directly.\n *\n * See Stake's \"Jurisdiction Requirements → forbidden phrases\" for the authoritative\n * list; this covers the common roots and their recommended replacements.\n */\nimport type { UISpec, BlockSpec } from './types';\nimport { openuiSocialDefaults } from '../i18n/translator';\n\nexport interface ForbiddenMatch {\n /** The restricted root that matched (\"pay*\", \"bet\", \"funds\", …). */\n term: string;\n /** The recommended compliant replacement. */\n replacement: string;\n}\nexport interface SocialPhraseIssue {\n /** Where the copy lives (e.g. `menu.rules[3]`, `locale.en[\"Paytable\"]`). */\n source: string;\n /** The offending string. */\n text: string;\n /** Every restricted phrase found in it. */\n matches: ForbiddenMatch[];\n}\n\n// Restricted roots → compliant replacements. Case-insensitive. Anchored so a bare root\n// can't over-flag (\"bet\" must not hit \"between\"/\"better\"); `\\w*` roots (pay*/cash*/…)\n// deliberately catch compounds like \"paytable\"/\"cashout\" — the whole point here.\nconst FORBIDDEN: ReadonlyArray<{ re: RegExp; term: string; replacement: string }> = [\n { re: /\\bpay\\w*/i, term: 'pay*', replacement: 'prize / award (e.g. \"paytable\" → \"prizes\")' },\n { re: /\\bpayout\\w*/i, term: 'payout', replacement: 'award' },\n { re: /\\bbets?\\b|\\bbetting\\b/i, term: 'bet', replacement: 'play' },\n { re: /\\bwager\\w*/i, term: 'wager', replacement: 'play' },\n { re: /\\bgambl\\w*/i, term: 'gamble', replacement: 'play' },\n { re: /\\bcash\\w*/i, term: 'cash', replacement: 'coins' },\n { re: /\\bfunds?\\b/i, term: 'funds', replacement: 'coins / balance' },\n { re: /\\bmoney\\b/i, term: 'money', replacement: 'coins' },\n { re: /\\bdeposit\\w*/i, term: 'deposit', replacement: 'purchase' },\n { re: /\\bwithdraw\\w*/i, term: 'withdraw', replacement: 'redeem' },\n { re: /\\bcredits?\\b/i, term: 'credit', replacement: 'coins / balance' },\n { re: /\\bwinnings?\\b/i, term: 'winnings', replacement: 'prizes' },\n { re: /\\bjackpots?\\b/i, term: 'jackpot', replacement: 'grand prize' },\n { re: /\\breal[-\\s]?money\\b/i, term: 'real money', replacement: 'coins' },\n];\n\n/** Every restricted phrase in `text` (empty when clean). Pure + total. */\nexport function findForbiddenPhrases(text: string): ForbiddenMatch[] {\n if (typeof text !== 'string' || !text) return [];\n const seen = new Set<string>();\n const out: ForbiddenMatch[] = [];\n for (const r of FORBIDDEN) {\n if (r.re.test(text) && !seen.has(r.term)) {\n seen.add(r.term);\n out.push({ term: r.term, replacement: r.replacement });\n }\n }\n return out;\n}\n\n/** A collected string. `text` is the base English (what renders with no social\n * override); `key` is the i18n key used to look up a social override — it defaults\n * to `text`, since a game's menu/rules copy doubles as its own key. */\ntype Entry = { source: string; text: string; key?: string };\n\nfunction walkBlock(b: BlockSpec, src: string, out: Entry[]): void {\n const add = (t: unknown, s: string = src): void => {\n if (typeof t === 'string' && t) out.push({ source: s, text: t });\n };\n const anyB = b as Record<string, unknown>;\n switch (b.kind) {\n case 'text':\n case 'heading':\n case 'subheading':\n case 'legal':\n add(b.text);\n break;\n case 'callout':\n add(b.title);\n add(b.text);\n break;\n case 'media':\n add(b.title);\n add(b.text);\n break;\n case 'slider':\n case 'toggle':\n case 'button':\n case 'select':\n case 'stepper':\n case 'value':\n add(anyB.label);\n add(anyB.hint);\n break;\n case 'steps':\n b.items.forEach((s, i) => add(s, `${src}.items[${i}]`));\n break;\n case 'table':\n (b.columns ?? []).forEach((c) => add(c));\n b.rows.forEach((row) => row.forEach((c) => add(c)));\n break;\n case 'paytable':\n b.rows.forEach((r) => {\n add(r.symbol);\n add(r.payouts);\n });\n break;\n case 'cards':\n b.items.forEach((it) => {\n add(it.title);\n add(it.text);\n });\n break;\n case 'stat-grid':\n b.items.forEach((it) => {\n add(it.label);\n add(it.value);\n });\n break;\n case 'mode-stats':\n // generated labels (\"RTP · <name>\" / \"Max win · <name>\") resolve through the\n // social dictionary at render; only host-supplied extras carry static copy.\n (b.extras ?? []).forEach((it) => {\n add(it.label);\n add(it.value);\n });\n break;\n case 'group':\n add(b.title);\n b.children.forEach((c, i) => walkBlock(c, `${src}.children[${i}]`, out));\n break;\n default:\n break;\n }\n}\n\n/** Collect every English string a spec ships (menu/rules blocks, titles, labels+hints,\n * game name, the `en` dictionary) with a source path — the input to {@link checkSocialPhrases}. */\nexport function collectSocialCopy(spec: UISpec): Entry[] {\n const out: Entry[] = [];\n const menu = spec.menu;\n if (menu) {\n const sections: Array<[string, BlockSpec[] | undefined]> = [\n ['settings', menu.settings],\n ['paytable', menu.paytable],\n ['rules', menu.rules],\n ];\n for (const [sec, blocks] of sections) (blocks ?? []).forEach((b, i) => walkBlock(b, `menu.${sec}[${i}]`, out));\n if (menu.titles) for (const [k, v] of Object.entries(menu.titles)) if (v) out.push({ source: `menu.titles.${k}`, text: v });\n if (menu.banner?.src) {\n /* image only, no copy */\n }\n }\n (spec.rules ?? []).forEach((b, i) => walkBlock(b, `rules[${i}]`, out));\n if (spec.game?.name) out.push({ source: 'game.name', text: spec.game.name });\n const en = spec.locale?.messages?.en;\n // The en dict is a translation SOURCE: in social mode the KEY resolves through the\n // social dictionary, so carry `key: k` and check what actually renders for that key.\n if (en) for (const [k, v] of Object.entries(en)) if (typeof v === 'string') out.push({ source: `locale.en[${JSON.stringify(k)}]`, text: v, key: k });\n return out;\n}\n\n/**\n * Scan a spec's English copy AS IT RENDERS IN SOCIAL MODE and return every restricted\n * phrase. Each collected string is first resolved through the social dictionary\n * (`locale.socialMessages.en` → built-in `openuiSocialDefaults` → the base text) —\n * exactly like the translator does — so a game that already swaps \"bet\"/\"pay(table)\"\n * for compliant wording in social mode is NOT flagged, while a phrase with NO social\n * override (the classic slipped-through \"paytable\") IS. English by design: the check\n * targets the base `en` copy that every jurisdiction review starts from.\n */\nexport function checkSocialPhrases(spec: UISpec): SocialPhraseIssue[] {\n const socialEn = spec.locale?.socialMessages?.en ?? {};\n const render = (e: Entry): string => socialEn[e.key ?? e.text] ?? openuiSocialDefaults[e.key ?? e.text] ?? e.text;\n const issues: SocialPhraseIssue[] = [];\n for (const e of collectSocialCopy(spec)) {\n const text = render(e);\n const matches = findForbiddenPhrases(text);\n if (matches.length) issues.push({ source: e.source, text, matches });\n }\n return issues;\n}\n","/**\n * createUI(spec) — assemble a complete, configured OpenUI from one JSON UISpec,\n * over the EXISTING reference HUD (Charter P1/P4/B9). Zero-arg `createUI()`\n * reproduces today's 16-control HUD. Pure assembly: validate → apply overrides →\n * wire the ref-counted spin lock → freeze the spec onto `ui.spec`.\n */\nimport { OpenUI } from '../OpenUI';\nimport { ValueDisplay } from '../controls/ValueDisplay';\nimport { resolveTheme } from '../theme/presets';\nimport { DictionaryTranslator } from '../i18n/translator';\nimport { validateSpec } from './validateSpec';\nimport { installResponsive } from './responsive';\nimport { resolveCurrency } from '../format/currency';\nimport { portraitDefaultLayouts } from '../layout/defaultLayouts';\nimport { checkSocialPhrases } from './socialPhrases';\nimport type { UISpec, HostHooks, TurboSpec, ResponsiveOverride } from './types';\nimport type { OpenUIEvents } from '../types';\n\n/** Resolve the turbo `modes` config (`2`/`3` presets or explicit names) to a ladder. */\nexport function resolveTurboModes(modes: TurboSpec['modes']): string[] {\n if (Array.isArray(modes)) return modes.length ? modes : ['off', 'on'];\n if (modes === 3) return ['off', 'turbo', 'super'];\n return ['off', 'on'];\n}\n\n/** Identity helper for typed authoring (IDE checks the shape); returns the spec. */\nexport function defineUI(spec: UISpec): UISpec {\n return spec;\n}\n\nconst ANALYTICS_EVENTS = [\n 'stateChanged',\n 'buttonActivated',\n 'valueChanged',\n 'toggled',\n 'optionSelected',\n 'panelToggled',\n 'autoplayStarted',\n 'autoplayStopped',\n] as const;\n\nexport function createUI(spec: UISpec = {}, hooks: HostHooks = {}): OpenUI {\n // Never-reject: report issues to the host, but still boot.\n const { issues } = validateSpec(spec);\n for (const issue of issues) hooks.onDataIssue?.(issue);\n\n const translator = spec.locale\n ? new DictionaryTranslator(spec.locale.messages, spec.locale.locale, spec.locale.socialMessages)\n : undefined;\n // Theme overrides are sanitized; any rejected value is reported, never fatal.\n const theme = resolveTheme(spec.theme, (i) => hooks.onDataIssue?.(i));\n const ui = new OpenUI({ theme, layout: spec.layout, translator, startMuted: spec.audio?.startMuted });\n\n if (spec.currency) {\n const cur = typeof spec.currency === 'string' ? resolveCurrency(spec.currency) : spec.currency;\n ui.balance.setCurrency(cur);\n ui.bet.setCurrency(cur);\n ui.totalWin.setCurrency(cur); // bonus total-win formats like the money displays\n ui.netPosition.setCurrency(cur);\n }\n\n // Social / sweepstakes mode: one switch swaps wording (+ a coin → GC/SC display).\n if (spec.social) {\n if (typeof spec.social === 'object') ui.setSocial(true, spec.social.coin);\n else ui.setSocial(true);\n }\n\n // In social mode, LINT the game's English copy for restricted gambling wording\n // (pay*/bet/funds/cash/…) and report each finding with a compliant replacement — so a\n // stray \"paytable\" can't ship. Never blocks boot; forwarded to onDataIssue + console.\n if (spec.social || spec.jurisdiction?.socialCasino) {\n const found = checkSocialPhrases(spec);\n for (const issue of found) {\n hooks.onDataIssue?.({\n level: 'warn',\n path: issue.source,\n code: 'social-forbidden-phrase',\n message: `Social mode restricted wording in \"${issue.text}\": ${issue.matches.map((m) => `“${m.term}” → ${m.replacement}`).join('; ')}`,\n });\n }\n if (found.length && typeof console !== 'undefined') {\n console.warn(`[open-ui] social mode: ${found.length} string(s) contain restricted phrases (see onDataIssue). First: ${found[0]!.source} → \"${found[0]!.text}\"`);\n }\n }\n\n if (typeof spec.rtp === 'number') ui.rtp.set(spec.rtp);\n if (spec.game) ui.gameInfo = { name: spec.game.name, version: spec.game.version };\n if (spec.facts) ui.declareFacts(spec.facts);\n\n if (spec.betLadder?.levels?.length) {\n ui.betStepper.setLevels(spec.betLadder.levels, spec.betLadder.index ?? 0);\n ui.bet.set(ui.betStepper.value);\n }\n\n if (spec.autoplay?.options?.length) {\n ui.autoplay.setOptions(spec.autoplay.options);\n }\n if (spec.autoplay?.mode) {\n ui.autoplay.mode = spec.autoplay.mode;\n }\n if (spec.autoplay?.lossLimits) ui.autoplay.setLossLimitOptions(spec.autoplay.lossLimits);\n if (spec.autoplay?.winLimits) ui.autoplay.setWinLimitOptions(spec.autoplay.winLimits);\n if (spec.autoplay?.insufficientFundsNotice === false) ui.autoplayInsufficientNotice = false;\n\n // Turbo: 2-mode (off/on) or 3-mode (off/turbo/super), or an explicit ladder.\n if (spec.turbo) {\n ui.turbo.setModes(resolveTurboModes(spec.turbo.modes));\n if (spec.turbo.index != null) ui.turbo.setIndex(spec.turbo.index);\n }\n\n // Spin: single tap vs press-and-hold turbo.\n if (spec.spin?.press) {\n ui.spin.holdToSpin = spec.spin.press === 'hold-to-spin';\n }\n\n if (spec.controls) {\n for (const [id, ov] of Object.entries(spec.controls)) {\n const c = ui.control(id);\n if (!c) continue;\n if (ov.layout) c.layout = ov.layout;\n // `hidden` can hide OR re-show (e.g. reveal the buy button, hidden by default).\n if (ov.hidden != null) ui.setHidden(id, ov.hidden);\n const disable = (c as { disable?: () => void }).disable;\n if (ov.disabled && typeof disable === 'function') disable.call(c);\n if (c instanceof ValueDisplay) {\n if (ov.currency) c.setCurrency(ov.currency);\n if (ov.initial != null) c.set(ov.initial);\n if (ov.digits != null) c.setDigits(ov.digits);\n }\n }\n }\n\n // Buy-feature confirm threshold (explicit config) — set before jurisdiction so a\n // platform jurisdiction can tighten it, but the game's own value is the default.\n if (spec.buyFeature?.confirmAboveCost != null && Number.isFinite(spec.buyFeature.confirmAboveCost)) {\n ui.confirmBuyAboveCost = Math.max(0, spec.buyFeature.confirmAboveCost);\n }\n\n // Jurisdiction (the Stake Engine compliance switchboard) is applied BEFORE the\n // responsive layer snapshots its base, so a `disabled*` hide is part of that base\n // and survives every resize (it's force-hidden too, belt-and-braces).\n if (spec.jurisdiction) ui.applyJurisdiction(spec.jurisdiction); // ui.* stores the snapshot for isDisabled()\n\n // Responsive overrides layer on top of the static `controls` (snapshotted as the\n // base), re-applied on every resize. Installed here — before the renderer mounts\n // — so it runs first on each screen change and the views read fresh layouts.\n //\n // The library ships a BUILT-IN portrait bucket (the Figma \"Mobile DEF\" reflow;\n // the base layouts are the landscape \"Desk DEF\" frame) so the zero-config HUD is\n // right on phones AND desktops. It layers UNDER host overrides: a host's static\n // `controls.{id}.layout` wins everywhere, and a host's own `responsive.portrait`\n // entry wins per-control.\n const portraitControls: NonNullable<ResponsiveOverride['controls']> = {};\n for (const [id, layout] of Object.entries(portraitDefaultLayouts)) {\n if (spec.controls?.[id]?.layout) continue; // host laid it out statically — respect it\n portraitControls[id] = { layout };\n }\n Object.assign(portraitControls, spec.responsive?.portrait?.controls);\n installResponsive(ui, {\n ...spec.responsive,\n portrait: { ...spec.responsive?.portrait, controls: portraitControls },\n });\n\n // Ref-counted whole-HUD lock for the duration of a spin (Charter P6/G7). The\n // host drives spin state via `ui.spin.busy()`; this just brackets it.\n if (spec.lockDuringSpin !== false) {\n let wasSpinning = false;\n ui.spin.state.subscribe((s) => {\n const now = s === 'spinning';\n if (now && !wasSpinning) ui.lock();\n else if (!now && wasSpinning) ui.unlock();\n wasSpinning = now;\n });\n }\n\n // Reality-check reminder (RTS 13) — open-ui owns the wall-clock timer + event +\n // modal; the spec supplies only the cadence and (optional) text. Torn down by dispose().\n if (spec.realityCheck && spec.realityCheck.everyMinutes > 0) {\n ui.startRealityCheck(spec.realityCheck);\n }\n\n // A select control with this id switches the whole UI locale; the host still\n // owns any persistence via HostHooks (Charter B8) — the lib only re-renders.\n const localeSelectId = spec.localeSelectId ?? 'lang';\n ui.on('optionSelected', ({ id, value }) => {\n if (id === localeSelectId) ui.setLocale(value);\n });\n\n if (hooks.onAnalyticsEvent) {\n const forward = hooks.onAnalyticsEvent;\n for (const type of ANALYTICS_EVENTS) {\n ui.on(type, (payload) => forward(type, payload as OpenUIEvents[typeof type]));\n }\n }\n\n ui.spec = Object.freeze(spec);\n return ui;\n}\n","/**\n * The unified MENU: one scrollable surface opened by the ☰ button, composed of\n * three ordered sections — Settings (Music/Sound + a Language switch + your\n * extras), Paytable, then Rules. `composeMenu` is pure: it flattens a `MenuSpec`\n * into the ordered `BlockSpec[]` the renderer draws, injecting section headings.\n * Section text is localizable (it flows through `ui.t` in the view).\n */\nimport type { BlockSpec } from './types';\n\n/**\n * How the Settings section exposes sound:\n * - `'toggle'` — a single Sound on/off switch (mute).\n * - `'master'` — the Sound switch + one Volume slider (music + effects together).\n * - `'sliders'` — the Sound switch + separate **Music** and **Effects** sliders. (default)\n */\nexport type SoundControls = 'toggle' | 'master' | 'sliders';\n\nexport interface MenuSpec {\n /** A banner image shown at the very top of the menu (e.g. a themed title art). */\n banner?: { src: string; width?: number; height?: number };\n /** How sound is configured in Settings (toggle · master slider · music+effects). Default `'sliders'`. */\n sound?: SoundControls;\n /** Extra settings, appended after the built-in Music/Sound (+ Language). */\n settings?: BlockSpec[];\n /** Paytable section content (omit → no Paytable section). */\n paytable?: BlockSpec[];\n /** Rules section content (omit → no Rules section). */\n rules?: BlockSpec[];\n /** Override the section heading text (each is run through `ui.t`). */\n titles?: { settings?: string; paytable?: string; rules?: string };\n}\n\n// The English section titles double as their i18n keys (a game's dict localizes them).\n// \"Paytable\" is social-restricted → the social dictionary swaps it to \"Prizes\" (see\n// openuiSocialDefaults), so the heading is compliant in social mode without extra config.\nexport const DEFAULT_MENU_TITLES = { settings: 'Settings', paytable: 'Paytable', rules: 'Rules' } as const;\n\n/** Native names for the language switch; falls back to the upper-cased code.\n * Covers Stake Engine's locale set (ar de en es fr id ja ko pl pt ru tr vi zh fi hi). */\nexport const LOCALE_LABELS: Record<string, string> = {\n en: 'English', es: 'Español', pt: 'Português', de: 'Deutsch', fr: 'Français',\n ru: 'Русский', tr: 'Türkçe', zh: '中文', ja: '日本語', ar: 'العربية',\n pl: 'Polski', ko: '한국어', hi: 'हिन्दी', id: 'Bahasa Indonesia', vi: 'Tiếng Việt',\n fi: 'Suomi', it: 'Italiano', nl: 'Nederlands',\n};\n\nexport interface ComposeMenuOptions {\n /** Locale codes available — when 2+, a Language select is added to Settings. */\n locales?: string[];\n /** The select id that switches locale (must match createUI's localeSelectId). */\n localeSelectId?: string;\n /** Back-compat: a top-level `rules` array used when `menu.rules` is absent. */\n rulesFallback?: BlockSpec[];\n}\n\n/**\n * Compose the ordered menu blocks. The built-in Music/Sound sliders reuse the\n * real `music`/`sfx` controls (the view's reuse resolver wires them), so the menu\n * drives the actual volume — it doesn't shadow it.\n */\nexport function composeMenu(menu: MenuSpec | undefined, opts: ComposeMenuOptions = {}): BlockSpec[] {\n const titles = { ...DEFAULT_MENU_TITLES, ...menu?.titles };\n const out: BlockSpec[] = [];\n\n // ── Banner (optional themed title art) ──────────────────────────────────────\n if (menu?.banner?.src) {\n out.push({ kind: 'image', id: 'menu-banner', src: menu.banner.src, width: menu.banner.width, height: menu.banner.height });\n }\n\n // ── Settings ──────────────────────────────────────────────────────────────\n out.push({ kind: 'heading', id: 'menu-sec-settings', text: titles.settings });\n out.push({ kind: 'slider', id: 'music', label: 'Music' });\n out.push({ kind: 'slider', id: 'sfx', label: 'Sound' });\n const locales = opts.locales ?? [];\n if (locales.length >= 2) {\n out.push({\n kind: 'select',\n id: opts.localeSelectId ?? 'lang',\n label: 'Language',\n options: locales.map((code) => ({ value: code, label: LOCALE_LABELS[code] ?? code.toUpperCase() })),\n });\n }\n if (menu?.settings?.length) out.push(...menu.settings);\n\n // ── Paytable ──────────────────────────────────────────────────────────────\n if (menu?.paytable?.length) {\n out.push({ kind: 'heading', id: 'menu-sec-paytable', text: titles.paytable });\n out.push(...menu.paytable);\n }\n\n // ── Rules ─────────────────────────────────────────────────────────────────\n const rules = menu?.rules?.length ? menu.rules : opts.rulesFallback;\n if (rules?.length) {\n out.push({ kind: 'heading', id: 'menu-sec-rules', text: titles.rules });\n out.push(...rules);\n }\n\n return out;\n}\n","/**\n * The UNIVERSAL RULES DOCUMENT — one portable, editable JSON file that carries a\n * game's whole rules surface: the ordered block list, its i18next-compatible\n * per-locale messages (flat keys, `{{token}}` interpolation — use i18next with\n * `keySeparator: false` if you consume them elsewhere), the social/sweepstakes\n * overrides, and (optionally) the game facts it was authored against.\n *\n * Authoring convention: a block's `text` is an i18n KEY (or literal English —\n * a string is its own key, the house convention); `messages` supplies per-locale\n * copy; any string may use the `factsVars` tokens (`{{rtp.base}}`,\n * `{{maxWin.bonus}}`, `{{freeSpins.count}}`, …) which the info menu resolves from\n * the LIVE declared facts — so stated numbers can never drift from config.\n *\n * A game consumes the file with ONE call:\n *\n * import doc from './rules.doc.json';\n * const hud = mountHud(app, applyRulesDoc(spec, doc as RulesDoc));\n *\n * The stakeplate rules editor (`npx` runnable) reads/writes this exact format and\n * validates it against `validateSpec` + `auditRules` while you edit.\n */\nimport type { BlockSpec, UISpec } from './types';\nimport { mergeFacts, auditRules, factsVars, type GameFacts, type RulesAuditIssue } from './facts';\n\nexport interface RulesDoc {\n /** Format version — currently 1. */\n version: 1;\n /** The ordered rules blocks (the same modular `BlockSpec` palette the menu renders). */\n blocks: BlockSpec[];\n /** i18next-compatible flat resources per locale (string keys → copy; `{{token}}` ok). */\n messages?: Record<string, Record<string, string>>;\n /** Social / sweepstakes wording overrides, same shape, consulted only in social mode. */\n socialMessages?: Record<string, Record<string, string>>;\n /** The facts this document was authored against — merged into `spec.facts` (the\n * spec's own facts win), and used by editors/CI to run the audit stand-alone. */\n facts?: GameFacts;\n}\n\n/** Runtime shape check — never throws. A malformed doc reports false and is skipped. */\nexport function isRulesDoc(doc: unknown): doc is RulesDoc {\n if (!doc || typeof doc !== 'object') return false;\n const d = doc as Record<string, unknown>;\n return d.version === 1 && Array.isArray(d.blocks);\n}\n\nconst mergeLocaleMaps = (\n under: Record<string, Record<string, string>> | undefined,\n over: Record<string, Record<string, string>> | undefined,\n): Record<string, Record<string, string>> => {\n const out: Record<string, Record<string, string>> = {};\n for (const src of [under, over]) {\n for (const [loc, map] of Object.entries(src ?? {})) out[loc] = { ...out[loc], ...map };\n }\n return out;\n};\n\n/**\n * Fold a rules document into a UISpec (pure — returns a NEW spec): the doc's blocks\n * become `menu.rules`, its messages/socialMessages merge UNDER the spec's own\n * dictionaries (host copy wins on conflicts), and its facts merge under `spec.facts`.\n * A malformed doc returns the spec unchanged (never-reject, Charter P11).\n */\nexport function applyRulesDoc(spec: UISpec, doc: RulesDoc): UISpec {\n if (!isRulesDoc(doc)) return spec;\n const messages = mergeLocaleMaps(doc.messages, spec.locale?.messages);\n const socialMessages = mergeLocaleMaps(doc.socialMessages, spec.locale?.socialMessages);\n return {\n ...spec,\n menu: { ...spec.menu, rules: doc.blocks },\n locale: {\n locale: spec.locale?.locale ?? 'en',\n messages: Object.keys(messages).length ? messages : { en: {} },\n ...(Object.keys(socialMessages).length ? { socialMessages } : {}),\n },\n ...(doc.facts ? { facts: mergeFacts(doc.facts, spec.facts ?? {}) } : {}),\n };\n}\n\n/**\n * Audit a rules document STAND-ALONE (editor / CI use): resolves each string through\n * the doc's own `locale` messages (default `'en'`) and interpolates the facts tokens,\n * exactly like the info menu renders it, then runs {@link auditRules}.\n */\nexport function auditRulesDoc(doc: RulesDoc, opts: { locale?: string; facts?: GameFacts } = {}): RulesAuditIssue[] {\n if (!isRulesDoc(doc)) return [];\n const facts = opts.facts ? mergeFacts(doc.facts ?? {}, opts.facts) : doc.facts;\n const dict = doc.messages?.[opts.locale ?? 'en'] ?? {};\n const vars = factsVars(facts);\n const resolve = (s: string): string =>\n (dict[s] ?? s).replace(/\\{\\{([\\w.-]+)\\}\\}/g, (_m, k: string) => String(vars[k] ?? `{{${k}}}`));\n return auditRules(facts, doc.blocks, { resolve });\n}\n","import type { UISpec } from './types';\n\n/**\n * The reference HUD expressed as data — the knobs `new OpenUI()` ships with.\n * `createUI(defaultHudSpec)` is byte-equivalent to zero-arg `createUI()` (a test\n * guards this). It's the canonical starting point for the docs editor and for\n * games that want to tweak from the default rather than start blank.\n */\nexport const defaultHudSpec: Readonly<UISpec> = Object.freeze({\n meta: { id: 'open-ui-reference-hud', version: 1 },\n currency: { code: 'USD', decimals: 2 },\n betLadder: { levels: [0.5, 1, 2, 5, 10, 20], index: 1 },\n autoplay: { options: [5, 10, 25, 50, 100, Infinity] },\n lockDuringSpin: true,\n});\n","import type { EventBus } from './events';\nimport type { OpenUIEvents } from './types';\n\nexport interface LoggedEvent {\n t: number;\n type: keyof OpenUIEvents;\n payload: unknown;\n}\n\nexport interface EventLogOptions {\n /** Max entries kept (ring buffer). Default 200. */\n capacity?: number;\n /** Monotonic clock; defaults to performance.now/Date.now. Injectable for tests. */\n now?: () => number;\n}\n\nconst ALL_EVENTS: Array<keyof OpenUIEvents> = [\n 'spinRequested',\n 'skipRequested',\n 'stateChanged',\n 'buttonActivated',\n 'valueChanged',\n 'panelToggled',\n 'toggled',\n 'optionSelected',\n 'autoplayStarted',\n 'autoplayStopped',\n 'cardActivated',\n 'localeChanged',\n];\n\n/**\n * An opt-in ring buffer over the one typed event bus — backs `BootedHud.events`\n * and the dev `window.__OPENUI__.events`, so e2e can assert \"exactly one\n * spinRequested fired during the round\" without timing guesses (Charter P10/G6).\n */\nexport class EventLog {\n private readonly buf: LoggedEvent[] = [];\n private readonly cap: number;\n private readonly clock: () => number;\n private readonly disposers: Array<() => void> = [];\n\n constructor(bus: EventBus<OpenUIEvents>, opts: EventLogOptions = {}) {\n this.cap = opts.capacity ?? 200;\n this.clock = opts.now ?? defaultNow;\n for (const type of ALL_EVENTS) {\n this.disposers.push(bus.on(type, (payload) => this.record(type, payload)));\n }\n }\n\n private record(type: keyof OpenUIEvents, payload: unknown): void {\n this.buf.push({ t: this.clock(), type, payload });\n if (this.buf.length > this.cap) this.buf.shift();\n }\n\n /** The most recent payload of `type`, or undefined. */\n last<K extends keyof OpenUIEvents>(type: K): OpenUIEvents[K] | undefined {\n for (let i = this.buf.length - 1; i >= 0; i--) {\n if (this.buf[i]!.type === type) return this.buf[i]!.payload as OpenUIEvents[K];\n }\n return undefined;\n }\n\n /** How many of `type` are in the buffer. */\n count(type: keyof OpenUIEvents): number {\n let n = 0;\n for (const e of this.buf) if (e.type === type) n += 1;\n return n;\n }\n\n /** Every event at or after timestamp `t`, in order. */\n since(t: number): LoggedEvent[] {\n return this.buf.filter((e) => e.t >= t);\n }\n\n clear(): void {\n this.buf.length = 0;\n }\n\n dispose(): void {\n for (const d of this.disposers) d();\n this.disposers.length = 0;\n }\n}\n\nfunction defaultNow(): number {\n if (typeof performance !== 'undefined' && typeof performance.now === 'function') return performance.now();\n return Date.now();\n}\n","/**\n * Build / clamp a bet ladder from a Stake Engine RGS bet config so the host doesn't\n * have to hand-tune `betLadder` (and can't ship a stake outside min/max/step). Pure.\n */\n\nexport interface RgsBetConfig {\n /** Allowed stake amounts in API minor units (Stake: dollars × 1_000_000). */\n betLevels?: number[];\n minBet?: number;\n maxBet?: number;\n stepBet?: number;\n /** Default stake in minor units (custom bets must be a multiple of this). */\n defaultBetLevel?: number;\n}\n\n/** Stake's API minor-unit divisor (1_000_000 minor units = 1.00). */\nexport const API_AMOUNT_DIVISOR = 1_000_000;\n\n/**\n * Turn an RGS bet config into a `{ levels, index }` ladder in MAJOR units (what\n * `UISpec.betLadder` wants). Uses `betLevels` if present, else derives from\n * min/max/step. `divisor` converts minor→major (default Stake's 1_000_000).\n */\nexport function buildBetLadder(cfg: RgsBetConfig, divisor = API_AMOUNT_DIVISOR): { levels: number[]; index: number } {\n let minor: number[];\n if (cfg.betLevels?.length) {\n minor = cfg.betLevels.slice();\n } else {\n const min = cfg.minBet ?? 0;\n const max = Math.max(min, cfg.maxBet ?? min);\n const step = cfg.stepBet && cfg.stepBet > 0 ? cfg.stepBet : max - min || 1;\n minor = [];\n for (let v = min; v <= max && minor.length < 500; v += step) minor.push(v);\n if (!minor.length) minor = [min];\n }\n const levels = minor.map((v) => v / divisor);\n const want = (cfg.defaultBetLevel ?? minor[0]!) / divisor;\n const found = levels.findIndex((v) => v >= want);\n return { levels, index: found < 0 ? 0 : found };\n}\n\n/**\n * Resolve the shown bet ladder from an authenticate response (MAJOR units): use EVERY\n * level the RGS offers, VERBATIM, and snap the default bet to the matching level.\n *\n * Deliberately does NOT filter out low levels. Stake requires every currency's full\n * ladder — including its true minimum (e.g. USD 0.01) — to come straight from\n * authenticate. A consequence is that the smallest win can be below one minimal\n * currency unit (USD 0.01 bet × a ×0.2 face = 0.002); the money displays render that\n * true sub-unit amount (see `formatAmountPrecise` / `ValueDisplay.autoPrecision`)\n * rather than hiding the level. Pure — share it between the UISpec builder and the\n * game's balance store so both agree on the bet.\n */\nexport function resolveBetLadder(\n availableBets: number[] | undefined,\n defaultBet: number,\n fallback: number[] = [0.2, 0.5, 1, 2, 5, 10],\n): { levels: number[]; index: number } {\n const levels = availableBets?.length ? availableBets.slice() : fallback.slice();\n const exact = levels.indexOf(defaultBet);\n const index = exact >= 0 ? exact : Math.max(0, levels.findIndex((b) => b >= defaultBet));\n return { levels, index };\n}\n\n/** Clamp a stake (major units) to the RGS min/max and snap to `stepBet`. Pure. */\nexport function clampBet(amount: number, cfg: RgsBetConfig, divisor = API_AMOUNT_DIVISOR): number {\n const min = (cfg.minBet ?? 0) / divisor;\n const max = (cfg.maxBet ?? Infinity) / divisor;\n const step = (cfg.stepBet ?? 0) / divisor;\n let v = Math.min(max, Math.max(min, Number.isFinite(amount) ? amount : min));\n if (step > 0) v = min + Math.round((v - min) / step) * step;\n return Math.min(max, Math.max(min, v));\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/signal.ts","../src/events.ts","../src/theme/tokens.ts","../src/layout/screen.ts","../src/layout/anchor.ts","../src/layout/defaultLayouts.ts","../src/transition/Transition.ts","../src/control/Control.ts","../src/controls/SpinControl.ts","../src/safe.ts","../src/format/currency.ts","../src/controls/ValueDisplay.ts","../src/controls/ButtonControl.ts","../src/controls/SliderControl.ts","../src/controls/PanelControl.ts","../src/controls/ToggleControl.ts","../src/controls/TurboControl.ts","../src/controls/StepperControl.ts","../src/controls/AutoplayControl.ts","../src/controls/ReadoutControl.ts","../src/controls/CardControl.ts","../src/controls/SelectControl.ts","../src/theme/presets.ts","../src/registry/ControlRegistry.ts","../src/spec/types.ts","../src/spec/validateSpec.ts","../src/spec/buildPanel.ts","../src/spec/jurisdiction.ts","../src/notice.ts","../src/i18n/translator.ts","../src/spec/facts.ts","../src/OpenUI.ts","../src/spec/responsive.ts","../src/spec/socialPhrases.ts","../src/spec/createUI.ts","../src/spec/menu.ts","../src/spec/rulesDoc.ts","../src/spec/rulesHtml.ts","../src/spec/defaultHudSpec.ts","../src/EventLog.ts","../src/bet.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Zero-dependency reactive primitives — the \"M\" substrate.\n * Deliberately tiny: a value box you can subscribe to, plus an effect helper.\n * No framework, no global graph, no magic. This is the whole reactivity story.\n */\n\nexport type Dispose = () => void;\n\nexport interface Subscribable {\n subscribe(fn: (value: never) => void): Dispose;\n}\n\nexport class Signal<T> {\n private _value: T;\n private readonly subs = new Set<(value: T) => void>();\n\n constructor(initial: T) {\n this._value = initial;\n }\n\n get(): T {\n return this._value;\n }\n\n set(next: T): void {\n if (Object.is(next, this._value)) return;\n this._value = next;\n // copy to tolerate (un)subscribe during emit\n for (const fn of [...this.subs]) fn(next);\n }\n\n /** Mutate-in-place then notify (for objects whose identity is stable). */\n update(mutate: (value: T) => void): void {\n mutate(this._value);\n for (const fn of [...this.subs]) fn(this._value);\n }\n\n subscribe(fn: (value: T) => void): Dispose {\n this.subs.add(fn);\n return () => {\n this.subs.delete(fn);\n };\n }\n\n get size(): number {\n return this.subs.size;\n }\n}\n\n/**\n * Run `fn` once now and again whenever any dependency changes.\n * Dependencies are explicit (no auto-tracking) — keeps the model trivial and predictable.\n */\nexport function effect(fn: () => void, deps: Subscribable[]): Dispose {\n const run = (): void => fn();\n const disposers = deps.map((d) => d.subscribe(run as (value: never) => void));\n run();\n return () => {\n for (const d of disposers) d();\n };\n}\n","import type { Dispose } from './signal';\n\n/** A typed event map: event name -> payload type. */\nexport type EventMap = Record<string, unknown>;\n\n/**\n * One typed event bus. Period. (Charter B1.)\n * No magic strings sprinkled around the codebase; payloads are checked.\n */\nexport class EventBus<E extends EventMap> {\n private readonly map = new Map<keyof E, Set<(payload: unknown) => void>>();\n\n on<K extends keyof E>(type: K, fn: (payload: E[K]) => void): Dispose {\n let set = this.map.get(type);\n if (!set) {\n set = new Set();\n this.map.set(type, set);\n }\n const wrapped = fn as (payload: unknown) => void;\n set.add(wrapped);\n return () => {\n set?.delete(wrapped);\n };\n }\n\n emit<K extends keyof E>(type: K, payload: E[K]): void {\n const set = this.map.get(type);\n if (!set) return;\n for (const fn of [...set]) fn(payload);\n }\n}\n","/**\n * Theming = data. Semantic tokens with safe fallbacks (Charter P8).\n * A game theme is a small override map; nothing renders un-themed because\n * the renderer always has these defaults to fall back on.\n */\n\nexport interface Theme {\n color: {\n accent: string;\n accentText: string;\n surface: string;\n surfaceAlt: string;\n text: string;\n textDim: string;\n disabled: string;\n };\n radius: { pill: number; card: number };\n space: { sm: number; md: number; lg: number };\n type: { family: string; size: { sm: number; md: number; lg: number } };\n /** Motion durations in ms. */\n motion: { fast: number; base: number; slow: number };\n}\n\n/** Neutral reference theme. The real game theme is built on top of this. */\nexport const defaultTheme: Theme = {\n color: {\n accent: '#ffc935',\n accentText: '#1a1a1a',\n surface: '#161b22',\n surfaceAlt: '#0b0e13',\n text: '#ffffff',\n textDim: '#7a8290',\n disabled: '#3a3f47',\n },\n radius: { pill: 999, card: 16 },\n space: { sm: 8, md: 16, lg: 24 },\n type: { family: 'system-ui, sans-serif', size: { sm: 14, md: 18, lg: 28 } },\n motion: { fast: 120, base: 200, slow: 360 },\n};\n\nexport type DeepPartial<T> = {\n [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];\n};\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\nfunction merge<T>(base: T, patch: DeepPartial<T>): T {\n const out = { ...base } as Record<string, unknown>;\n for (const key of Object.keys(patch)) {\n const pv = (patch as Record<string, unknown>)[key];\n const bv = (base as Record<string, unknown>)[key];\n out[key] = isObject(pv) && isObject(bv) ? merge(bv, pv as DeepPartial<typeof bv>) : pv;\n }\n return out as T;\n}\n\n/** Produce a new theme from the default (or any base) plus an override patch. */\nexport function extendTheme(base: Theme, patch: DeepPartial<Theme>): Theme {\n return merge(base, patch);\n}\n","/** Responsive screen model: orientation, a named breakpoint, and a fit scale. */\n\nexport type Orientation = 'landscape' | 'portrait';\n\n/** A named device bucket. Config can target these to restyle per device. */\nexport type Breakpoint = 'mobile' | 'tablet' | 'desktop';\n\n/** The uniformly-scaled DESIGN FRAME (\"stage\") rect, in screen pixels. */\nexport interface StageRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface ScreenState {\n width: number;\n height: number;\n orientation: Orientation;\n /** Named device bucket, derived from the shorter screen edge (see LayoutConfig). */\n breakpoint: Breakpoint;\n /** Multiply reference-px sizes by this to fit the current screen. */\n scale: number;\n /**\n * The reference design frame, scaled UNIFORMLY by `scale` and placed in the viewport\n * (letterboxed by `stageAnchor` when the aspect ratio differs). Every control anchors\n * to THIS rect — not the raw screen — so the whole HUD scales as one homogeneous unit\n * and the relative gaps between controls never change with aspect ratio. At the\n * reference resolution `stage` exactly equals the screen, so authored layouts are\n * pixel-identical there.\n */\n stage: StageRect;\n}\n\nexport interface LayoutConfig {\n /** Reference design resolution for landscape / portrait. */\n refLandscape: [number, number];\n refPortrait: [number, number];\n /** Aspect ratio (w/h) below which we switch to the portrait layout. */\n portraitBelowAspect: number;\n /**\n * Breakpoint thresholds on the SHORTER screen edge (px). A phone is \"mobile\" in\n * both orientations because its short edge stays small — the right intuition for\n * \"what device is this\". `<= mobile` → mobile, `<= tablet` → tablet, else desktop.\n */\n breakpoints: { mobile: number; tablet: number };\n /**\n * Where the uniformly-scaled design frame sits in the viewport when the aspect ratio\n * doesn't match the reference (i.e. how the letterbox margins are distributed), as\n * `[x, y]` factors in `0..1`. `[0.5, 1]` (default) = bottom-centre: the bottom bar\n * always hugs the screen bottom and any extra vertical room opens ABOVE (the reel\n * area, filled by the game); horizontal slack splits evenly. `[0.5, 0.5]` centres it.\n */\n stageAnchor: [number, number];\n}\n\nexport const defaultLayoutConfig: LayoutConfig = {\n // Reference design frames, matching the Figma \"DEF\" frames 1:1 so offsets map\n // directly: desktop 1920×1080, mobile 360×779 (×3 = 1080×2337). The portrait\n // aspect matches real phones (~0.46), so scaling no longer squashes vertically.\n refLandscape: [1920, 1080],\n refPortrait: [1080, 2337],\n portraitBelowAspect: 0.85,\n breakpoints: { mobile: 480, tablet: 840 },\n // Bottom bar hugs the screen bottom; extra height opens above (reel area).\n stageAnchor: [0.5, 1],\n};\n\n/** Classify the shorter edge into a named device bucket. Pure, total. */\nexport function breakpointFor(width: number, height: number, cfg: LayoutConfig): Breakpoint {\n const short = Math.min(Math.max(width, 1), Math.max(height, 1));\n if (short <= cfg.breakpoints.mobile) return 'mobile';\n if (short <= cfg.breakpoints.tablet) return 'tablet';\n return 'desktop';\n}\n\nexport function computeScreen(width: number, height: number, cfg: LayoutConfig): ScreenState {\n const w = Math.max(width, 1);\n const h = Math.max(height, 1);\n const orientation: Orientation = w / h < cfg.portraitBelowAspect ? 'portrait' : 'landscape';\n const [rw, rh] = orientation === 'portrait' ? cfg.refPortrait : cfg.refLandscape;\n const scale = Math.min(w / rw, h / rh);\n // The design frame, scaled uniformly and letterbox-positioned. At the reference\n // aspect it fills the screen exactly (stage == screen).\n const sw = rw * scale;\n const sh = rh * scale;\n const [ax, ay] = cfg.stageAnchor ?? [0.5, 1];\n const stage: StageRect = { x: (w - sw) * ax, y: (h - sh) * ay, width: sw, height: sh };\n return { width: w, height: h, orientation, breakpoint: breakpointFor(w, h, cfg), scale, stage };\n}\n","import type { ScreenState } from './screen';\n\n/** Explicit anchors — no magic numbers buried in components (Charter P9). */\nexport type Anchor =\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'center-left'\n | 'center'\n | 'center-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right';\n\nexport interface LayoutSpec {\n anchor: Anchor;\n /** Offset from the anchor, in reference px (scaled with the screen). */\n offset?: [number, number];\n /** Extra scale multiplier on top of the screen's fit scale. */\n scale?: number;\n /** Rotation in degrees, clockwise. Default 0. */\n rotation?: number;\n}\n\nexport interface Placement {\n x: number;\n y: number;\n scale: number;\n /** Rotation in radians (resolved from `LayoutSpec.rotation`, which is degrees). */\n rotation: number;\n}\n\nfunction anchorFactors(anchor: Anchor): [number, number] {\n const ax = anchor.includes('left') ? 0 : anchor.includes('right') ? 1 : 0.5;\n const ay = anchor.includes('top') ? 0 : anchor.includes('bottom') ? 1 : 0.5;\n return [ax, ay];\n}\n\n/**\n * Resolve a control's layout against the current screen. Pure math.\n *\n * Anchors to the uniformly-scaled `screen.stage` frame — NOT the raw screen — so the\n * whole HUD scales as one homogeneous unit: the gap between two controls is always a\n * fixed fraction of the (uniformly-scaled) frame, never a function of the viewport's\n * aspect ratio. That's what stops a growing value or a narrow window from letting\n * controls drift into each other. At the reference resolution `stage` equals the\n * screen, so authored offsets land pixel-identically.\n */\nexport function resolvePlacement(spec: LayoutSpec, screen: ScreenState): Placement {\n const [ax, ay] = anchorFactors(spec.anchor);\n const [ox, oy] = spec.offset ?? [0, 0];\n const st = screen.stage;\n return {\n x: st.x + ax * st.width + ox * screen.scale,\n y: st.y + ay * st.height + oy * screen.scale,\n scale: screen.scale * (spec.scale ?? 1),\n rotation: ((spec.rotation ?? 0) * Math.PI) / 180,\n };\n}\n","import type { LayoutSpec } from './anchor';\n\n/**\n * The reference HUD arrangement, cloned 1:1 from the Figma design frames.\n *\n * Landscape (\"Desk DEF\", 1920×1080 = the landscape reference, so px map\n * directly): a bottom bar — balance · play · SPIN · turbo · bet (with the ±\n * steppers stacked to its right) — plus the ☰ menu on the lower-left rail and\n * the buy (bonus) button on the lower-right rail. Everything lives in the\n * bottom ~320 reference px so the reels area above stays clear.\n *\n * Portrait (\"Mobile DEF\", 360-wide × 3 = the 1080×2337 portrait reference):\n * a thumb-friendly stack — buy · play · SPIN · turbo · ☰ on one row, the bet ±\n * steppers below SPIN, balance/bet tilted into the corners, readouts larger.\n *\n * These are the LIBRARY defaults: `OpenUI` constructs controls with the\n * landscape values, and `createUI` installs the portrait set as a built-in\n * `responsive.portrait` bucket (layered UNDER host overrides — a host's static\n * `controls.{id}.layout` wins everywhere, and a host's own\n * `responsive.portrait` entry wins per-control).\n */\nexport const landscapeDefaultLayouts: Readonly<Record<string, LayoutSpec>> = Object.freeze({\n // Measured 1:1 from the Figma \"Desk DEF\" frame (1920×1080): spin ~0.95 of the base\n // 220px coin, dropped to −124, autoplay/turbo flanking at ±204. (The homogeneous\n // stage keeps this off the reels, so it no longer needs shrinking.)\n spin: { anchor: 'bottom-center', offset: [0, -124], scale: 0.95 },\n autoplay: { anchor: 'bottom-center', offset: [-204, -100] },\n turbo: { anchor: 'bottom-center', offset: [204, -100] },\n balance: { anchor: 'bottom-left', offset: [135, -104], rotation: -5 },\n bet: { anchor: 'bottom-right', offset: [-186, -104], rotation: 5 },\n 'bet-plus': { anchor: 'bottom-right', offset: [-120, -188], rotation: 5 },\n 'bet-minus': { anchor: 'bottom-right', offset: [-120, -104], rotation: 5 },\n bonus: { anchor: 'bottom-center', offset: [740, -320] },\n // Bonus \"total win\" readout — occupies the buy-feature corner; the renderer swaps\n // the two so only one shows at a time (buy in base play, total-win in a bonus round).\n // Right-anchored so a long localized caption grows LEFT and never clips the edge.\n 'total-win': { anchor: 'bottom-right', offset: [-150, -300] },\n settings: { anchor: 'bottom-center', offset: [-740, -320], rotation: -5 },\n mute: { anchor: 'top-right', offset: [-122, 46] },\n fullscreen: { anchor: 'top-right', offset: [-46, 46] },\n rtp: { anchor: 'top-left', offset: [20, 18] },\n 'session-timer': { anchor: 'top-left', offset: [20, 46] },\n 'net-position': { anchor: 'top-left', offset: [20, 74] },\n});\n\nexport const portraitDefaultLayouts: Readonly<Record<string, LayoutSpec>> = Object.freeze({\n // Mobile sizes run ~1.5× the desktop base (the Figma mobile frame draws the\n // controls larger relative to its width) so the buttons read well on a phone.\n spin: { anchor: 'bottom-center', offset: [0, -510], scale: 1.35 },\n autoplay: { anchor: 'bottom-center', offset: [-258, -510], scale: 1.5 },\n turbo: { anchor: 'bottom-center', offset: [258, -510], scale: 1.5 },\n bonus: { anchor: 'bottom-center', offset: [-438, -480], scale: 1.3 },\n // Figma \"Mobile FS\": the total-win sits on the LEFT at the spin's level (where the\n // buy coin lives in base play), left-aligned + tilted −10° — NOT centred over spin.\n 'total-win': { anchor: 'bottom-left', offset: [30, -520], rotation: -10 },\n settings: { anchor: 'bottom-center', offset: [438, -480], scale: 1.5, rotation: -5 },\n 'bet-minus': { anchor: 'bottom-center', offset: [-105, -267], scale: 1.5 },\n 'bet-plus': { anchor: 'bottom-center', offset: [105, -267], scale: 1.5 },\n mute: { anchor: 'top-right', offset: [-159, 57], scale: 1.5 },\n fullscreen: { anchor: 'top-right', offset: [-57, 57], scale: 1.5 },\n // Compliance readouts scale up ~2× on mobile with wider line spacing.\n rtp: { anchor: 'top-left', offset: [16, 16], scale: 2 },\n 'session-timer': { anchor: 'top-left', offset: [16, 66], scale: 2 },\n 'net-position': { anchor: 'top-left', offset: [16, 116], scale: 2 },\n balance: { anchor: 'bottom-left', offset: [36, -110], rotation: -5 },\n bet: { anchor: 'bottom-right', offset: [-36, -110], rotation: 5 },\n});\n\n/** A control's default layout for the landscape reference frame (cloned — safe to mutate). */\nexport function defaultLayout(id: string): LayoutSpec {\n const l = landscapeDefaultLayouts[id];\n if (!l) return { anchor: 'center' };\n return { anchor: l.anchor, offset: l.offset ? [l.offset[0], l.offset[1]] : undefined, scale: l.scale, rotation: l.rotation };\n}\n","/**\n * Transitions are composable OOP descriptors (Charter B6) — pure data, renderer-agnostic.\n * The renderer interprets the `kind`; the core never animates anything itself.\n * Some controls turn, some squish, some tick up, some emit particles — all from these.\n */\n\nexport class Squish {\n readonly kind = 'squish' as const;\n constructor(public scale = 0.92, public ms = 120) {}\n}\n\nexport class Pulse {\n readonly kind = 'pulse' as const;\n constructor(public scale = 1.06, public ms = 160) {}\n}\n\nexport class Turn {\n readonly kind = 'turn' as const;\n /** Rotations per second; loops until the state changes. */\n constructor(public rps = 1, public loop = true) {}\n}\n\nexport class Fade {\n readonly kind = 'fade' as const;\n constructor(public alpha = 0.4, public ms = 160) {}\n}\n\nexport class Sequence {\n readonly kind = 'sequence' as const;\n constructor(public steps: Transition[]) {}\n}\n\nexport class Parallel {\n readonly kind = 'parallel' as const;\n constructor(public steps: Transition[]) {}\n}\n\nexport type Transition = Squish | Pulse | Turn | Fade | Sequence | Parallel;\n","import { Signal, type Dispose } from '../signal';\nimport type { Transition } from '../transition/Transition';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { Rect } from '../types';\n\n/** One state of a control: is it interactable, and what plays on entry. */\nexport interface StateDef {\n interactable: boolean;\n transition?: Transition;\n}\n\nexport type StateMap = Record<string, StateDef>;\n\nexport interface ControlOptions {\n id: string;\n role: string;\n layout: LayoutSpec;\n}\n\n/** What a view reports back for introspection. Set by the renderer's view. */\nexport type ViewInspect = () => { bounds: Rect | null; animating: boolean };\n\n/**\n * Base of every control: a finite state machine that is the single source of\n * truth for look, interactivity, AND tests (Charter P5/P6/P12).\n * Renderer-agnostic — it knows nothing about Pixi or the DOM.\n */\nexport abstract class Control {\n readonly id: string;\n readonly role: string;\n layout: LayoutSpec;\n\n /** Declared by the subclass: the legal states and their transitions. */\n abstract readonly states: StateMap;\n\n /** Current state name, observable. */\n readonly state: Signal<string>;\n\n /** The renderer sets this so `inspect()` can report bounds/animation. */\n viewInspect?: ViewInspect;\n\n /**\n * Optional host gate (e.g. a ref-counted input lock). When set, the control is\n * interactable only if its state allows it AND the gate returns true. Set per\n * instance — by OpenUI on register — so multiple HUDs on one page never share\n * lock state. Interactability stays *derived*, never stored (Charter P6).\n */\n gate?: () => boolean;\n\n protected readonly disposers: Dispose[] = [];\n private readonly transitionSubs = new Set<(t: Transition | undefined, to: string, from: string) => void>();\n\n constructor(opts: ControlOptions, initial: string) {\n this.id = opts.id;\n this.role = opts.role;\n this.layout = opts.layout;\n this.state = new Signal<string>(initial);\n }\n\n get current(): string {\n return this.state.get();\n }\n\n /** Derived, never stored (Charter P6). Folds in the optional host gate. */\n get interactable(): boolean {\n const base = this.states[this.current]?.interactable ?? false;\n return base && (this.gate?.() ?? true);\n }\n\n /** Transition to a new state. Throws on unknown states (illegal states unrepresentable). */\n setState(to: string): void {\n if (!(to in this.states)) {\n throw new Error(`[open-ui] control \"${this.id}\": unknown state \"${to}\"`);\n }\n const from = this.current;\n if (to === from) return;\n this.state.set(to);\n const t = this.states[to]?.transition;\n for (const fn of [...this.transitionSubs]) fn(t, to, from);\n }\n\n /** The renderer subscribes to play the entry transition for each state change. */\n onTransition(fn: (t: Transition | undefined, to: string, from: string) => void): Dispose {\n this.transitionSubs.add(fn);\n return () => {\n this.transitionSubs.delete(fn);\n };\n }\n\n inspect(): { bounds: Rect | null; animating: boolean } {\n return this.viewInspect?.() ?? { bounds: null, animating: false };\n }\n\n /** Leak-free teardown (Charter P12). */\n dispose(): void {\n for (const d of this.disposers) d();\n this.disposers.length = 0;\n this.transitionSubs.clear();\n this.viewInspect = undefined;\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Signal } from '../signal';\nimport { Squish, Pulse, Fade } from '../transition/Transition';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\n/**\n * The spin control — the vertical-spine exemplar.\n * A full state machine: each state declares interactability + an entry transition.\n * The game drives it via the façade (`busy/idle/stop/disable`); the view drives\n * the transient input states (`hover/pressed`) and calls `activate()` on release.\n */\nexport class SpinControl extends Control {\n readonly states: StateMap = {\n idle: { interactable: true, transition: new Squish(0.94, 120) },\n hover: { interactable: true, transition: new Pulse(1.06, 160) },\n pressed: { interactable: true, transition: new Squish(0.86, 70) },\n // Spinning no longer rotates — the button just squishes on press and sits.\n spinning: { interactable: false, transition: new Squish(0.94, 120) },\n stop: { interactable: true, transition: new Pulse(1.08, 140) },\n auto: { interactable: true, transition: new Pulse(1.06, 160) },\n disabled: { interactable: false, transition: new Fade(0.4, 160) },\n };\n\n /**\n * When true, the view arms press-and-hold: holding the spin button fires a\n * `holdSpinStarted` and the host turbo-spins until release (`holdSpinStopped`).\n * A quick tap still spins once. Toggleable via the `spin.press` config.\n */\n holdToSpin = false;\n\n /**\n * Whether tapping mid-spin slam-stops/skips the reels. Stake Engine's\n * `disabledSlamstop` jurisdiction flag sets this false → the button then LOCKS\n * (dims, no tap) during a spin instead of skipping. Observable so the view can\n * re-dim if it flips at runtime (e.g. on `applyJurisdiction`).\n */\n readonly allowSlamStop = new Signal<boolean>(true);\n\n /**\n * Whether the keyboard (Space / Enter) can trigger a spin. Stake's\n * `disabledSpacebar` sets this false (and turns off hold-to-spin). The renderer\n * reads it; RTS 14D requires a fresh press per cycle (no auto-repeat).\n */\n readonly allowKeyboard = new Signal<boolean>(true);\n\n /**\n * Remaining free spins (0 = normal play). Set it > 0 and the spin button switches\n * to its free-spins face — a big remaining count over an \"FS\" label — via the view;\n * back to 0 returns the normal play button. The host drives the loop; this is just\n * the display. Set with {@link setFreeSpins}.\n */\n readonly freeSpins = new Signal<number>(0);\n\n constructor(\n opts: { id?: string; layout: LayoutSpec; holdToSpin?: boolean },\n private readonly bus: EventBus<OpenUIEvents>,\n ) {\n super({ id: opts.id ?? 'spin', role: 'button', layout: opts.layout }, 'idle');\n this.holdToSpin = opts.holdToSpin ?? false;\n }\n\n /**\n * Derived (Charter P6), with the slam-stop guard folded in: when slam-stop is\n * disabled, the in-spin `stop`/`auto` affordance is locked — the button can't be\n * tapped to skip; it just dims.\n */\n override get interactable(): boolean {\n if (!this.allowSlamStop.get() && (this.current === 'auto' || this.current === 'stop')) return false;\n return super.interactable;\n }\n\n // ---- façade (the game talks to these) ----\n busy(): void {\n this.setState('spinning');\n }\n idle(): void {\n this.setState('idle');\n }\n stopState(): void {\n this.setState('stop');\n }\n /** Show the autoplay-engaged look (press to stop). */\n auto(): void {\n this.setState('auto');\n }\n enable(): void {\n if (this.current === 'disabled') this.setState('idle');\n }\n disable(): void {\n this.setState('disabled');\n }\n\n // ---- input (the view calls this on a valid press-release) ----\n activate(): void {\n if (this.current === 'auto') {\n // autoplay-engaged: tapping slam-stops / skips the reels — it does NOT stop\n // autoplay. Suppressed when slam-stop is disabled by jurisdiction.\n if (this.allowSlamStop.get()) this.bus.emit('skipRequested', undefined);\n return;\n }\n if (this.interactable) this.bus.emit('spinRequested', undefined);\n }\n\n /** View calls this when a press is held past the hold threshold. Returns whether\n * hold-to-spin engaged (so the view knows to wait for release). */\n holdBegin(): boolean {\n if (!this.holdToSpin || !this.interactable) return false;\n this.bus.emit('holdSpinStarted', undefined);\n return true;\n }\n /** View calls this on release after a hold — the host stops the turbo loop. */\n holdEnd(): void {\n this.bus.emit('holdSpinStopped', undefined);\n }\n\n /** Switch the button to / from its free-spins face. `n > 0` shows \"n FS\"; `0`\n * restores the normal play button. Non-number/negative is clamped to 0 (P11). */\n setFreeSpins(n: number): void {\n this.freeSpins.set(typeof n === 'number' && Number.isFinite(n) && n > 0 ? Math.floor(n) : 0);\n }\n}\n","/**\n * Never-reject inbound boundary helpers (Charter P11). The UI *displays* values\n * the host sets and computes no money — so malformed host data must degrade to a\n * no-op, never throw into the render loop.\n */\n\n/** Return `n` if it is a finite number, else fall back to the last good value. */\nexport function safeAmount(n: number, lastGood: number): number {\n return typeof n === 'number' && Number.isFinite(n) ? n : lastGood;\n}\n\n/** Clamp a currency's fractional digits to a sane 0..8 integer (default 2). */\nexport function clampDecimals(d: number): number {\n if (typeof d !== 'number' || !Number.isFinite(d)) return 2;\n return Math.max(0, Math.min(8, Math.trunc(d)));\n}\n\n/** Clamp the value counter's fit WIDTH budget to a sane 1..18 column count (default 9). */\nexport function clampDigits(n: number): number {\n if (typeof n !== 'number' || !Number.isFinite(n)) return 9;\n return Math.max(1, Math.min(18, Math.trunc(n)));\n}\n\n/** Clamp a value-display's MINIMUM column width: 0..18, where 0 means \"auto\" — size\n * the odometer tightly to the value. Garbage → 0 (auto). */\nexport function clampMinDigits(n: number): number {\n if (typeof n !== 'number' || !Number.isFinite(n)) return 0;\n return Math.max(0, Math.min(18, Math.trunc(n)));\n}\n\n/** How many integer (whole-part) digits a value needs, minimum 1 (so `0.x` shows a\n * leading `0`). Uses string length, not log10, to dodge the `log10(1000)=2.999…` trap. */\nexport function integerDigits(value: number): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) return 1;\n return String(Math.floor(Math.abs(value))).length;\n}\n\n/**\n * Total odometer columns to show `value` at `decimals` precision TIGHTLY — exactly\n * the integer digits the value needs plus the fraction columns, so there are no\n * hidden leading-zero columns padding the number (a fixed reserve would either gap\n * small values like `$1.00` or clamp large ones like `12.34 BTC` on a 9-col budget).\n * Never below `minTotal` (a host-set stable width) nor `decimals + 1` (the counter\n * needs `decimals < digits`); capped at 18. The renderer grows the counter as the\n * value grows, so the magnitude is never clamped.\n */\nexport function displayDigits(value: number, minTotal: number, decimals: number): number {\n const d = clampDecimals(decimals);\n const min = clampMinDigits(minTotal);\n return Math.min(18, Math.max(min, integerDigits(value) + d, d + 1));\n}\n\n/**\n * On-screen width budget (px) the value counter is allowed before `fit` scales it\n * down. Keyed to a fixed display budget (≥ 9 columns, or the host's wider `digits`)\n * so a normal-magnitude readout renders full-size while a very large value scales to\n * fit (\"won't go too far\"). `+64` leaves room for the currency affix.\n */\nexport function valueFitMaxWidth(digits: number, columnWidth: number): number {\n return clampDigits(digits) * columnWidth + 64;\n}\n","/**\n * Currency display metadata + a pure formatter (Charter P11: data, not code).\n *\n * This is the **Stake Engine currency table**: every code Stake supports, mapped to\n * its display SYMBOL, minor-unit decimals, and symbol side (before/after the number).\n * A game shouldn't hand-tune any of this — it either passes a full `CurrencySpec`, or\n * just the CODE (`currency: 'CNY'`) and gets the Stake formatting for free\n * (\"I use the Stake currency formatter\"). Unknown codes fall back to a 2-decimal,\n * code-suffix spec so nothing ever breaks. The UI computes no money — it only formats\n * what the game sets.\n */\nimport type { CurrencySpec } from '../controls/ValueDisplay';\nimport { clampDecimals } from '../safe';\n\nexport interface CurrencyInfo {\n /** The glyph shown to the player (\"$\", \"CN¥\", \"GC\"). */\n symbol: string;\n /** Fractional digits to show (JPY/KRW/IDR = 0, USD = 2, BTC = 8). */\n decimals: number;\n /** Symbol AFTER the number (\"10,00 zł\") rather than before (\"$10.00\"). Default before. */\n symbolAfter?: boolean;\n /** A social / sweepstakes coin (Gold Coins / Stake Cash) — never fiat wording. */\n social?: boolean;\n}\n\n/**\n * The Stake Engine supported-currency matrix (symbol · decimals · placement), 1:1 with\n * the platform's `CurrencyMeta`. Symbol placement: prefix by default, SUFFIX for the\n * few that render after the amount (DKK/NOK/PLN/VND/CLP/ARS/PEN). Decimals follow the\n * ISO minor units — 0 for JPY/KRW/IDR/VND/CLP, 3 for the KWD/JOD/BHD dinars (1000 fils),\n * 2 otherwise. Crypto is included (8-dp) so high-precision balances also format right.\n */\nexport const CURRENCY_TABLE: Readonly<Record<string, CurrencyInfo>> = Object.freeze({\n // ── fiat — symbol BEFORE the amount ──────────────────────────────────────────\n USD: { symbol: '$', decimals: 2 },\n CAD: { symbol: 'CA$', decimals: 2 },\n JPY: { symbol: '¥', decimals: 0 },\n EUR: { symbol: '€', decimals: 2 },\n RUB: { symbol: '₽', decimals: 2 },\n CNY: { symbol: 'CN¥', decimals: 2 },\n PHP: { symbol: '₱', decimals: 2 },\n INR: { symbol: '₹', decimals: 2 },\n IDR: { symbol: 'Rp', decimals: 0 },\n KRW: { symbol: '₩', decimals: 0 },\n BRL: { symbol: 'R$', decimals: 2 },\n MXN: { symbol: 'MX$', decimals: 2 },\n TRY: { symbol: '₺', decimals: 2 },\n GBP: { symbol: '£', decimals: 2 },\n NGN: { symbol: '₦', decimals: 2 },\n TWD: { symbol: 'NT$', decimals: 2 },\n SGD: { symbol: 'SG$', decimals: 2 },\n MYR: { symbol: 'RM', decimals: 2 },\n CRC: { symbol: '₡', decimals: 2 },\n // three-decimal dinars/rials (1 unit = 1000 fils) — the >2-decimal path must format these\n KWD: { symbol: 'KD', decimals: 3 },\n JOD: { symbol: 'JD', decimals: 3 },\n BHD: { symbol: 'BD', decimals: 3 },\n OMR: { symbol: 'OMR', decimals: 3 },\n TND: { symbol: 'DT', decimals: 3 },\n LYD: { symbol: 'LD', decimals: 3 },\n IQD: { symbol: 'IQD', decimals: 3 },\n // ── fiat — symbol AFTER the amount ───────────────────────────────────────────\n DKK: { symbol: 'kr', decimals: 2, symbolAfter: true },\n NOK: { symbol: 'kr', decimals: 2, symbolAfter: true },\n PLN: { symbol: 'zł', decimals: 2, symbolAfter: true },\n VND: { symbol: '₫', decimals: 0, symbolAfter: true },\n CLP: { symbol: 'CLP', decimals: 0, symbolAfter: true },\n ARS: { symbol: 'ARS', decimals: 2, symbolAfter: true },\n PEN: { symbol: 'S/', decimals: 2, symbolAfter: true },\n // ── crypto (8-dp, so sub-cent + high precision format correctly) ─────────────\n BTC: { symbol: '₿', decimals: 8 },\n ETH: { symbol: 'Ξ', decimals: 8 },\n LTC: { symbol: 'Ł', decimals: 8 },\n BCH: { symbol: 'BCH', decimals: 8 },\n DOGE: { symbol: 'Ð', decimals: 8 },\n USDT: { symbol: '₮', decimals: 2 },\n USDC: { symbol: 'USDC', decimals: 2 },\n // ── Stake social coins — Gold Coins / Stake Cash (shown as GC / SC) ───────────\n XGC: { symbol: 'GC', decimals: 2, social: true },\n XSC: { symbol: 'SC', decimals: 2, social: true },\n GC: { symbol: 'GC', decimals: 2, social: true },\n SC: { symbol: 'SC', decimals: 2, social: true },\n});\n\nconst upper = (code: string): string => (typeof code === 'string' ? code.toUpperCase() : '');\n\n/** True if `code` is a Stake social/sweepstakes coin (displayed \"GC\"/\"SC\"). */\nexport function isSocialCurrency(code: string): boolean {\n return CURRENCY_TABLE[upper(code)]?.social === true;\n}\n\n/**\n * Resolve a currency code to a complete, display-ready {@link CurrencySpec} using the\n * Stake table: fills the SYMBOL (rendered tight, `display:'symbol'`), its side\n * (`position`), and the minor-unit `decimals`. Anything in `overrides` wins so a game\n * can still hand-tune (e.g. force more decimals for sub-cent payouts). An unknown code\n * degrades to a 2-decimal code-suffix spec. Never throws.\n */\nexport function resolveCurrency(code: string, overrides: Partial<CurrencySpec> = {}): CurrencySpec {\n const info = CURRENCY_TABLE[upper(code)];\n if (!info) {\n // Unknown code → show the raw code as a suffix (safe default).\n return {\n code: overrides.code ?? code,\n decimals: clampDecimals(overrides.decimals ?? 2),\n position: overrides.position ?? 'suffix',\n separator: overrides.separator ?? ',',\n decimalChar: overrides.decimalChar ?? '.',\n ...(overrides.symbol ? { symbol: overrides.symbol, display: overrides.display ?? 'symbol' } : {}),\n };\n }\n return {\n // Social coins carry their DISPLAY code (XGC → \"GC\", XSC → \"SC\"); fiat/crypto keep\n // their ISO code (the symbol is what's actually rendered under `display:'symbol'`).\n code: overrides.code ?? (info.social ? info.symbol : code),\n symbol: overrides.symbol ?? info.symbol,\n display: overrides.display ?? 'symbol',\n position: overrides.position ?? (info.symbolAfter ? 'suffix' : 'prefix'),\n decimals: clampDecimals(overrides.decimals ?? info.decimals),\n separator: overrides.separator ?? ',',\n decimalChar: overrides.decimalChar ?? '.',\n };\n}\n\n/**\n * Format an amount (major units) per a {@link CurrencySpec}: grouped integer part,\n * fixed decimals, and the affix on the configured side. When `display:'symbol'` (and a\n * symbol is set) the SYMBOL sits tight against the number (`CN¥1,234.56` · `1.234,56 zł`);\n * otherwise the ISO code is spaced (`1,234.56 USD`). `signed` adds an explicit \"+\" for\n * non-negative values (used by the net-position readout). Pure + total: a malformed\n * number renders as \"0\".\n */\n/**\n * How many fraction digits a value ACTUALLY uses — never fewer than the currency's\n * native `base` precision, never more than the 8-decimal ceiling. Snaps float noise\n * (0.1+0.2) by measuring at 8 dp, then strips trailing zeros back down to `base`.\n *\n * Why: Stake requires a currency's FULL bet ladder verbatim from authenticate —\n * including its true minimum (USD 0.01) — so a win (0.01 bet × a ×0.2 face = 0.002)\n * or a running balance (999.982) can carry sub-unit precision the currency's fixed\n * decimals would CROP to \"0.00\". This tells the display exactly how many digits that\n * value needs; a clean value keeps the ordinary native look (5.00, 1,000.00).\n */\nexport function neededDecimals(value: number, base: number): number {\n const b = clampDecimals(base);\n if (!Number.isFinite(value) || value === 0) return b;\n let scaled = Math.round(Math.abs(value) * 1e8); // integer minor units at 8 dp\n let d = 8;\n while (d > b && scaled % 10 === 0) {\n scaled /= 10;\n d--;\n }\n return d;\n}\n\n/**\n * Format an amount at the precision it actually needs (see {@link neededDecimals}),\n * so a sub-unit win renders in full (\"$0.002\") instead of rounding to \"$0.00\".\n * Values within the currency's native precision format exactly like {@link formatAmount}.\n */\nexport function formatAmountPrecise(value: number, spec: CurrencySpec, opts: { signed?: boolean } = {}): string {\n const base = clampDecimals(spec.decimals ?? 2);\n const d = neededDecimals(value, base);\n return d === base ? formatAmount(value, spec, opts) : formatAmount(value, { ...spec, decimals: d }, opts);\n}\n\nexport function formatAmount(value: number, spec: CurrencySpec, opts: { signed?: boolean } = {}): string {\n const decimals = clampDecimals(spec.decimals);\n const sep = spec.separator ?? ',';\n const dot = spec.decimalChar ?? '.';\n const n = Number.isFinite(value) ? value : 0;\n const fixed = Math.abs(n).toFixed(decimals);\n const [int = '0', frac] = fixed.split('.');\n const grouped = int.replace(/\\B(?=(\\d{3})+(?!\\d))/g, sep);\n const body = frac ? `${grouped}${dot}${frac}` : grouped;\n const sign = n < 0 ? '-' : opts.signed ? '+' : '';\n const number = `${sign}${body}`;\n const symbolMode = spec.display === 'symbol' && !!spec.symbol;\n const affix = symbolMode ? (spec.symbol as string) : spec.code;\n const prefix = (spec.position ?? 'suffix') === 'prefix';\n // Stake DisplayBalance: a PREFIX symbol hugs the number (\"CN¥10.00\"); a SUFFIX symbol\n // is spaced (\"10.00 zł\"); the ISO code is always spaced.\n const gap = symbolMode && prefix ? '' : ' ';\n return prefix ? `${affix}${gap}${number}` : `${number}${gap}${affix}`;\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Signal } from '../signal';\nimport { safeAmount, clampDecimals, clampMinDigits } from '../safe';\nimport { neededDecimals } from '../format/currency';\nimport type { LayoutSpec } from '../layout/anchor';\n\n/** Currency / crypto descriptor — the code/symbol + how to format it. */\nexport interface CurrencySpec {\n /** ISO code or crypto name: \"USD\", \"EUR\", \"BTC\", \"mBTC\", \"SATS\". */\n code: string;\n /**\n * The minimal-unit precision — how many fractional digits show after the `.`:\n * 2 (USD/EUR cents), 0 (JPY/SATS), 5 (mBTC), 8 (BTC). Values are held + rolled as\n * integer minor units (no float drift). Clamped to 0..8.\n */\n decimals: number;\n /** Symbol for `display: 'symbol'` (e.g. \"$\", \"€\", \"₿\"). */\n symbol?: string;\n /** Show the ISO/crypto `code` (default) or the `symbol` (when one is set). */\n display?: 'code' | 'symbol';\n /** Affix on the left or right of the number. Default 'suffix'. */\n position?: 'prefix' | 'suffix';\n /** Thousands separator char. Default ','. */\n separator?: string;\n /** Decimal point char. Default '.'. */\n decimalChar?: string;\n}\n\nexport interface ValueDisplayOptions {\n id: string;\n layout: LayoutSpec;\n currency: CurrencySpec;\n /** Optional caption (\"Balance\" / \"Bet\"). */\n label?: string;\n /** Initial value, in major units (e.g. 1234.56). */\n initial?: number;\n /** Optional MINIMUM total column width for the rolling counter (integer + fraction).\n * `0`/unset = auto: the odometer is sized tightly to the value and grows as it does,\n * so the currency symbol hugs the number and large balances never clamp. Set it only\n * to reserve a stable, wider odometer. Clamped 0..18. Default 0 (auto). */\n digits?: number;\n}\n\n/**\n * A value display: a number plus a currency/crypto code. Not interactive — the\n * host sets the value (`ui.balance.set(...)`) and the renderer animates it.\n * Value is held in major units; `minorUnits` is the integer the counter rolls.\n */\nexport class ValueDisplay extends Control {\n readonly states: StateMap = { idle: { interactable: false } };\n readonly value = new Signal<number>(0);\n readonly currency: Signal<CurrencySpec>;\n readonly label?: string;\n /**\n * Show a value at the precision it ACTUALLY carries (default on): when the value has\n * more fraction digits than the currency's native precision — a sub-unit win like a\n * USD 0.01 bet × a ×0.2 face = 0.002, or the 999.982 balance it leaves behind — the\n * display decimals bump just enough to reveal them ($0.002), and drop back to the\n * native look (5.00) once the value is clean again. Set `false` for hard-fixed decimals.\n */\n autoPrecision = true;\n /** The currency's NATIVE precision — what `autoPrecision` returns to on clean values. */\n private baseDecimals: number;\n /** Minimum odometer column width (0 = auto: sized tightly to the value, grows as it\n * does). Read by the renderer at build time, so set it before mount (or declaratively\n * via `controls.{id}.digits`). */\n digits: number;\n\n constructor(opts: ValueDisplayOptions) {\n super({ id: opts.id, role: 'status', layout: opts.layout }, 'idle');\n // Clamp at construction too (not just setCurrency) so the stored spec is the\n // single source of truth — `minorUnits` and the counter never see decimals > 8.\n const c = opts.currency;\n this.currency = new Signal<CurrencySpec>(\n c && typeof c.code === 'string' ? { ...c, decimals: clampDecimals(c.decimals) } : { code: 'USD', decimals: 2 },\n );\n this.baseDecimals = this.currency.get().decimals;\n this.label = opts.label;\n this.digits = clampMinDigits(opts.digits ?? 0);\n if (opts.initial != null) this.value.set(opts.initial);\n this.applyPrecision();\n }\n\n /** Set the minimum odometer column width (clamped 0..18; 0 = auto). Read by the\n * renderer at build time, so set it before mount (or via `controls.{id}.digits`). */\n setDigits(n: number): void {\n this.digits = clampMinDigits(n);\n }\n\n /** Never-reject: NaN/Infinity/non-number degrade to a no-op, keeping the last\n * good value — malformed host data never throws into the render loop (P11). */\n set(amount: number): void {\n this.value.set(safeAmount(amount, this.value.get()));\n this.applyPrecision();\n }\n\n get(): number {\n return this.value.get();\n }\n\n /** Keep the prior spec on malformed input; clamp decimals to 0..8 (P11). The given\n * decimals become the NATIVE precision (`autoPrecision` bumps above it as needed). */\n setCurrency(spec: CurrencySpec): void {\n if (!spec || typeof spec.code !== 'string') return;\n this.baseDecimals = clampDecimals(spec.decimals);\n this.currency.set({ ...spec, decimals: this.baseDecimals });\n this.applyPrecision();\n }\n\n /** Bump the display decimals to what the current value needs — never below the\n * currency's native precision — and drop back once the value is clean again.\n * No-op (and no signal churn) when the shown precision is already right. */\n private applyPrecision(): void {\n if (!this.autoPrecision) return;\n const want = neededDecimals(this.value.get(), this.baseDecimals);\n const cur = this.currency.get();\n if (cur.decimals !== want) this.currency.set({ ...cur, decimals: want });\n }\n\n /** Accent emphasis: the renderer tints the value in the theme accent while on.\n * For \"this number is modified\" moments — e.g. a bet display showing the\n * EFFECTIVE stake while an ante/boost multiplies it. */\n readonly emphasized = new Signal<boolean>(false);\n\n setEmphasis(on: boolean): void {\n this.emphasized.set(on === true);\n }\n\n /** Integer minor units for the counter (no float drift). */\n get minorUnits(): number {\n return Math.round(this.value.get() * Math.pow(10, this.currency.get().decimals));\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Squish, Pulse, Fade } from '../transition/Transition';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\nexport interface ButtonOptions {\n id: string;\n layout: LayoutSpec;\n /** Optional text label (e.g. \"Rules\"). */\n label?: string;\n /** ARIA-ish role; default 'button'. */\n role?: string;\n}\n\n/**\n * A generic tap button: idle / hover / pressed / disabled, emitting\n * `buttonActivated` on a valid press-release. Used for settings, rules, close, …\n */\nexport class ButtonControl extends Control {\n readonly states: StateMap = {\n idle: { interactable: true, transition: new Squish(0.94, 110) },\n hover: { interactable: true, transition: new Pulse(1.05, 140) },\n pressed: { interactable: true, transition: new Squish(0.88, 70) },\n disabled: { interactable: false, transition: new Fade(0.4, 150) },\n };\n readonly label?: string;\n\n constructor(opts: ButtonOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n super({ id: opts.id, role: opts.role ?? 'button', layout: opts.layout }, 'idle');\n this.label = opts.label;\n }\n\n enable(): void {\n if (this.current === 'disabled') this.setState('idle');\n }\n disable(): void {\n this.setState('disabled');\n }\n\n /** The view calls this on a valid press-release. */\n activate(): void {\n if (this.interactable) this.bus?.emit('buttonActivated', { id: this.id });\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Signal } from '../signal';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\nconst clamp01 = (v: number): number => Math.min(1, Math.max(0, v));\n\nexport interface SliderOptions {\n id: string;\n layout: LayoutSpec;\n /** Initial value, 0..1. Default 0.5. */\n initial?: number;\n label?: string;\n}\n\n/**\n * A 0..1 slider (sound volume, etc.). The view drives `setNormalized` while\n * dragging; the lib holds the value and emits `valueChanged`. The host applies\n * the actual effect (e.g. sets audio volume).\n */\nexport class SliderControl extends Control {\n readonly states: StateMap = {\n idle: { interactable: true },\n dragging: { interactable: true },\n };\n readonly value = new Signal<number>(0.5);\n readonly label?: string;\n\n constructor(opts: SliderOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n super({ id: opts.id, role: 'slider', layout: opts.layout }, 'idle');\n this.label = opts.label;\n if (opts.initial != null) this.value.set(clamp01(opts.initial));\n }\n\n /** Set the normalized value (0..1) and notify. */\n setNormalized(v: number): void {\n const c = clamp01(v);\n if (c === this.value.get()) return;\n this.value.set(c);\n this.bus?.emit('valueChanged', { id: this.id, value: c });\n }\n\n beginDrag(): void {\n this.setState('dragging');\n }\n endDrag(): void {\n this.setState('idle');\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\nexport type PanelVariant = 'modal' | 'popover';\n\nexport interface PanelOptions {\n id: string;\n variant: PanelVariant;\n layout?: LayoutSpec;\n /** Title shown at the top of a modal. */\n title?: string;\n}\n\n/**\n * A panel that opens/closes. `modal` = full-screen backdrop + scrollable content\n * + close button; `popover` = small anchored cluster (e.g. the settings flyout).\n * State is the single source of truth (open|closed); the view animates it.\n */\nexport class PanelControl extends Control {\n readonly states: StateMap = {\n closed: { interactable: false },\n open: { interactable: true },\n };\n readonly variant: PanelVariant;\n readonly title?: string;\n\n constructor(opts: PanelOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n super({ id: opts.id, role: 'dialog', layout: opts.layout ?? { anchor: 'center' } }, 'closed');\n this.variant = opts.variant;\n this.title = opts.title;\n }\n\n get isOpen(): boolean {\n return this.current === 'open';\n }\n\n openPanel(): void {\n if (this.isOpen) return;\n this.setState('open');\n this.bus?.emit('panelToggled', { id: this.id, open: true });\n }\n closePanel(): void {\n if (!this.isOpen) return;\n this.setState('closed');\n this.bus?.emit('panelToggled', { id: this.id, open: false });\n }\n toggle(): void {\n if (this.isOpen) this.closePanel();\n else this.openPanel();\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Squish, Pulse, Fade } from '../transition/Transition';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\nexport interface ToggleOptions {\n id: string;\n layout: LayoutSpec;\n /** Initial on/off. Default false. */\n on?: boolean;\n}\n\n/**\n * An on/off toggle (e.g. Turbo). State IS the value: `off` | `on`. Emits `toggled`.\n * The view skins each state (e.g. the Turbo off/on frames).\n */\nexport class ToggleControl extends Control {\n readonly states: StateMap = {\n off: { interactable: true, transition: new Squish(0.92, 110) },\n on: { interactable: true, transition: new Pulse(1.08, 150) },\n disabled: { interactable: false, transition: new Fade(0.4, 150) },\n };\n\n constructor(opts: ToggleOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n super({ id: opts.id, role: 'switch', layout: opts.layout }, opts.on ? 'on' : 'off');\n }\n\n get isOn(): boolean {\n return this.current === 'on';\n }\n\n set(on: boolean): void {\n const next = on ? 'on' : 'off';\n if (next === this.current) return;\n this.setState(next);\n this.bus?.emit('toggled', { id: this.id, on });\n }\n\n /** Called by the view on a valid press-release. */\n toggle(): void {\n if (this.current === 'disabled') return;\n this.set(!this.isOn);\n }\n\n enable(): void {\n if (this.current === 'disabled') this.setState('off');\n }\n disable(): void {\n this.setState('disabled');\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Signal } from '../signal';\nimport { Squish, Pulse, Fade } from '../transition/Transition';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\nexport interface TurboOptions {\n id: string;\n layout: LayoutSpec;\n /**\n * The ordered modes this switcher cycles through. The FIRST mode is \"off\".\n * Two modes (`['off','on']`) behave exactly like a plain on/off toggle; three\n * (`['off','turbo','super']`) make a 3-mode switcher. Default `['off','on']`.\n */\n modes?: string[];\n /** Initial mode index. Default 0 (off). */\n index?: number;\n}\n\n/**\n * Turbo switcher. Each press advances to the next mode and wraps back to \"off\"\n * — so the SAME control is a 2-mode toggle or a 3-mode (off / turbo / super)\n * switcher purely by configuration. The current FSM state IS the current mode,\n * so look + interactivity + tests all read from one place (Charter P5).\n *\n * Emits both `turboChanged` (mode + index, the full story) and `toggled`\n * (`on` = \"any mode past off\") so existing 2-mode listeners keep working.\n */\nexport class TurboControl extends Control {\n states: StateMap;\n private _modes: string[];\n /** Current mode index, observable (0 = off). */\n readonly index: Signal<number>;\n\n constructor(opts: TurboOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n const modes = opts.modes?.length ? opts.modes.slice() : ['off', 'on'];\n const start = clampIndex(opts.index ?? 0, modes.length);\n super({ id: opts.id, role: 'switch', layout: opts.layout }, modes[start]!);\n this._modes = modes;\n this.states = TurboControl.buildStates(modes);\n this.index = new Signal<number>(start);\n }\n\n private static buildStates(modes: string[]): StateMap {\n const states: StateMap = {};\n modes.forEach((m, i) => {\n // \"off\" squishes in; engaged modes pulse, brighter further up the ladder.\n states[m] = { interactable: true, transition: i === 0 ? new Squish(0.92, 110) : new Pulse(1.06 + i * 0.02, 150) };\n });\n states.disabled = { interactable: false, transition: new Fade(0.4, 150) };\n return states;\n }\n\n /** The ordered modes (the first is \"off\"). */\n get modes(): string[] {\n return this._modes;\n }\n /** Number of modes (2 = toggle, 3 = three-mode switcher). */\n get modeCount(): number {\n return this._modes.length;\n }\n /** The current mode name. */\n get mode(): string {\n return this.current;\n }\n /** True for any mode past \"off\" — the 2-mode `isOn` semantics, preserved. */\n get isOn(): boolean {\n return this.current !== 'disabled' && this.index.get() > 0;\n }\n\n /** Replace the mode ladder (e.g. switch a game from 2-mode to 3-mode at runtime). */\n setModes(modes: string[]): void {\n if (!modes.length) return;\n this._modes = modes.slice();\n this.states = TurboControl.buildStates(this._modes);\n this.goTo(clampIndex(this.index.get(), this._modes.length), false);\n }\n\n /** Advance to the next mode, wrapping back to \"off\". The view's tap handler. */\n cycle(): void {\n if (this.current === 'disabled') return;\n this.goTo((this.index.get() + 1) % this._modes.length);\n }\n\n /** Jump to a specific mode index (clamped). */\n setIndex(i: number): void {\n if (this.current === 'disabled') return;\n this.goTo(clampIndex(i, this._modes.length));\n }\n\n /** 2-mode convenience: off (index 0) or on (index 1). */\n set(on: boolean): void {\n this.goTo(on ? Math.min(1, this._modes.length - 1) : 0);\n }\n /** Alias kept so old `toggle()` callers compile — same as `cycle()`. */\n toggle(): void {\n this.cycle();\n }\n\n private goTo(i: number, emit = true): void {\n const next = this._modes[i]!;\n const changed = next !== this.current || i !== this.index.get();\n this.index.set(i);\n this.setState(next); // no-op transition if same state name, but index already synced\n if (emit && changed) {\n this.bus?.emit('turboChanged', { id: this.id, mode: next, index: i });\n this.bus?.emit('toggled', { id: this.id, on: i > 0 });\n }\n }\n\n enable(): void {\n if (this.current === 'disabled') this.goTo(this.index.get(), false);\n }\n disable(): void {\n this.setState('disabled');\n }\n}\n\nfunction clampIndex(i: number, len: number): number {\n if (!Number.isFinite(i)) return 0;\n return Math.max(0, Math.min(Math.floor(i), len - 1));\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Signal } from '../signal';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\nexport interface StepperOptions {\n id: string;\n layout: LayoutSpec;\n /** Ordered list of allowed values (e.g. bet levels). */\n levels: number[];\n /** Starting index into `levels`. Default 0. */\n index?: number;\n /** Optional caption (e.g. \"Bet\"). */\n label?: string;\n}\n\n/**\n * Steps through a host-provided ordered list of values (bet levels). `inc`/`dec`\n * move the index and clamp at the ends; `canInc`/`canDec` drive the +/- buttons'\n * enabled state. Emits `valueChanged` with the resolved value.\n */\nexport class StepperControl extends Control {\n readonly states: StateMap = { idle: { interactable: true } };\n readonly index: Signal<number>;\n /** Optional caption (e.g. \"Bet\"). */\n readonly label?: string;\n private levels: number[];\n\n constructor(opts: StepperOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n super({ id: opts.id, role: 'spinbutton', layout: opts.layout }, 'idle');\n this.levels = opts.levels.length ? opts.levels : [0];\n this.index = new Signal<number>(this.clampIndex(opts.index ?? 0));\n this.label = opts.label;\n }\n\n private clampIndex(i: number): number {\n return Math.max(0, Math.min(this.levels.length - 1, i));\n }\n\n get value(): number {\n return this.levels[this.index.get()] ?? 0;\n }\n get canInc(): boolean {\n return this.index.get() < this.levels.length - 1;\n }\n get canDec(): boolean {\n return this.index.get() > 0;\n }\n\n inc(): void {\n if (this.canInc) this.setIndex(this.index.get() + 1);\n }\n dec(): void {\n if (this.canDec) this.setIndex(this.index.get() - 1);\n }\n\n setIndex(i: number): void {\n const next = this.clampIndex(i);\n if (next === this.index.get()) return;\n this.index.set(next);\n this.bus?.emit('valueChanged', { id: this.id, value: this.value });\n }\n\n /** Replace the level list (e.g. when the currency/limits change). */\n setLevels(levels: number[], index = 0): void {\n const prior = this.value;\n if (levels.length) this.levels = levels;\n this.index.set(this.clampIndex(index));\n // Emit only when the resolved value actually changed (mirrors setIndex) —\n // a no-op setLevels must not fire a spurious public valueChanged / log entry.\n if (this.value !== prior) this.bus?.emit('valueChanged', { id: this.id, value: this.value });\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Signal } from '../signal';\nimport { Squish, Pulse, Fade } from '../transition/Transition';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\n/**\n * How tapping autoplay behaves:\n * - `'options'` — tap opens a picker (a bottom drawer) to choose a spin count, then Start.\n * - `'infinite'` — tap starts infinite autoplay immediately; tap again stops. No picker.\n */\nexport type AutoplayMode = 'options' | 'infinite';\n\n/** Responsible-gambling stop limits for an autoplay session (multiples of bet). */\nexport interface AutoplayLimits {\n /** Stop when cumulative net loss reaches `lossLimit × bet`. Infinity = no limit. */\n lossLimit?: number;\n /** Stop on a single win ≥ `singleWinLimit × bet`. Infinity = no limit. */\n singleWinLimit?: number;\n}\n\nexport interface AutoplayOptions {\n id: string;\n layout: LayoutSpec;\n /** Count choices shown in the picker. Use Infinity for \"∞\". */\n options?: number[];\n /** Tap behavior. Default `'options'`. */\n mode?: AutoplayMode;\n /**\n * Optional responsible-gambling limit choices offered in the picker (multiples\n * of the bet; Infinity = \"no limit\"). When present, the picker shows a\n * \"stop if total loss reaches N×\" / \"stop on a single win ≥ N×\" row, and the\n * host must feed each round's outcome via {@link AutoplayControl.reportResult}.\n */\n lossLimitOptions?: number[];\n winLimitOptions?: number[];\n}\n\n/**\n * Autoplay button. In `'options'` mode, tapping (idle) opens a count picker;\n * choosing a count starts autoplay. In `'infinite'` mode, tapping starts infinite\n * autoplay straight away. While active it shows the live remaining count (fed by\n * the host via `setCount`); tapping stops. open-ui owns the picker UI + the\n * displayed count; the host runs the actual spin loop.\n */\nexport class AutoplayControl extends Control {\n readonly states: StateMap = {\n idle: { interactable: true, transition: new Squish(0.94, 110) },\n picking: { interactable: true },\n active: { interactable: true, transition: new Pulse(1.06, 150) },\n disabled: { interactable: false, transition: new Fade(0.4, 150) },\n };\n /** Remaining spins while active (Infinity = ∞). 0 when not active. */\n readonly count: Signal<number>;\n private _options: number[];\n private _lossLimitOptions: number[];\n private _winLimitOptions: number[];\n /** Active stop-on-total-loss (multiples of bet; Infinity = no limit). */\n lossLimit = Infinity;\n /** Active stop-on-single-win (multiples of bet; Infinity = no limit). */\n singleWinLimit = Infinity;\n /** Running net loss this autoplay session (bet − win, summed). */\n private netLoss = 0;\n /** Tap behavior (`'options'` opens the picker, `'infinite'` starts immediately). */\n mode: AutoplayMode;\n\n constructor(opts: AutoplayOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n super({ id: opts.id, role: 'button', layout: opts.layout }, 'idle');\n this._options = opts.options ?? [10, 25, 50, 100, Infinity];\n this._lossLimitOptions = opts.lossLimitOptions ?? [];\n this._winLimitOptions = opts.winLimitOptions ?? [];\n this.mode = opts.mode ?? 'options';\n this.count = new Signal<number>(0);\n }\n\n /** Count choices shown in the picker (Infinity allowed = ∞). */\n get options(): number[] {\n return this._options;\n }\n /** Loss-limit choices for the picker (multiples of bet; Infinity = no limit). */\n get lossLimitOptions(): number[] {\n return this._lossLimitOptions;\n }\n /** Single-win-stop choices for the picker (multiples of bet; Infinity = no limit). */\n get winLimitOptions(): number[] {\n return this._winLimitOptions;\n }\n\n /** Replace the picker's count choices (e.g. when limits change). */\n setOptions(options: number[]): void {\n if (options.length) this._options = options.slice();\n }\n /** Replace the picker's loss-limit / single-win-stop choices. */\n setLossLimitOptions(options: number[]): void {\n this._lossLimitOptions = Array.isArray(options) ? options.slice() : [];\n }\n setWinLimitOptions(options: number[]): void {\n this._winLimitOptions = Array.isArray(options) ? options.slice() : [];\n }\n\n get isActive(): boolean {\n return this.current === 'active';\n }\n\n openPicker(): void {\n if (this.current === 'idle') this.setState('picking');\n }\n cancelPicker(): void {\n if (this.current === 'picking') this.setState('idle');\n }\n\n /** Choose a count (+ optional RG limits) from the picker → start autoplay. */\n pick(count: number, limits: AutoplayLimits = {}): void {\n if (this.current !== 'picking') return;\n this.begin(count, limits);\n }\n\n /** Start autoplay with a count (Infinity = ∞) + optional RG limits, from idle or\n * the picker. The limits are enforced as the host reports each round's outcome\n * via {@link reportResult}. */\n begin(count: number, limits: AutoplayLimits = {}): void {\n if (this.current !== 'idle' && this.current !== 'picking') return;\n this.lossLimit = limits.lossLimit ?? Infinity;\n this.singleWinLimit = limits.singleWinLimit ?? Infinity;\n this.netLoss = 0;\n this.count.set(count);\n this.setState('active');\n this.bus?.emit('autoplayStarted', { count, lossLimit: this.lossLimit, singleWinLimit: this.singleWinLimit });\n }\n\n /**\n * The host reports one completed autoplay round's outcome (major units) — this is\n * the responsible-gambling guardrail. It advances the remaining count and stops\n * autoplay if: the count is exhausted, the cumulative net loss reaches the\n * loss-limit, or this single win reaches the single-win-stop. No-op when autoplay\n * isn't active or the inputs are malformed (Charter P11).\n */\n reportResult(win: number, bet: number): void {\n if (this.current !== 'active') return;\n if (!Number.isFinite(win) || !Number.isFinite(bet)) return;\n this.netLoss += bet - win;\n const c = this.count.get();\n if (Number.isFinite(c)) this.count.set(Math.max(0, c - 1));\n const winHit = Number.isFinite(this.singleWinLimit) && win >= this.singleWinLimit * bet;\n const lossHit = Number.isFinite(this.lossLimit) && this.netLoss >= this.lossLimit * bet;\n if (this.count.get() <= 0 || winHit || lossHit) this.stop();\n }\n\n stop(): void {\n if (this.current !== 'active') return;\n this.count.set(0);\n this.setState('idle');\n this.bus?.emit('autoplayStopped', undefined);\n }\n\n /** Host updates the remaining count during play. Infinity is valid (∞); only\n * NaN/non-number is rejected, so bad host data never corrupts the badge (P11). */\n setCount(n: number): void {\n if (typeof n !== 'number' || Number.isNaN(n)) return;\n this.count.set(n);\n }\n\n /** The view's tap handler. In `'infinite'` mode, idle starts straight away;\n * in `'options'` mode, idle opens the picker. Active always stops. */\n press(): void {\n if (this.current === 'idle') {\n if (this.mode === 'infinite') this.begin(Infinity);\n else this.openPicker();\n } else if (this.current === 'active') this.stop();\n else if (this.current === 'picking') this.cancelPicker();\n }\n\n disable(): void {\n this.setState('disabled');\n }\n enable(): void {\n if (this.current === 'disabled') this.setState('idle');\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Signal } from '../signal';\nimport { safeAmount } from '../safe';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { CurrencySpec } from './ValueDisplay';\n\n/**\n * What a readout shows:\n * - `'percent'` → a number + \"%\" (RTP disclosure — `displayRTP`)\n * - `'currency'` → a signed currency amount (net position — `displayNetPosition`)\n * - `'duration'` → an elapsed clock the view ticks (session timer — `displaySessionTimer`)\n * - `'plain'` → the grouped number\n */\nexport type ReadoutKind = 'percent' | 'currency' | 'duration' | 'plain';\n\nexport interface ReadoutOptions {\n id: string;\n layout: LayoutSpec;\n kind?: ReadoutKind;\n label?: string;\n /** Initial value (percent: 96, currency: major units, duration: seconds). */\n value?: number;\n /** Decimals for `percent`/`plain`. Default 1 for percent, 0 otherwise. */\n decimals?: number;\n /** Currency descriptor for the `currency` kind. */\n currency?: CurrencySpec;\n /** Whether a `currency` readout shows an explicit +/- sign. Default true. */\n signed?: boolean;\n}\n\n/**\n * A small, non-interactive text readout for the compliance display elements Stake\n * Engine's jurisdiction config can mandate: RTP (`displayRTP`), net position\n * (`displayNetPosition`), and the session timer (`displaySessionTimer`). It is the\n * single source of truth for the value; the renderer formats it (and, for\n * `'duration'`, ticks it). Hidden by default — `applyJurisdiction` reveals the ones\n * a jurisdiction requires. Never-reject inbound boundary (Charter P11).\n */\nexport class ReadoutControl extends Control {\n readonly states: StateMap = { idle: { interactable: false } };\n readonly value = new Signal<number>(0);\n /** Whether a `'duration'` readout is currently advancing. */\n readonly running = new Signal<boolean>(false);\n /** Accent emphasis: the renderer tints the value in the theme accent while on — for\n * a MODIFIED readout (e.g. net position while a bet boost is active). Mirrors\n * {@link ValueDisplay.emphasized}. */\n readonly emphasized = new Signal<boolean>(false);\n readonly kind: ReadoutKind;\n readonly label?: string;\n readonly decimals: number;\n readonly signed: boolean;\n /** Present for the `'currency'` kind so the view can format + react to changes. */\n readonly currency?: Signal<CurrencySpec>;\n\n constructor(opts: ReadoutOptions) {\n super({ id: opts.id, role: 'status', layout: opts.layout }, 'idle');\n this.kind = opts.kind ?? 'plain';\n this.label = opts.label;\n this.decimals = opts.decimals ?? (this.kind === 'percent' ? 1 : 0);\n this.signed = opts.signed ?? true;\n if (opts.currency) this.currency = new Signal<CurrencySpec>(opts.currency);\n if (opts.value != null) this.value.set(safeAmount(opts.value, 0));\n }\n\n /** Never-reject: malformed input keeps the last good value (P11). */\n set(v: number): void {\n this.value.set(safeAmount(v, this.value.get()));\n }\n /** Accent-tint the value (\"this readout is modified\"). Strict boolean. */\n setEmphasis(on: boolean): void {\n this.emphasized.set(on === true);\n }\n get(): number {\n return this.value.get();\n }\n setCurrency(spec: CurrencySpec): void {\n if (this.currency && spec && typeof spec.code === 'string') this.currency.set(spec);\n }\n\n // ── duration / session timer ────────────────────────────────────────────────\n /** Advance an elapsed-time readout by `deltaSec` (the renderer calls this each frame). */\n tick(deltaSec: number): void {\n if (this.kind !== 'duration' || !this.running.get()) return;\n if (!Number.isFinite(deltaSec) || deltaSec <= 0) return;\n this.value.set(this.value.get() + deltaSec);\n }\n start(): void {\n this.running.set(true);\n }\n stop(): void {\n this.running.set(false);\n }\n reset(): void {\n this.value.set(0);\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Squish, Pulse, Fade } from '../transition/Transition';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\nexport interface CardOptions {\n id: string;\n layout: LayoutSpec;\n /** Card title (e.g. the feature name). */\n title?: string;\n /** Price / cost shown on the card (formatted string or number). */\n price?: string;\n /** Asset id/key for the card image (resolved by the view/host). */\n image?: string;\n}\n\n/**\n * A selectable buy-feature card: image + title + price + a buy action.\n * Emits `cardActivated` on a valid press-release. Lives inside a buy-feature panel.\n */\nexport class CardControl extends Control {\n readonly states: StateMap = {\n idle: { interactable: true, transition: new Squish(0.96, 110) },\n hover: { interactable: true, transition: new Pulse(1.04, 140) },\n pressed: { interactable: true, transition: new Squish(0.9, 70) },\n disabled: { interactable: false, transition: new Fade(0.4, 150) },\n };\n title?: string;\n price?: string;\n image?: string;\n\n constructor(opts: CardOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n super({ id: opts.id, role: 'button', layout: opts.layout }, 'idle');\n this.title = opts.title;\n this.price = opts.price;\n this.image = opts.image;\n }\n\n enable(): void {\n if (this.current === 'disabled') this.setState('idle');\n }\n disable(): void {\n this.setState('disabled');\n }\n\n /** The view calls this on a valid press-release. */\n activate(): void {\n if (this.interactable) this.bus?.emit('cardActivated', { id: this.id });\n }\n}\n","import { Control, type StateMap } from '../control/Control';\nimport { Signal } from '../signal';\nimport { Squish, Pulse, Fade } from '../transition/Transition';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\n\nexport interface SelectOption {\n value: string;\n label: string;\n}\n\nexport interface SelectControlOptions {\n id: string;\n layout: LayoutSpec;\n options: SelectOption[];\n index?: number;\n /** Caption shown beside the control (e.g. \"Language\"). */\n label?: string;\n role?: string;\n}\n\n/**\n * A single-choice select (language, quality, …). FSM peer of StepperControl:\n * `closed | open | disabled`. Tapping cycles or opens a list; all logic is\n * headless and the renderer just draws it. Emits its OWN typed `optionSelected`\n * event rather than overloading the numeric `valueChanged` (Charter B1, P5).\n */\nexport class SelectControl extends Control {\n readonly states: StateMap = {\n closed: { interactable: true, transition: new Squish(0.96, 100) },\n open: { interactable: true, transition: new Pulse(1.04, 140) },\n disabled: { interactable: false, transition: new Fade(0.4, 150) },\n };\n readonly index: Signal<number>;\n /** Caption (e.g. \"Language\") — distinct from the selected option's label. */\n readonly caption?: string;\n private _options: SelectOption[];\n\n constructor(opts: SelectControlOptions, private readonly bus?: EventBus<OpenUIEvents>) {\n if (!opts.options || opts.options.length === 0) {\n throw new Error(`[open-ui] select \"${opts.id}\": needs at least one option`);\n }\n super({ id: opts.id, role: opts.role ?? 'listbox', layout: opts.layout }, 'closed');\n this._options = opts.options.slice();\n this.caption = opts.label;\n this.index = new Signal<number>(this.clamp(opts.index ?? 0));\n }\n\n private clamp(i: number): number {\n if (!Number.isFinite(i)) return 0;\n return Math.max(0, Math.min(this._options.length - 1, Math.trunc(i)));\n }\n\n get options(): ReadonlyArray<SelectOption> {\n return this._options;\n }\n get value(): string {\n return this._options[this.index.get()]?.value ?? '';\n }\n get optionLabel(): string {\n return this._options[this.index.get()]?.label ?? '';\n }\n get isOpen(): boolean {\n return this.current === 'open';\n }\n\n openList(): void {\n if (this.current === 'closed') this.setState('open');\n }\n closeList(): void {\n if (this.current === 'open') this.setState('closed');\n }\n\n /** Choose by value (the view's list-item handler). Closes the list. */\n choose(value: string): void {\n const i = this._options.findIndex((o) => o.value === value);\n if (i < 0) return;\n if (i !== this.index.get()) {\n this.index.set(i);\n this.bus?.emit('optionSelected', { id: this.id, value: this.value, index: i });\n }\n if (this.current === 'open') this.setState('closed');\n }\n\n /** Jump to an index (clamped). Emits only if it changed. */\n setIndex(i: number): void {\n const next = this.clamp(i);\n if (next === this.index.get()) return;\n this.index.set(next);\n this.bus?.emit('optionSelected', { id: this.id, value: this.value, index: next });\n }\n\n /** Advance to the next option, wrapping (the view's cycle-on-tap handler). */\n cycle(): void {\n if (this._options.length < 2) return;\n this.setIndex((this.index.get() + 1) % this._options.length);\n }\n\n /** Replace the option list (e.g. when limits or locale change). */\n setOptions(options: SelectOption[], index = 0): void {\n if (!options.length) return;\n this._options = options.slice();\n this.index.set(this.clamp(index));\n this.bus?.emit('optionSelected', { id: this.id, value: this.value, index: this.index.get() });\n }\n\n enable(): void {\n if (this.current === 'disabled') this.setState('closed');\n }\n disable(): void {\n this.setState('disabled');\n }\n}\n","import { defaultTheme, extendTheme, type Theme, type DeepPartial } from './tokens';\n\n/** Built-in presets. open-ui ships a SINGLE canonical look — black & white with a\n * yellow accent (the `default` token theme). Hosts restyle via `ThemeOverrides`\n * (sanitized colours/radius/font), so the library stays themeable without shipping\n * a palette zoo. Unknown preset names resolve to `default`. */\nexport type ThemePreset = 'default';\n\n/**\n * The SAFE, curated surface a host may override (Charter P8 + \"configure, don't\n * break\"). Deliberately a subset of the full `Theme`: colours, corner radii, and\n * the font family — the look knobs. Structural tokens (spacing, motion timing,\n * font sizes) are NOT exposed, so a theme can restyle the HUD but cannot break its\n * layout or timing. Every value is validated/clamped at runtime too (see below).\n */\nexport interface ThemeOverrides {\n color?: Partial<Theme['color']>;\n radius?: Partial<Theme['radius']>;\n type?: { family?: string };\n}\n\n/** A reportable theme problem (structurally a `SpecIssue`, kept dependency-free). */\nexport interface ThemeIssue {\n level: 'warn' | 'error';\n path: string;\n code: string;\n message: string;\n}\n\n/**\n * What a host can pass for `theme`: a preset name, a safe override (layered on the\n * default), or `{ preset, overrides }` to layer a safe override on a chosen preset.\n */\nexport type ThemeChoice =\n | ThemePreset\n | ThemeOverrides\n | { preset?: ThemePreset; overrides?: ThemeOverrides };\n\n/** The one ready-to-use theme: black & white with a yellow accent (`defaultTheme`). */\nexport const themePresets: Readonly<Record<ThemePreset, Theme>> = Object.freeze({\n default: defaultTheme,\n}) as Readonly<Record<ThemePreset, Theme>>;\n\n// A pragmatic CSS-colour check: hex (#rgb/#rgba/#rrggbb/#rrggbbaa) or rgb()/rgba().\nconst HEX = /^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;\nconst RGB = /^rgba?\\(\\s*[0-9.\\s,%/]+\\)$/i;\n\n/** True for a colour string the renderer can safely use. */\nexport function isSafeColor(v: unknown): v is string {\n return typeof v === 'string' && (HEX.test(v.trim()) || RGB.test(v.trim()));\n}\n\nconst clamp = (n: number, lo: number, hi: number): number => Math.max(lo, Math.min(hi, n));\n\n/**\n * Turn host overrides into a guaranteed-safe `DeepPartial<Theme>`: invalid colours\n * are dropped (the base token shows through), radii are clamped to a sane range,\n * and a non-string font family is ignored. Each rejection is reported, never fatal.\n */\nexport function sanitizeThemeOverrides(ov: ThemeOverrides, onIssue?: (i: ThemeIssue) => void): DeepPartial<Theme> {\n const out: DeepPartial<Theme> = {};\n if (ov.color) {\n const color: Partial<Theme['color']> = {};\n for (const [k, v] of Object.entries(ov.color)) {\n if (isSafeColor(v)) color[k as keyof Theme['color']] = v.trim();\n else onIssue?.({ level: 'warn', path: `theme.color.${k}`, code: 'bad-color', message: `\"${String(v)}\" is not a valid colour — kept the theme default` });\n }\n if (Object.keys(color).length) out.color = color;\n }\n if (ov.radius) {\n const radius: Partial<Theme['radius']> = {};\n for (const [k, v] of Object.entries(ov.radius)) {\n if (typeof v === 'number' && Number.isFinite(v)) radius[k as keyof Theme['radius']] = clamp(v, 0, 999);\n else onIssue?.({ level: 'warn', path: `theme.radius.${k}`, code: 'bad-radius', message: `radius \"${String(v)}\" must be a finite number — ignored` });\n }\n if (Object.keys(radius).length) out.radius = radius;\n }\n if (ov.type?.family != null) {\n if (typeof ov.type.family === 'string' && ov.type.family.trim()) out.type = { family: ov.type.family };\n else onIssue?.({ level: 'warn', path: 'theme.type.family', code: 'bad-family', message: 'font family must be a non-empty string — ignored' });\n }\n return out;\n}\n\nfunction isPresetChoice(c: ThemeChoice): c is { preset?: ThemePreset; overrides?: ThemeOverrides } {\n return typeof c === 'object' && c !== null && ('preset' in c || 'overrides' in c);\n}\n\n/**\n * Resolve any `ThemeChoice` into a concrete, frozen Theme. Overrides are\n * sanitized first, so a host can restyle the HUD but never break it: bad values\n * fall back to the safe token (Charter P8/G5/P11). Pass `onIssue` to surface\n * rejections (createUI forwards these to `HostHooks.onDataIssue`).\n */\nexport function resolveTheme(choice?: ThemeChoice, onIssue?: (i: ThemeIssue) => void): Theme {\n if (!choice) return defaultTheme;\n if (typeof choice === 'string') return themePresets[choice] ?? defaultTheme;\n if (isPresetChoice(choice)) {\n const base = choice.preset ? themePresets[choice.preset] ?? defaultTheme : defaultTheme;\n if (!choice.overrides) return base;\n return Object.freeze(extendTheme(base, sanitizeThemeOverrides(choice.overrides, onIssue)));\n }\n return Object.freeze(extendTheme(defaultTheme, sanitizeThemeOverrides(choice as ThemeOverrides, onIssue)));\n}\n","/**\n * Resolves a declarative BlockSpec into a real Control. This is the swap-by-class\n * seam (Charter P7): the defaults can be overridden per kind, so a game can drop\n * in its own control class without forking. Keyed by block `kind`.\n */\nimport type { Control } from '../control/Control';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\nimport type { BlockSpec } from '../spec/types';\nimport { SliderControl } from '../controls/SliderControl';\nimport { ToggleControl } from '../controls/ToggleControl';\nimport { ButtonControl } from '../controls/ButtonControl';\nimport { SelectControl } from '../controls/SelectControl';\nimport { StepperControl } from '../controls/StepperControl';\nimport { ValueDisplay } from '../controls/ValueDisplay';\n\nexport type BlockFactory = (block: BlockSpec, bus: EventBus<OpenUIEvents>) => Control | null;\n\n/** Leaf controls are laid out by the panel body, so they anchor at center here. */\nconst CENTER = { anchor: 'center' } as const;\n\nexport class ControlRegistry {\n private readonly factories = new Map<string, BlockFactory>();\n\n register(kind: string, factory: BlockFactory): void {\n this.factories.set(kind, factory);\n }\n\n has(kind: string): boolean {\n return this.factories.has(kind);\n }\n\n /** Build the Control for a block, or null for non-control blocks / unknown kinds. */\n resolve(block: BlockSpec, bus: EventBus<OpenUIEvents>): Control | null {\n return this.factories.get(block.kind)?.(block, bus) ?? null;\n }\n\n /** A registry with every built-in block kind wired to its reference control. */\n static defaults(): ControlRegistry {\n const r = new ControlRegistry();\n r.register('slider', (b, bus) =>\n b.kind === 'slider' ? new SliderControl({ id: b.id, layout: CENTER, label: b.label, initial: b.initial }, bus) : null);\n r.register('toggle', (b, bus) =>\n b.kind === 'toggle' ? new ToggleControl({ id: b.id, layout: CENTER, on: b.on }, bus) : null);\n r.register('button', (b, bus) =>\n b.kind === 'button' ? new ButtonControl({ id: b.id, layout: CENTER, label: b.label, role: b.role }, bus) : null);\n r.register('select', (b, bus) =>\n b.kind === 'select' ? new SelectControl({ id: b.id, layout: CENTER, options: b.options, index: b.index, label: b.label }, bus) : null);\n r.register('stepper', (b, bus) =>\n b.kind === 'stepper' ? new StepperControl({ id: b.id, layout: CENTER, levels: b.levels, index: b.index, label: b.label }, bus) : null);\n r.register('value', (b) =>\n b.kind === 'value' ? new ValueDisplay({ id: b.id, layout: CENTER, label: b.label, currency: b.currency ?? { code: 'USD', decimals: 2 }, initial: b.initial }) : null);\n // 'text' and 'group' carry no control — buildPanel handles them directly.\n return r;\n }\n}\n","/**\n * The JSON-serializable UISpec — the single source of truth that builds the\n * control tree, drives e2e, and powers the docs panel editor (the \"SpecKit\"\n * design). Authoring it is type-checked; `validateSpec` guards it at runtime;\n * `createUI` assembles it over the existing OpenUI machinery.\n */\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { LayoutConfig, Breakpoint, Orientation } from '../layout/screen';\nimport type { ThemeChoice } from '../theme/presets';\nimport type { CurrencySpec } from '../controls/ValueDisplay';\nimport type { SelectOption } from '../controls/SelectControl';\nimport type { AutoplayMode } from '../controls/AutoplayControl';\nimport type { PanelVariant, PanelControl } from '../controls/PanelControl';\nimport type { Control } from '../control/Control';\nimport type { OpenUIEvents } from '../types';\nimport type { MenuSpec } from './menu';\nimport type { JurisdictionConfig } from './jurisdiction';\nimport type { GameFacts } from './facts';\n\n/** The reference-HUD control ids — typed so a typo is a compile error. */\nexport type KnownControlId =\n | 'spin'\n | 'balance'\n | 'bet'\n | 'settings'\n | 'settings-panel'\n | 'music'\n | 'sfx'\n | 'rules'\n | 'info-panel'\n | 'info-close'\n | 'turbo'\n | 'autoplay'\n | 'bonus'\n | 'bet-stepper'\n | 'bet-plus'\n | 'bet-minus'\n | 'fullscreen'\n | 'mute'\n | 'rtp'\n | 'net-position'\n | 'session-timer'\n | 'notice-panel';\n\n/** One issue from the never-throw validator. */\nexport interface SpecIssue {\n level: 'error' | 'warn';\n path: string;\n code: string;\n message: string;\n}\n\n/** Host-owned side effects, injected (the lib performs none itself — Charter B8). */\nexport interface HostHooks {\n onDataIssue?(issue: SpecIssue): void;\n onAnalyticsEvent?: <K extends keyof OpenUIEvents>(type: K, payload: OpenUIEvents[K]) => void;\n}\n\n/** A targeted override for one shipped control. Anything omitted keeps the default. */\nexport interface ControlOverride {\n layout?: LayoutSpec;\n label?: string;\n hidden?: boolean;\n disabled?: boolean;\n currency?: CurrencySpec;\n initial?: number;\n /** Value-display only: MINIMUM odometer column width. `0`/unset = auto — the counter\n * is sized tightly to the value (symbol hugs the number) and grows as it does, so\n * balances never clamp. Set it only to reserve a stable, wider readout. Clamped\n * 0..18; ignored by non-value controls. Default 0 (auto). */\n digits?: number;\n}\n\n/**\n * Turbo switcher config. Choose how many modes the one Turbo control cycles\n * through — `2` (off/on) or `3` (off/turbo/super) — or pass explicit mode names.\n */\nexport interface TurboSpec {\n /** `2` → off/on · `3` → off/turbo/super · or a custom ordered ladder (first = off). */\n modes?: 2 | 3 | string[];\n /** Initial mode index (0 = off). */\n index?: number;\n}\n\n/** How pressing the spin button behaves. */\nexport type SpinPress = 'tap' | 'hold-to-spin';\n\nexport interface SpinSpec {\n /** `'tap'` = one spin per tap · `'hold-to-spin'` = turbo-spin while held. Default `'tap'`. */\n press?: SpinPress;\n}\n\n/** A responsive bucket the config can target: a device size OR an orientation. */\nexport type ResponsiveKey = Breakpoint | Orientation;\n\n/** What a responsive bucket may change. Layout + visibility, per control. */\nexport interface ResponsiveOverride {\n controls?: Record<string, Pick<ControlOverride, 'layout' | 'hidden'>>;\n}\n\n/**\n * A declarative menu/panel content block. Discriminated by `kind` so a \"shown but\n * no payload\" bug is uncompilable (Charter B10): a `select` cannot omit options,\n * a `slider` cannot carry them.\n *\n * Every block may carry `covers` — rules-audit topic tags (e.g. `'rtp:bonus'`,\n * `'freespins'`) marking that this block's hand-written prose covers a declaration\n * the audit's text heuristics can't see. See `auditRules` in `spec/facts`.\n */\nexport type BlockSpec = {\n /** Rules-audit topics this block covers (see `auditRules`). */\n covers?: string[];\n /** The declared mode id this block EXPLAINS (e.g. `'bonus'`). Every declared mode\n * must have its own rules section — a heading naming it, or blocks tagged with\n * `explains` — with real prose; the audit enforces it (see `auditRules`). */\n explains?: string;\n} & (\n // `hint` is a short description of what the control does, shown dim UNDER it — so\n // every interactive control in the Info/settings menu explains its own function.\n | { kind: 'slider'; id: string; label?: string; initial?: number; hint?: string }\n | { kind: 'toggle'; id: string; label?: string; on?: boolean; hint?: string }\n | { kind: 'button'; id: string; label: string; action?: 'closePanel' | 'openPanel' | 'emit'; target?: string; role?: string; hint?: string }\n | { kind: 'select'; id: string; label?: string; options: SelectOption[]; index?: number; hint?: string }\n | { kind: 'stepper'; id: string; label?: string; levels: number[]; index?: number; hint?: string }\n | { kind: 'value'; id: string; label?: string; currency?: CurrencySpec; initial?: number }\n | { kind: 'text'; id: string; text: string }\n // ── static \"rules\"/info content (no control; every text run through `ui.t`) ──\n | { kind: 'heading'; id: string; text: string }\n | { kind: 'subheading'; id: string; text: string }\n | { kind: 'callout'; id: string; tone?: 'info' | 'bonus' | 'warning'; title?: string; text: string }\n | { kind: 'stat-grid'; id: string; items: Array<{ label: string; value: string }> }\n // AUTO-GENERATED per-mode RTP / Max-win grid, rendered straight from `UISpec.facts`\n // (+ `ui.declareFacts`) — declared once, so the table can never drift from the config.\n | { kind: 'mode-stats'; id: string; extras?: Array<{ label: string; value: string }> }\n | { kind: 'steps'; id: string; ordered?: boolean; items: string[] }\n | { kind: 'table'; id: string; columns?: string[]; rows: string[][] }\n | { kind: 'paytable'; id: string; columns?: number; rows: Array<{ symbol?: string; payouts: string; icon?: string }> }\n | { kind: 'image'; id: string; src: string; alt?: string; width?: number; height?: number }\n | { kind: 'media'; id: string; src: string; alt?: string; side?: 'left' | 'right'; title?: string; text: string; width?: number; height?: number }\n | { kind: 'cards'; id: string; items: Array<{ icon?: string; title: string; text?: string }> }\n | { kind: 'legal'; id: string; text: string }\n | { kind: 'divider'; id: string }\n | { kind: 'group'; id: string; title?: string; children: BlockSpec[] }\n);\n\n/** All block kinds, for runtime validation of untyped host data. */\nexport const BLOCK_KINDS = [\n 'slider',\n 'toggle',\n 'button',\n 'select',\n 'stepper',\n 'value',\n 'text',\n 'heading',\n 'subheading',\n 'callout',\n 'stat-grid',\n 'mode-stats',\n 'steps',\n 'table',\n 'paytable',\n 'image',\n 'media',\n 'cards',\n 'legal',\n 'divider',\n 'group',\n] as const;\n\nexport interface PanelSpec {\n id: string;\n variant: PanelVariant;\n title?: string;\n layout?: LayoutSpec;\n blocks: BlockSpec[];\n}\n\n/** The whole UI as one optional, JSON-serializable object. Omit any field → default. */\nexport interface UISpec {\n meta?: { id: string; version: number };\n theme?: ThemeChoice;\n layout?: LayoutConfig;\n /** Balance + bet currency: a full spec, or a code string (e.g. `'JPY'`, `'XGC'`)\n * auto-resolved (decimals, social coins) via the built-in currency table. */\n currency?: CurrencySpec | string;\n betLadder?: { levels: number[]; index?: number };\n /**\n * Autoplay count choices + tap behavior (`'options'` drawer or `'infinite'`), plus\n * optional responsible-gambling limit choices (multiples of bet; Infinity = none).\n * When `lossLimits`/`winLimits` are set, the picker offers them and the host must\n * feed each round to `hud.reportRound(win, bet)` so they're enforced.\n * `insufficientFundsNotice` (default true): when autoplay stops with the balance\n * unable to cover the next round, show the same insufficient-funds modal a manual\n * spin shows (ERR_IPB) instead of ending silently.\n */\n autoplay?: { options?: number[]; mode?: AutoplayMode; lossLimits?: number[]; winLimits?: number[]; insufficientFundsNotice?: boolean };\n /** Turbo switcher: 2-mode (off/on) or 3-mode (off/turbo/super). */\n turbo?: TurboSpec;\n /** Spin button behavior: single `'tap'` or `'hold-to-spin'` turbo. */\n spin?: SpinSpec;\n /**\n * Per-device / per-orientation overrides, layered on top of `controls`. Keys are\n * `'mobile' | 'tablet' | 'desktop'` (device size) and `'portrait' | 'landscape'`\n * (orientation); on each resize the matching buckets re-apply, so the HUD can\n * reflow or drop controls per screen. Order: base → orientation → size.\n */\n responsive?: Partial<Record<ResponsiveKey, ResponsiveOverride>>;\n controls?: Partial<Record<KnownControlId, ControlOverride>> & Record<string, ControlOverride>;\n /** The unified scrollable MENU opened by ☰: Settings → Paytable → Rules. */\n menu?: MenuSpec;\n /** Back-compat: rules blocks, folded into the menu's Rules section if `menu.rules` is absent. */\n rules?: BlockSpec[];\n /** Additional declarative panels. */\n panels?: PanelSpec[];\n /** i18n dictionary + starting locale (built into a DictionaryTranslator). */\n locale?: {\n messages: Record<string, Record<string, string>>;\n locale: string;\n /** SEPARATE social/sweepstakes wording dictionary (same keys as `messages`),\n * used only in social mode — kept apart so the two can't be mixed up. */\n socialMessages?: Record<string, Record<string, string>>;\n };\n /** Block/control id whose `optionSelected` switches the locale. Default 'lang'. */\n localeSelectId?: string;\n /** Auto-lock the whole HUD while the spin control is spinning. Default true. */\n lockDuringSpin?: boolean;\n /**\n * Stake Engine per-player jurisdiction config — the compliance switchboard. Usually\n * known only after the game authenticates, so prefer the runtime\n * `hud.applyJurisdiction(jur)`; set it here when known up front (createUI applies it\n * before the responsive layer so `disabled*` hides survive resizes).\n */\n jurisdiction?: JurisdictionConfig;\n /** Initial RTP percentage for the RTP readout (e.g. 96 → \"96.0%\"). */\n rtp?: number;\n /** Game name + version — shown in the menu footer (support / certification). */\n game?: { name?: string; version?: string };\n /**\n * Structured GAME FACTS — what the game HAS: its math modes (base / buy features /\n * boosts) with RTP + max win, its free-spins behavior, volatility and cap. Drives\n * the auto `mode-stats` rules block AND the rules-completeness audit: a configured\n * mode whose RTP / max win / description is missing from the rules is called out\n * explicitly in the info menu (see `auditRules`). The buy-feature modal declares\n * its configured features into this automatically (`ui.declareFacts`).\n */\n facts?: GameFacts;\n /** Buy-feature / bet-mode confirmation. `confirmAboveCost` (× base bet) makes any\n * play costing MORE than that require a confirm step before it commits — Stake\n * requires bet modes above 2× to never activate on a single click, so set `2`.\n * The game routes a purchase/activation through `hud.requestBuyFeature(...)`, which\n * shows the confirm popup itself when the cost exceeds the threshold. A jurisdiction\n * can set the same threshold (`JurisdictionConfig.confirmBuyAboveCost`). */\n buyFeature?: { confirmAboveCost?: number };\n /** Reality-check reminder (RTS 13): open-ui runs a wall-clock timer, emits a\n * `realityCheck` event, stops autoplay, and (unless `showModal:false`) shows an\n * acknowledge modal. You supply only the cadence + text. `title`/`message` are\n * literal-or-key with `{{minutes}}`/`{{spent}}`/`{{won}}` interpolation. */\n realityCheck?: { everyMinutes: number; title?: string; message?: string; showModal?: boolean };\n /** Social / sweepstakes mode: `true` swaps gambling wording (Bet/Buy → social\n * terms); `{ coin }` also shows balance/bet/net in that coin (e.g. `'GC'`/`'SC'`). */\n social?: boolean | { coin?: string };\n /** Audio start state. `startMuted` boots muted (the mute icon reflects it; unmuting\n * restores the configured volumes). */\n audio?: { startMuted?: boolean };\n}\n\n/** The result of building a PanelSpec: the panel + every leaf control, in render order. */\nexport interface BuiltPanel {\n panel: PanelControl;\n controls: Control[];\n blocks: BlockSpec[];\n}\n","/**\n * Never-throw spec validator (Charter P11/B9). Returns a report; callers\n * (createUI) drop only the offending pieces and degrade — a malformed HUD still\n * boots. Every guardrail check lives here; it is pure and unit-tested.\n */\nimport type { UISpec, BlockSpec, SpecIssue } from './types';\nimport { BLOCK_KINDS } from './types';\n\nconst ANCHORS = new Set([\n 'top-left', 'top-center', 'top-right',\n 'center-left', 'center', 'center-right',\n 'bottom-left', 'bottom-center', 'bottom-right',\n]);\n\nconst AUTOPLAY_MODES = new Set(['options', 'infinite']);\nconst SPIN_PRESS = new Set(['tap', 'hold-to-spin']);\nconst RESPONSIVE_KEYS = new Set(['mobile', 'tablet', 'desktop', 'portrait', 'landscape']);\n\nexport function validateSpec(spec: UISpec): { ok: boolean; issues: SpecIssue[] } {\n const issues: SpecIssue[] = [];\n const add = (level: SpecIssue['level'], path: string, code: string, message: string): void => {\n issues.push({ level, path, code, message });\n };\n const ids = new Set<string>();\n const seeId = (id: string | undefined, path: string): void => {\n if (!id || !id.trim()) add('error', path, 'blank-id', 'control id must be a non-empty string');\n else if (ids.has(id)) add('error', path, 'dup-id', `duplicate control id \"${id}\"`);\n else ids.add(id);\n };\n const checkLayout = (anchor: string | undefined, path: string): void => {\n if (anchor && !ANCHORS.has(anchor)) add('error', path, 'bad-anchor', `unknown anchor \"${anchor}\"`);\n };\n\n try {\n if (spec.betLadder) {\n const lv = spec.betLadder.levels;\n if (!Array.isArray(lv) || lv.length === 0) {\n add('error', 'betLadder.levels', 'empty-levels', 'bet ladder needs at least one level');\n } else if (spec.betLadder.index != null && (spec.betLadder.index < 0 || spec.betLadder.index >= lv.length)) {\n add('error', 'betLadder.index', 'index-oor', `index ${spec.betLadder.index} is out of range 0..${lv.length - 1}`);\n }\n }\n\n if (spec.autoplay?.options) {\n spec.autoplay.options.forEach((o, i) => {\n if (!(typeof o === 'number' && o > 0)) {\n add('error', `autoplay.options[${i}]`, 'bad-option', `autoplay option must be > 0 (Infinity allowed), got ${String(o)}`);\n }\n });\n }\n if (spec.autoplay?.mode && !AUTOPLAY_MODES.has(spec.autoplay.mode)) {\n add('error', 'autoplay.mode', 'bad-mode', `autoplay.mode must be 'options' or 'infinite', got \"${String(spec.autoplay.mode)}\"`);\n }\n for (const key of ['lossLimits', 'winLimits'] as const) {\n const arr = spec.autoplay?.[key];\n if (arr) {\n arr.forEach((o, i) => {\n if (!(typeof o === 'number' && o > 0)) add('error', `autoplay.${key}[${i}]`, 'bad-limit', `autoplay ${key} must be > 0 (Infinity allowed), got ${String(o)}`);\n });\n }\n }\n\n if (spec.turbo) {\n const m = spec.turbo.modes;\n if (Array.isArray(m)) {\n if (m.length < 2) add('error', 'turbo.modes', 'turbo-too-few', 'a turbo ladder needs at least 2 modes (first = off)');\n if (m.some((x) => typeof x !== 'string' || !x.trim())) add('error', 'turbo.modes', 'turbo-bad-mode', 'turbo mode names must be non-empty strings');\n if (new Set(m).size !== m.length) add('error', 'turbo.modes', 'turbo-dup-mode', 'turbo mode names must be unique');\n } else if (m != null && m !== 2 && m !== 3) {\n add('error', 'turbo.modes', 'turbo-bad-count', `turbo.modes preset must be 2 or 3, got ${String(m)}`);\n }\n const len = Array.isArray(m) ? m.length : (m ?? 2);\n if (spec.turbo.index != null && (spec.turbo.index < 0 || spec.turbo.index >= len)) {\n add('error', 'turbo.index', 'index-oor', `turbo.index ${spec.turbo.index} is out of range 0..${len - 1}`);\n }\n }\n\n if (spec.spin?.press && !SPIN_PRESS.has(spec.spin.press)) {\n add('error', 'spin.press', 'bad-press', `spin.press must be 'tap' or 'hold-to-spin', got \"${String(spec.spin.press)}\"`);\n }\n\n if (spec.responsive) {\n for (const [key, ov] of Object.entries(spec.responsive)) {\n if (!RESPONSIVE_KEYS.has(key)) {\n add('error', `responsive.${key}`, 'bad-bucket', `unknown responsive bucket \"${key}\" (expected ${[...RESPONSIVE_KEYS].join(', ')})`);\n }\n if (ov?.controls) {\n for (const [id, co] of Object.entries(ov.controls)) {\n checkLayout(co.layout?.anchor, `responsive.${key}.controls.${id}.layout.anchor`);\n }\n }\n }\n }\n\n if (spec.currency && typeof spec.currency === 'object' && typeof spec.currency.decimals === 'number') {\n const d = spec.currency.decimals;\n if (d < 0 || d > 8) add('warn', 'currency.decimals', 'decimals-range', `decimals ${d} clamped to 0..8`);\n }\n\n if (spec.jurisdiction) {\n for (const [k, v] of Object.entries(spec.jurisdiction)) {\n if (k === 'minimumRoundDuration') {\n if (v != null && !(typeof v === 'number' && Number.isFinite(v) && v >= 0)) {\n add('error', `jurisdiction.${k}`, 'bad-duration', `minimumRoundDuration must be a non-negative number, got ${String(v)}`);\n }\n } else if (v != null && typeof v !== 'boolean') {\n add('error', `jurisdiction.${k}`, 'bad-flag', `jurisdiction.${k} must be a boolean, got ${String(v)}`);\n }\n }\n }\n if (spec.rtp != null && !(typeof spec.rtp === 'number' && Number.isFinite(spec.rtp))) {\n add('error', 'rtp', 'bad-rtp', `rtp must be a number, got ${String(spec.rtp)}`);\n }\n if (spec.realityCheck != null && !(typeof spec.realityCheck.everyMinutes === 'number' && spec.realityCheck.everyMinutes > 0)) {\n add('error', 'realityCheck.everyMinutes', 'bad-interval', 'realityCheck.everyMinutes must be a number > 0');\n }\n if (spec.buyFeature?.confirmAboveCost != null && !(typeof spec.buyFeature.confirmAboveCost === 'number' && Number.isFinite(spec.buyFeature.confirmAboveCost) && spec.buyFeature.confirmAboveCost >= 0)) {\n add('error', 'buyFeature.confirmAboveCost', 'bad-threshold', 'buyFeature.confirmAboveCost must be a finite number >= 0');\n }\n\n if (spec.controls) {\n for (const [id, ov] of Object.entries(spec.controls)) {\n checkLayout(ov.layout?.anchor, `controls.${id}.layout.anchor`);\n if (ov.digits != null) {\n if (!(typeof ov.digits === 'number' && Number.isFinite(ov.digits))) {\n add('error', `controls.${id}.digits`, 'bad-digits', `digits must be a number, got ${String(ov.digits)}`);\n } else if (ov.digits < 0 || ov.digits > 18) {\n add('warn', `controls.${id}.digits`, 'digits-range', `digits ${ov.digits} clamped to 0..18 (0 = auto)`);\n }\n }\n }\n }\n\n const walkBlocks = (blocks: BlockSpec[] | undefined, base: string): void => {\n blocks?.forEach((b, i) => {\n const p = `${base}[${i}]`;\n if (!BLOCK_KINDS.includes(b.kind as (typeof BLOCK_KINDS)[number])) {\n add('error', `${p}.kind`, 'unknown-kind', `unknown block kind \"${String(b.kind)}\"`);\n return;\n }\n seeId(b.id, `${p}.id`);\n if (b.explains && b.explains !== 'freeSpins' && spec.facts?.modes?.length && !spec.facts.modes.some((m) => m.id === b.explains)) {\n add('warn', `${p}.explains`, 'explains-unknown-mode', `explains \"${b.explains}\" matches no declared mode id (facts.modes)`);\n }\n if (b.kind === 'select' && (!b.options || b.options.length === 0)) {\n add('error', `${p}.options`, 'select-empty', 'a select block needs at least one option');\n }\n if (b.kind === 'slider' && b.initial != null && (b.initial < 0 || b.initial > 1)) {\n add('error', `${p}.initial`, 'slider-range', `slider initial ${b.initial} must be 0..1`);\n }\n if (b.kind === 'stepper' && (!b.levels || b.levels.length === 0)) {\n add('error', `${p}.levels`, 'empty-levels', 'a stepper block needs at least one level');\n }\n if (b.kind === 'stat-grid' && (!b.items || b.items.length === 0)) {\n add('warn', `${p}.items`, 'empty-grid', 'a stat-grid block has no items');\n }\n if (b.kind === 'mode-stats' && !spec.facts?.modes?.length) {\n add('warn', `${p}`, 'mode-stats-no-facts', 'a mode-stats block renders from spec.facts.modes, but no modes are declared');\n }\n if (b.kind === 'steps' && (!b.items || b.items.length === 0)) {\n add('warn', `${p}.items`, 'empty-steps', 'a steps block has no items');\n }\n if (b.kind === 'paytable' && (!b.rows || b.rows.length === 0)) {\n add('warn', `${p}.rows`, 'empty-paytable', 'a paytable block has no rows');\n }\n if (b.kind === 'image' && (!b.src || !b.src.trim())) {\n add('error', `${p}.src`, 'image-src', 'an image block needs a src');\n }\n if (b.kind === 'image' && ((b.width != null && b.width <= 0) || (b.height != null && b.height <= 0))) {\n add('error', `${p}.width`, 'image-dims', 'image width/height must be > 0 when set');\n }\n if (b.kind === 'media' && (!b.src || !b.src.trim())) {\n add('error', `${p}.src`, 'image-src', 'a media block needs an image src');\n }\n if (b.kind === 'media' && ((b.width != null && b.width <= 0) || (b.height != null && b.height <= 0))) {\n add('error', `${p}.width`, 'image-dims', 'media width/height must be > 0 when set');\n }\n if (b.kind === 'cards' && (!b.items || b.items.length === 0)) {\n add('warn', `${p}.items`, 'empty-cards', 'a cards block has no items');\n }\n if (b.kind === 'table' && (!b.rows || b.rows.length === 0)) {\n add('warn', `${p}.rows`, 'empty-table', 'a table block has no rows');\n }\n if (b.kind === 'group') walkBlocks(b.children, `${p}.children`);\n });\n };\n\n if (spec.menu?.banner && (!spec.menu.banner.src || !spec.menu.banner.src.trim())) {\n add('error', 'menu.banner.src', 'image-src', 'a menu banner needs a src');\n }\n walkBlocks(spec.menu?.settings, 'menu.settings');\n walkBlocks(spec.menu?.paytable, 'menu.paytable');\n walkBlocks(spec.menu?.rules, 'menu.rules');\n walkBlocks(spec.rules, 'rules');\n spec.panels?.forEach((pn, i) => {\n seeId(pn.id, `panels[${i}].id`);\n checkLayout(pn.layout?.anchor, `panels[${i}].layout.anchor`);\n walkBlocks(pn.blocks, `panels[${i}].blocks`);\n });\n } catch (e) {\n // The validator must never throw — a crash here is itself a reportable issue.\n add('error', '', 'validator-crash', e instanceof Error ? e.message : String(e));\n }\n\n return { ok: !issues.some((i) => i.level === 'error'), issues };\n}\n","/**\n * Turns a declarative PanelSpec into a PanelControl plus one Control per leaf\n * block (resolved through the registry, so blocks are swappable too — Charter P7).\n * Pure assembly: it instantiates and returns; action wiring + registration is the\n * caller's job (createUI / OpenUIPixi), so buildPanel stays leak-free and testable.\n */\nimport { PanelControl } from '../controls/PanelControl';\nimport type { Control } from '../control/Control';\nimport type { EventBus } from '../events';\nimport type { OpenUIEvents } from '../types';\nimport type { BlockSpec, PanelSpec, BuiltPanel } from './types';\nimport { ControlRegistry } from '../registry/ControlRegistry';\n\n/** Resolve a block tree to its flat leaf controls, in render order. text/group carry none. */\nexport function buildBlocks(\n blocks: BlockSpec[],\n bus: EventBus<OpenUIEvents>,\n registry: ControlRegistry = ControlRegistry.defaults(),\n /** If a block id already resolves to a control (e.g. a built-in like 'music'),\n * reuse it instead of building a shadow copy that would overwrite it. */\n reuse?: (id: string) => Control | undefined,\n): Control[] {\n const controls: Control[] = [];\n const walk = (bs: BlockSpec[]): void => {\n for (const b of bs) {\n if (b.kind === 'group') {\n walk(b.children);\n continue;\n }\n if (b.kind === 'text') continue;\n const existing = reuse?.(b.id);\n if (existing) {\n controls.push(existing);\n continue;\n }\n const c = registry.resolve(b, bus);\n if (c) controls.push(c);\n }\n };\n walk(blocks);\n return controls;\n}\n\nexport function buildPanel(\n spec: PanelSpec,\n bus: EventBus<OpenUIEvents>,\n registry: ControlRegistry = ControlRegistry.defaults(),\n): BuiltPanel {\n const panel = new PanelControl(\n { id: spec.id, variant: spec.variant, title: spec.title, layout: spec.layout },\n bus,\n );\n const controls = buildBlocks(spec.blocks, bus, registry);\n return { panel, controls, blocks: spec.blocks };\n}\n\n/** Flatten a block tree to its button blocks (used to wire panel actions). */\nexport function buttonBlocks(blocks: BlockSpec[]): Array<Extract<BlockSpec, { kind: 'button' }>> {\n const out: Array<Extract<BlockSpec, { kind: 'button' }>> = [];\n const walk = (bs: BlockSpec[]): void => {\n for (const b of bs) {\n if (b.kind === 'button') out.push(b);\n else if (b.kind === 'group') walk(b.children);\n }\n };\n walk(blocks);\n return out;\n}\n","import type { OpenUI } from '../OpenUI';\n\n/**\n * Stake Engine's per-player jurisdiction config — the object the RGS returns at\n * `/wallet/authenticate` as `config.jurisdiction`. It is the platform's regulatory\n * switchboard: each `disabled*` flag must HIDE/limit a feature, each `display*`\n * flag must SHOW a readout, and `minimumRoundDuration` is a hint the GAME enforces\n * (open-ui never throttles the round). Every field is optional — an omitted flag\n * leaves the HUD's configured default untouched.\n *\n * @see https://github.com/StakeEngine/web-sdk — packages/rgs-fetcher/src/schema.ts\n */\nexport interface JurisdictionConfig {\n /** Social / sweepstakes mode (coins shown as GC/SC). */\n socialCasino?: boolean;\n disabledFullscreen?: boolean;\n disabledTurbo?: boolean;\n disabledAutoplay?: boolean;\n disabledSlamstop?: boolean;\n disabledSpacebar?: boolean;\n disabledBuyFeature?: boolean;\n displayNetPosition?: boolean;\n displayRTP?: boolean;\n displaySessionTimer?: boolean;\n /** Minimum ms a round must take — stored on the HUD for the GAME to enforce. */\n minimumRoundDuration?: number;\n /** Buy-feature confirm threshold (× base bet). A play costing more than this must\n * be confirmed before it commits — Stake requires that bet modes above 2× never\n * activate on a single click, so a Stake preset sets this to `2`. Not part of the\n * wallet schema; a convenience so a jurisdiction can require the confirm step. */\n confirmBuyAboveCost?: number;\n}\n\n/**\n * Apply a Stake Engine `jurisdiction` config to a live HUD — the whole switchboard\n * in one call. Safe to run at any time (typically right after the game\n * authenticates and learns the player's jurisdiction): it only acts on the flags\n * that are set, so it composes with the game's own `controls`/`responsive` config\n * and is idempotent. `disabled*` hides are made permanent (resize-proof) via\n * `ui.forceHidden`; `display*` flags reveal/hide the mandated readouts. It reuses\n * the primitives open-ui already has, so honoring the platform is one line.\n */\nexport function applyJurisdiction(ui: OpenUI, jur: JurisdictionConfig | undefined): void {\n if (!jur) return;\n\n const lockHidden = (id: string): void => {\n ui.forceHidden.add(id); // can never be re-shown by responsive (compliance)\n ui.setHidden(id, true);\n };\n\n // ── \"disable X\" → hide AND really disable the feature (not just visual) ───────\n if (jur.disabledFullscreen) lockHidden('fullscreen');\n if (jur.disabledTurbo) lockHidden('turbo');\n if (jur.disabledAutoplay) {\n lockHidden('autoplay');\n ui.autoplay.disable(); // a real guard: begin()/press() now no-op (state 'disabled')\n }\n if (jur.disabledBuyFeature) {\n lockHidden('bonus');\n ui.bonusButton.disable(); // the buy button can't be tapped; confirmBuy() also no-ops\n }\n // Slam-stop off → the spin button locks (dims) during the spin; no tap-to-stop.\n if (jur.disabledSlamstop) ui.spin.allowSlamStop.set(false);\n // Spacebar / hold-to-spin off → no keyboard spin + each cycle needs a fresh press.\n if (jur.disabledSpacebar) {\n ui.spin.holdToSpin = false;\n ui.spin.allowKeyboard.set(false);\n }\n\n // ── \"display X\" → reveal the mandated readout (jurisdiction owns these) ───────\n if (jur.displayRTP != null) ui.setHidden('rtp', !jur.displayRTP);\n if (jur.displayNetPosition != null) ui.setHidden('net-position', !jur.displayNetPosition);\n if (jur.displaySessionTimer != null) {\n ui.setHidden('session-timer', !jur.displaySessionTimer);\n if (jur.displaySessionTimer) ui.sessionTimer.start();\n else ui.sessionTimer.stop();\n }\n\n // Social / sweepstakes mode — swaps gambling wording (and shows GC/SC when the\n // game has set a social coin). The round-duration hint stays GAME-enforced.\n if (jur.socialCasino != null) ui.setSocial(jur.socialCasino);\n if (typeof jur.minimumRoundDuration === 'number' && Number.isFinite(jur.minimumRoundDuration)) {\n ui.minimumRoundDuration = Math.max(0, jur.minimumRoundDuration);\n }\n if (typeof jur.confirmBuyAboveCost === 'number' && Number.isFinite(jur.confirmBuyAboveCost)) {\n ui.confirmBuyAboveCost = Math.max(0, jur.confirmBuyAboveCost);\n }\n}\n","/**\n * The notice / error modal model.\n *\n * The HUD shows a menu-style modal built from declarative {@link BlockSpec} content\n * plus a row of action buttons. EVERY string — title, message, and each button\n * label — is passed through the translator (`ui.t`), so the host can either pass the\n * EXACT literal text they want, or a translation key they localize themselves (their\n * `locale.messages` dict overrides the built-in English defaults). Nothing is\n * hard-coded in the renderer, and every default is overridable per call.\n */\nimport type { BlockSpec } from './spec/types';\n\nexport interface NoticeAction {\n /** Button label — a literal string OR an i18n key (resolved via the translator). */\n label: string;\n /** Called when the button is pressed. */\n onSelect?: () => void;\n /** Also emit a `buttonActivated` event with this id (for analytics / host wiring). */\n emit?: string;\n /** Visual weight (default: first action `primary`, the rest `secondary`). */\n variant?: 'primary' | 'secondary';\n /** Keep the modal open after pressing (default: dismiss it). */\n keepOpen?: boolean;\n}\n\nexport interface NoticeOptions {\n /** Title — literal or i18n key. Default `'openui.error'` for errors. */\n title?: string;\n /** Callout tone. Default `'warning'` for errors. */\n tone?: 'info' | 'warning' | 'bonus';\n /** Action buttons. Omitted → a single dismiss button (`openui.ok`), or NONE when\n * `blocking` (so a fatal modal is dismissable only in code). */\n actions?: NoticeAction[];\n /** FATAL/blocking modal: locks the HUD, no backdrop/✕ dismiss; remove via `hideNotice`. */\n blocking?: boolean;\n}\n\n/** Reality-check reminder config (RTS 13). You supply the cadence + text; open-ui\n * owns the (wall-clock) timer, the event, and the modal. */\nexport interface RealityCheckOptions {\n /** Reminder interval in minutes (wall-clock). */\n everyMinutes: number;\n /** Modal title — literal or i18n key. `{{minutes}}`/`{{spent}}`/`{{won}}` interpolate. */\n title?: string;\n /** Modal message — literal or i18n key. Same interpolation tokens. */\n message?: string;\n /** Show the built-in acknowledge modal (default true). `false` → only the event fires. */\n showModal?: boolean;\n /** Custom action buttons (default a single \"Continue\"). */\n actions?: NoticeAction[];\n}\n\n/** What `showRgsError` accepts: notice options plus an exact message override. */\nexport interface RgsErrorOptions extends NoticeOptions {\n /** Override the default message for this code with exact text (or your own key). */\n message?: string;\n /** Stop an in-progress autoplay session (default true — most RGS errors should). */\n stopAutoplay?: boolean;\n}\n\n/** RGS status codes open-ui ships a default message for (the TS enum + the HTTP groups). */\nexport type RgsErrorCode =\n | 'ERR_IPB'\n | 'ERR_IS'\n | 'ERR_ATE'\n | 'ERR_GLE'\n | 'ERR_BE'\n | 'ERR_BNF'\n | 'ERR_LOC'\n | 'ERR_MAINTENANCE'\n | 'ERR_VAL'\n | 'ERR_GEN'\n | 'ERR_UE'\n | 'ERR_TIMEOUT';\n\n/**\n * Code → default title/message i18n KEYS. The English text for these keys lives in\n * the translator defaults (`openuiDefaults`), so a host localizes errors by adding\n * those keys to their `messages` dict — or overrides any single one per call via\n * `showRgsError(code, { title, message })`. Unknown codes fall back to generic.\n */\nexport const RGS_ERROR_KEYS: Readonly<Record<string, { title: string; message: string }>> = Object.freeze({\n ERR_IPB: { title: 'openui.err.insufficient.title', message: 'openui.err.insufficient.message' },\n ERR_IS: { title: 'openui.err.session.title', message: 'openui.err.session.message' },\n ERR_ATE: { title: 'openui.err.session.title', message: 'openui.err.session.message' },\n ERR_GLE: { title: 'openui.err.limit.title', message: 'openui.err.limit.message' },\n ERR_BE: { title: 'openui.err.activebet.title', message: 'openui.err.activebet.message' },\n ERR_BNF: { title: 'openui.err.generic.title', message: 'openui.err.generic.message' },\n ERR_LOC: { title: 'openui.err.location.title', message: 'openui.err.location.message' },\n ERR_MAINTENANCE: { title: 'openui.err.maintenance.title', message: 'openui.err.maintenance.message' },\n ERR_VAL: { title: 'openui.err.generic.title', message: 'openui.err.generic.message' },\n ERR_GEN: { title: 'openui.err.generic.title', message: 'openui.err.generic.message' },\n ERR_UE: { title: 'openui.err.generic.title', message: 'openui.err.generic.message' },\n ERR_TIMEOUT: { title: 'openui.err.connection.title', message: 'openui.err.connection.message' },\n});\n\n/** The default dismiss action used when a notice supplies none. */\nexport const DEFAULT_NOTICE_ACTION: NoticeAction = { label: 'openui.ok', variant: 'primary' };\n\n/** Build the title + message blocks for an error/notice (used by `showError`).\n * The Figma \"default\" modal is plain: a heading + body text (no tinted callout).\n * `tone` is kept for API compatibility but no longer changes the rendering. */\nexport function errorBlocks(message: string, title: string, _tone: NonNullable<NoticeOptions['tone']>): BlockSpec[] {\n return [\n { kind: 'heading', id: 'notice-title', text: title },\n { kind: 'text', id: 'notice-body', text: message },\n ];\n}\n","import type { Dispose } from '../signal';\n\n/**\n * i18n port (Charter B5/B8): the core depends on this tiny interface, NOT on i18next.\n * Ship adapters (`@open-slot-ui/i18n-i18next`, the built-in `dictionary()`), never a hard dep.\n */\nexport interface Translator {\n t(key: string, vars?: Record<string, string | number>): string;\n readonly locale: string;\n /** Switch the active locale (a no-op for the same locale); fires onChange. */\n setLocale(next: string): void;\n onChange(cb: (locale: string) => void): Dispose;\n /** Switch social/sweepstakes wording on/off. In social mode `t` resolves from a\n * SEPARATE social dictionary first, so social copy can never be mixed into the\n * normal keys by accident (by design). No-op if unsupported. */\n setSocial?(on: boolean): void;\n}\n\n/** open-ui owns this namespace; the host's translator may override any key. */\nexport const openuiDefaults: Record<string, string> = {\n 'openui.spin': 'Spin',\n 'openui.stop': 'Stop',\n 'openui.autoplay': 'Autoplay',\n 'openui.bet': 'Bet',\n 'openui.balance': 'Balance',\n 'openui.win': 'Win',\n 'openui.totalWin': 'Total Win',\n 'openui.menu': 'Menu',\n 'openui.rules': 'Rules',\n 'openui.paytable': 'Paytable',\n 'openui.settings': 'Settings',\n 'openui.close': 'Close',\n 'openui.language': 'Language',\n // compliance readouts + autoplay limit headings\n 'openui.rtp': 'RTP',\n 'openui.net': 'Net',\n 'openui.session': 'Session',\n 'openui.lossLimit': 'Stop on loss',\n 'openui.winLimit': 'Stop on single win',\n // notice / error modal\n 'openui.ok': 'OK',\n 'openui.cancel': 'Cancel',\n 'openui.confirm': 'Confirm',\n 'openui.continue': 'Continue',\n 'openui.reload': 'Reload',\n 'openui.error': 'Error',\n 'openui.notice': 'Notice',\n 'openui.replay': 'Replay',\n // Replay panel (Stake \"Replay Support\"): the round's cost + worth is shown at the\n // start; a Replay button re-runs it at the end.\n 'openui.replay.title': 'Replay',\n 'openui.replay.baseBet': 'Base Bet',\n 'openui.replay.costMultiplier': 'Cost Multiplier',\n 'openui.replay.payoutMultiplier': 'Payout Multiplier',\n 'openui.replay.amount': 'Final amount',\n 'openui.replay.play': 'Play',\n 'openui.replay.again': 'Replay',\n 'openui.buyFeature.title': 'Buy feature',\n 'openui.buyFeature.message': 'Buy this feature now?',\n // Confirm step for a higher-cost play — {{name}} / {{price}} are interpolated.\n 'openui.buyFeature.confirm': 'Buy {{name}} for {{price}}?',\n 'openui.freeSpins': 'FS',\n // reality check (RTS 13) — {{minutes}} is interpolated by open-ui's scheduler\n 'openui.realityCheck.title': 'Reality check',\n 'openui.realityCheck.message': \"You've been playing for {{minutes}} minutes. Take a moment before continuing.\",\n // Rules-completeness audit (the info menu's \"forgotten declarations\" card)\n 'openui.rulesAudit.title': 'Rules incomplete',\n 'openui.rulesAudit.required': 'Missing required information:',\n 'openui.rulesAudit.recommended': 'Highly recommended:',\n // RGS error defaults (override via your messages dict or per-call)\n 'openui.err.generic.title': 'Something went wrong',\n 'openui.err.generic.message': 'Sorry, something went wrong. Please try again.',\n 'openui.err.insufficient.title': 'Insufficient funds',\n 'openui.err.insufficient.message': \"You don't have enough balance to place this bet.\",\n 'openui.err.session.title': 'Session expired',\n 'openui.err.session.message': 'Your session has expired. Reload the game to continue.',\n 'openui.err.limit.title': 'Limit reached',\n 'openui.err.limit.message': 'A gambling limit has been reached. Please try again later.',\n 'openui.err.activebet.title': 'Round in progress',\n 'openui.err.activebet.message': 'You already have a round in progress. Reload to finish it.',\n 'openui.err.location.title': 'Unavailable here',\n 'openui.err.location.message': 'This game is not available in your location.',\n 'openui.err.maintenance.title': 'Under maintenance',\n 'openui.err.maintenance.message': 'The game is briefly down for maintenance. Please try again soon.',\n 'openui.err.connection.title': 'Connection lost',\n 'openui.err.connection.message': 'A stable connection is required. Reload to finish any open round.',\n};\n\n/**\n * Social / sweepstakes wording — a SEPARATE dictionary (same keys as the normal\n * ones). Kept apart on purpose so a host can never mix gambling and social copy in\n * one map: provide your social overrides under `locale.socialMessages`, not inline.\n */\nexport const openuiSocialDefaults: Record<string, string> = {\n 'openui.bet': 'Play',\n 'openui.balance': 'Balance',\n 'openui.win': 'Prize',\n 'openui.totalWin': 'Total Prize',\n // \"Paytable\" (contains \"pay\") and \"Insufficient funds\" (\"funds\") are restricted in\n // social mode → their compliant equivalents. The literal \"Paytable\" is overridden too\n // because the menu SECTION heading uses it as its key (DEFAULT_MENU_TITLES).\n 'openui.paytable': 'Prizes',\n Paytable: 'Prizes',\n 'openui.err.insufficient.title': 'Insufficient balance',\n 'openui.buyFeature.title': 'Play bonus',\n 'openui.buyFeature.message': 'Play this bonus now?',\n 'openui.buyFeature.confirm': 'Play {{name}} for {{price}}?',\n // Stake.us replay terms: Base Bet → Base Play, Cost Multiplier → Feature Multiplier,\n // Payout Multiplier → Final Multiplier.\n 'openui.replay.baseBet': 'Base Play',\n 'openui.replay.costMultiplier': 'Feature Multiplier',\n 'openui.replay.payoutMultiplier': 'Final Multiplier',\n 'openui.err.insufficient.message': \"You don't have enough balance for this play.\",\n 'openui.err.limit.message': 'A play limit has been reached. Please try again later.',\n // The auto mode-stats grid's label words (used as their own keys at render time).\n 'Max win': 'Max prize',\n};\n\nfunction interpolate(template: string, vars?: Record<string, string | number>): string {\n if (!vars) return template;\n // i18next-style {{token}}; dotted tokens ({{rtp.base}}, {{cost.free-spins}}) are the\n // facts-vars namespace (see `factsVars`) — flat lookup, same as i18next keySeparator:false.\n return template.replace(/\\{\\{([\\w.-]+)\\}\\}/g, (_m, k: string) => String(vars[k] ?? `{{${k}}}`));\n}\n\n/**\n * Zero-dep dictionary translator. Falls back to open-ui defaults, then to the\n * key itself only if nothing is found — but built-in keys always resolve, so the\n * library never renders a raw key (the text analog of \"never break un-themed\").\n */\nexport class DictionaryTranslator implements Translator {\n private _locale: string;\n private _social = false;\n private readonly subs = new Set<(locale: string) => void>();\n\n constructor(\n private readonly messages: Record<string, Record<string, string>>,\n locale: string,\n /** SEPARATE social/sweepstakes dictionary — consulted first in social mode. */\n private readonly socialMessages: Record<string, Record<string, string>> = {},\n ) {\n this._locale = locale;\n }\n\n get locale(): string {\n return this._locale;\n }\n\n setLocale(next: string): void {\n if (next === this._locale) return;\n this._locale = next;\n for (const cb of [...this.subs]) cb(next);\n }\n\n setSocial(on: boolean): void {\n this._social = on;\n }\n\n t(key: string, vars?: Record<string, string | number>): string {\n // Social mode resolves from the dedicated social dictionary FIRST (host social\n // overrides → built-in social defaults), then falls back to the normal chain —\n // so social and gambling copy are kept structurally separate.\n const social = this._social\n ? this.socialMessages[this._locale]?.[key] ?? openuiSocialDefaults[key]\n : undefined;\n const resolved = social ?? this.messages[this._locale]?.[key] ?? openuiDefaults[key] ?? key;\n return interpolate(resolved, vars);\n }\n\n onChange(cb: (locale: string) => void): Dispose {\n this.subs.add(cb);\n return () => {\n this.subs.delete(cb);\n };\n }\n}\n\n/** Convenience factory for a zero-dep dictionary translator. */\nexport function dictionary(\n messages: Record<string, Record<string, string>>,\n locale: string,\n socialMessages?: Record<string, Record<string, string>>,\n): DictionaryTranslator {\n return new DictionaryTranslator(messages, locale, socialMessages);\n}\n","/**\n * GAME FACTS + the rules-completeness AUDIT — the \"can't forget\" layer for the\n * Info/Rules menu (Charter P11: data, not prose).\n *\n * A game declares WHAT IT HAS as structured facts — its math modes (base game, buy\n * features, bet boosts) with their RTP and max win, its free-spins behavior, its\n * volatility/cap — via `UISpec.facts` and/or `ui.declareFacts` (the buy-feature modal\n * declares its configured features automatically). The rules content stays modular\n * blocks (the \"block builder\"), and two mechanisms tie the two together:\n *\n * 1. The `mode-stats` block AUTO-RENDERS the per-mode RTP / Max-win grid straight\n * from the facts — declared once, so the table can never drift from the config.\n * 2. `auditRules(facts, rules)` checks the rules blocks against the facts and\n * reports every REQUIRED declaration that is missing (a mode's RTP or max win,\n * an undescribed buy feature) plus the HIGHLY RECOMMENDED ones (free-spins count\n * + retrigger policy, the legal disclaimer, a controls guide). The info menu\n * renders these findings as an explicit warning card when the rules open — a\n * forgotten declaration is stated, never silent.\n *\n * Any block may carry `covers: ['rtp:bonus', 'freespins', …]` to mark a topic as\n * covered by hand-written prose the text heuristics can't see.\n */\nimport type { BlockSpec } from './types';\n\n/** One math mode / play mode the game exposes (base · buy feature · bet boost · ante). */\nexport interface GameModeFact {\n /** Stable id (matches the buy-feature card / RGS mode id), e.g. `'base'`, `'bonus'`. */\n id: string;\n /** Display name, e.g. `'Golden Rush'` — run through `ui.t` (social swaps apply). */\n name: string;\n /** What kind of mode this is. `'base'` is the plain game; everything else is a\n * configured feature that MUST be described in the rules. */\n kind?: 'base' | 'buy' | 'boost' | 'ante' | 'bonus';\n /** Cost as a multiple of the base bet (buy price / per-spin surcharge). */\n cost?: number;\n /** The mode's RTP in percent (e.g. 95.5). Required in the rules for every mode. */\n rtp?: number;\n /** The mode's maximum win as a multiple of the base bet (e.g. 5000). Required. */\n maxWinX?: number;\n}\n\n/** Free-spins behavior — HIGHLY RECOMMENDED to declare (or `false` = game has none). */\nexport interface FreeSpinsFact {\n /** How many free spins the bonus awards (e.g. exactly 3). */\n count?: number;\n /** Whether free spins can be retriggered during the bonus. */\n retrigger?: boolean;\n /** Free-form note (not audited). */\n note?: string;\n}\n\n/** Everything the game HAS, declared as data. Drives `mode-stats` + `auditRules`. */\nexport interface GameFacts {\n modes?: GameModeFact[];\n /** Free-spins facts, or `false` to state explicitly the game has none. */\n freeSpins?: FreeSpinsFact | false;\n /** Volatility label shown by `mode-stats` (e.g. `'Very high'`). */\n volatility?: string;\n /** The overall round win cap (× base bet) shown by `mode-stats` (e.g. 5000). */\n maxWinCapX?: number;\n}\n\n/** Merge two facts declarations: modes merge BY ID (defined incoming fields win);\n * scalar facts take the incoming value when defined. Pure — never mutates inputs. */\nexport function mergeFacts(base: GameFacts, add: GameFacts): GameFacts {\n const modes = [...(base.modes ?? [])];\n for (const m of add.modes ?? []) {\n const i = modes.findIndex((x) => x.id === m.id);\n if (i < 0) modes.push({ ...m });\n else {\n const merged = { ...modes[i] } as unknown as Record<string, unknown>;\n for (const [k, v] of Object.entries(m)) if (v !== undefined) merged[k] = v;\n modes[i] = merged as unknown as GameModeFact;\n }\n }\n return {\n ...(modes.length ? { modes } : {}),\n freeSpins: add.freeSpins !== undefined ? add.freeSpins : base.freeSpins,\n volatility: add.volatility ?? base.volatility,\n maxWinCapX: add.maxWinCapX ?? base.maxWinCapX,\n };\n}\n\n/** Format an RTP percent the Stake way: always two decimals (95.5 → \"95.50%\"). */\nexport function formatRtp(rtp: number): string {\n return `${rtp.toFixed(2)}%`;\n}\n\n/** Format a × multiple with thousands grouping (5000 → \"5,000×\"). */\nexport function formatTimes(x: number): string {\n return `${x.toLocaleString('en-US', { maximumFractionDigits: 2 })}×`;\n}\n\n/**\n * The auto-generated per-mode stat rows a `mode-stats` block renders: one\n * `RTP · <mode>` + `Max win · <mode>` pair per declared mode, then Volatility and\n * the round cap when declared. `tr` localizes the label words + mode names (social\n * mode swaps \"Max win\" → \"Max prize\" via the built-in social dictionary).\n */\nexport function modeStatsItems(\n facts: GameFacts | undefined,\n tr: (s: string) => string = (s) => s,\n): Array<{ label: string; value: string }> {\n const out: Array<{ label: string; value: string }> = [];\n for (const m of facts?.modes ?? []) {\n if (m.rtp != null) out.push({ label: `${tr('RTP')} · ${tr(m.name)}`, value: formatRtp(m.rtp) });\n if (m.maxWinX != null) out.push({ label: `${tr('Max win')} · ${tr(m.name)}`, value: formatTimes(m.maxWinX) });\n }\n if (facts?.volatility) out.push({ label: tr('Volatility'), value: tr(facts.volatility) });\n if (facts?.maxWinCapX != null) out.push({ label: tr('Round cap'), value: formatTimes(facts.maxWinCapX) });\n return out;\n}\n\n/**\n * The INTERPOLATION VARIABLES the declared facts expose to rules copy — the\n * \"universal interpolatable rules\" contract. Any rules text (inline blocks or a\n * {@link RulesDoc}) may use i18next-style tokens; the info menu resolves them from\n * the LIVE facts, so a stated RTP / max win / price can never drift from config:\n *\n * `{{rtp.<modeId>}}` → \"95.50%\" `{{maxWin.<modeId>}}` → \"5,000×\"\n * `{{cost.<modeId>}}` → \"185×\" `{{name.<modeId>}}` → the mode name\n * `{{freeSpins.count}}` → 3 `{{freeSpins.retrigger}}` → \"can\"/\"cannot\"\n * `{{volatility}}` → \"Very high\" `{{maxWinCap}}` → \"5,000×\"\n *\n * `extra` merges additional host vars (e.g. `game.name`) on top.\n */\nexport function factsVars(\n facts: GameFacts | undefined,\n extra?: Record<string, string | number>,\n): Record<string, string | number> {\n const vars: Record<string, string | number> = {};\n for (const m of facts?.modes ?? []) {\n if (!m.id) continue;\n vars[`name.${m.id}`] = m.name;\n if (m.rtp != null) vars[`rtp.${m.id}`] = formatRtp(m.rtp);\n if (m.maxWinX != null) vars[`maxWin.${m.id}`] = formatTimes(m.maxWinX);\n if (m.cost != null) vars[`cost.${m.id}`] = formatTimes(m.cost);\n }\n const fs = facts?.freeSpins;\n if (fs) {\n if (fs.count != null) vars['freeSpins.count'] = fs.count;\n if (fs.retrigger != null) vars['freeSpins.retrigger'] = fs.retrigger ? 'can' : 'cannot';\n }\n if (facts?.volatility) vars['volatility'] = facts.volatility;\n if (facts?.maxWinCapX != null) vars['maxWinCap'] = formatTimes(facts.maxWinCapX);\n return extra ? { ...vars, ...extra } : vars;\n}\n\n/** One finding from the rules audit. `required` findings are compliance gaps\n * (RTP / max win / an undescribed configured feature); `recommended` are the\n * strongly-advised ones (free-spins details, legal disclaimer, controls guide). */\nexport interface RulesAuditIssue {\n level: 'required' | 'recommended';\n /** Machine code, e.g. `'rules-missing-rtp'`, `'facts-missing-maxwin'`. */\n code: string;\n /** The coverage topic that would satisfy it, e.g. `'rtp:bonus'`, `'freespins'`. */\n topic: string;\n /** Human sentence shown in the info menu's warning card. */\n message: string;\n}\n\n/** One RULES SECTION: a heading (or the pre-heading preamble) + everything under it\n * until the next heading. The unit of \"this mode is explained HERE\". */\ninterface RulesSection {\n /** The resolved heading text ('' for the preamble before the first heading). */\n heading: string;\n /** Resolved prose under the heading (the heading itself excluded). */\n text: string;\n /** `explains` tags carried by any block in the section. */\n explains: Set<string>;\n /** `covers` tags carried by any block in the section. */\n covers: Set<string>;\n}\n\n/** Everything the audit extracts from the rules blocks in one pass. */\ninterface RulesScan {\n text: string;\n headings: string;\n covers: Set<string>;\n hasModeStats: boolean;\n hasLegal: boolean;\n sections: RulesSection[];\n}\n\nfunction scanBlocks(blocks: BlockSpec[] | undefined, resolve: (s: string) => string = (s) => s): RulesScan {\n const scan: RulesScan = { text: '', headings: '', covers: new Set(), hasModeStats: false, hasLegal: false, sections: [] };\n let section: RulesSection = { heading: '', text: '', explains: new Set(), covers: new Set() };\n scan.sections.push(section);\n const addText = (t: unknown): void => {\n if (typeof t === 'string' && t) {\n const r = resolve(t);\n scan.text += `\\n${r}`;\n section.text += `\\n${r}`;\n }\n };\n const walk = (list: BlockSpec[] | undefined): void => {\n for (const b of list ?? []) {\n // A heading starts a NEW section (the unit a mode's explanation lives in).\n if (b.kind === 'heading' || b.kind === 'subheading') {\n section = { heading: resolve(b.text), text: '', explains: new Set(), covers: new Set() };\n scan.sections.push(section);\n }\n for (const c of b.covers ?? []) {\n scan.covers.add(c);\n section.covers.add(c);\n }\n if (b.explains) section.explains.add(b.explains);\n const anyB = b as Record<string, unknown>;\n switch (b.kind) {\n case 'mode-stats':\n scan.hasModeStats = true;\n (b.extras ?? []).forEach((it) => {\n addText(it.label);\n addText(it.value);\n });\n break;\n case 'legal':\n scan.hasLegal = true;\n addText(b.text);\n break;\n case 'heading':\n case 'subheading': {\n // Global text/headings only — a section's `text` is the prose UNDER its\n // heading, so a bare heading can't pass for an explanation.\n const r = resolve(b.text);\n scan.headings += `\\n${r}`;\n scan.text += `\\n${r}`;\n break;\n }\n case 'text':\n addText(b.text);\n break;\n case 'callout':\n addText(b.title);\n addText(b.text);\n break;\n case 'media':\n addText(b.title);\n addText(b.text);\n break;\n case 'steps':\n b.items.forEach(addText);\n break;\n case 'table':\n (b.columns ?? []).forEach(addText);\n b.rows.forEach((r) => r.forEach(addText));\n break;\n case 'paytable':\n b.rows.forEach((r) => {\n addText(r.symbol);\n addText(r.payouts);\n });\n break;\n case 'cards':\n b.items.forEach((it) => {\n addText(it.title);\n addText(it.text);\n });\n break;\n case 'stat-grid':\n b.items.forEach((it) => {\n addText(it.label);\n addText(it.value);\n });\n break;\n case 'group':\n addText(b.title);\n walk(b.children);\n break;\n default:\n addText(anyB.label);\n addText(anyB.hint);\n break;\n }\n }\n };\n walk(blocks);\n return scan;\n}\n\nconst escapeRe = (s: string): string => s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n/** Does the text state this RTP? Accepts \"95.5%\" / \"95.50%\" (and \"96%\" / \"96.00%\"). */\nfunction mentionsRtp(text: string, rtp: number): boolean {\n const s = String(rtp);\n const [int = '', frac = ''] = s.split('.');\n const body = frac ? `${escapeRe(int)}[.,]${escapeRe(frac)}0*` : `${escapeRe(int)}(?:[.,]0{1,2})?`;\n return new RegExp(`\\\\b${body}\\\\s*%`).test(text);\n}\n\n/** Does the text state this × multiple? Accepts \"5,000×\" / \"5000x\" / \"5 000 x\". */\nfunction mentionsTimes(text: string, x: number): boolean {\n const digits = String(Math.trunc(Math.abs(x)));\n let grouped = '';\n for (let i = 0; i < digits.length; i++) {\n if (i > 0 && (digits.length - i) % 3 === 0) grouped += '[,.\\\\s\\\\u00a0]?';\n grouped += digits[i];\n }\n const frac = Math.abs(x) % 1 !== 0 ? `[.,]\\\\d+` : `(?:[.,]\\\\d+)?`;\n return new RegExp(`\\\\b${grouped}${frac}\\\\s*[x×]`, 'i').test(text);\n}\n\nconst mentionsName = (text: string, name: string): boolean => text.toLowerCase().includes(name.toLowerCase());\n\n/** Does a mode's OWN section state its cost? Accepts the surcharge as `0.5×`, the\n * total as `1.5×` (games phrase antes either way), or a `+50%` percentage form. */\nfunction mentionsCost(text: string, cost: number): boolean {\n if (mentionsTimes(text, cost) || mentionsTimes(text, cost + 1)) return true;\n if (cost > 0 && cost < 1) return new RegExp(`\\\\b${Math.round(cost * 100)}\\\\s*%`).test(text);\n return false;\n}\n\n/** A section counts as EXPLAINING a mode when a block in it is tagged\n * `explains: <id>` / `covers: ['feature:<id>']`, or its heading names the mode —\n * and, for the base game, a \"How to play\" / \"About the game\" heading qualifies. */\nfunction findModeSection(sections: RulesSection[], m: GameModeFact): RulesSection | undefined {\n return sections.find(\n (s) =>\n s.explains.has(m.id) ||\n s.covers.has(`feature:${m.id}`) ||\n (s.heading !== '' && m.name !== '' && mentionsName(s.heading, m.name)) ||\n ((m.kind === 'base' || !m.kind) && /how to play|about the game/i.test(s.heading)),\n );\n}\n\n/** The minimum resolved prose (chars) a mode's section must carry to count as an\n * actual explanation — a heading with a one-liner underneath is not \"explained\". */\nconst MIN_SECTION_PROSE = 40;\n\n/**\n * Audit the rules blocks against the declared game facts. Pure + never-throw.\n * Findings come back most severe first (`required`, then `recommended`); an empty\n * array means the rules declare everything the game's configuration demands.\n *\n * `opts.resolve` maps each collected string BEFORE the text heuristics run — pass\n * the same translate-and-interpolate the renderer uses (`(s) => ui.t(s, factsVars(...))`)\n * so localized copy and `{{rtp.base}}`-style tokens are audited AS RENDERED: a rules\n * text that states its RTP via the token is, by construction, always correct.\n */\nexport function auditRules(\n facts: GameFacts | undefined,\n rules: BlockSpec[] | undefined,\n opts: { resolve?: (s: string) => string } = {},\n): RulesAuditIssue[] {\n const out: RulesAuditIssue[] = [];\n try {\n const scan = scanBlocks(rules, opts.resolve);\n const add = (level: RulesAuditIssue['level'], code: string, topic: string, message: string): void => {\n out.push({ level, code, topic, message });\n };\n const covered = (topic: string): boolean => scan.covers.has(topic);\n\n for (const m of facts?.modes ?? []) {\n const nameIn = mentionsName(scan.text, m.name);\n // RTP — required for every mode.\n if (m.rtp == null) {\n add('required', 'facts-missing-rtp', `rtp:${m.id}`, `“${m.name}” declares no RTP — set facts.modes[].rtp so the rules can state it.`);\n } else if (!(scan.hasModeStats || covered(`rtp:${m.id}`) || (nameIn && mentionsRtp(scan.text, m.rtp)))) {\n add('required', 'rules-missing-rtp', `rtp:${m.id}`, `The RTP of “${m.name}” (${formatRtp(m.rtp)}) is not stated in the rules.`);\n }\n // Max win — required for every mode.\n if (m.maxWinX == null) {\n add('required', 'facts-missing-maxwin', `maxwin:${m.id}`, `“${m.name}” declares no max win — set facts.modes[].maxWinX so the rules can state it.`);\n } else if (!(scan.hasModeStats || covered(`maxwin:${m.id}`) || (nameIn && mentionsTimes(scan.text, m.maxWinX)))) {\n add('required', 'rules-missing-maxwin', `maxwin:${m.id}`, `The max win of “${m.name}” (${formatTimes(m.maxWinX)}) is not stated in the rules.`);\n }\n // EVERY declared mode — the base game and each bonus/buy/boost — must be\n // explained EXPLICITLY in its OWN rules section: a heading naming the mode\n // (or blocks tagged `explains`) followed by real prose. A passing mention in\n // some shared paragraph does not count.\n if (!m.id) continue; // garbage-tolerant: an id-less mode can't be tracked\n const sec = findModeSection(scan.sections, m);\n if (!sec) {\n add('required', 'rules-missing-mode-section', `section:${m.id}`, `“${m.name}” has no rules section of its own — add a heading naming it (or tag its blocks with explains: \"${m.id}\") and explain how the mode plays.`);\n } else {\n if (sec.text.trim().length < MIN_SECTION_PROSE) {\n add('required', 'rules-mode-section-empty', `section:${m.id}`, `The “${m.name}” section has a heading but no real explanation — describe how the mode actually plays.`);\n }\n // A costed feature must state its price INSIDE its own section.\n if (m.kind && m.kind !== 'base' && m.cost != null && !(sec.covers.has(`cost:${m.id}`) || mentionsCost(sec.text, m.cost))) {\n add('required', 'rules-mode-missing-cost', `cost:${m.id}`, `State what “${m.name}” costs (${formatTimes(m.cost)} the bet — e.g. via {{cost.${m.id}}}) inside its own section.`);\n }\n }\n }\n\n // Free spins — highly recommended (only nag games that opted into facts at all).\n const fs = facts?.freeSpins;\n if (fs === undefined) {\n if (facts?.modes?.length) {\n add('recommended', 'facts-missing-freespins', 'freespins', 'Free-spins info is highly recommended: declare facts.freeSpins { count, retrigger } — or freeSpins: false if the game has none.');\n }\n } else if (fs !== false) {\n const fsIn = covered('freespins') || /free\\s*spins?/i.test(scan.text);\n if (!fsIn) {\n add('recommended', 'rules-missing-freespins', 'freespins', 'The rules never mention the free spins this game declares.');\n } else {\n if (fs.count != null && !covered('freespins:count') && !new RegExp(`\\\\b${fs.count}\\\\b[\\\\s\\\\S]{0,60}?spins?|spins?[\\\\s\\\\S]{0,60}?\\\\b${fs.count}\\\\b`, 'i').test(scan.text)) {\n add('recommended', 'rules-missing-fs-count', 'freespins:count', `State that the bonus awards exactly ${fs.count} free spins.`);\n }\n if (fs.retrigger != null && !covered('freespins:retrigger') && !/re-?trigger/i.test(scan.text)) {\n add('recommended', 'rules-missing-fs-retrigger', 'freespins:retrigger', `State that free spins ${fs.retrigger ? 'CAN' : 'CANNOT'} be retriggered.`);\n }\n }\n }\n\n // Legal disclaimer + a controls guide — recommended for every game.\n if (rules?.length && !scan.hasLegal && !/malfunction/i.test(scan.text)) {\n add('recommended', 'rules-missing-legal', 'legal', 'Add the platform legal disclaimer (a `legal` block).');\n }\n if (rules?.length && !covered('controls') && !/\\bcontrols?\\b/i.test(scan.headings)) {\n add('recommended', 'rules-missing-controls', 'controls', 'Describe every interactive control (a “Controls” section or covers: [\"controls\"]).');\n }\n\n out.sort((a, b) => (a.level === b.level ? 0 : a.level === 'required' ? -1 : 1));\n } catch {\n /* the audit must never break the menu */\n }\n return out;\n}\n","import { Signal, type Dispose } from './signal';\nimport { EventBus } from './events';\nimport { Control } from './control/Control';\nimport { SpinControl } from './controls/SpinControl';\nimport { ValueDisplay } from './controls/ValueDisplay';\nimport { ButtonControl } from './controls/ButtonControl';\nimport { SliderControl } from './controls/SliderControl';\nimport { PanelControl } from './controls/PanelControl';\nimport { TurboControl } from './controls/TurboControl';\nimport { StepperControl } from './controls/StepperControl';\nimport { AutoplayControl } from './controls/AutoplayControl';\nimport { ReadoutControl } from './controls/ReadoutControl';\nimport { defaultTheme, type Theme } from './theme/tokens';\nimport {\n computeScreen,\n defaultLayoutConfig,\n type LayoutConfig,\n type ScreenState,\n} from './layout/screen';\nimport { defaultLayout } from './layout/defaultLayouts';\nimport type { ControlSnapshot, OpenUIEvents } from './types';\nimport type { UISpec, BlockSpec } from './spec/types';\nimport { applyJurisdiction as applyJurisdictionTo, type JurisdictionConfig } from './spec/jurisdiction';\nimport {\n type NoticeAction,\n type NoticeOptions,\n type RgsErrorOptions,\n type RealityCheckOptions,\n RGS_ERROR_KEYS,\n DEFAULT_NOTICE_ACTION,\n errorBlocks,\n} from './notice';\nimport { DictionaryTranslator, type Translator } from './i18n/translator';\nimport { resolveCurrency } from './format/currency';\nimport { mergeFacts, type GameFacts } from './spec/facts';\n\nexport interface OpenUIOptions {\n theme?: Theme;\n layout?: LayoutConfig;\n /** i18n port. Default: an empty dictionary on locale 'en' (keys fall through). */\n translator?: Translator;\n /** Start with audio muted (the icon reflects it). Unmute restores the volumes. */\n startMuted?: boolean;\n}\n\n/**\n * The headless root: owns the control tree, the active theme, the responsive\n * screen state, and the typed event bus. This is the object the game holds and\n * \"talks to\" (Charter P1/P4). Renderer-agnostic — a renderer binds to it.\n */\nexport class OpenUI {\n readonly theme: Theme;\n readonly layoutConfig: LayoutConfig;\n readonly bus = new EventBus<OpenUIEvents>();\n readonly screen: Signal<ScreenState>;\n\n /** i18n translator (the port — no hard i18next dep, Charter B5/B8). */\n readonly translator: Translator;\n /** Current locale, observable — views re-render their text when it changes. */\n readonly locale: Signal<string>;\n\n /**\n * Ref-counted input lock. While the count is above zero, `locked` is true and\n * EVERY registered control reports not-interactable through its derived getter\n * (Charter P6/G7) — no per-button bookkeeping, no desync. Instance-scoped: the\n * gate each control receives in `register` reads THIS ui's `locked`.\n */\n readonly locked = new Signal<boolean>(false);\n private lockCount = 0;\n\n /** Every subscription this ui owns, torn down by `dispose()` (Charter P12). */\n private readonly disposers: Dispose[] = [];\n\n /** Control ids the spec marked hidden — still registered (so they stay\n * introspectable in `snapshot()`) but skipped by the renderer (Charter P10). */\n readonly hidden = new Set<string>();\n /** Ids hidden UNCONDITIONALLY (e.g. a jurisdiction `disabled*` flag): `setHidden`\n * refuses to re-show these, so a responsive resize can't undo a compliance hide. */\n readonly forceHidden = new Set<string>();\n\n /** Master mute (music+sfx), observable so an icon can reflect it. */\n readonly muted = new Signal<boolean>(false);\n /** Social / sweepstakes mode: swaps gambling wording (Bet/Buy → social terms) and,\n * paired with a social coin, shows GC/SC. Toggle with {@link setSocial}. */\n readonly social = new Signal<boolean>(false);\n /** Declarative blocks backing the menu-style notice/error modal. */\n readonly noticeBlocks = new Signal<BlockSpec[]>([]);\n /** Action buttons for the notice/error modal (a single dismiss when empty). */\n readonly noticeActions = new Signal<NoticeAction[]>([]);\n /** Whether the open notice is a BLOCKING/fatal modal — no backdrop/✕ dismiss and\n * the HUD is locked; it can be removed only in code (`hideNotice`). */\n readonly noticeBlocking = new Signal<boolean>(false);\n private noticeLockHeld = false;\n /** Cumulative amount staked this session (major units) — RTS 12 \"money spent\". */\n readonly totalStaked = new Signal<number>(0);\n /** Cumulative amount won this session (major units). */\n readonly totalWon = new Signal<number>(0);\n /** The Stake jurisdiction config currently applied (read-back for guards/queries). */\n jurisdiction: Readonly<JurisdictionConfig> = {};\n /** Replay mode (Stake `replay=true`): the HUD locks + a REPLAY badge shows. */\n readonly replay = new Signal<boolean>(false);\n /** Game name + version (shown in the menu footer; for support / certification). */\n gameInfo: { name?: string; version?: string } = {};\n /** Declared GAME FACTS (modes + RTP/max win, free spins, volatility, cap) — seeded\n * from `spec.facts`, extended at runtime via {@link declareFacts} (the buy-feature\n * modal declares its configured features automatically). Drives the `mode-stats`\n * rules block + the rules-completeness audit in the info menu. */\n readonly facts = new Signal<GameFacts>({});\n /** Minimum round duration (ms) from jurisdiction — stored for the GAME to enforce. */\n minimumRoundDuration = 0;\n /** Buy-feature confirm threshold, as a multiple of the base bet. A play (buy or\n * bet-mode activation) that costs STRICTLY MORE than this must show a confirm step\n * — Stake requires that bet modes above 2× never activate on a single click. `0`\n * (the default) = off. Set via `spec.buyFeature.confirmAboveCost` or a jurisdiction. */\n confirmBuyAboveCost = 0;\n /** When autoplay stops while the balance can no longer cover the next round —\n * whether the built-in RG enforcement stopped it, the game's own pre-check did, or\n * the player pressed Stop already broke — pop the SAME insufficient-funds modal a\n * manual spin shows (ERR_IPB) instead of ending silently. A normal stop with funds\n * in hand shows nothing. Default on; `spec.autoplay.insufficientFundsNotice: false`\n * opts out. */\n autoplayInsufficientNotice = true;\n private sessionNet = 0;\n private prevVolumes: { music: number; sfx: number } | null = null;\n\n /** The frozen UISpec `createUI` built this from, if any — authored = run = tested. */\n spec?: Readonly<UISpec>;\n\n /** Typed convenience handles for the controls. */\n readonly spin: SpinControl;\n readonly balance: ValueDisplay;\n readonly bet: ValueDisplay;\n /** Bonus \"total win\" readout — shown in the buy-feature slot during a bonus/free-\n * spins round (the renderer swaps it for the buy button). Same money logic as `bet`. */\n readonly totalWin: ValueDisplay;\n readonly settingsButton: ButtonControl;\n readonly settingsPanel: PanelControl;\n readonly musicSlider: SliderControl;\n readonly sfxSlider: SliderControl;\n readonly turbo: TurboControl;\n readonly autoplay: AutoplayControl;\n readonly bonusButton: ButtonControl;\n readonly betStepper: StepperControl;\n readonly betPlus: ButtonControl;\n readonly betMinus: ButtonControl;\n readonly fullscreenButton: ButtonControl;\n readonly muteButton: ButtonControl;\n /** Compliance display readouts — hidden until a jurisdiction reveals them. */\n readonly rtp: ReadoutControl;\n readonly netPosition: ReadoutControl;\n readonly sessionTimer: ReadoutControl;\n /** Menu-style notice/error modal (content set via `showNotice`). */\n readonly noticePanel: PanelControl;\n\n private readonly controls = new Map<string, Control>();\n\n constructor(opts: OpenUIOptions = {}) {\n this.theme = opts.theme ?? defaultTheme;\n this.layoutConfig = opts.layout ?? defaultLayoutConfig;\n this.screen = new Signal<ScreenState>(computeScreen(1920, 1080, this.layoutConfig));\n\n this.translator = opts.translator ?? new DictionaryTranslator({}, 'en');\n this.locale = new Signal<string>(this.translator.locale);\n this.disposers.push(\n this.translator.onChange((loc) => {\n if (this.locale.get() === loc) return;\n this.locale.set(loc);\n this.bus.emit('localeChanged', loc);\n }),\n );\n\n this.spin = new SpinControl({ layout: defaultLayout('spin') }, this.bus);\n\n this.balance = new ValueDisplay({\n id: 'balance',\n label: 'openui.balance', // i18n key → localizes + swaps in social mode\n layout: defaultLayout('balance'),\n currency: { code: 'USD', decimals: 2 },\n initial: 1000,\n });\n this.bet = new ValueDisplay({\n id: 'bet',\n label: 'openui.bet',\n layout: defaultLayout('bet'),\n currency: { code: 'USD', decimals: 2 },\n initial: 1,\n });\n // Bonus total-win readout — same look/money logic as bet (caption pill + rolling\n // value), parked in the buy-feature slot; the renderer shows it only in a bonus.\n this.totalWin = new ValueDisplay({\n id: 'total-win',\n label: 'openui.totalWin',\n layout: defaultLayout('total-win'),\n currency: { code: 'USD', decimals: 2 },\n initial: 0,\n });\n\n // settings flyout: a button that toggles a popover with sound sliders + a Rules button\n this.settingsButton = new ButtonControl(\n { id: 'settings', layout: defaultLayout('settings') },\n this.bus,\n );\n this.settingsPanel = new PanelControl(\n { id: 'settings-panel', variant: 'popover', layout: { anchor: 'bottom-right', offset: [-24, -470] } },\n this.bus,\n );\n this.musicSlider = new SliderControl({ id: 'music', label: 'Music', layout: { anchor: 'center' }, initial: 0.7 }, this.bus);\n this.sfxSlider = new SliderControl({ id: 'sfx', label: 'Sound', layout: { anchor: 'center' }, initial: 0.5 }, this.bus);\n\n // bottom-bar controls\n this.bonusButton = new ButtonControl({ id: 'bonus', layout: defaultLayout('bonus') }, this.bus);\n this.autoplay = new AutoplayControl(\n { id: 'autoplay', layout: defaultLayout('autoplay'), options: [5, 10, 25, 50, 100, Infinity] },\n this.bus,\n );\n this.turbo = new TurboControl({ id: 'turbo', layout: defaultLayout('turbo') }, this.bus);\n this.betMinus = new ButtonControl({ id: 'bet-minus', layout: defaultLayout('bet-minus') }, this.bus);\n this.betPlus = new ButtonControl({ id: 'bet-plus', layout: defaultLayout('bet-plus') }, this.bus);\n this.betStepper = new StepperControl({ id: 'bet-stepper', layout: { anchor: 'center' }, levels: [0.5, 1, 2, 5, 10, 20], index: 1 }, this.bus);\n\n // edge controls: master mute + fullscreen (icon buttons at the screen corner)\n // Figma \"default\": two prominent b&w round buttons in the top-right corner with a\n // comfortable edge margin (sound on the left, fullscreen on the right).\n this.muteButton = new ButtonControl({ id: 'mute', layout: defaultLayout('mute') }, this.bus);\n this.fullscreenButton = new ButtonControl({ id: 'fullscreen', layout: defaultLayout('fullscreen') }, this.bus);\n\n // compliance readouts — created hidden; a jurisdiction's display* flag reveals them\n // Figma \"default\" compliance block: three plain `Label: value` lines stacked in\n // the top-left corner (RTP · Session Time · Net).\n this.rtp = new ReadoutControl({ id: 'rtp', kind: 'percent', label: 'RTP', layout: defaultLayout('rtp') });\n this.sessionTimer = new ReadoutControl({ id: 'session-timer', kind: 'duration', label: 'Session Time', layout: defaultLayout('session-timer') });\n this.netPosition = new ReadoutControl({ id: 'net-position', kind: 'currency', label: 'Net', currency: { code: 'USD', symbol: '$', display: 'symbol', position: 'prefix', decimals: 2 }, layout: defaultLayout('net-position') });\n\n // notice / error modal (rendered in the unified menu style)\n this.noticePanel = new PanelControl({ id: 'notice-panel', variant: 'modal', layout: { anchor: 'center' } }, this.bus);\n\n for (const c of [\n this.spin,\n this.balance,\n this.bet,\n this.totalWin,\n this.settingsButton,\n this.settingsPanel,\n this.musicSlider,\n this.sfxSlider,\n this.bonusButton,\n this.autoplay,\n this.turbo,\n this.betMinus,\n this.betPlus,\n this.betStepper,\n this.muteButton,\n this.fullscreenButton,\n this.rtp,\n this.netPosition,\n this.sessionTimer,\n this.noticePanel,\n ]) {\n this.register(c);\n }\n\n // compliance readouts start hidden — applyJurisdiction reveals the mandated ones\n this.hidden.add('rtp');\n this.hidden.add('net-position');\n this.hidden.add('session-timer');\n // The buy/bonus button is hidden until a host configures a buy feature (reveal it\n // with `controls.bonus.hidden = false` or `ui.setHidden('bonus', false)`) — so a\n // game with nothing to buy never shows a stray, purposeless button.\n this.hidden.add('bonus');\n\n // the library owns this navigation (a biased, stateful UI)\n this.bus.on('buttonActivated', ({ id }) => {\n if (id === 'settings') this.settingsPanel.toggle();\n else if (id === 'bet-plus') {\n this.betStepper.inc();\n } else if (id === 'bet-minus') {\n this.betStepper.dec();\n } else if (id === 'mute') {\n this.toggleMute();\n }\n });\n\n // bet stepper drives the bet value display + keeps +/- enabled within range\n this.bus.on('valueChanged', ({ id, value }) => {\n if (id === 'bet-stepper') this.bet.set(value);\n });\n const syncStepperButtons = (): void => {\n this.betStepper.canInc ? this.betPlus.enable() : this.betPlus.disable();\n this.betStepper.canDec ? this.betMinus.enable() : this.betMinus.disable();\n };\n this.disposers.push(this.betStepper.index.subscribe(syncStepperButtons));\n this.bet.set(this.betStepper.value);\n syncStepperButtons();\n\n // Autoplay that stops with the balance unable to cover the next round surfaces the\n // SAME insufficient-funds modal a manual spin shows — never a silent end. Guarded\n // against stomping a notice that is already open (e.g. `showRgsError` for another\n // code stops autoplay first, then presents its own message — that one must win).\n this.disposers.push(\n this.bus.on('autoplayStopped', () => {\n if (!this.autoplayInsufficientNotice || this.replay.get()) return;\n if (this.noticePanel.isOpen) return;\n if (this.balance.get() < this.bet.get()) this.showRgsError('ERR_IPB');\n }),\n );\n\n // When the notice/error modal closes, release a blocking lock + announce it.\n this.disposers.push(\n this.noticePanel.state.subscribe(() => {\n if (this.noticePanel.isOpen) return;\n if (this.noticeLockHeld) {\n this.unlock();\n this.noticeLockHeld = false;\n }\n if (this.noticeBlocking.get()) this.noticeBlocking.set(false);\n this.bus.emit('noticeDismissed', undefined);\n }),\n );\n\n if (opts.startMuted) this.setMuted(true);\n }\n\n register(control: Control): void {\n this.controls.set(control.id, control);\n control.gate = () => !this.locked.get();\n this.disposers.push(\n control.onTransition((_t, to, from) => {\n this.bus.emit('stateChanged', { id: control.id, from, to });\n }),\n );\n }\n\n control(id: string): Control | undefined {\n return this.controls.get(id);\n }\n\n all(): Control[] {\n return [...this.controls.values()];\n }\n\n /** Renderer calls this on resize; recomputes breakpoint + fit scale. */\n setScreen(width: number, height: number): void {\n this.screen.set(computeScreen(width, height, this.layoutConfig));\n }\n\n /**\n * Hide or show a control at runtime and tell the renderer (Charter P10). The\n * control stays registered — still in `snapshot()` — but the view is not drawn.\n * Used by the responsive layer to drop controls on small screens.\n */\n setHidden(id: string, hidden: boolean): void {\n if (!hidden && this.forceHidden.has(id)) return; // jurisdiction-locked: can't re-show\n const was = this.hidden.has(id);\n if (hidden === was) return;\n if (hidden) this.hidden.add(id);\n else this.hidden.delete(id);\n this.bus.emit('visibilityChanged', { id, hidden });\n }\n\n /** Push the ref-counted input lock (e.g. for the duration of a spin round). */\n lock(): void {\n this.lockCount += 1;\n if (this.lockCount === 1) this.locked.set(true);\n }\n\n /** Pop the lock; the HUD becomes interactable again only at zero. */\n unlock(): void {\n if (this.lockCount === 0) return;\n this.lockCount -= 1;\n if (this.lockCount === 0) this.locked.set(false);\n }\n\n /** Toggle master mute (music + sfx). */\n toggleMute(): void {\n this.setMuted(!this.muted.get());\n }\n\n /** Mute/unmute music+sfx, remembering the levels to restore on unmute. */\n setMuted(m: boolean): void {\n if (m === this.muted.get()) return;\n if (m) {\n this.prevVolumes = { music: this.musicSlider.value.get(), sfx: this.sfxSlider.value.get() };\n this.musicSlider.setNormalized(0);\n this.sfxSlider.setNormalized(0);\n } else if (this.prevVolumes) {\n this.musicSlider.setNormalized(this.prevVolumes.music);\n this.sfxSlider.setNormalized(this.prevVolumes.sfx);\n this.prevVolumes = null;\n }\n this.muted.set(m);\n }\n\n /**\n * Report one completed round (major units): updates the net-position readout and,\n * while autoplay is running, advances its count + enforces its RG loss/single-win\n * limits. One feed point powers both `displayNetPosition` and the autoplay stops.\n */\n reportRound(win: number, bet: number): void {\n if (!Number.isFinite(win) || !Number.isFinite(bet)) return;\n this.sessionNet += win - bet;\n this.netPosition.set(this.sessionNet);\n this.totalStaked.set(this.totalStaked.get() + bet);\n this.totalWon.set(this.totalWon.get() + win);\n if (this.autoplay.isActive) {\n this.autoplay.reportResult(win, bet);\n // auto-stop autoplay when the next round is no longer affordable (RG)\n if (this.autoplay.isActive && this.balance.get() < this.bet.get()) this.autoplay.stop();\n }\n }\n\n /** Merge more game facts into {@link facts} (modes merge by id; defined incoming\n * fields win). The info menu re-audits + re-renders its rules automatically. */\n declareFacts(add: GameFacts): void {\n if (!add || typeof add !== 'object') return;\n this.facts.set(mergeFacts(this.facts.get(), add));\n }\n\n /** Reset the running session net + aggregates + timer (e.g. on a fresh session). */\n resetSession(): void {\n this.sessionNet = 0;\n this.netPosition.set(0);\n this.totalStaked.set(0);\n this.totalWon.set(0);\n this.sessionTimer.reset();\n }\n\n /** Show the menu-style notice modal: declarative blocks + optional action buttons.\n * Every string (block text + button labels) runs through `ui.t`, so pass exact\n * literals OR your own i18n keys. Omit `actions` → a single dismiss button. */\n showNotice(blocks: BlockSpec[], actions?: NoticeAction[], opts: { blocking?: boolean } = {}): void {\n const blocking = !!opts.blocking;\n this.noticeBlocks.set(Array.isArray(blocks) ? blocks : []);\n // A blocking modal with no actions is dismissable ONLY in code (no default OK).\n this.noticeActions.set(actions && actions.length ? actions : blocking ? [] : [DEFAULT_NOTICE_ACTION]);\n this.noticeBlocking.set(blocking);\n // Keep the blocking lock in step even if one notice REPLACES another while open\n // (openPanel is idempotent, so the close-subscription wouldn't fire to release it).\n if (blocking && !this.noticeLockHeld) {\n this.lock();\n this.noticeLockHeld = true;\n } else if (!blocking && this.noticeLockHeld) {\n this.unlock();\n this.noticeLockHeld = false;\n }\n this.noticePanel.openPanel();\n this.bus.emit('noticeShown', { blocking });\n }\n\n /** Show a simple error/notice: a title + a tone-coloured message. `message` and\n * `opts.title` are literal-or-key (localized via `ui.t`); `opts.actions` adds\n * custom buttons (e.g. a \"Reload\"). `opts.blocking` → a fatal modal (locks the\n * HUD, no backdrop/✕ dismiss; removable only via `hideNotice`). */\n showError(message: string, opts: NoticeOptions = {}): void {\n this.showNotice(errorBlocks(message, opts.title ?? 'openui.error', opts.tone ?? 'warning'), opts.actions, {\n blocking: opts.blocking,\n });\n }\n\n /** Show a FATAL error: a blocking modal that locks the HUD and can be removed only\n * in code (`hideNotice`) — for unrecoverable RGS states. Pass `actions` (e.g. a\n * \"Reload\" that reloads the page) for the only way out. */\n showFatal(message: string, opts: NoticeOptions = {}): void {\n this.showError(message, { ...opts, blocking: true });\n }\n\n /** Show the default (localizable, overridable) message for an RGS status code.\n * Override the exact text per call via `opts.title` / `opts.message`. Stops an\n * active autoplay by default (`opts.stopAutoplay = false` to keep it). Pass\n * `opts.blocking` for unrecoverable codes (session expiry, maintenance). */\n showRgsError(code: string, opts: RgsErrorOptions = {}): void {\n const def = RGS_ERROR_KEYS[code] ?? RGS_ERROR_KEYS.ERR_GEN!;\n if (opts.stopAutoplay !== false && this.autoplay.isActive) this.autoplay.stop();\n this.showError(opts.message ?? def.message, {\n title: opts.title ?? def.title,\n tone: opts.tone ?? 'warning',\n actions: opts.actions,\n blocking: opts.blocking,\n });\n }\n\n /** Close the notice / error modal. */\n hideNotice(): void {\n this.noticePanel.closePanel();\n }\n\n /** Enter/leave replay mode (Stake `replay=true`) — locks the HUD so no real bet is\n * placed; the renderer shows a REPLAY badge while it's on. */\n setReplay(on: boolean): void {\n if (on === this.replay.get()) return;\n this.replay.set(on);\n if (on) this.lock();\n else this.unlock();\n }\n\n /** Apply a Stake Engine `jurisdiction` config to the live HUD (whole switchboard).\n * The merged config is stored for `isDisabled()` read-back. */\n applyJurisdiction(jur: JurisdictionConfig): void {\n this.jurisdiction = Object.freeze({ ...this.jurisdiction, ...jur });\n applyJurisdictionTo(this, jur);\n }\n\n /** Tear down every subscription and control this ui created (Charter P12). */\n dispose(): void {\n for (const d of this.disposers) d();\n this.disposers.length = 0;\n for (const c of this.controls.values()) c.dispose();\n this.controls.clear();\n }\n\n /**\n * Switch language. Drives the translator (if it can self-switch) and emits\n * `localeChanged`; controls' views, subscribed to `locale`, re-render their text.\n */\n setLocale(next: string): void {\n // The translator owns locale state; its onChange handler (wired in the\n // constructor) updates `locale` and emits localeChanged. No-op for same locale.\n this.translator.setLocale(next);\n }\n\n /** Translate a key (or pass plain text through) via the active translator. Social\n * wording is resolved by the translator from a SEPARATE social dictionary (see\n * `setSocial`), so gambling and social copy can never be mixed by accident. */\n t(key: string, vars?: Record<string, string | number>): string {\n return this.translator.t(key, vars);\n }\n\n /**\n * Turn social / sweepstakes mode on or off (one switch). Flips the translator to\n * its SEPARATE social dictionary (Bet→Play, Buy feature→Play bonus, etc.) and,\n * when a `coin` is given (e.g. `'GC'`/`'SC'`), shows balance/bet/net in that coin.\n * Wording re-renders live. Social copy lives in `locale.socialMessages` — kept\n * apart from your normal `locale.messages` by design.\n */\n setSocial(on: boolean, coin?: string): void {\n if (on !== this.social.get()) {\n this.social.set(on);\n this.translator.setSocial?.(on);\n this.locale.update(() => {}); // nudge text views (they subscribe to `locale`) to re-translate\n }\n if (coin) {\n const cur = resolveCurrency(coin);\n this.balance.setCurrency(cur);\n this.bet.setCurrency(cur);\n this.netPosition.setCurrency(cur);\n }\n }\n\n /** Read-back: did the applied jurisdiction disable this feature? (real guard, not\n * just a hide — `confirmBuy`/autoplay entry points consult this). */\n isDisabled(feature: 'autoplay' | 'buyFeature' | 'turbo' | 'fullscreen' | 'slamstop' | 'spacebar'): boolean {\n const j = this.jurisdiction;\n return (\n (feature === 'autoplay' && !!j.disabledAutoplay) ||\n (feature === 'buyFeature' && !!j.disabledBuyFeature) ||\n (feature === 'turbo' && !!j.disabledTurbo) ||\n (feature === 'fullscreen' && !!j.disabledFullscreen) ||\n (feature === 'slamstop' && !!j.disabledSlamstop) ||\n (feature === 'spacebar' && !!j.disabledSpacebar)\n );\n }\n\n /** True when a buy / bet-mode activation of `cost`× the base bet must be confirmed\n * before it commits (Stake: no one-click activation above `confirmBuyAboveCost`×).\n * Always false when the threshold is 0/unset or `cost` isn't a finite number. */\n shouldConfirmBuy(cost: number): boolean {\n const t = this.confirmBuyAboveCost;\n return t > 0 && Number.isFinite(cost) && cost > t;\n }\n\n /**\n * Start a reality-check reminder (RTS 13). Every `everyMinutes` (WALL-CLOCK, so a\n * backgrounded tab can't cheat it) it emits a `realityCheck` event, stops autoplay,\n * and — unless `showModal: false` — shows an acknowledge modal. You provide only\n * the interval + (optional) title/message text; `{{minutes}}`/`{{spent}}`/`{{won}}`\n * are interpolated. Returns a disposer (also torn down by `dispose()`).\n */\n startRealityCheck(opts: RealityCheckOptions): Dispose {\n const everyMs = Math.max(1, opts.everyMinutes) * 60_000;\n let last = Date.now();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const tick = (): void => {\n // don't stack on an already-open modal — re-check shortly\n if (this.noticePanel.isOpen) {\n timer = setTimeout(tick, 1000);\n return;\n }\n const elapsedMs = Date.now() - last;\n last = Date.now();\n this.fireRealityCheck(opts, elapsedMs);\n timer = setTimeout(tick, everyMs);\n };\n timer = setTimeout(tick, everyMs);\n const dispose = (): void => {\n if (timer) clearTimeout(timer);\n timer = undefined;\n };\n this.disposers.push(dispose);\n return dispose;\n }\n\n /** Fire one reality check now: emit the event (+ session totals), stop autoplay,\n * and show the modal unless `showModal:false`. Exposed for manual triggers / tests. */\n fireRealityCheck(opts: RealityCheckOptions, elapsedMs = 0): void {\n const minutes = Math.max(1, Math.round(opts.everyMinutes));\n const totalStaked = this.totalStaked.get();\n const totalWon = this.totalWon.get();\n this.bus.emit('realityCheck', { minutes, elapsedMs, totalStaked, totalWon });\n if (this.autoplay.isActive) this.autoplay.stop();\n if (opts.showModal === false) return;\n const vars = { minutes, spent: totalStaked, won: totalWon };\n this.showNotice(\n [\n { kind: 'heading', id: 'rc-title', text: this.t(opts.title ?? 'openui.realityCheck.title', vars) },\n { kind: 'text', id: 'rc-body', text: this.t(opts.message ?? 'openui.realityCheck.message', vars) },\n ],\n opts.actions ?? [{ label: 'openui.continue', variant: 'primary' }],\n );\n }\n\n on<K extends keyof OpenUIEvents>(type: K, fn: (payload: OpenUIEvents[K]) => void): Dispose {\n return this.bus.on(type, fn);\n }\n\n /** Serializable snapshot for the introspection / e2e API (Charter P10). */\n snapshot(): ControlSnapshot[] {\n return this.all().map((c) => {\n const { bounds, animating } = c.inspect();\n return {\n id: c.id,\n role: c.role,\n state: c.current,\n interactable: c.interactable,\n bounds,\n animating,\n };\n });\n }\n}\n","/**\n * The responsive layer: re-apply per-device / per-orientation control overrides\n * every time the screen bucket changes. Pure assembly over the existing layout\n * machinery — it only ever sets `control.layout` and toggles `ui.setHidden`, both\n * of which the views already react to (Charter P6/P10). No new rendering concepts.\n */\nimport type { OpenUI } from '../OpenUI';\nimport type { Dispose } from '../signal';\nimport type { LayoutSpec } from '../layout/anchor';\nimport type { ScreenState } from '../layout/screen';\nimport type { ResponsiveKey, ResponsiveOverride } from './types';\n\ntype Responsive = Partial<Record<ResponsiveKey, ResponsiveOverride>>;\n\ninterface Base {\n layout: LayoutSpec;\n hidden: boolean;\n}\n\nfunction cloneLayout(l: LayoutSpec): LayoutSpec {\n return { anchor: l.anchor, offset: l.offset ? [l.offset[0], l.offset[1]] : undefined, scale: l.scale, rotation: l.rotation };\n}\n\n/** The buckets that apply to a screen, least → most specific (size wins over orientation). */\nfunction activeKeys(screen: ScreenState): ResponsiveKey[] {\n return [screen.orientation, screen.breakpoint];\n}\n\n/**\n * Install responsive overrides. Snapshots each referenced control's CURRENT layout\n * + hidden state as the \"base\" (so callers must apply static `controls` overrides\n * first), then on every screen change re-derives base → orientation → size and\n * applies it. Returns a disposer. Runs once immediately for the current screen.\n */\nexport function installResponsive(ui: OpenUI, responsive: Responsive): Dispose {\n // Every control id mentioned in any bucket.\n const ids = new Set<string>();\n for (const key of Object.keys(responsive) as ResponsiveKey[]) {\n const ov = responsive[key];\n if (ov?.controls) for (const id of Object.keys(ov.controls)) ids.add(id);\n }\n if (!ids.size) return () => {};\n\n // Snapshot the base layout + visibility for each (the post-`controls` truth).\n const base = new Map<string, Base>();\n for (const id of ids) {\n const c = ui.control(id);\n if (!c) continue;\n base.set(id, { layout: cloneLayout(c.layout), hidden: ui.hidden.has(id) });\n }\n\n let applying = false;\n const apply = (screen: ScreenState): void => {\n applying = true;\n try {\n const keys = activeKeys(screen);\n for (const [id, b] of base) {\n const c = ui.control(id);\n if (!c) continue;\n let layout = b.layout;\n let hidden = b.hidden;\n for (const key of keys) {\n const ov = responsive[key]?.controls?.[id];\n if (!ov) continue;\n if (ov.layout) layout = ov.layout;\n if (ov.hidden != null) hidden = ov.hidden;\n }\n c.layout = cloneLayout(layout);\n ui.setHidden(id, hidden);\n }\n } finally {\n applying = false;\n }\n };\n\n // A visibility change we did NOT cause is the base truth moving at runtime —\n // e.g. `applyJurisdiction` revealing the RTP/session readouts after mount, or a\n // host calling `setHidden` — so fold it into the base instead of reverting it\n // on the next screen change.\n const offVis = ui.on('visibilityChanged', ({ id, hidden }) => {\n if (applying) return;\n const b = base.get(id);\n if (b) b.hidden = hidden;\n });\n\n // Subscribe in createUI (before the renderer mounts) so this runs BEFORE the\n // views' own screen subscribers — they then read the freshly-set layouts.\n const off = ui.screen.subscribe(apply);\n apply(ui.screen.get());\n return () => {\n off();\n offVis();\n };\n}\n","/**\n * Social-mode FORBIDDEN-PHRASE checker (Charter B8/P11). Stake US social/sweepstakes\n * jurisdiction restricts gambling wording; a game must not surface \"bet\", \"pay(table)\",\n * \"funds\", \"cash\", etc. anywhere in its copy. This scans the ENGLISH strings a game\n * ships (menu blocks, rules, section titles, control labels/hints, the `en` dictionary,\n * the game name) and reports every restricted phrase with a compliant replacement, so\n * the classic \"we shipped a *paytable* while `pay` is banned\" slips through no longer.\n *\n * It's a lint, not a gate — never throws; `createUI` runs it automatically in social\n * mode and forwards findings to `HostHooks.onDataIssue` (+ a console warning), and a\n * game's own test can call {@link checkSocialPhrases} directly.\n *\n * See Stake's \"Jurisdiction Requirements → forbidden phrases\" for the authoritative\n * list; this covers the common roots and their recommended replacements.\n */\nimport type { UISpec, BlockSpec } from './types';\nimport { openuiSocialDefaults } from '../i18n/translator';\n\nexport interface ForbiddenMatch {\n /** The restricted root that matched (\"pay*\", \"bet\", \"funds\", …). */\n term: string;\n /** The recommended compliant replacement. */\n replacement: string;\n}\nexport interface SocialPhraseIssue {\n /** Where the copy lives (e.g. `menu.rules[3]`, `locale.en[\"Paytable\"]`). */\n source: string;\n /** The offending string. */\n text: string;\n /** Every restricted phrase found in it. */\n matches: ForbiddenMatch[];\n}\n\n// Restricted roots → compliant replacements. Case-insensitive. Anchored so a bare root\n// can't over-flag (\"bet\" must not hit \"between\"/\"better\"); `\\w*` roots (pay*/cash*/…)\n// deliberately catch compounds like \"paytable\"/\"cashout\" — the whole point here.\nconst FORBIDDEN: ReadonlyArray<{ re: RegExp; term: string; replacement: string }> = [\n { re: /\\bpay\\w*/i, term: 'pay*', replacement: 'prize / award (e.g. \"paytable\" → \"prizes\")' },\n { re: /\\bpayout\\w*/i, term: 'payout', replacement: 'award' },\n { re: /\\bbets?\\b|\\bbetting\\b/i, term: 'bet', replacement: 'play' },\n { re: /\\bwager\\w*/i, term: 'wager', replacement: 'play' },\n { re: /\\bgambl\\w*/i, term: 'gamble', replacement: 'play' },\n { re: /\\bcash\\w*/i, term: 'cash', replacement: 'coins' },\n { re: /\\bfunds?\\b/i, term: 'funds', replacement: 'coins / balance' },\n { re: /\\bmoney\\b/i, term: 'money', replacement: 'coins' },\n { re: /\\bdeposit\\w*/i, term: 'deposit', replacement: 'purchase' },\n { re: /\\bwithdraw\\w*/i, term: 'withdraw', replacement: 'redeem' },\n { re: /\\bcredits?\\b/i, term: 'credit', replacement: 'coins / balance' },\n { re: /\\bwinnings?\\b/i, term: 'winnings', replacement: 'prizes' },\n { re: /\\bjackpots?\\b/i, term: 'jackpot', replacement: 'grand prize' },\n { re: /\\breal[-\\s]?money\\b/i, term: 'real money', replacement: 'coins' },\n];\n\n/** Every restricted phrase in `text` (empty when clean). Pure + total. */\nexport function findForbiddenPhrases(text: string): ForbiddenMatch[] {\n if (typeof text !== 'string' || !text) return [];\n const seen = new Set<string>();\n const out: ForbiddenMatch[] = [];\n for (const r of FORBIDDEN) {\n if (r.re.test(text) && !seen.has(r.term)) {\n seen.add(r.term);\n out.push({ term: r.term, replacement: r.replacement });\n }\n }\n return out;\n}\n\n/** A collected string. `text` is the base English (what renders with no social\n * override); `key` is the i18n key used to look up a social override — it defaults\n * to `text`, since a game's menu/rules copy doubles as its own key. */\ntype Entry = { source: string; text: string; key?: string };\n\nfunction walkBlock(b: BlockSpec, src: string, out: Entry[]): void {\n const add = (t: unknown, s: string = src): void => {\n if (typeof t === 'string' && t) out.push({ source: s, text: t });\n };\n const anyB = b as Record<string, unknown>;\n switch (b.kind) {\n case 'text':\n case 'heading':\n case 'subheading':\n case 'legal':\n add(b.text);\n break;\n case 'callout':\n add(b.title);\n add(b.text);\n break;\n case 'media':\n add(b.title);\n add(b.text);\n break;\n case 'slider':\n case 'toggle':\n case 'button':\n case 'select':\n case 'stepper':\n case 'value':\n add(anyB.label);\n add(anyB.hint);\n break;\n case 'steps':\n b.items.forEach((s, i) => add(s, `${src}.items[${i}]`));\n break;\n case 'table':\n (b.columns ?? []).forEach((c) => add(c));\n b.rows.forEach((row) => row.forEach((c) => add(c)));\n break;\n case 'paytable':\n b.rows.forEach((r) => {\n add(r.symbol);\n add(r.payouts);\n });\n break;\n case 'cards':\n b.items.forEach((it) => {\n add(it.title);\n add(it.text);\n });\n break;\n case 'stat-grid':\n b.items.forEach((it) => {\n add(it.label);\n add(it.value);\n });\n break;\n case 'mode-stats':\n // generated labels (\"RTP · <name>\" / \"Max win · <name>\") resolve through the\n // social dictionary at render; only host-supplied extras carry static copy.\n (b.extras ?? []).forEach((it) => {\n add(it.label);\n add(it.value);\n });\n break;\n case 'group':\n add(b.title);\n b.children.forEach((c, i) => walkBlock(c, `${src}.children[${i}]`, out));\n break;\n default:\n break;\n }\n}\n\n/** Collect every English string a spec ships (menu/rules blocks, titles, labels+hints,\n * game name, the `en` dictionary) with a source path — the input to {@link checkSocialPhrases}. */\nexport function collectSocialCopy(spec: UISpec): Entry[] {\n const out: Entry[] = [];\n const menu = spec.menu;\n if (menu) {\n const sections: Array<[string, BlockSpec[] | undefined]> = [\n ['settings', menu.settings],\n ['paytable', menu.paytable],\n ['rules', menu.rules],\n ];\n for (const [sec, blocks] of sections) (blocks ?? []).forEach((b, i) => walkBlock(b, `menu.${sec}[${i}]`, out));\n if (menu.titles) for (const [k, v] of Object.entries(menu.titles)) if (v) out.push({ source: `menu.titles.${k}`, text: v });\n if (menu.banner?.src) {\n /* image only, no copy */\n }\n }\n (spec.rules ?? []).forEach((b, i) => walkBlock(b, `rules[${i}]`, out));\n if (spec.game?.name) out.push({ source: 'game.name', text: spec.game.name });\n const en = spec.locale?.messages?.en;\n // The en dict is a translation SOURCE: in social mode the KEY resolves through the\n // social dictionary, so carry `key: k` and check what actually renders for that key.\n if (en) for (const [k, v] of Object.entries(en)) if (typeof v === 'string') out.push({ source: `locale.en[${JSON.stringify(k)}]`, text: v, key: k });\n return out;\n}\n\n/**\n * Scan a spec's English copy AS IT RENDERS IN SOCIAL MODE and return every restricted\n * phrase. Each collected string is first resolved through the social dictionary\n * (`locale.socialMessages.en` → built-in `openuiSocialDefaults` → the base text) —\n * exactly like the translator does — so a game that already swaps \"bet\"/\"pay(table)\"\n * for compliant wording in social mode is NOT flagged, while a phrase with NO social\n * override (the classic slipped-through \"paytable\") IS. English by design: the check\n * targets the base `en` copy that every jurisdiction review starts from.\n */\nexport function checkSocialPhrases(spec: UISpec): SocialPhraseIssue[] {\n const socialEn = spec.locale?.socialMessages?.en ?? {};\n const render = (e: Entry): string => socialEn[e.key ?? e.text] ?? openuiSocialDefaults[e.key ?? e.text] ?? e.text;\n const issues: SocialPhraseIssue[] = [];\n for (const e of collectSocialCopy(spec)) {\n const text = render(e);\n const matches = findForbiddenPhrases(text);\n if (matches.length) issues.push({ source: e.source, text, matches });\n }\n return issues;\n}\n","/**\n * createUI(spec) — assemble a complete, configured OpenUI from one JSON UISpec,\n * over the EXISTING reference HUD (Charter P1/P4/B9). Zero-arg `createUI()`\n * reproduces today's 16-control HUD. Pure assembly: validate → apply overrides →\n * wire the ref-counted spin lock → freeze the spec onto `ui.spec`.\n */\nimport { OpenUI } from '../OpenUI';\nimport { ValueDisplay } from '../controls/ValueDisplay';\nimport { resolveTheme } from '../theme/presets';\nimport { DictionaryTranslator } from '../i18n/translator';\nimport { validateSpec } from './validateSpec';\nimport { installResponsive } from './responsive';\nimport { resolveCurrency } from '../format/currency';\nimport { portraitDefaultLayouts } from '../layout/defaultLayouts';\nimport { checkSocialPhrases } from './socialPhrases';\nimport type { UISpec, HostHooks, TurboSpec, ResponsiveOverride } from './types';\nimport type { OpenUIEvents } from '../types';\n\n/** Resolve the turbo `modes` config (`2`/`3` presets or explicit names) to a ladder. */\nexport function resolveTurboModes(modes: TurboSpec['modes']): string[] {\n if (Array.isArray(modes)) return modes.length ? modes : ['off', 'on'];\n if (modes === 3) return ['off', 'turbo', 'super'];\n return ['off', 'on'];\n}\n\n/** Identity helper for typed authoring (IDE checks the shape); returns the spec. */\nexport function defineUI(spec: UISpec): UISpec {\n return spec;\n}\n\nconst ANALYTICS_EVENTS = [\n 'stateChanged',\n 'buttonActivated',\n 'valueChanged',\n 'toggled',\n 'optionSelected',\n 'panelToggled',\n 'autoplayStarted',\n 'autoplayStopped',\n] as const;\n\nexport function createUI(spec: UISpec = {}, hooks: HostHooks = {}): OpenUI {\n // Never-reject: report issues to the host, but still boot.\n const { issues } = validateSpec(spec);\n for (const issue of issues) hooks.onDataIssue?.(issue);\n\n const translator = spec.locale\n ? new DictionaryTranslator(spec.locale.messages, spec.locale.locale, spec.locale.socialMessages)\n : undefined;\n // Theme overrides are sanitized; any rejected value is reported, never fatal.\n const theme = resolveTheme(spec.theme, (i) => hooks.onDataIssue?.(i));\n const ui = new OpenUI({ theme, layout: spec.layout, translator, startMuted: spec.audio?.startMuted });\n\n if (spec.currency) {\n const cur = typeof spec.currency === 'string' ? resolveCurrency(spec.currency) : spec.currency;\n ui.balance.setCurrency(cur);\n ui.bet.setCurrency(cur);\n ui.totalWin.setCurrency(cur); // bonus total-win formats like the money displays\n ui.netPosition.setCurrency(cur);\n }\n\n // Social / sweepstakes mode: one switch swaps wording (+ a coin → GC/SC display).\n if (spec.social) {\n if (typeof spec.social === 'object') ui.setSocial(true, spec.social.coin);\n else ui.setSocial(true);\n }\n\n // In social mode, LINT the game's English copy for restricted gambling wording\n // (pay*/bet/funds/cash/…) and report each finding with a compliant replacement — so a\n // stray \"paytable\" can't ship. Never blocks boot; forwarded to onDataIssue + console.\n if (spec.social || spec.jurisdiction?.socialCasino) {\n const found = checkSocialPhrases(spec);\n for (const issue of found) {\n hooks.onDataIssue?.({\n level: 'warn',\n path: issue.source,\n code: 'social-forbidden-phrase',\n message: `Social mode restricted wording in \"${issue.text}\": ${issue.matches.map((m) => `“${m.term}” → ${m.replacement}`).join('; ')}`,\n });\n }\n if (found.length && typeof console !== 'undefined') {\n console.warn(`[open-ui] social mode: ${found.length} string(s) contain restricted phrases (see onDataIssue). First: ${found[0]!.source} → \"${found[0]!.text}\"`);\n }\n }\n\n if (typeof spec.rtp === 'number') ui.rtp.set(spec.rtp);\n if (spec.game) ui.gameInfo = { name: spec.game.name, version: spec.game.version };\n if (spec.facts) ui.declareFacts(spec.facts);\n\n if (spec.betLadder?.levels?.length) {\n ui.betStepper.setLevels(spec.betLadder.levels, spec.betLadder.index ?? 0);\n ui.bet.set(ui.betStepper.value);\n }\n\n if (spec.autoplay?.options?.length) {\n ui.autoplay.setOptions(spec.autoplay.options);\n }\n if (spec.autoplay?.mode) {\n ui.autoplay.mode = spec.autoplay.mode;\n }\n if (spec.autoplay?.lossLimits) ui.autoplay.setLossLimitOptions(spec.autoplay.lossLimits);\n if (spec.autoplay?.winLimits) ui.autoplay.setWinLimitOptions(spec.autoplay.winLimits);\n if (spec.autoplay?.insufficientFundsNotice === false) ui.autoplayInsufficientNotice = false;\n\n // Turbo: 2-mode (off/on) or 3-mode (off/turbo/super), or an explicit ladder.\n if (spec.turbo) {\n ui.turbo.setModes(resolveTurboModes(spec.turbo.modes));\n if (spec.turbo.index != null) ui.turbo.setIndex(spec.turbo.index);\n }\n\n // Spin: single tap vs press-and-hold turbo.\n if (spec.spin?.press) {\n ui.spin.holdToSpin = spec.spin.press === 'hold-to-spin';\n }\n\n if (spec.controls) {\n for (const [id, ov] of Object.entries(spec.controls)) {\n const c = ui.control(id);\n if (!c) continue;\n if (ov.layout) c.layout = ov.layout;\n // `hidden` can hide OR re-show (e.g. reveal the buy button, hidden by default).\n if (ov.hidden != null) ui.setHidden(id, ov.hidden);\n const disable = (c as { disable?: () => void }).disable;\n if (ov.disabled && typeof disable === 'function') disable.call(c);\n if (c instanceof ValueDisplay) {\n if (ov.currency) c.setCurrency(ov.currency);\n if (ov.initial != null) c.set(ov.initial);\n if (ov.digits != null) c.setDigits(ov.digits);\n }\n }\n }\n\n // Buy-feature confirm threshold (explicit config) — set before jurisdiction so a\n // platform jurisdiction can tighten it, but the game's own value is the default.\n if (spec.buyFeature?.confirmAboveCost != null && Number.isFinite(spec.buyFeature.confirmAboveCost)) {\n ui.confirmBuyAboveCost = Math.max(0, spec.buyFeature.confirmAboveCost);\n }\n\n // Jurisdiction (the Stake Engine compliance switchboard) is applied BEFORE the\n // responsive layer snapshots its base, so a `disabled*` hide is part of that base\n // and survives every resize (it's force-hidden too, belt-and-braces).\n if (spec.jurisdiction) ui.applyJurisdiction(spec.jurisdiction); // ui.* stores the snapshot for isDisabled()\n\n // Responsive overrides layer on top of the static `controls` (snapshotted as the\n // base), re-applied on every resize. Installed here — before the renderer mounts\n // — so it runs first on each screen change and the views read fresh layouts.\n //\n // The library ships a BUILT-IN portrait bucket (the Figma \"Mobile DEF\" reflow;\n // the base layouts are the landscape \"Desk DEF\" frame) so the zero-config HUD is\n // right on phones AND desktops. It layers UNDER host overrides: a host's static\n // `controls.{id}.layout` wins everywhere, and a host's own `responsive.portrait`\n // entry wins per-control.\n const portraitControls: NonNullable<ResponsiveOverride['controls']> = {};\n for (const [id, layout] of Object.entries(portraitDefaultLayouts)) {\n if (spec.controls?.[id]?.layout) continue; // host laid it out statically — respect it\n portraitControls[id] = { layout };\n }\n Object.assign(portraitControls, spec.responsive?.portrait?.controls);\n installResponsive(ui, {\n ...spec.responsive,\n portrait: { ...spec.responsive?.portrait, controls: portraitControls },\n });\n\n // Ref-counted whole-HUD lock for the duration of a spin (Charter P6/G7). The\n // host drives spin state via `ui.spin.busy()`; this just brackets it.\n if (spec.lockDuringSpin !== false) {\n let wasSpinning = false;\n ui.spin.state.subscribe((s) => {\n const now = s === 'spinning';\n if (now && !wasSpinning) ui.lock();\n else if (!now && wasSpinning) ui.unlock();\n wasSpinning = now;\n });\n }\n\n // Reality-check reminder (RTS 13) — open-ui owns the wall-clock timer + event +\n // modal; the spec supplies only the cadence and (optional) text. Torn down by dispose().\n if (spec.realityCheck && spec.realityCheck.everyMinutes > 0) {\n ui.startRealityCheck(spec.realityCheck);\n }\n\n // A select control with this id switches the whole UI locale; the host still\n // owns any persistence via HostHooks (Charter B8) — the lib only re-renders.\n const localeSelectId = spec.localeSelectId ?? 'lang';\n ui.on('optionSelected', ({ id, value }) => {\n if (id === localeSelectId) ui.setLocale(value);\n });\n\n if (hooks.onAnalyticsEvent) {\n const forward = hooks.onAnalyticsEvent;\n for (const type of ANALYTICS_EVENTS) {\n ui.on(type, (payload) => forward(type, payload as OpenUIEvents[typeof type]));\n }\n }\n\n ui.spec = Object.freeze(spec);\n return ui;\n}\n","/**\n * The unified MENU: one scrollable surface opened by the ☰ button, composed of\n * three ordered sections — Settings (Music/Sound + a Language switch + your\n * extras), Paytable, then Rules. `composeMenu` is pure: it flattens a `MenuSpec`\n * into the ordered `BlockSpec[]` the renderer draws, injecting section headings.\n * Section text is localizable (it flows through `ui.t` in the view).\n */\nimport type { BlockSpec } from './types';\n\n/**\n * How the Settings section exposes sound:\n * - `'toggle'` — a single Sound on/off switch (mute).\n * - `'master'` — the Sound switch + one Volume slider (music + effects together).\n * - `'sliders'` — the Sound switch + separate **Music** and **Effects** sliders. (default)\n */\nexport type SoundControls = 'toggle' | 'master' | 'sliders';\n\nexport interface MenuSpec {\n /** A banner image shown at the very top of the menu (e.g. a themed title art). */\n banner?: { src: string; width?: number; height?: number };\n /** How sound is configured in Settings (toggle · master slider · music+effects). Default `'sliders'`. */\n sound?: SoundControls;\n /** Extra settings, appended after the built-in Music/Sound (+ Language). */\n settings?: BlockSpec[];\n /** Paytable section content (omit → no Paytable section). */\n paytable?: BlockSpec[];\n /** Rules section content (omit → no Rules section). */\n rules?: BlockSpec[];\n /** Override the section heading text (each is run through `ui.t`). */\n titles?: { settings?: string; paytable?: string; rules?: string };\n}\n\n// The English section titles double as their i18n keys (a game's dict localizes them).\n// \"Paytable\" is social-restricted → the social dictionary swaps it to \"Prizes\" (see\n// openuiSocialDefaults), so the heading is compliant in social mode without extra config.\nexport const DEFAULT_MENU_TITLES = { settings: 'Settings', paytable: 'Paytable', rules: 'Rules' } as const;\n\n/** Native names for the language switch; falls back to the upper-cased code.\n * Covers Stake Engine's locale set (ar de en es fr id ja ko pl pt ru tr vi zh fi hi). */\nexport const LOCALE_LABELS: Record<string, string> = {\n en: 'English', es: 'Español', pt: 'Português', de: 'Deutsch', fr: 'Français',\n ru: 'Русский', tr: 'Türkçe', zh: '中文', ja: '日本語', ar: 'العربية',\n pl: 'Polski', ko: '한국어', hi: 'हिन्दी', id: 'Bahasa Indonesia', vi: 'Tiếng Việt',\n fi: 'Suomi', it: 'Italiano', nl: 'Nederlands',\n};\n\nexport interface ComposeMenuOptions {\n /** Locale codes available — when 2+, a Language select is added to Settings. */\n locales?: string[];\n /** The select id that switches locale (must match createUI's localeSelectId). */\n localeSelectId?: string;\n /** Back-compat: a top-level `rules` array used when `menu.rules` is absent. */\n rulesFallback?: BlockSpec[];\n}\n\n/**\n * Compose the ordered menu blocks. The built-in Music/Sound sliders reuse the\n * real `music`/`sfx` controls (the view's reuse resolver wires them), so the menu\n * drives the actual volume — it doesn't shadow it.\n */\nexport function composeMenu(menu: MenuSpec | undefined, opts: ComposeMenuOptions = {}): BlockSpec[] {\n const titles = { ...DEFAULT_MENU_TITLES, ...menu?.titles };\n const out: BlockSpec[] = [];\n\n // ── Banner (optional themed title art) ──────────────────────────────────────\n if (menu?.banner?.src) {\n out.push({ kind: 'image', id: 'menu-banner', src: menu.banner.src, width: menu.banner.width, height: menu.banner.height });\n }\n\n // ── Settings ──────────────────────────────────────────────────────────────\n out.push({ kind: 'heading', id: 'menu-sec-settings', text: titles.settings });\n out.push({ kind: 'slider', id: 'music', label: 'Music' });\n out.push({ kind: 'slider', id: 'sfx', label: 'Sound' });\n const locales = opts.locales ?? [];\n if (locales.length >= 2) {\n out.push({\n kind: 'select',\n id: opts.localeSelectId ?? 'lang',\n label: 'Language',\n options: locales.map((code) => ({ value: code, label: LOCALE_LABELS[code] ?? code.toUpperCase() })),\n });\n }\n if (menu?.settings?.length) out.push(...menu.settings);\n\n // ── Paytable ──────────────────────────────────────────────────────────────\n if (menu?.paytable?.length) {\n out.push({ kind: 'heading', id: 'menu-sec-paytable', text: titles.paytable });\n out.push(...menu.paytable);\n }\n\n // ── Rules ─────────────────────────────────────────────────────────────────\n const rules = menu?.rules?.length ? menu.rules : opts.rulesFallback;\n if (rules?.length) {\n out.push({ kind: 'heading', id: 'menu-sec-rules', text: titles.rules });\n out.push(...rules);\n }\n\n return out;\n}\n","/**\n * The UNIVERSAL RULES DOCUMENT — one portable, editable JSON file that carries a\n * game's whole rules surface: the ordered block list, its i18next-compatible\n * per-locale messages (flat keys, `{{token}}` interpolation — use i18next with\n * `keySeparator: false` if you consume them elsewhere), the social/sweepstakes\n * overrides, and (optionally) the game facts it was authored against.\n *\n * Authoring convention: a block's `text` is an i18n KEY (or literal English —\n * a string is its own key, the house convention); `messages` supplies per-locale\n * copy; any string may use the `factsVars` tokens (`{{rtp.base}}`,\n * `{{maxWin.bonus}}`, `{{freeSpins.count}}`, …) which the info menu resolves from\n * the LIVE declared facts — so stated numbers can never drift from config.\n *\n * A game consumes the file with ONE call:\n *\n * import doc from './rules.doc.json';\n * const hud = mountHud(app, applyRulesDoc(spec, doc as RulesDoc));\n *\n * The stakeplate rules editor (`npx` runnable) reads/writes this exact format and\n * validates it against `validateSpec` + `auditRules` while you edit.\n */\nimport type { BlockSpec, UISpec } from './types';\nimport { mergeFacts, auditRules, factsVars, type GameFacts, type RulesAuditIssue } from './facts';\n\nexport interface RulesDoc {\n /** Format version — currently 1. */\n version: 1;\n /** The ordered rules blocks (the same modular `BlockSpec` palette the menu renders). */\n blocks: BlockSpec[];\n /** i18next-compatible flat resources per locale (string keys → copy; `{{token}}` ok). */\n messages?: Record<string, Record<string, string>>;\n /** Social / sweepstakes wording overrides, same shape, consulted only in social mode. */\n socialMessages?: Record<string, Record<string, string>>;\n /** The facts this document was authored against — merged into `spec.facts` (the\n * spec's own facts win), and used by editors/CI to run the audit stand-alone. */\n facts?: GameFacts;\n}\n\n/** Runtime shape check — never throws. A malformed doc reports false and is skipped. */\nexport function isRulesDoc(doc: unknown): doc is RulesDoc {\n if (!doc || typeof doc !== 'object') return false;\n const d = doc as Record<string, unknown>;\n return d.version === 1 && Array.isArray(d.blocks);\n}\n\nconst mergeLocaleMaps = (\n under: Record<string, Record<string, string>> | undefined,\n over: Record<string, Record<string, string>> | undefined,\n): Record<string, Record<string, string>> => {\n const out: Record<string, Record<string, string>> = {};\n for (const src of [under, over]) {\n for (const [loc, map] of Object.entries(src ?? {})) out[loc] = { ...out[loc], ...map };\n }\n return out;\n};\n\n/**\n * Fold a rules document into a UISpec (pure — returns a NEW spec): the doc's blocks\n * become `menu.rules`, its messages/socialMessages merge UNDER the spec's own\n * dictionaries (host copy wins on conflicts), and its facts merge under `spec.facts`.\n * A malformed doc returns the spec unchanged (never-reject, Charter P11).\n */\nexport function applyRulesDoc(spec: UISpec, doc: RulesDoc): UISpec {\n if (!isRulesDoc(doc)) return spec;\n const messages = mergeLocaleMaps(doc.messages, spec.locale?.messages);\n const socialMessages = mergeLocaleMaps(doc.socialMessages, spec.locale?.socialMessages);\n return {\n ...spec,\n menu: { ...spec.menu, rules: doc.blocks },\n locale: {\n locale: spec.locale?.locale ?? 'en',\n messages: Object.keys(messages).length ? messages : { en: {} },\n ...(Object.keys(socialMessages).length ? { socialMessages } : {}),\n },\n ...(doc.facts ? { facts: mergeFacts(doc.facts, spec.facts ?? {}) } : {}),\n };\n}\n\n/**\n * Audit a rules document STAND-ALONE (editor / CI use): resolves each string through\n * the doc's own `locale` messages (default `'en'`) and interpolates the facts tokens,\n * exactly like the info menu renders it, then runs {@link auditRules}.\n */\nexport function auditRulesDoc(doc: RulesDoc, opts: { locale?: string; facts?: GameFacts } = {}): RulesAuditIssue[] {\n if (!isRulesDoc(doc)) return [];\n const facts = opts.facts ? mergeFacts(doc.facts ?? {}, opts.facts) : doc.facts;\n const dict = doc.messages?.[opts.locale ?? 'en'] ?? {};\n const vars = factsVars(facts);\n const resolve = (s: string): string =>\n (dict[s] ?? s).replace(/\\{\\{([\\w.-]+)\\}\\}/g, (_m, k: string) => String(vars[k] ?? `{{${k}}}`));\n return auditRules(facts, doc.blocks, { resolve });\n}\n","/**\n * The ONE in-game rules/menu HTML renderer — the white-card-with-gold-accents\n * design the info menu shows in every game — as PURE string builders (zero deps,\n * no DOM required), so the SAME renderer that draws the menu in-game also powers\n * external tooling (the stakeplate rules editor's WYSIWYG preview, docs, CI\n * snapshots). `@open-slot-ui/pixi`'s `mountInfoMenu` consumes these — there is\n * exactly one source of truth for how a rules block looks.\n */\nimport type { BlockSpec } from './types';\nimport { modeStatsItems, type GameFacts, type RulesAuditIssue } from './facts';\n\n/** Escape text for safe HTML interpolation. */\nexport const escapeHtml = (s: string): string => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n/** Escape, then turn `**bold**` runs into `<b>` — the shared inline syntax. */\nexport const richHtml = (s: string): string => escapeHtml(s).replace(/\\*\\*(.+?)\\*\\*/g, '<b>$1</b>');\n\nconst esc = escapeHtml;\nconst rich = richHtml;\n\n/** The stat-grid `<dl>` markup shared by `stat-grid` and the auto `mode-stats` block. */\nfunction statGridHtml(items: ReadonlyArray<{ label: string; value: string }>, tr: (s: string) => string): string {\n const rows = items.map((it) => `<div><dt>${esc(tr(it.label))}</dt><dd>${esc(tr(it.value))}</dd></div>`).join('');\n return `<dl class=\"ohm-stats\">${rows}</dl>`;\n}\n\ntype PayRow = Extract<BlockSpec, { kind: 'paytable' }>['rows'][number];\n\n/** The Figma symbols grid: an icon (image or emoji/text) + its payout lines. */\nfunction renderPaytable(rows: readonly PayRow[], tr: (s: string) => string): string {\n return rows\n .map((r) => {\n const icon = r.icon ? `<img class=\"ohm-symimg\" src=\"${r.icon}\" alt=\"\" loading=\"lazy\">` : `<span class=\"ohm-emoji\">${esc(tr(r.symbol ?? ''))}</span>`;\n const lines = r.payouts\n .split('\\n')\n .map((line) => {\n const i = line.indexOf(':');\n return i >= 0 ? `<div><b>${esc(line.slice(0, i))}</b><span>${esc(line.slice(i + 1))}</span></div>` : `<div><span>${esc(line)}</span></div>`;\n })\n .join('');\n return `<div class=\"ohm-sym\">${icon}<div class=\"ohm-pay\">${lines}</div></div>`;\n })\n .join('');\n}\n\n/**\n * Render a declarative rules `BlockSpec[]` to the in-game HTML — the full modular\n * palette. `tr` is the translate function (pass a translate-and-interpolate so\n * `{{rtp.base}}`-style tokens resolve — see `factsVars`); `facts` feeds the auto\n * `mode-stats` block.\n */\nexport function renderBlocksHtml(blocks: BlockSpec[], tr: (s: string) => string, facts?: GameFacts): string {\n const out: string[] = [];\n for (const b of blocks) {\n switch (b.kind) {\n case 'text':\n out.push(`<p>${rich(tr(b.text))}</p>`);\n break;\n case 'heading':\n out.push(`<div class=\"ohm-sec\"><span>${esc(tr(b.text))}</span></div>`);\n break;\n case 'subheading':\n out.push(`<h4 class=\"ohm-subh\">${esc(tr(b.text))}</h4>`);\n break;\n case 'legal':\n out.push(`<p class=\"ohm-legal\">${rich(tr(b.text))}</p>`);\n break;\n case 'divider':\n out.push('<hr class=\"ohm-hr\">');\n break;\n case 'image':\n out.push(`<img class=\"ohm-feature\" alt=\"${esc(tr(b.alt ?? ''))}\" src=\"${b.src}\" loading=\"lazy\">`);\n break;\n case 'media': {\n const img = `<img alt=\"${esc(tr(b.alt ?? ''))}\" src=\"${b.src}\" loading=\"lazy\">`;\n const body = `<div class=\"ohm-media-body\">${b.title ? `<h4>${esc(tr(b.title))}</h4>` : ''}<p>${rich(tr(b.text))}</p></div>`;\n out.push(`<div class=\"ohm-media ohm-media--${b.side ?? 'left'}\">${img}${body}</div>`);\n break;\n }\n case 'cards': {\n const cards = b.items\n .map((it) => `<div class=\"ohm-fcard\">${it.icon ? `<img src=\"${it.icon}\" alt=\"\" loading=\"lazy\">` : ''}<h5>${esc(tr(it.title))}</h5>${it.text ? `<p>${rich(tr(it.text))}</p>` : ''}</div>`)\n .join('');\n out.push(`<div class=\"ohm-cards\">${cards}</div>`);\n break;\n }\n case 'paytable':\n out.push(`<div class=\"ohm-grid\">${renderPaytable(b.rows, tr)}</div>`);\n break;\n case 'table': {\n const head = b.columns?.length ? `<thead><tr>${b.columns.map((c) => `<th>${esc(tr(c))}</th>`).join('')}</tr></thead>` : '';\n const body = b.rows.map((r) => `<tr>${r.map((c) => `<td>${esc(tr(c))}</td>`).join('')}</tr>`).join('');\n out.push(`<table class=\"ohm-table\">${head}<tbody>${body}</tbody></table>`);\n break;\n }\n case 'stat-grid':\n out.push(statGridHtml(b.items, tr));\n break;\n // The AUTO per-mode RTP / Max-win grid — rendered straight from the declared\n // game facts (+ any host extras), so the table can never drift from the config.\n // `modeStatsItems` localizes the label PARTS itself (\"Max win\" · the mode name),\n // so the grid renderer gets identity-tr — no double translation.\n case 'mode-stats': {\n const extras = (b.extras ?? []).map((e) => ({ label: tr(e.label), value: tr(e.value) }));\n out.push(statGridHtml([...modeStatsItems(facts, tr), ...extras], (s) => s));\n break;\n }\n case 'steps': {\n const items = b.items.map((s) => `<li>${rich(tr(s))}</li>`).join('');\n out.push(b.ordered ? `<ol class=\"ohm-steps\">${items}</ol>` : `<ul class=\"ohm-steps\">${items}</ul>`);\n break;\n }\n case 'callout':\n out.push(`<div class=\"ohm-callout ohm-callout--${b.tone ?? 'info'}\">${b.title ? `<b>${esc(tr(b.title))}</b>` : ''}<p>${rich(tr(b.text))}</p></div>`);\n break;\n case 'group':\n out.push(`<div class=\"ohm-group\">${b.title ? `<h4 class=\"ohm-subh\">${esc(tr(b.title))}</h4>` : ''}${renderBlocksHtml(b.children, tr, facts)}</div>`);\n break;\n default:\n break; // interactive kinds render in the Settings section, not the rules body\n }\n }\n return out.join('\\n');\n}\n\n/**\n * The \"⚠ Rules incomplete\" warning card the info menu shows at the top of Rules\n * when the audit finds forgotten declarations. `tr` localizes the chrome strings\n * (`openui.rulesAudit.*`) + the finding messages. Empty issues → ''.\n */\nexport function renderRulesAuditHtml(issues: RulesAuditIssue[], tr: (s: string) => string): string {\n if (!issues.length) return '';\n const req = issues.filter((i) => i.level === 'required');\n const rec = issues.filter((i) => i.level === 'recommended');\n const list = (items: RulesAuditIssue[]): string => `<ul>${items.map((i) => `<li>${esc(tr(i.message))}</li>`).join('')}</ul>`;\n return `<div class=\"ohm-audit\" role=\"alert\">\n <div class=\"ohm-audit-title\">⚠ ${esc(tr('openui.rulesAudit.title'))}</div>\n ${req.length ? `<div class=\"ohm-audit-sub\">${esc(tr('openui.rulesAudit.required'))}</div>${list(req)}` : ''}\n ${rec.length ? `<div class=\"ohm-audit-sub ohm-audit-sub--rec\">${esc(tr('openui.rulesAudit.recommended'))}</div><div class=\"ohm-audit-rec\">${list(rec)}</div>` : ''}\n </div>`;\n}\n\n/**\n * The in-game info-menu stylesheet (the white card + gold accents design). One\n * copy, used by `mountInfoMenu` AND any external preview. Expects the CSS custom\n * properties `--accent --accent-text --surface --surface-alt --text --text-dim\n * --card-radius --font` on the `.ohm-root` (see {@link INFO_MENU_VARS}).\n */\nexport const INFO_MENU_VARS: Readonly<Record<string, string>> = Object.freeze({\n '--accent': '#d99000',\n '--accent-text': '#1a1200',\n '--surface': '#ffffff',\n '--surface-alt': '#eef1f6',\n '--text': '#181b20',\n '--text-dim': '#5b6472',\n '--card-radius': '8px',\n '--font': 'system-ui, sans-serif',\n});\n\nexport const INFO_MENU_CSS = `\n.ohm-root { position: fixed; inset: 0; z-index: 10000; display: grid; place-items: center; font-family: var(--font); opacity: 0; pointer-events: none; transition: opacity .18s ease; }\n.ohm-root.open { opacity: 1; pointer-events: auto; }\n.ohm-backdrop { position: absolute; inset: 0; background: rgba(8,6,4,0); backdrop-filter: blur(0px) saturate(1); -webkit-backdrop-filter: blur(0px) saturate(1); transition: background .4s ease, backdrop-filter .4s ease, -webkit-backdrop-filter .4s ease; }\n.ohm-root.open .ohm-backdrop { background: rgba(8,6,4,.34); backdrop-filter: blur(6px) saturate(1.1); -webkit-backdrop-filter: blur(6px) saturate(1.1); }\n.ohm-card { position: relative; width: min(92%, 1100px); max-height: 86vh; display: flex; flex-direction: column; background: var(--surface); color: var(--text); border: 1.5px solid #000; border-radius: var(--card-radius); box-shadow: 0 30px 80px rgba(0,0,0,.5); overflow: hidden; transform: translateY(8px) scale(.99); transition: transform .18s ease; }\n.ohm-root.open .ohm-card { transform: none; }\n.ohm-x { position: absolute; top: 18px; right: 22px; width: 46px; height: 46px; border-radius: 999px; border: 0; background: rgba(18,14,10,.82); color: #fff; font-size: 18px; cursor: pointer; display: grid; place-items: center; box-shadow: 0 6px 18px rgba(0,0,0,.45); z-index: 2; transition: transform .12s, background .12s; }\n.ohm-x:hover { transform: scale(1.08); background: rgba(18,14,10,.95); }\n.ohm-body { padding: 24px 26px 26px; overflow-y: scroll; }\n.ohm-body::-webkit-scrollbar { width: 18px; }\n.ohm-body::-webkit-scrollbar-track { background: transparent; margin: 12px 0; }\n.ohm-body::-webkit-scrollbar-thumb { background-color: #111; border: 6px solid transparent; background-clip: padding-box; border-radius: 999px; min-height: 44px; }\n.ohm-body::-webkit-scrollbar-thumb:hover { background-color: #000; }\n.ohm-logo { display: block; margin: 6px auto 18px; max-width: 64%; height: auto; }\n.ohm-logo-text { margin: 6px 0 18px; text-align: center; font-size: 30px; font-weight: 900; letter-spacing: 1px; color: var(--text); }\n.ohm-sec { display: flex; align-items: center; gap: 14px; margin: 26px 0 14px; color: var(--text); font-weight: 800; letter-spacing: 1px; }\n.ohm-sec::before, .ohm-sec::after { content: \"\"; flex: 1; height: 2px; background: color-mix(in srgb, var(--text) 80%, transparent); border-radius: 2px; }\n.ohm-root *, .ohm-root *::before, .ohm-root *::after { box-sizing: border-box; }\n.ohm-row { display: flex; align-items: center; gap: 16px; margin: 14px 0; font-weight: 700; }\n.ohm-setting { margin: 14px 0; }\n.ohm-setting .ohm-row { margin: 0; }\n.ohm-hint { margin: 3px 0 0; font-size: 12.5px; font-weight: 500; color: var(--text-dim); }\n.ohm-row > span:first-child { flex: none; min-width: 110px; }\n.ohm-row input[type=range] { flex: 1; min-width: 0; max-width: min(440px, 60dvw); accent-color: var(--accent); height: 6px; }\n.ohm-row select { flex: 1; min-width: 0; max-width: min(440px, 60dvw); padding: 11px 14px; border-radius: 4px; border: 2px solid var(--accent); background: var(--surface-alt); color: var(--text); font-weight: 700; font-size: 15px; cursor: pointer; }\n.ohm-row select option { background: var(--surface); color: var(--text); font-weight: 600; }\n.ohm-row select option:checked { background: var(--accent); color: var(--accent-text); }\n.ohm-ctl { flex: 1; min-width: 0; max-width: min(440px, 60dvw); display: flex; align-items: center; justify-content: flex-end; }\n.ohm-check input[type=checkbox] { appearance: none; -webkit-appearance: none; width: 50px; height: 28px; border-radius: 999px; background: color-mix(in srgb, var(--text-dim) 38%, transparent); position: relative; cursor: pointer; transition: background .15s; flex: none; }\n.ohm-check input[type=checkbox]:checked { background: var(--accent); }\n.ohm-check input[type=checkbox]::before { content: \"\"; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 999px; background: #fff; transition: left .15s; box-shadow: 0 1px 3px rgba(0,0,0,.3); }\n.ohm-check input[type=checkbox]:checked::before { left: 25px; }\n.ohm-segmented { display: inline-flex; gap: 4px; padding: 4px; background: var(--surface-alt); border-radius: 999px; border: 1px solid color-mix(in srgb, var(--text-dim) 30%, transparent); }\n.ohm-seg { border: 0; background: transparent; color: var(--text-dim); font-weight: 700; font-size: 14px; padding: 8px 18px; border-radius: 999px; cursor: pointer; transition: background .12s, color .12s; }\n.ohm-seg.active { background: var(--accent); color: var(--accent-text); }\n.ohm-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; }\n.ohm-sym { display: flex; align-items: center; gap: 16px; padding: 6px 4px; }\n.ohm-emoji { font-size: 48px; line-height: 1; filter: drop-shadow(0 2px 4px rgba(0,0,0,.3)); }\n.ohm-symimg { width: 56px; height: 56px; object-fit: contain; flex: none; }\n.ohm-pay { font-size: 13px; line-height: 1.6; }\n.ohm-pay div { display: flex; gap: 6px; }\n.ohm-pay b { min-width: 42px; }\n.ohm-pay span { color: var(--accent); font-weight: 700; }\n.ohm-body p { color: var(--text-dim); line-height: 1.6; }\n.ohm-body p b { color: var(--text); }\n.ohm-feature { display: block; width: 100%; height: auto; margin: 10px 0; }\n.ohm-stats { margin: 12px 0; display: grid; grid-template-columns: 1fr 1fr; gap: 0 28px; }\n.ohm-stats > div { display: flex; justify-content: space-between; padding: 9px 0; border-bottom: 1px solid color-mix(in srgb, var(--text-dim) 20%, transparent); }\n.ohm-stats dt { color: var(--text-dim); margin: 0; } .ohm-stats dd { margin: 0; font-weight: 700; }\n.ohm-audit { margin: 12px 0 18px; padding: 14px 16px; border-radius: 12px; border: 2px solid #d03131; background: color-mix(in srgb, #d03131 8%, transparent); }\n.ohm-audit-title { font-weight: 900; letter-spacing: .5px; color: #b31d1d; }\n.ohm-audit-sub { margin-top: 8px; font-size: 13px; font-weight: 800; color: #b31d1d; }\n.ohm-audit-sub--rec { color: #b07d09; }\n.ohm-audit ul { margin: 6px 0 0; padding-left: 20px; color: var(--text); font-size: 13.5px; line-height: 1.55; }\n.ohm-audit li { margin: 3px 0; }\n.ohm-audit-rec ul { color: var(--text-dim); }\n.ohm-callout { margin: 16px 0 4px; padding: 14px 16px; border-radius: 12px; border-left: 4px solid var(--accent); background: color-mix(in srgb, var(--accent) 9%, transparent); }\n.ohm-callout b { color: var(--accent); } .ohm-callout p { margin: 4px 0 0; color: var(--text); }\n.ohm-callout--warning { border-left-color: #e0a106; background: color-mix(in srgb, #e0a106 10%, transparent); }\n.ohm-callout--warning b { color: #b07d09; }\n.ohm-subh { margin: 22px 0 8px; font-size: 15px; font-weight: 800; letter-spacing: .5px; color: var(--text); }\n.ohm-legal { font-size: 12px; line-height: 1.6; color: var(--text-dim); opacity: .85; }\n.ohm-hr { border: 0; border-top: 1px solid color-mix(in srgb, var(--text-dim) 30%, transparent); margin: 18px 0; }\n.ohm-media { display: flex; align-items: center; gap: 18px; margin: 14px 0; }\n.ohm-media--right { flex-direction: row-reverse; }\n.ohm-media > img { width: 40%; max-width: 320px; height: auto; flex: none; }\n.ohm-media-body { flex: 1; }\n.ohm-media-body h4 { margin: 0 0 6px; font-size: 16px; color: var(--text); }\n.ohm-media-body p { margin: 0; }\n.ohm-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin: 12px 0; }\n.ohm-fcard { padding: 8px 6px; text-align: center; }\n.ohm-fcard img { display: block; width: 48px; height: 48px; margin: 0 auto 8px; }\n.ohm-fcard h5 { margin: 0 0 4px; font-size: 14px; color: var(--text); }\n.ohm-fcard p { margin: 0; font-size: 12px; line-height: 1.5; }\n.ohm-table { width: 100%; border-collapse: collapse; margin: 12px 0; font-size: 14px; }\n.ohm-table th { text-align: left; padding: 8px 10px; font-weight: 800; color: var(--text); border-bottom: 2px solid color-mix(in srgb, var(--text-dim) 35%, transparent); }\n.ohm-table td { padding: 8px 10px; border-bottom: 1px solid color-mix(in srgb, var(--text-dim) 18%, transparent); }\n.ohm-table td:first-child { color: var(--text); font-weight: 700; }\n.ohm-table td:not(:first-child) { color: var(--accent); font-weight: 700; }\n.ohm-steps { margin: 12px 0; padding-left: 22px; color: var(--text-dim); line-height: 1.7; }\n.ohm-steps li { margin: 5px 0; }\n.ohm-steps b { color: var(--text); }\n.ohm-group { margin: 8px 0; }\n`;\n","import type { UISpec } from './types';\n\n/**\n * The reference HUD expressed as data — the knobs `new OpenUI()` ships with.\n * `createUI(defaultHudSpec)` is byte-equivalent to zero-arg `createUI()` (a test\n * guards this). It's the canonical starting point for the docs editor and for\n * games that want to tweak from the default rather than start blank.\n */\nexport const defaultHudSpec: Readonly<UISpec> = Object.freeze({\n meta: { id: 'open-ui-reference-hud', version: 1 },\n currency: { code: 'USD', decimals: 2 },\n betLadder: { levels: [0.5, 1, 2, 5, 10, 20], index: 1 },\n autoplay: { options: [5, 10, 25, 50, 100, Infinity] },\n lockDuringSpin: true,\n});\n","import type { EventBus } from './events';\nimport type { OpenUIEvents } from './types';\n\nexport interface LoggedEvent {\n t: number;\n type: keyof OpenUIEvents;\n payload: unknown;\n}\n\nexport interface EventLogOptions {\n /** Max entries kept (ring buffer). Default 200. */\n capacity?: number;\n /** Monotonic clock; defaults to performance.now/Date.now. Injectable for tests. */\n now?: () => number;\n}\n\nconst ALL_EVENTS: Array<keyof OpenUIEvents> = [\n 'spinRequested',\n 'skipRequested',\n 'stateChanged',\n 'buttonActivated',\n 'valueChanged',\n 'panelToggled',\n 'toggled',\n 'optionSelected',\n 'autoplayStarted',\n 'autoplayStopped',\n 'cardActivated',\n 'localeChanged',\n];\n\n/**\n * An opt-in ring buffer over the one typed event bus — backs `BootedHud.events`\n * and the dev `window.__OPENUI__.events`, so e2e can assert \"exactly one\n * spinRequested fired during the round\" without timing guesses (Charter P10/G6).\n */\nexport class EventLog {\n private readonly buf: LoggedEvent[] = [];\n private readonly cap: number;\n private readonly clock: () => number;\n private readonly disposers: Array<() => void> = [];\n\n constructor(bus: EventBus<OpenUIEvents>, opts: EventLogOptions = {}) {\n this.cap = opts.capacity ?? 200;\n this.clock = opts.now ?? defaultNow;\n for (const type of ALL_EVENTS) {\n this.disposers.push(bus.on(type, (payload) => this.record(type, payload)));\n }\n }\n\n private record(type: keyof OpenUIEvents, payload: unknown): void {\n this.buf.push({ t: this.clock(), type, payload });\n if (this.buf.length > this.cap) this.buf.shift();\n }\n\n /** The most recent payload of `type`, or undefined. */\n last<K extends keyof OpenUIEvents>(type: K): OpenUIEvents[K] | undefined {\n for (let i = this.buf.length - 1; i >= 0; i--) {\n if (this.buf[i]!.type === type) return this.buf[i]!.payload as OpenUIEvents[K];\n }\n return undefined;\n }\n\n /** How many of `type` are in the buffer. */\n count(type: keyof OpenUIEvents): number {\n let n = 0;\n for (const e of this.buf) if (e.type === type) n += 1;\n return n;\n }\n\n /** Every event at or after timestamp `t`, in order. */\n since(t: number): LoggedEvent[] {\n return this.buf.filter((e) => e.t >= t);\n }\n\n clear(): void {\n this.buf.length = 0;\n }\n\n dispose(): void {\n for (const d of this.disposers) d();\n this.disposers.length = 0;\n }\n}\n\nfunction defaultNow(): number {\n if (typeof performance !== 'undefined' && typeof performance.now === 'function') return performance.now();\n return Date.now();\n}\n","/**\n * Build / clamp a bet ladder from a Stake Engine RGS bet config so the host doesn't\n * have to hand-tune `betLadder` (and can't ship a stake outside min/max/step). Pure.\n */\n\nexport interface RgsBetConfig {\n /** Allowed stake amounts in API minor units (Stake: dollars × 1_000_000). */\n betLevels?: number[];\n minBet?: number;\n maxBet?: number;\n stepBet?: number;\n /** Default stake in minor units (custom bets must be a multiple of this). */\n defaultBetLevel?: number;\n}\n\n/** Stake's API minor-unit divisor (1_000_000 minor units = 1.00). */\nexport const API_AMOUNT_DIVISOR = 1_000_000;\n\n/**\n * Turn an RGS bet config into a `{ levels, index }` ladder in MAJOR units (what\n * `UISpec.betLadder` wants). Uses `betLevels` if present, else derives from\n * min/max/step. `divisor` converts minor→major (default Stake's 1_000_000).\n */\nexport function buildBetLadder(cfg: RgsBetConfig, divisor = API_AMOUNT_DIVISOR): { levels: number[]; index: number } {\n let minor: number[];\n if (cfg.betLevels?.length) {\n minor = cfg.betLevels.slice();\n } else {\n const min = cfg.minBet ?? 0;\n const max = Math.max(min, cfg.maxBet ?? min);\n const step = cfg.stepBet && cfg.stepBet > 0 ? cfg.stepBet : max - min || 1;\n minor = [];\n for (let v = min; v <= max && minor.length < 500; v += step) minor.push(v);\n if (!minor.length) minor = [min];\n }\n const levels = minor.map((v) => v / divisor);\n const want = (cfg.defaultBetLevel ?? minor[0]!) / divisor;\n const found = levels.findIndex((v) => v >= want);\n return { levels, index: found < 0 ? 0 : found };\n}\n\n/**\n * Resolve the shown bet ladder from an authenticate response (MAJOR units): use EVERY\n * level the RGS offers, VERBATIM, and snap the default bet to the matching level.\n *\n * Deliberately does NOT filter out low levels. Stake requires every currency's full\n * ladder — including its true minimum (e.g. USD 0.01) — to come straight from\n * authenticate. A consequence is that the smallest win can be below one minimal\n * currency unit (USD 0.01 bet × a ×0.2 face = 0.002); the money displays render that\n * true sub-unit amount (see `formatAmountPrecise` / `ValueDisplay.autoPrecision`)\n * rather than hiding the level. Pure — share it between the UISpec builder and the\n * game's balance store so both agree on the bet.\n */\nexport function resolveBetLadder(\n availableBets: number[] | undefined,\n defaultBet: number,\n fallback: number[] = [0.2, 0.5, 1, 2, 5, 10],\n): { levels: number[]; index: number } {\n const levels = availableBets?.length ? availableBets.slice() : fallback.slice();\n const exact = levels.indexOf(defaultBet);\n const index = exact >= 0 ? exact : Math.max(0, levels.findIndex((b) => b >= defaultBet));\n return { levels, index };\n}\n\n/** Clamp a stake (major units) to the RGS min/max and snap to `stepBet`. Pure. */\nexport function clampBet(amount: number, cfg: RgsBetConfig, divisor = API_AMOUNT_DIVISOR): number {\n const min = (cfg.minBet ?? 0) / divisor;\n const max = (cfg.maxBet ?? Infinity) / divisor;\n const step = (cfg.stepBet ?? 0) / divisor;\n let v = Math.min(max, Math.max(min, Number.isFinite(amount) ? amount : min));\n if (step > 0) v = min + Math.round((v - min) / step) * step;\n return Math.min(max, Math.max(min, v));\n}\n"]}
|