{"version":3,"sources":["../src/action-state.ts","../src/gamepad-feedback.ts","../src/browser-gamepad-feedback.ts","../src/digital-input.ts","../src/gamepad-frame.ts","../src/gesture-recognizer.ts","../src/input-snapshot.ts","../src/ui-ownership.ts","../src/virtual-joystick.ts","../src/browser-backend.ts","../src/canvas-input-boundary.ts","../src/composite-backend.ts","../src/frame-start-scan-system.ts","../src/plugin-service.ts"],"names":["a","b"],"mappings":"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","file":"index.mjs","sourcesContent":["// action-state.ts — action mapping pure-function module for forgeax-engine.\n//\n// Derives per-frame ActionState[] from an InputBackendSample and an InputMap.\n// Zero ECS/DOM dependencies; fully node-testable.\n//\n// charter awareness:\n//   P3 explicit failure — unmapped action names return empty signal, never throw\n//   P4 consistent abstraction — consumer only sees action name, never device\n\nimport type { GamepadAxisIndex, GamepadButtonIndex, InputBackendSample } from './input-snapshot';\n\n// ─── Types ───────────────────────────────────────────────────────\n\n/**\n * Closed 4-member discriminant union for mapping raw input sources to actions.\n * The `type` field is the discriminant; consumers switch on it with no `default`\n * branch (AC-08b: TypeScript checks exhaustiveness at compile time).\n */\nexport type ActionBinding =\n  | { readonly type: 'key'; readonly key: string }\n  | { readonly type: 'mouseButton'; readonly button: 0 | 1 | 2 }\n  | { readonly type: 'gamepadButton'; readonly button: GamepadButtonIndex }\n  | {\n      readonly type: 'gamepadAxis';\n      readonly axis: GamepadAxisIndex;\n      /**\n       * Sign applied to the raw axis value before aggregation.\n       * - Omitted: contributes |value| (trigger semantics, e.g. right trigger on axis 2).\n       * - `1`: contributes max(0, value) (positive direction).\n       * - `-1`: contributes max(0, -value) (negative direction, e.g. left stick).\n       */\n      readonly sign?: 1 | -1;\n    };\n\n/**\n * An action definition in the InputMap: a semantic name + one or more bindings\n * to raw input sources, plus an optional per-action deadzone override.\n */\nexport interface ActionConfig {\n  /** Semantic action name (e.g. 'jump', 'moveRight'). Referenced by snap.action(name). */\n  readonly action: string;\n  /** Raw input bindings that contribute to this action. Aggregated via OR/MAX. */\n  readonly bindings: readonly ActionBinding[];\n  /**\n   * Per-action deadzone applied to analog strength remapping.\n   * Default: 0.2 (Godot prior-art, F2). Analog values with |raw| < deadzone\n   * produce strength=0. Values >= deadzone are linearly remapped into [0,1].\n   */\n  readonly deadzone?: number;\n}\n\n/**\n * Per-frame derived action state. Returned by deriveActionStates(); consumed\n * by snap.action(name) readpoints. All fields are frame-frozen (AC-11).\n */\nexport interface ActionState {\n  readonly action: string;\n  /** Resolved at frame sampling; radial vector reads use this value. */\n  readonly deadzone: number;\n  /** true when ANY binding contributes a press (OR aggregation). */\n  readonly pressed: boolean;\n  /**\n   * true only on the frame when pressed transitions false→true.\n   * One-frame lifetime; held state does not re-fire (AC-03).\n   */\n  readonly justPressed: boolean;\n  /**\n   * true only on the frame when pressed transitions true→false.\n   * One-frame lifetime (AC-03).\n   */\n  readonly justReleased: boolean;\n  /**\n   * Deadzone-remapped analog strength in [0, 1]. Digital press → 1.0.\n   * Analog values < deadzone → 0. Aggregate: MAX across bindings.\n   */\n  readonly strength: number;\n  /**\n   * Raw un-deadzoned magnitude in [0, 1]. Used by getVector (which applies its\n   * own single radial deadzone to avoid per-axis deadzone stacking, F2).\n   * Aggregate: MAX across bindings.\n   */\n  readonly raw: number;\n}\n\n// ─── Constants ───────────────────────────────────────────────────\n\n/**\n * Resource key for the immutable InputMap (ActionConfig[]) inserted into\n * the World. Canvas-form createApp does this automatically; assemble-form\n * hosts insert it directly (D-7).\n */\nexport const INPUT_MAP_KEY = 'InputMap';\n\n/** Default per-action deadzone (Godot prior-art, F2). */\nconst DEFAULT_DEADZONE = 0.2;\n\n// ─── Helpers ─────────────────────────────────────────────────────\n\n/**\n * Inverse lerp: maps a value from [a, b] to [0, 1] linearly.\n * Returns 0 when val <= a, 1 when val >= b.\n */\nfunction inverseLerp(a: number, b: number, val: number): number {\n  if (val <= a) return 0;\n  if (val >= b) return 1;\n  return (val - a) / (b - a);\n}\n\n/**\n * Deadzone remap: maps |raw| from [deadzone, 1] to [0, 1].\n * |raw| < deadzone → 0. |raw| >= deadzone → inverse_lerp(deadzone, 1, |raw|).\n */\nfunction applyDeadzone(rawAbs: number, deadzone: number): number {\n  return rawAbs < deadzone ? 0 : inverseLerp(deadzone, 1, rawAbs);\n}\n\n/**\n * Extract the raw contribution from a single binding against the sample.\n * Returns the raw magnitude before the action-level deadzone.\n *\n * - Digital types (key/mouseButton/gamepadButton): rawAbs = 1.0 if pressed, 0 otherwise.\n * - Analog type (gamepadAxis): rawAbs = max(0, |value| or max(0, value*sign)).\n *   For gamepadAxis, aggregates across ALL connected standardMapping slots (D-9).\n */\nfunction bindingContribution(binding: ActionBinding, sample: InputBackendSample): number {\n  switch (binding.type) {\n    case 'key': {\n      const down = sample.downKeys.has(binding.key);\n      return down ? 1 : 0;\n    }\n    case 'mouseButton': {\n      const down = sample.buttons[binding.button] === true;\n      return down ? 1 : 0;\n    }\n    case 'gamepadButton': {\n      // D-9: aggregate across ALL connected standardMapping slots.\n      const slots = sample.gamepads ?? [];\n      let anyPressed = false;\n      for (const slot of slots) {\n        if (!slot.standardMapping) continue;\n        if (slot.pressed.has(binding.button)) {\n          anyPressed = true;\n          break;\n        }\n      }\n      return anyPressed ? 1 : 0;\n    }\n    case 'gamepadAxis': {\n      // D-9: aggregate across ALL connected standardMapping slots (MAX).\n      const slots = sample.gamepads ?? [];\n      let maxRawAbs = 0;\n      for (const slot of slots) {\n        if (!slot.standardMapping) continue;\n        const rawAxis = slot.axes[binding.axis];\n        const sign = binding.sign;\n        if (sign === undefined) {\n          // Trigger semantics: contribute |value|\n          const abs = Math.abs(rawAxis);\n          if (abs > maxRawAbs) maxRawAbs = abs;\n        } else if (sign === 1) {\n          const v = Math.max(0, rawAxis);\n          if (v > maxRawAbs) maxRawAbs = v;\n        } else {\n          // sign === -1\n          const v = Math.max(0, -rawAxis);\n          if (v > maxRawAbs) maxRawAbs = v;\n        }\n      }\n      return maxRawAbs;\n    }\n  }\n}\n\n// ─── deriveActionStates ──────────────────────────────────────────\n\n/**\n * Derive per-frame action states from a backend sample and an InputMap.\n *\n * Pure function with no side effects. Called once per frame by the\n * frame-start scan system. The result is frozen into the InputSnapshot\n * so all snap.action() calls in the same frame see identical state (AC-11).\n *\n * @param sample - One frame's raw input backend sample (POD).\n * @param inputMap - ActionConfig array; duplicate action names → last-wins (D-8).\n * @param prevActionStates - Previous frame's action states for edge diff\n *   (justPressed/justReleased derivation). Omitted on the first frame or\n *   when actions are not being tracked across frames.\n * @returns ActionState[] with one entry per action name in inputMap (last-wins dedup).\n */\nexport function deriveActionStates(\n  sample: InputBackendSample,\n  inputMap: readonly ActionConfig[],\n  prevActionStates?: readonly ActionState[],\n): ActionState[] {\n  // D-8: last-wins dedup — later configs overwrite earlier for same action name.\n  const deduped = new Map<string, ActionConfig>();\n  for (const config of inputMap) {\n    deduped.set(config.action, config);\n  }\n\n  // Build prev lookup for edge diff.\n  const prevByAction = new Map<string, boolean>();\n  if (prevActionStates) {\n    for (const s of prevActionStates) {\n      prevByAction.set(s.action, s.pressed);\n    }\n  }\n\n  const results: ActionState[] = [];\n\n  for (const config of deduped.values()) {\n    const deadzone = config.deadzone ?? DEFAULT_DEADZONE;\n\n    // Aggregate across all bindings: OR for pressed, MAX for strength/raw.\n    let aggregatedPressed = false;\n    let aggregatedStrength = 0;\n    let aggregatedRaw = 0;\n\n    for (const binding of config.bindings) {\n      const rawAbs = bindingContribution(binding, sample);\n\n      // Update raw: MAX aggregation.\n      if (rawAbs > aggregatedRaw) aggregatedRaw = rawAbs;\n\n      // Update pressed: need to consider analog deadzone threshold.\n      if (rawAbs >= deadzone) {\n        aggregatedPressed = true;\n        const str = applyDeadzone(rawAbs, deadzone);\n        if (str > aggregatedStrength) aggregatedStrength = str;\n      }\n\n      // Digital sources already contribute 1.0/0 rawAbs.\n      // For digital, rawAbs=1.0 >= deadzone(0.2) → pressed=true, strength=applyDeadzone(1.0,0.2)=1.0.\n    }\n\n    // Edge detection: justPressed / justReleased from prev frame's pressed state.\n    const prevPressed = prevByAction.get(config.action) ?? false;\n    const justPressed = aggregatedPressed && !prevPressed;\n    const justReleased = sample.focusReset !== true && !aggregatedPressed && prevPressed;\n\n    results.push({\n      action: config.action,\n      deadzone,\n      pressed: aggregatedPressed,\n      justPressed,\n      justReleased,\n      strength: aggregatedStrength,\n      raw: aggregatedRaw,\n    });\n  }\n\n  return results;\n}\n\n// ─── getAxis / getVector ───────────────────────────────────────────\n\n/**\n * Options for getVector deadzone override.\n */\nexport interface GetVectorOptions {\n  /**\n   * Override the default radial deadzone. When omitted, the deadzone is\n   * computed as the average of the 4 per-action deadzones.\n   */\n  readonly deadzone?: number;\n}\n\n/**\n * Compose a 1D axis value from two opposing actions.\n *\n * Returns `strength(pos) - strength(neg)`, range [-1, 1].\n *\n * - Both registered: combines normally.\n * - One unregistered (E-3): contributes 0.\n * - Neither registered: returns 0.\n * - Same action for both ends (E-12): always 0.\n *\n * @param actionStates - Derived action states (from deriveActionStates).\n * @param neg - Action name for the negative direction (e.g. 'moveLeft').\n * @param pos - Action name for the positive direction (e.g. 'moveRight').\n */\nexport function getAxis(actionStates: readonly ActionState[], neg: string, pos: string): number {\n  const posState = actionStates.find((s) => s.action === pos);\n  const negState = actionStates.find((s) => s.action === neg);\n  const posStrength = posState?.strength ?? 0;\n  const negStrength = negState?.strength ?? 0;\n  if (neg === pos) return 0;\n  return posStrength - negStrength;\n}\n\n/**\n * Compose a 2D vector from four directional actions using a single radial\n * deadzone (Godot input.cpp three-branch formula, F2).\n *\n * Reads `raw` (not `strength`) from actionStates to avoid per-axis deadzone\n * stacking into a square deadzone. Applies one radial deadzone:\n *\n * - length <= deadzone → (0, 0)\n * - length > 1 → vector / length  (clamp to unit circle)\n * - otherwise → vector * inverse_lerp(deadzone, 1, length) / length\n *\n * Default deadzone = average of the 4 actions' per-action deadzones.\n * `opts.deadzone` overrides it.\n *\n * @param actionStates - Derived action states.\n * @param negX - Action name for negative X (e.g. 'moveLeft').\n * @param posX - Action name for positive X (e.g. 'moveRight').\n * @param negY - Action name for negative Y (e.g. 'moveUp').\n * @param posY - Action name for positive Y (e.g. 'moveDown').\n * @param opts - Optional override (deadzone).\n */\nexport function getVector(\n  actionStates: readonly ActionState[],\n  negX: string,\n  posX: string,\n  negY: string,\n  posY: string,\n  opts?: GetVectorOptions,\n): { readonly x: number; readonly y: number } {\n  // Look up raw values (not strength!) for each directional action.\n  // getVector uses raw to avoid per-action deadzone stacking into a square\n  // deadzone (F2: Godot getVector applies a SINGLE radial deadzone).\n  const posXState = actionStates.find((s) => s.action === posX);\n  const negXState = actionStates.find((s) => s.action === negX);\n  const posYState = actionStates.find((s) => s.action === posY);\n  const negYState = actionStates.find((s) => s.action === negY);\n\n  const x = (posXState?.raw ?? 0) - (negXState?.raw ?? 0);\n  const y = (posYState?.raw ?? 0) - (negYState?.raw ?? 0);\n\n  // Compute radial deadzone.\n  // Default = average of the 4 per-action deadzones, using only registered actions.\n  const deadzone = opts?.deadzone ?? computeAverageDeadzone(actionStates, negX, posX, negY, posY);\n\n  const length = Math.sqrt(x * x + y * y);\n\n  // Three-branch formula (Godot input.cpp, F2):\n  if (length <= deadzone) {\n    // Below deadzone → zero vector (deadzone applied).\n    return { x: 0, y: 0 };\n  }\n  if (length > 1) {\n    // Clamp to unit circle.\n    return { x: x / length, y: y / length };\n  }\n  // Intermediate zone: smoothly remap from deadzone→1 to 0→unit.\n  // vec * inverse_lerp(deadzone, 1, length) / length\n  const factor = inverseLerp(deadzone, 1, length) / length;\n  return { x: x * factor, y: y * factor };\n}\n\n/**\n * Compute the average deadzone for 4 action names from the input map.\n * Actions not registered contribute DEFAULT_DEADZONE.\n */\nfunction computeAverageDeadzone(\n  actionStates: readonly ActionState[],\n  negX: string,\n  posX: string,\n  negY: string,\n  posY: string,\n): number {\n  const map = new Map(actionStates.map((state) => [state.action, state.deadzone]));\n  const dzNegX = map.get(negX) ?? DEFAULT_DEADZONE;\n  const dzPosX = map.get(posX) ?? DEFAULT_DEADZONE;\n  const dzNegY = map.get(negY) ?? DEFAULT_DEADZONE;\n  const dzPosY = map.get(posY) ?? DEFAULT_DEADZONE;\n  return (dzNegX + dzPosX + dzNegY + dzPosY) / 4;\n}\n","/** Realm-neutral, bounded output. Targets come only from the frozen input scan. */\nexport interface GamepadFeedbackTarget {\n  readonly attachment: number;\n  readonly index: number;\n  readonly generation: number;\n}\nexport interface GamepadRumble {\n  readonly durationMs: number;\n  readonly strongMagnitude: number;\n  readonly weakMagnitude: number;\n}\nexport type GamepadFeedbackIntent = {\n  readonly id: number;\n  readonly target: GamepadFeedbackTarget;\n} & ({ readonly kind: 'play'; readonly effect: GamepadRumble } | { readonly kind: 'stop' });\nexport type GamepadFeedbackStatus =\n  | 'complete'\n  | 'preempted'\n  | 'invalid'\n  | 'unsupported'\n  | 'disconnected'\n  | 'stale'\n  | 'hidden'\n  | 'busy'\n  | 'rejected'\n  | 'timeout'\n  | 'disposed'\n  | 'result-overflow';\nexport interface GamepadFeedbackResult {\n  readonly id: number;\n  readonly status: GamepadFeedbackStatus;\n  /** POD native rejection name/message, never the native exception. */\n  readonly detail?: string;\n}\nexport const GAMEPAD_FEEDBACK_KEY = 'GamepadFeedback' as const;\nexport const GAMEPAD_FEEDBACK_CAPACITY = 32;\nexport const GAMEPAD_FEEDBACK_MAX_DURATION_MS = 10_000;\nexport function validGamepadRumble(effect: GamepadRumble): boolean {\n  return (\n    effect != null &&\n    Number.isFinite(effect.durationMs) &&\n    effect.durationMs > 0 &&\n    effect.durationMs <= GAMEPAD_FEEDBACK_MAX_DURATION_MS &&\n    Number.isFinite(effect.strongMagnitude) &&\n    effect.strongMagnitude >= 0 &&\n    effect.strongMagnitude <= 1 &&\n    Number.isFinite(effect.weakMagnitude) &&\n    effect.weakMagnitude >= 0 &&\n    effect.weakMagnitude <= 1\n  );\n}\nexport type GamepadFeedbackAdmission =\n  | { readonly ok: true; readonly id: number }\n  | { readonly ok: false; readonly reason: 'invalid' | 'capacity' | 'disposed' };\nexport interface GamepadFeedback {\n  play(target: GamepadFeedbackTarget, effect: GamepadRumble): GamepadFeedbackAdmission;\n  stop(target: GamepadFeedbackTarget): GamepadFeedbackAdmission;\n  /** Poll terminal results in arrival order. Polling releases their capacity. */\n  readResults(): readonly GamepadFeedbackResult[];\n  /** Transport seams: both arrays contain POD only. */\n  drainIntents(): readonly GamepadFeedbackIntent[];\n  acceptResults(results: readonly GamepadFeedbackResult[], lost?: number): void;\n  dispose(): void;\n}\nexport function createGamepadFeedback(): GamepadFeedback {\n  let nextId = 1;\n  let disposed = false;\n  let intents: GamepadFeedbackIntent[] = [];\n  let results: GamepadFeedbackResult[] = [];\n  let droppedDiagnostics = 0;\n  const pending = new Set<number>();\n  function enqueue(\n    target: GamepadFeedbackTarget,\n    effect?: GamepadRumble,\n  ): GamepadFeedbackAdmission {\n    if (disposed) return { ok: false, reason: 'disposed' };\n    if (\n      !target ||\n      !Number.isSafeInteger(target.attachment) ||\n      target.attachment <= 0 ||\n      !Number.isSafeInteger(target.index) ||\n      target.index < 0 ||\n      !Number.isSafeInteger(target.generation) ||\n      target.generation <= 0 ||\n      (effect !== undefined && !validGamepadRumble(effect))\n    )\n      return { ok: false, reason: 'invalid' };\n    if (pending.size + results.length >= GAMEPAD_FEEDBACK_CAPACITY)\n      return { ok: false, reason: 'capacity' };\n    const id = nextId++;\n    pending.add(id);\n    const ownedTarget = Object.freeze({ ...target });\n    intents.push(\n      effect === undefined\n        ? { id, target: ownedTarget, kind: 'stop' }\n        : { id, target: ownedTarget, kind: 'play', effect: Object.freeze({ ...effect }) },\n    );\n    return { ok: true, id };\n  }\n  return {\n    play: (target, effect) =>\n      validGamepadRumble(effect) ? enqueue(target, effect) : { ok: false, reason: 'invalid' },\n    stop: (target) => enqueue(target),\n    drainIntents() {\n      const out = intents;\n      intents = [];\n      return out;\n    },\n    readResults() {\n      const out = results;\n      results = [];\n      droppedDiagnostics = 0;\n      return out;\n    },\n    acceptResults(incoming, lost = 0) {\n      for (const result of incoming) {\n        if (pending.delete(result.id)) {\n          results.push(Object.freeze({ ...result }));\n        } else if (result.id === 0) {\n          if (pending.size + results.length < GAMEPAD_FEEDBACK_CAPACITY * 2) {\n            results.push(Object.freeze({ ...result }));\n          } else {\n            // Never evict an authored terminal to make room for lifecycle evidence.\n            const diagnostic = results.findIndex((item) => item.id === 0);\n            if (diagnostic >= 0) results.splice(diagnostic, 1);\n            droppedDiagnostics++;\n            results.push({\n              id: 0,\n              status: 'result-overflow',\n              detail: `Dropped ${droppedDiagnostics} lifecycle diagnostics. Latest: ${result.status}: ${result.detail ?? ''}`,\n            });\n          }\n        }\n      }\n      if (lost > 0) {\n        for (const id of pending) results.push({ id, status: 'result-overflow' });\n        pending.clear();\n        intents = [];\n      }\n    },\n    dispose() {\n      if (disposed) return;\n      disposed = true;\n      intents = [];\n      for (const id of pending) results.push({ id, status: 'disposed' });\n      pending.clear();\n    },\n  };\n}\n","import {\n  createGamepadFeedback,\n  GAMEPAD_FEEDBACK_CAPACITY,\n  type GamepadFeedbackIntent,\n  type GamepadFeedbackResult,\n  type GamepadFeedbackStatus,\n  type GamepadFeedbackTarget,\n  validGamepadRumble,\n} from './gamepad-feedback';\nimport type { RawGamepadStub } from './gamepad-frame';\n\ninterface Actuator {\n  readonly effects?: readonly string[];\n  readonly type?: string;\n  playEffect(\n    type: 'dual-rumble',\n    params: {\n      duration: number;\n      startDelay: number;\n      strongMagnitude: number;\n      weakMagnitude: number;\n    },\n  ): Promise<string>;\n  reset(): Promise<string>;\n}\ntype NativePad = RawGamepadStub & { readonly vibrationActuator?: Actuator };\ninterface ActiveEffect {\n  owner: number;\n  finish: (status: GamepadFeedbackStatus, detail?: string) => void;\n  actuator: Actuator;\n}\ninterface Connection {\n  id: string;\n  generation: number;\n  pad: NativePad;\n  pending: number;\n  resetting: number;\n  active?: ActiveEffect;\n}\ninterface Hub {\n  connections: Map<number, Connection>;\n  pending: number;\n  owners: number;\n}\n// One actuator arbitration boundary per browser document. No second polling path.\nconst hubs = new WeakMap<object, Hub>();\nlet nextAttachment = 1;\nlet nextGeneration = 1;\nconst MAX_TARGET_PENDING = 8;\nconst SETTLE_GRACE_MS = 1000;\nconst MAX_RESULTS = GAMEPAD_FEEDBACK_CAPACITY * 2;\n\nexport function attachBrowserGamepadFeedback(doc: Document | undefined, win: Window | undefined) {\n  const host = doc ?? win;\n  let hub = host ? hubs.get(host) : undefined;\n  if (!hub) {\n    hub = { connections: new Map(), pending: 0, owners: 0 };\n    if (host) hubs.set(host, hub);\n  }\n  const shared = hub;\n  shared.owners++;\n  let attachment = nextAttachment++;\n  let detached = false;\n  let lastCommand = 0;\n  let results: GamepadFeedbackResult[] = [];\n  let lost = 0;\n  const feedback = createGamepadFeedback();\n  function publish(result: GamepadFeedbackResult) {\n    if (detached) {\n      if (result.id === 0) feedback.acceptResults([result]);\n      return;\n    }\n    if (results.length === MAX_RESULTS) {\n      results.shift();\n      lost++;\n    }\n    results.push(result);\n  }\n  function supports(pad: NativePad): boolean {\n    const actuator = pad.vibrationActuator;\n    return (\n      !!actuator &&\n      typeof actuator.playEffect === 'function' &&\n      typeof actuator.reset === 'function' &&\n      (actuator.effects?.includes('dual-rumble') ?? actuator.type === 'dual-rumble')\n    );\n  }\n  function run(\n    connection: Connection,\n    reset: boolean,\n    duration: number,\n    invoke: () => Promise<string>,\n    finish: ActiveEffect['finish'],\n  ) {\n    if (shared.pending >= GAMEPAD_FEEDBACK_CAPACITY || connection.pending >= MAX_TARGET_PENDING) {\n      finish('busy', 'Native call capacity includes promises that timed out but have not settled.');\n      return;\n    }\n    shared.pending++;\n    connection.pending++;\n    if (reset) connection.resetting++;\n    let terminal: ActiveEffect['finish'] | undefined = finish;\n    const timer = setTimeout(() => {\n      terminal?.('timeout', 'Native promise did not settle before duration + 1000ms.');\n      terminal = undefined;\n      // Keep the native slot occupied until actual settlement. A timeout is not cancellation.\n      if (!reset && connection.active?.finish === finish) stopOwned(connection, 'timeout');\n    }, duration + SETTLE_GRACE_MS);\n    function settled(status: GamepadFeedbackStatus, detail?: string) {\n      clearTimeout(timer);\n      shared.pending--;\n      connection.pending--;\n      if (reset) connection.resetting--;\n      terminal?.(status, detail);\n      terminal = undefined;\n      if (connection.active?.finish === finish) delete connection.active;\n    }\n    try {\n      const promise = invoke();\n      Promise.resolve(promise).then(\n        (value) =>\n          settled(\n            value === 'complete' ? 'complete' : value === 'preempted' ? 'preempted' : 'rejected',\n            value === 'complete' || value === 'preempted'\n              ? undefined\n              : `Unexpected native result: ${String(value).slice(0, 256)}`,\n          ),\n        (cause) => settled('rejected', rejectionDetail(cause)),\n      );\n    } catch (cause) {\n      settled('rejected', rejectionDetail(cause));\n    }\n  }\n  function stopOwned(connection: Connection, status: GamepadFeedbackStatus) {\n    const active = connection.active;\n    if (!active || active.owner !== attachment) return;\n    delete connection.active;\n    active.finish(status);\n    run(\n      connection,\n      true,\n      0,\n      () => active.actuator.reset(),\n      (outcome, detail) => {\n        if (outcome === 'rejected' || outcome === 'timeout' || outcome === 'busy')\n          publish({ id: 0, status: outcome, detail: `Lifecycle reset: ${detail ?? outcome}` });\n      },\n    );\n  }\n  function invalidate(index: number) {\n    const connection = shared.connections.get(index);\n    if (!connection) return;\n    connection.active?.finish('disconnected');\n    delete connection.active;\n    shared.connections.delete(index);\n  }\n  function onConnection(event: Event) {\n    invalidate((event as GamepadEvent).gamepad.index);\n  }\n  function release() {\n    for (const connection of shared.connections.values()) stopOwned(connection, 'preempted');\n    // Old queued targets cannot revive an effect after a control boundary.\n    attachment = nextAttachment++;\n    lastCommand = 0;\n  }\n  function onHidden() {\n    if (doc?.visibilityState === 'hidden') release();\n  }\n  win?.addEventListener?.('gamepaddisconnected', onConnection);\n  win?.addEventListener?.('gamepadconnected', onConnection);\n  doc?.addEventListener?.('visibilitychange', onHidden);\n\n  function observe(pads: readonly RawGamepadStub[]) {\n    const present = new Set(pads.map((pad) => pad.index));\n    for (const index of shared.connections.keys()) if (!present.has(index)) invalidate(index);\n    for (const raw of pads) {\n      const pad = raw as NativePad;\n      let connection = shared.connections.get(pad.index);\n      if (connection && connection.id !== pad.id) {\n        invalidate(pad.index);\n        connection = undefined;\n      }\n      if (!connection) {\n        connection = { id: pad.id, generation: nextGeneration++, pad, pending: 0, resetting: 0 };\n        shared.connections.set(pad.index, connection);\n      } else {\n        connection.pad = pad;\n      }\n    }\n  }\n  function target(index: number): GamepadFeedbackTarget | undefined {\n    const connection = shared.connections.get(index);\n    if (!connection || detached) return undefined;\n    return Object.freeze({ attachment, index, generation: connection.generation });\n  }\n  function dispatch(intents: readonly GamepadFeedbackIntent[]) {\n    if (detached) return;\n    // An oversized transport batch is rejected as one bounded loss observation.\n    if (intents.length > GAMEPAD_FEEDBACK_CAPACITY) {\n      lost += intents.length;\n      return;\n    }\n    for (const intent of intents) {\n      if (!Number.isSafeInteger(intent.id) || intent.id <= 0 || !intent.target) continue;\n      if (intent.target.attachment !== attachment) {\n        publish({ id: intent.id, status: 'stale' });\n        continue;\n      }\n      if (intent.id <= lastCommand) continue; // Duplicate/late transport never replays native work.\n      lastCommand = intent.id;\n      let finished = false;\n      const finish: ActiveEffect['finish'] = (status, detail) => {\n        if (finished) return;\n        finished = true;\n        publish({ id: intent.id, status, ...(detail === undefined ? {} : { detail }) });\n      };\n      const connection = shared.connections.get(intent.target.index);\n      if (!connection) {\n        finish('disconnected');\n        continue;\n      }\n      if (connection.generation !== intent.target.generation) {\n        finish('stale');\n        continue;\n      }\n      if (doc?.visibilityState === 'hidden') {\n        finish('hidden');\n        continue;\n      }\n      if (!supports(connection.pad)) {\n        finish('unsupported');\n        continue;\n      }\n      if (\n        connection.resetting ||\n        shared.pending >= GAMEPAD_FEEDBACK_CAPACITY ||\n        connection.pending >= MAX_TARGET_PENDING\n      ) {\n        finish('busy');\n        continue;\n      }\n      const actuator = connection.pad.vibrationActuator as Actuator;\n      if (intent.kind === 'stop') {\n        if (connection.active && connection.active.owner !== attachment) {\n          finish('busy');\n          continue;\n        }\n        connection.active?.finish('preempted');\n        delete connection.active;\n        run(connection, true, 0, () => actuator.reset(), finish);\n      } else if (intent.kind === 'play' && validGamepadRumble(intent.effect)) {\n        // Reserve one reset slot for every active connection, including this play.\n        let activeCount = 0;\n        for (const item of shared.connections.values()) if (item.active) activeCount++;\n        if (\n          connection.pending >= MAX_TARGET_PENDING - 1 ||\n          shared.pending + activeCount + (connection.active ? 1 : 2) > GAMEPAD_FEEDBACK_CAPACITY\n        ) {\n          finish('busy');\n          continue;\n        }\n        connection.active?.finish('preempted');\n        connection.active = { owner: attachment, finish, actuator };\n        run(\n          connection,\n          false,\n          intent.effect.durationMs,\n          () =>\n            actuator.playEffect('dual-rumble', {\n              duration: intent.effect.durationMs,\n              startDelay: 0,\n              strongMagnitude: intent.effect.strongMagnitude,\n              weakMagnitude: intent.effect.weakMagnitude,\n            }),\n          finish,\n        );\n      } else {\n        finish('invalid');\n      }\n    }\n  }\n  return {\n    feedback,\n    observe,\n    target,\n    supported: (index: number) => {\n      const pad = shared.connections.get(index)?.pad;\n      return pad ? supports(pad) : false;\n    },\n    dispatch,\n    sampleResults() {\n      dispatch(feedback.drainIntents());\n      const out = results;\n      results = [];\n      const dropped = lost;\n      lost = 0;\n      return { feedbackResults: out, feedbackLostResults: dropped };\n    },\n    release,\n    inspect: () => ({\n      pendingNative: shared.pending,\n      queuedResults: results.length,\n      lostResults: lost,\n    }),\n    detach() {\n      if (detached) return;\n      release();\n      detached = true;\n      feedback.dispose();\n      if (--shared.owners === 0) shared.connections.clear();\n      results = [];\n      win?.removeEventListener?.('gamepaddisconnected', onConnection);\n      win?.removeEventListener?.('gamepadconnected', onConnection);\n      doc?.removeEventListener?.('visibilitychange', onHidden);\n    },\n  };\n}\nfunction rejectionDetail(cause: unknown): string {\n  return (cause instanceof Error ? `${cause.name}: ${cause.message}` : String(cause)).slice(0, 512);\n}\n","/** Held state and frame edges; admission, focus and source merging belong to the backend. */\nexport class KeyLatch {\n  readonly held = new Set<string>();\n  readonly pressed = new Set<string>();\n  readonly released = new Set<string>();\n\n  press(key: string): void {\n    if (!this.held.has(key)) this.pressed.add(key);\n    this.held.add(key);\n  }\n\n  release(key: string): void {\n    this.held.delete(key);\n    this.released.add(key);\n  }\n\n  clearFrame(): void {\n    this.pressed.clear();\n    this.released.clear();\n  }\n\n  clear(): void {\n    this.clearFrame();\n    this.held.clear();\n  }\n\n  releaseAll(): void {\n    this.clearFrame();\n    for (const key of this.held) this.released.add(key);\n    this.held.clear();\n  }\n}\n\nexport class ButtonLatch {\n  readonly held: [boolean, boolean, boolean] = [false, false, false];\n  readonly pressed: [boolean, boolean, boolean] = [false, false, false];\n  readonly released: [boolean, boolean, boolean] = [false, false, false];\n\n  set(slot: 0 | 1 | 2, down: boolean): void {\n    if (down && !this.held[slot]) this.pressed[slot] = true;\n    if (!down && this.held[slot]) this.released[slot] = true;\n    this.held[slot] = down;\n  }\n\n  clearFrame(): void {\n    this.pressed.fill(false);\n    this.released.fill(false);\n  }\n\n  clear(): void {\n    this.clearFrame();\n    this.held.fill(false);\n  }\n\n  releaseAll(): void {\n    this.clearFrame();\n    for (const slot of [0, 1, 2] as const) this.set(slot, false);\n  }\n}\n","// gamepad-frame.ts -- pure functions for per-frame gamepad diff from raw\n// navigator.getGamepads() output. No DOM dependency; only called by\n// browser-backend.ts @internal.\n//\n// D-1: edge diff (justPressed / justReleased) derived via set-delta from\n// prev vs cur pressed sets — same pattern as Bevy button_input.rs.\n// D-1: slot diff (connect / disconnect) derived via set difference from\n// prev vs cur slot index sets.\n// OOS-4: no deadzone applied — axes pass through raw.\n//\n// M3 D-1 (option A): non-standard-layout gamepads are normalized at the\n// acquisition layer. When a caller-supplied remapLookup returns SDL\n// gamecontrollerdb.txt mapping tokens for the gamepad's id, raw HID\n// button/axis indices are re-projected onto the standard layout and the\n// slot is reported with standardMapping=true. No lookup / no match keeps\n// the Feat1 empty-signal behaviour (graceful degradation).\n\nimport type { MappingTokens } from './controller-db';\nimport type { GamepadSlotSample } from './input-snapshot';\n\n/**\n * Minimal raw Gamepad shape from browser API (no DOM types here).\n *\n * M3 F-2 seam fix: `id` mirrors the browser `Gamepad.id` string so the\n * remap lookup can derive the SDL GUID keyed by device identity (not by\n * slot index, which is unstable across reconnects).\n */\nexport interface RawGamepadStub {\n  readonly index: number;\n  readonly id: string;\n  readonly connected: boolean;\n  readonly mapping: string;\n  readonly buttons: readonly { readonly value: number; readonly pressed: boolean }[];\n  readonly axes: readonly number[];\n}\n\n/**\n * Standard layout button count (17: 0-16) and axis count (4: 0-3).\n * Non-standard gamepads without a DB match report standardMapping=false\n * and empty readpoints.\n */\nconst STANDARD_BUTTON_COUNT = 17;\n\n/**\n * SDL logical name -> standard-layout button index (W3C Gamepad standard\n * mapping, KB source section 4.3). `guide` occupies the optional 17th slot.\n */\nconst STANDARD_BUTTON_INDEX: Readonly<Record<string, number>> = {\n  a: 0,\n  b: 1,\n  x: 2,\n  y: 3,\n  leftshoulder: 4,\n  rightshoulder: 5,\n  lefttrigger: 6,\n  righttrigger: 7,\n  back: 8,\n  start: 9,\n  leftstick: 10,\n  rightstick: 11,\n  dpup: 12,\n  dpdown: 13,\n  dpleft: 14,\n  dpright: 15,\n  guide: 16,\n};\n\n/** SDL logical name -> standard-layout axis index (KB source section 4.3). */\nconst STANDARD_AXIS_INDEX: Readonly<Record<string, number>> = {\n  leftx: 0,\n  lefty: 1,\n  rightx: 2,\n  righty: 3,\n};\n\n/** Analog trigger threshold: a trigger mapped to an axis counts as pressed above this. */\nconst TRIGGER_PRESS_THRESHOLD = 0.5;\n\ninterface RemappedReadpoints {\n  readonly pressed: Set<number>;\n  readonly buttonValues: Map<number, number>;\n  readonly axes: [number, number, number, number];\n}\n\n/**\n * Re-project a non-standard raw gamepad onto the standard layout using SDL\n * mapping tokens. Browser getGamepads() exposes only buttons[] and axes[]\n * (no hats), so hat tokens (dpad-as-hat) cannot be resolved from raw data\n * and are skipped — a documented graceful degradation for the rare hat-only\n * dpad devices under the web Gamepad API.\n */\nfunction remapToStandardLayout(gp: RawGamepadStub, tokens: MappingTokens): RemappedReadpoints {\n  const pressed = new Set<number>();\n  const buttonValues = new Map<number, number>();\n  const axes: [number, number, number, number] = [0, 0, 0, 0];\n\n  for (const [name, token] of Object.entries(tokens)) {\n    const stdButton = STANDARD_BUTTON_INDEX[name];\n    const stdAxis = STANDARD_AXIS_INDEX[name];\n\n    if (stdButton !== undefined) {\n      if (token.kind === 'button') {\n        const raw = gp.buttons[token.index];\n        if (raw) {\n          buttonValues.set(stdButton, raw.value);\n          if (raw.pressed) pressed.add(stdButton);\n        }\n      } else if (token.kind === 'axis') {\n        // Trigger (or button) mapped to a raw axis: value = raw axis reading.\n        const value = gp.axes[token.index] ?? 0;\n        buttonValues.set(stdButton, value);\n        if (value > TRIGGER_PRESS_THRESHOLD) pressed.add(stdButton);\n      }\n      // hat -> button (dpad): no hat source in the browser API; skip.\n      continue;\n    }\n\n    if (stdAxis !== undefined && token.kind === 'axis') {\n      const raw = gp.axes[token.index] ?? 0;\n      axes[stdAxis] = token.half === '-' ? -raw : raw;\n    }\n  }\n\n  return { pressed, buttonValues, axes };\n}\n\n/** Build an empty-signal slot sample for a connected non-standard pad with no mapping. */\nfunction emptySlot(index: number): GamepadSlotSample {\n  return {\n    index,\n    standardMapping: false,\n    pressed: new Set(),\n    justPressed: new Set(),\n    justReleased: new Set(),\n    buttonValues: new Map(),\n    axes: [0, 0, 0, 0],\n  };\n}\n\n/** Derive justPressed / justReleased edge sets from prev vs cur pressed sets. */\nfunction edges(\n  prevPressed: ReadonlySet<number>,\n  curPressed: ReadonlySet<number>,\n): { justPressed: Set<number>; justReleased: Set<number> } {\n  const justPressed = new Set<number>();\n  const justReleased = new Set<number>();\n  for (const b of curPressed) {\n    if (!prevPressed.has(b)) justPressed.add(b);\n  }\n  for (const b of prevPressed) {\n    if (!curPressed.has(b)) justReleased.add(b);\n  }\n  return { justPressed, justReleased };\n}\n\n/**\n * Diff prev vs cur frames for all gamepad slots. Returns a flat\n * GamepadSlotSample[] array keyed by gamepad.index.\n *\n * - Standard-mapping slots produce GamepadSlotSample with edge sets filled\n *   from prev vs cur pressed-set delta.\n * - Non-standard slots: when `remapLookup` returns mapping tokens for the\n *   gamepad id, raw HID indices are re-projected onto the standard layout\n *   and the slot reports standardMapping=true (D-1 semantic redefinition).\n *   With no lookup or no match, the slot reports standardMapping=false with\n *   empty readpoints and connected=true (Feat1 behaviour, AC-04).\n * - Disconnected slots (in prev but not in cur) produce no entry: a slot\n *   absent from the sample reads as connected=false.\n * - Null entries in the browser getGamepads() array are skipped by the\n *   caller before calling this function.\n *\n * @param remapLookup - Optional acquisition-layer normalizer. Given a\n *   browser Gamepad.id, returns SDL mapping tokens or null. Only consulted\n *   for non-standard-mapping gamepads (D-1 option A).\n */\nexport function diffGamepadFrame(\n  prev: ReadonlyMap<number, GamepadSlotSample>,\n  curGamepads: readonly RawGamepadStub[],\n  remapLookup?: (gamepadId: string) => MappingTokens | null,\n): GamepadSlotSample[] {\n  const results: GamepadSlotSample[] = [];\n\n  for (const gp of curGamepads) {\n    const tokens = gp.mapping === 'standard' ? undefined : remapLookup?.(gp.id);\n    if (gp.mapping !== 'standard' && !tokens) {\n      results.push(emptySlot(gp.index));\n      continue;\n    }\n    const readpoints = tokens ? remapToStandardLayout(gp, tokens) : standardReadpoints(gp);\n    const prevPressed = prev.get(gp.index)?.pressed ?? new Set<number>();\n    results.push({\n      index: gp.index,\n      standardMapping: true,\n      ...readpoints,\n      ...edges(prevPressed, readpoints.pressed),\n    });\n  }\n\n  return results;\n}\n\n/** Read standard-mapping indices without remapping or applying deadzones. */\nfunction standardReadpoints(gp: RawGamepadStub): RemappedReadpoints {\n  const curPressed = new Set<number>();\n  const buttonValues = new Map<number, number>();\n  const btnCount = Math.min(gp.buttons.length, STANDARD_BUTTON_COUNT);\n  for (let b = 0; b < btnCount; b++) {\n    const btn = gp.buttons[b];\n    if (!btn) continue;\n    buttonValues.set(b, btn.value);\n    if (btn.pressed) curPressed.add(b);\n  }\n  // Axes: raw values, no deadzone (OOS-4).\n  const axes: [number, number, number, number] = [\n    gp.axes[0] ?? 0,\n    gp.axes[1] ?? 0,\n    gp.axes[2] ?? 0,\n    gp.axes[3] ?? 0,\n  ];\n  return { pressed: curPressed, buttonValues, axes };\n}\n","// gesture-recognizer.ts -- pure-function gesture state machines for\n// forgeax-engine input (M5). Zero DOM / ECS dependencies: node-testable.\n//\n// charter awareness:\n//   C-3 (single legal cross-frame state holder) -- the recognizer owns the\n//     only sanctioned cross-frame gesture state. The browser backend stores\n//     a `RecognizerState` in its closure (alongside prevGamepadFrame /\n//     pointerMap / vjBindState) and threads it through `processGestureFrame`\n//     every `sample()`. This module never mutates its inputs; it returns a\n//     fresh `newState` the producer must store for the next frame.\n//   D-3 clock decoupling -- all timers advance off the injected `now`\n//     value, NOT off pointer-event arrival. An idle frame (empty phase\n//     queue) still advances long-press timing, so recognition is decoupled\n//     from event frequency (AC-16). The F-1 falsification test proves an\n//     event-frequency-coupled impl fails.\n//   D-4 dual channel -- returns continuous values (`gestureState`:\n//     pinchScale / rotationAngle) plus a one-frame lifecycle event list\n//     (`gestureEvents`). The backend forwards these as the optional\n//     `gestures?` / `gestureEvents?` sample fields (D-4 / F1 precedent).\n//   D-10 thresholds -- long-press 500ms + slop 10px, double-tap 350ms +\n//     10px, swipe 0.5 px/ms over a 100ms window; exported as constants.\n//   D-11 pinch/rotate -- lock the earliest two pointers, ignore a third;\n//     2->1 emits end + freezes continuous values; a fresh pair emits begin\n//     and resets to identity (1.0 / 0).\n\nimport type { PointerPhaseEvent, PointerType } from './input-snapshot';\n\n// D-10 threshold defaults (LayaAir + Godot prior-art, plan-strategy section 2).\nexport const LONG_PRESS_DURATION_MS = 500;\nexport const LONG_PRESS_SLOP = 10;\nexport const DOUBLE_TAP_INTERVAL_MS = 350;\nexport const DOUBLE_TAP_DISTANCE = 10;\nexport const SWIPE_VELOCITY_THRESHOLD = 0.5;\nexport const SWIPE_WINDOW_MS = 100;\n\n/** Swipe direction taken from the dominant displacement axis (D-10). */\nconst SWIPE_DIRECTIONS = ['left', 'right', 'up', 'down'] as const;\nexport type SwipeDirection = (typeof SWIPE_DIRECTIONS)[number];\n\n/**\n * Continuous gesture values read each frame via `snap.gesture` (D-4).\n * Identity when no gesture is active or after a cancel/reset (AC-12):\n * pinchScale = 1.0, rotationAngle = 0.\n */\nexport interface GestureState {\n  readonly pinchScale: number;\n  readonly rotationAngle: number;\n}\n\n/**\n * Closed discriminant union of gesture lifecycle + instantaneous events\n * (AC-13). One-frame lifecycle: an event appears in exactly one frame's\n * `gestureEvents`. Every member carries `pointerType` (narrowed union,\n * AC-19) so consumers can exhaustively switch on gesture kind AND device\n * type without a default branch.\n */\nexport type GestureEvent =\n  | {\n      readonly kind: 'pinch-begin';\n      readonly pointerIds: readonly [number, number];\n      readonly pointerType: PointerType;\n      readonly timestamp: number;\n    }\n  | {\n      readonly kind: 'pinch-end';\n      readonly pointerIds: readonly [number, number];\n      readonly pointerType: PointerType;\n      readonly timestamp: number;\n    }\n  | {\n      readonly kind: 'pinch-cancel';\n      readonly pointerIds: readonly [number, number];\n      readonly pointerType: PointerType;\n      readonly timestamp: number;\n    }\n  | {\n      readonly kind: 'rotate-begin';\n      readonly pointerIds: readonly [number, number];\n      readonly pointerType: PointerType;\n      readonly timestamp: number;\n    }\n  | {\n      readonly kind: 'rotate-end';\n      readonly pointerIds: readonly [number, number];\n      readonly pointerType: PointerType;\n      readonly timestamp: number;\n    }\n  | {\n      readonly kind: 'rotate-cancel';\n      readonly pointerIds: readonly [number, number];\n      readonly pointerType: PointerType;\n      readonly timestamp: number;\n    }\n  | {\n      readonly kind: 'swipe';\n      readonly pointerId: number;\n      readonly direction: SwipeDirection;\n      readonly pointerType: PointerType;\n      readonly timestamp: number;\n    }\n  | {\n      readonly kind: 'long-press';\n      readonly pointerId: number;\n      readonly x: number;\n      readonly y: number;\n      readonly pointerType: PointerType;\n      readonly timestamp: number;\n    }\n  | {\n      readonly kind: 'double-tap';\n      readonly pointerId: number;\n      readonly x: number;\n      readonly y: number;\n      readonly pointerType: PointerType;\n      readonly timestamp: number;\n    };\n\n/** Live position + device type for a pointer (subset of the backend pointerMap entry). */\nexport interface RecognizerPointer {\n  readonly x: number;\n  readonly y: number;\n  readonly pointerType: PointerType;\n}\n\n/** Locked dual-finger tracker for pinch + rotate (D-11). */\nexport interface PinchRotateTracker {\n  readonly pointerA: number;\n  readonly pointerB: number;\n  readonly initialDistance: number;\n  /** Previous frame's raw atan2 angle; rotation accumulates frame deltas (D-11). */\n  readonly lastAngle: number;\n  readonly pointerType: PointerType;\n}\n\n/** Per-pointer long-press arming state (D-10). */\nexport interface LongPressTracker {\n  readonly downTime: number;\n  readonly x: number;\n  readonly y: number;\n  readonly pointerType: PointerType;\n  readonly armed: boolean;\n  readonly fired: boolean;\n}\n\n/** Timestamped position sample for swipe velocity (D-10, 100ms window). */\nexport interface SwipeSample {\n  readonly t: number;\n  readonly x: number;\n  readonly y: number;\n}\n\n/** Last recorded tap for double-tap window matching (D-10). */\nexport interface TapRecord {\n  readonly time: number;\n  readonly x: number;\n  readonly y: number;\n}\n\n/**\n * The single legal cross-frame gesture state (C-3). Immutable: each\n * `processGestureFrame` returns a fresh copy; the producer stores it for\n * the next frame. `gesture` is the current continuous value read by\n * `snap.gesture` -- live during pinch, frozen after a 2->1 end, identity\n * after cancel/reset or when no gesture ever activated.\n */\nexport interface RecognizerState {\n  readonly pinch: PinchRotateTracker | null;\n  readonly gesture: GestureState;\n  readonly longPresses: ReadonlyMap<number, LongPressTracker>;\n  readonly lastTap: TapRecord | null;\n  readonly swipeHistory: ReadonlyMap<number, readonly SwipeSample[]>;\n}\n\n/** Result of processing one frame of phase events (D-4 dual channel). */\nexport interface GestureFrameResult {\n  readonly newState: RecognizerState;\n  readonly gestureState: GestureState;\n  readonly gestureEvents: readonly GestureEvent[];\n}\n\n/** Identity continuous value (AC-12): no scale, no rotation. */\nexport const IDENTITY_GESTURE: GestureState = Object.freeze({ pinchScale: 1, rotationAngle: 0 });\n\n/** Fresh recognizer state with no active gestures. */\nexport function createRecognizerState(): RecognizerState {\n  return {\n    pinch: null,\n    gesture: IDENTITY_GESTURE,\n    longPresses: new Map(),\n    lastTap: null,\n    swipeHistory: new Map(),\n  };\n}\n\n// ─── pure math helpers ───────────────────────────────────────────────\n\nfunction distance(ax: number, ay: number, bx: number, by: number): number {\n  return Math.hypot(bx - ax, by - ay);\n}\n\nfunction angleOf(ax: number, ay: number, bx: number, by: number): number {\n  return Math.atan2(by - ay, bx - ax);\n}\n\n/** Wrap an angle to (-PI, PI] so accumulated rotation never jumps a full turn. */\nfunction normalizeAngle(a: number): number {\n  let r = a;\n  while (r > Math.PI) r -= 2 * Math.PI;\n  while (r <= -Math.PI) r += 2 * Math.PI;\n  return r;\n}\n\nfunction dominantDirection(dx: number, dy: number): SwipeDirection {\n  if (Math.abs(dx) >= Math.abs(dy)) return dx >= 0 ? SWIPE_DIRECTIONS[1] : SWIPE_DIRECTIONS[0];\n  // Screen space: +y points down.\n  return dy >= 0 ? SWIPE_DIRECTIONS[3] : SWIPE_DIRECTIONS[2];\n}\n\n/**\n * AC-19 real consumption path: exhaustive switch on `PointerType` with no\n * default branch. Every gesture event's `pointerType` flows through here at\n * construction, so adding a 4th `PointerType` member fails to compile\n * (the function would then be able to return `undefined`, violating its\n * `PointerType` return type). This is the sanctioned AC-19 consumption\n * proof required by plan-strategy section 7 (M5 boundary).\n */\nfunction narrowGesturePointerType(pt: PointerType): PointerType {\n  switch (pt) {\n    case 'mouse':\n      return 'mouse';\n    case 'pen':\n      return 'pen';\n    case 'touch':\n      return 'touch';\n  }\n}\n\n// ─── mutable per-frame working context ───────────────────────────────\n\ninterface WorkContext {\n  pinch: PinchRotateTracker | null;\n  gesture: { pinchScale: number; rotationAngle: number };\n  longPresses: Map<number, LongPressTracker>;\n  lastTap: TapRecord | null;\n  swipeHistory: Map<number, SwipeSample[]>;\n  events: GestureEvent[];\n}\n\nfunction emitPinchLifecycle(\n  ctx: WorkContext,\n  phase: 'begin' | 'end' | 'cancel',\n  tracker: PinchRotateTracker,\n  now: number,\n): void {\n  const pointerIds: readonly [number, number] = [tracker.pointerA, tracker.pointerB];\n  const pointerType = narrowGesturePointerType(tracker.pointerType);\n  ctx.events.push({ kind: `pinch-${phase}`, pointerIds, pointerType, timestamp: now });\n  ctx.events.push({ kind: `rotate-${phase}`, pointerIds, pointerType, timestamp: now });\n}\n\nfunction handleDown(ctx: WorkContext, ev: PointerPhaseEvent, now: number): void {\n  // Arm a long-press timer + start a swipe velocity window + tap start.\n  ctx.longPresses.set(ev.pointerId, {\n    downTime: now,\n    x: ev.x,\n    y: ev.y,\n    pointerType: ev.pointerType,\n    armed: true,\n    fired: false,\n  });\n  ctx.swipeHistory.set(ev.pointerId, [{ t: now, x: ev.x, y: ev.y }]);\n}\n\nfunction handleMove(ctx: WorkContext, ev: PointerPhaseEvent, now: number): void {\n  // Disarm the long-press if the finger strays beyond slop (D-10).\n  const lp = ctx.longPresses.get(ev.pointerId);\n  if (lp?.armed && distance(lp.x, lp.y, ev.x, ev.y) > LONG_PRESS_SLOP) {\n    ctx.longPresses.set(ev.pointerId, { ...lp, armed: false });\n  }\n  // Append to the swipe velocity window, pruning samples outside it.\n  const hist = ctx.swipeHistory.get(ev.pointerId);\n  if (hist) {\n    hist.push({ t: now, x: ev.x, y: ev.y });\n    pruneSwipeWindow(hist, now);\n  }\n}\n\nfunction pruneSwipeWindow(hist: SwipeSample[], now: number): void {\n  const cutoff = now - SWIPE_WINDOW_MS;\n  // Keep at least the last sample so an up always has a reference point.\n  while (hist.length > 1 && hist[0] !== undefined && hist[0].t < cutoff) {\n    hist.shift();\n  }\n}\n\nfunction detectSwipe(ctx: WorkContext, ev: PointerPhaseEvent, now: number): void {\n  const hist = ctx.swipeHistory.get(ev.pointerId);\n  if (!hist || hist.length === 0) return;\n  const cutoff = now - SWIPE_WINDOW_MS;\n  const oldest = hist.find((s) => s.t >= cutoff) ?? hist[0];\n  if (!oldest) return;\n  const dt = now - oldest.t;\n  if (dt <= 0) return;\n  const dist = distance(oldest.x, oldest.y, ev.x, ev.y);\n  if (dist / dt < SWIPE_VELOCITY_THRESHOLD) return;\n  ctx.events.push({\n    kind: 'swipe',\n    pointerId: ev.pointerId,\n    direction: dominantDirection(ev.x - oldest.x, ev.y - oldest.y),\n    pointerType: narrowGesturePointerType(ev.pointerType),\n    timestamp: now,\n  });\n}\n\nfunction detectDoubleTap(ctx: WorkContext, ev: PointerPhaseEvent, now: number): void {\n  const prev = ctx.lastTap;\n  const withinTime = prev !== null && now - prev.time <= DOUBLE_TAP_INTERVAL_MS;\n  const withinDist = prev !== null && distance(prev.x, prev.y, ev.x, ev.y) <= DOUBLE_TAP_DISTANCE;\n  if (prev !== null && withinTime && withinDist) {\n    ctx.events.push({\n      kind: 'double-tap',\n      pointerId: ev.pointerId,\n      x: ev.x,\n      y: ev.y,\n      pointerType: narrowGesturePointerType(ev.pointerType),\n      timestamp: now,\n    });\n    ctx.lastTap = null; // consumed; a 3rd tap starts a fresh pair\n    return;\n  }\n  ctx.lastTap = { time: now, x: ev.x, y: ev.y };\n}\n\nfunction endPinchIfMember(\n  ctx: WorkContext,\n  pointerId: number,\n  phase: 'end' | 'cancel',\n  now: number,\n): void {\n  const pinch = ctx.pinch;\n  if (!pinch || (pinch.pointerA !== pointerId && pinch.pointerB !== pointerId)) return;\n  emitPinchLifecycle(ctx, phase, pinch, now);\n  ctx.pinch = null;\n  if (phase === 'cancel') {\n    // Cancel resets to identity (AC-18); end (2->1) freezes the last value (D-11).\n    ctx.gesture = { pinchScale: 1, rotationAngle: 0 };\n  }\n}\n\nfunction handleUp(ctx: WorkContext, ev: PointerPhaseEvent, now: number): void {\n  detectSwipe(ctx, ev, now);\n  detectDoubleTap(ctx, ev, now);\n  ctx.longPresses.delete(ev.pointerId);\n  ctx.swipeHistory.delete(ev.pointerId);\n  endPinchIfMember(ctx, ev.pointerId, 'end', now);\n}\n\nfunction handleCancel(ctx: WorkContext, ev: PointerPhaseEvent, now: number): void {\n  ctx.longPresses.delete(ev.pointerId);\n  ctx.swipeHistory.delete(ev.pointerId);\n  endPinchIfMember(ctx, ev.pointerId, 'cancel', now);\n}\n\nfunction tryLockPair(\n  ctx: WorkContext,\n  pointerMap: ReadonlyMap<number, RecognizerPointer>,\n  now: number,\n): void {\n  if (ctx.pinch !== null || pointerMap.size < 2) return;\n  // D-11: lock the earliest two pointers by ascending pointerId; a later\n  // (third+) finger is ignored while the pair holds.\n  const ids = [...pointerMap.keys()].sort((a, b) => a - b);\n  const idA = ids[0];\n  const idB = ids[1];\n  if (idA === undefined || idB === undefined) return;\n  const a = pointerMap.get(idA);\n  const b = pointerMap.get(idB);\n  if (!a || !b) return;\n  ctx.pinch = {\n    pointerA: idA,\n    pointerB: idB,\n    initialDistance: distance(a.x, a.y, b.x, b.y) || 1,\n    lastAngle: angleOf(a.x, a.y, b.x, b.y),\n    pointerType: a.pointerType,\n  };\n  ctx.gesture = { pinchScale: 1, rotationAngle: 0 };\n  emitPinchLifecycle(ctx, 'begin', ctx.pinch, now);\n}\n\nfunction updatePinchContinuous(\n  ctx: WorkContext,\n  pointerMap: ReadonlyMap<number, RecognizerPointer>,\n): void {\n  const pinch = ctx.pinch;\n  if (!pinch) return;\n  const a = pointerMap.get(pinch.pointerA);\n  const b = pointerMap.get(pinch.pointerB);\n  if (!a || !b) return; // a member briefly absent: keep the last value\n  const curDist = distance(a.x, a.y, b.x, b.y);\n  const curAngle = angleOf(a.x, a.y, b.x, b.y);\n  const delta = normalizeAngle(curAngle - pinch.lastAngle);\n  ctx.gesture = {\n    pinchScale: curDist / pinch.initialDistance,\n    rotationAngle: ctx.gesture.rotationAngle + delta,\n  };\n  ctx.pinch = { ...pinch, lastAngle: curAngle };\n}\n\nfunction fireLongPresses(\n  ctx: WorkContext,\n  pointerMap: ReadonlyMap<number, RecognizerPointer>,\n  now: number,\n): void {\n  const pinch = ctx.pinch;\n  for (const [id, lp] of ctx.longPresses) {\n    if (!lp.armed || lp.fired) continue;\n    if (now - lp.downTime < LONG_PRESS_DURATION_MS) continue;\n    if (!pointerMap.has(id)) continue; // finger must still be down\n    // A finger locked into an active pinch pair is committed to the dual\n    // gesture and must not also fire a long-press (D-11 dual-finger lock).\n    if (pinch && (pinch.pointerA === id || pinch.pointerB === id)) continue;\n    ctx.events.push({\n      kind: 'long-press',\n      pointerId: id,\n      x: lp.x,\n      y: lp.y,\n      pointerType: narrowGesturePointerType(lp.pointerType),\n      timestamp: now,\n    });\n    ctx.longPresses.set(id, { ...lp, fired: true });\n  }\n}\n\n/**\n * Process one frame of pointer phase events, advancing all timers off\n * `now`, and return the new state + continuous values + one-frame event\n * list (D-4). Never mutates its inputs.\n */\nexport function processGestureFrame(\n  phaseQueue: readonly PointerPhaseEvent[],\n  pointerMap: ReadonlyMap<number, RecognizerPointer>,\n  prevState: RecognizerState,\n  now: number,\n): GestureFrameResult {\n  const ctx: WorkContext = {\n    pinch: prevState.pinch,\n    gesture: { ...prevState.gesture },\n    longPresses: new Map(prevState.longPresses),\n    lastTap: prevState.lastTap,\n    swipeHistory: cloneSwipeHistory(prevState.swipeHistory),\n    events: [],\n  };\n\n  for (const ev of phaseQueue) {\n    switch (ev.phase) {\n      case 'down':\n        handleDown(ctx, ev, now);\n        break;\n      case 'move':\n        handleMove(ctx, ev, now);\n        break;\n      case 'up':\n        handleUp(ctx, ev, now);\n        break;\n      case 'cancel':\n        handleCancel(ctx, ev, now);\n        break;\n    }\n  }\n\n  tryLockPair(ctx, pointerMap, now);\n  updatePinchContinuous(ctx, pointerMap);\n  fireLongPresses(ctx, pointerMap, now);\n\n  const gesture: GestureState = Object.freeze({\n    pinchScale: ctx.gesture.pinchScale,\n    rotationAngle: ctx.gesture.rotationAngle,\n  });\n  const newState: RecognizerState = {\n    pinch: ctx.pinch,\n    gesture,\n    longPresses: ctx.longPresses,\n    lastTap: ctx.lastTap,\n    swipeHistory: ctx.swipeHistory,\n  };\n  return { newState, gestureState: gesture, gestureEvents: ctx.events };\n}\n\nfunction cloneSwipeHistory(\n  src: ReadonlyMap<number, readonly SwipeSample[]>,\n): Map<number, SwipeSample[]> {\n  const out = new Map<number, SwipeSample[]>();\n  for (const [id, samples] of src) out.set(id, [...samples]);\n  return out;\n}\n","// input-snapshot.ts -- frozen frame-start input snapshot Resource for\n// forgeax-engine. Multi-device surface (keyboard + mouse + gamepad + pointer +\n// virtualAxis) — each cluster is a frozen reader on the per-frame Sample.\n//\n// charter awareness:\n//   F1 single-entry indexability -- barrel exports all types; IDE autocomplete\n//     reaches the full surface from one import\n//   F2 minimal surface -- each device cluster exposes only its natural\n//     readpoints; no phantom methods or modal parameters\n//   P3 explicit failure -- no thrown errors from accessor methods; absent\n//     keys / pre-start state / disconnected slots / unsupported devices\n//     all report `false` / `0` / zero-vector (the empty signal IS the\n//     signal). `mouse.button(i)` / `gamepad.button(b)` parameters are\n//     literal unions so out-of-range indices are TS compile errors rather\n//     than runtime bounds-clamps.\n//   P4 consistent abstraction -- the snapshot hides the producer\n//     (browser listener wiring + gamepad polling) entirely; consumers read\n//     via the `InputSnapshot` Resource regardless of backend\n//   P5 producer/consumer split -- the InputBackend protocol decouples\n//     the producer from the snapshot; `frame-start-scan-system.ts` is the\n//     bridge that calls `backend.sample()` and writes the Resource\n\nimport type { ActionState, GetVectorOptions } from './action-state';\nimport { getAxis, getVector } from './action-state';\nimport type { GestureEvent, GestureState } from './gesture-recognizer';\nimport { IDENTITY_GESTURE } from './gesture-recognizer';\n\n// D-5 / AC-19: pointerType is narrowed from string to a 3-literal union.\n// The W3C Pointer Events spec allows '' when the device type cannot be\n// detected; coercion maps '' to 'mouse' at the producer, so the snapshot\n// only ever sees one of these three canonical values.\nexport type PointerType = 'mouse' | 'pen' | 'touch';\n\n/** Standard-layout gamepad button index (0-16 per W3C Gamepad spec). */\nexport type GamepadButtonIndex =\n  | 0\n  | 1\n  | 2\n  | 3\n  | 4\n  | 5\n  | 6\n  | 7\n  | 8\n  | 9\n  | 10\n  | 11\n  | 12\n  | 13\n  | 14\n  | 15\n  | 16;\n\n/** Standard-layout gamepad axis index (0-3 per W3C Gamepad spec). */\nimport type {\n  GamepadFeedback,\n  GamepadFeedbackIntent,\n  GamepadFeedbackResult,\n  GamepadFeedbackTarget,\n} from './gamepad-feedback';\n\nexport type GamepadAxisIndex = 0 | 1 | 2 | 3;\n\n/** W3C MouseEvent.button index (0=primary, 1=auxiliary, 2=secondary). */\nexport type MouseButtonIndex = 0 | 1 | 2;\n\n/** Per-slot gamepad frame data produced by `sample()`. */\nexport interface GamepadSlotSample {\n  readonly feedbackTarget?: GamepadFeedbackTarget;\n  readonly dualRumble?: boolean;\n  readonly index: number;\n  /**\n   * True when the browser reports a standard mapping OR the SDL controller\n   * DB has normalized a non-standard layout at the acquisition layer (M3\n   * D-1 redefinition). The Feat1 meaning (\"browser-reported standard\n   * mapping only\") is widened here: a non-standard pad whose GUID matches\n   * gamecontrollerdb.txt is re-projected onto the standard layout and\n   * reported as standardMapping=true, so bindings and direct reads see a\n   * uniform standard button/axis space. A non-standard pad with no DB match\n   * (or before the DB has loaded) keeps standardMapping=false + empty\n   * readpoints (graceful degradation).\n   */\n  readonly standardMapping: boolean;\n  readonly pressed: ReadonlySet<number>;\n  readonly justPressed: ReadonlySet<number>;\n  readonly justReleased: ReadonlySet<number>;\n  readonly buttonValues: ReadonlyMap<number, number>;\n  readonly axes: readonly [number, number, number, number];\n}\n\n/** Per-pointer live state (active contacts tracked by pointerId).\n *\n * D-5 / E-10: `pointerType` is a 3-literal union. `'mouse'` is the default\n * placeholder for inactive pointers — when `active=false`, `pointerType` is\n * always `'mouse'`. The semantic \"no pointer\" is carried by the `active`\n * field, never by a sentinel string value.\n */\nexport interface PointerSample {\n  readonly pointerId: number;\n  readonly x: number;\n  readonly y: number;\n  readonly pressure: number;\n  readonly pointerType: PointerType;\n  readonly active: boolean;\n  readonly delta: { readonly x: number; readonly y: number };\n}\n\n/** Per-frame phase event (down/move/up/cancel queue, one-frame lifecycle). */\nexport interface PointerPhaseEvent {\n  readonly pointerId: number;\n  readonly phase: 'down' | 'move' | 'up' | 'cancel';\n  readonly x: number;\n  readonly y: number;\n  readonly pressure: number;\n  readonly pointerType: PointerType;\n}\n\n/** Per-frame virtual axis output (named joystick derived from pointer input). */\nexport interface VirtualAxisSample {\n  readonly name: string;\n  readonly x: number;\n  readonly y: number;\n}\n\n/**\n * Configuration for an on-screen virtual joystick (M3). Consumed by\n * attachBrowserInputBackend and passed through to deriveVirtualAxes.\n *\n * Fixed mode: origin is config.anchor (or region center if anchor omitted).\n * Floating mode: origin is the first pointerdown position within the region.\n */\nexport interface VirtualJoystickConfig {\n  readonly name: string;\n  readonly mode: 'fixed' | 'floating';\n  /** Canvas-pixel region where touches are eligible to bind this joystick. */\n  readonly region: {\n    readonly x: number;\n    readonly y: number;\n    readonly width: number;\n    readonly height: number;\n  };\n  /** Fixed-mode origin anchor. Defaults to region center when omitted. */\n  readonly anchor?: { readonly x: number; readonly y: number } | undefined;\n  /** Max drag radius in canvas pixels. Vector is clamped then normalized to radius. */\n  readonly radius: number;\n  /** Normalized deadzone (0..1). |vec| < deadzone → zero vector output. */\n  readonly deadzone: number;\n}\n\n/** Capability snapshot (frozen at backend attach time). */\nexport interface Capabilities {\n  readonly gamepad: boolean;\n  readonly pointer: boolean;\n}\n\n/**\n * Frozen value-shape view exposed to user systems via the `InputSnapshot`\n * Resource. The methods are pure reads; calling them does not mutate any\n * accumulator (charter P3 -- no observable side effects from the accessor\n * surface). A fresh `InputSnapshot` instance is constructed by the\n * frame-start scan system once per `world.update()` and replaces the\n * previous Resource value.\n */\nexport interface InputSnapshot {\n  /** Keyboard view (held state plus frame edges). */\n  readonly keyboard: {\n    /**\n     * `true` while `key` is currently held. `key` matches the value the\n     * backend records (KeyboardEvent.key for the browser backend). When\n     * the key is not in the held set, returns `false` -- never throws\n     * (charter P3: empty signal is the signal).\n     */\n    down(key: string): boolean;\n    /** `true` for the first frame in which `key` becomes held. */\n    justPressed(key: string): boolean;\n    /**\n     * `true` for one frame after the key was released (the up-edge). The\n     * edge collapses on the following `world.update()`. `key` not in the\n     * up-edge set returns `false`.\n     */\n    up(key: string): boolean;\n    /** Code-key equivalent of `down`, using KeyboardEvent.code identity. */\n    downCode(code: string): boolean;\n    /** Code-key equivalent of `justPressed`. */\n    justPressedCode(code: string): boolean;\n    /** Code-key equivalent of `up`. */\n    upCode(code: string): boolean;\n  };\n  /** Mouse view (charter F2 minimal surface: position + movementDelta + button + wheelDelta). */\n  readonly mouse: {\n    /**\n     * Latest canvas-pixel cursor position. This is available during hover;\n     * it does not require a button press or pointer capture. The position is\n     * frozen with the rest of the frame-start snapshot.\n     */\n    readonly position: { readonly x: number; readonly y: number } | undefined;\n    /**\n     * PointerLock-style accumulated movement since the previous frame.\n     * Value is frozen at frame-start; reading it does not clear the\n     * accumulator. The next `world.update()` produces a fresh delta\n     * (zero if no movement events arrived).\n     */\n    readonly movementDelta: { readonly x: number; readonly y: number };\n    /**\n     * Merged pointer-lock state: true when either W3C pointer-lock\n     * (pointerLockElement === this backend's canvas) OR the lockProvider\n     * path has engaged. Consumers read this to decide whether to consume\n     * movementDelta for look/camera rotation. Required field, alongside\n     * movementDelta -- both facts sit at the same attribute path for\n     * single-point indexing (charter F1).\n     */\n    readonly pointerLocked: boolean;\n    /**\n     * `true` while the W3C MouseEvent.button slot `i` is held. `i` is\n     * narrowed to the literal `0 | 1 | 2` so out-of-range indices are\n     * rejected at compile time (charter P3 explicit failure: TS literal\n     * narrowing replaces a runtime bounds-clamp).\n     *\n     * - 0 -- primary button (left)\n     * - 1 -- auxiliary button (middle)\n     * - 2 -- secondary button (right)\n     */\n    button(i: MouseButtonIndex): boolean;\n    /** `true` for the first frame in which button `i` becomes held. */\n    justPressed(i: MouseButtonIndex): boolean;\n    /** `true` for the frame in which button `i` is released. */\n    justReleased(i: MouseButtonIndex): boolean;\n    /**\n     * Discrete wheel notches accumulated since the previous frame.\n     * Plan-strategy D-5 sign-discrete: each `WheelEvent` contributes\n     * `Math.sign(event.deltaY)` to the per-frame accumulator regardless\n     * of `deltaMode` (PIXEL / LINE / PAGE all collapse). Sign convention\n     * follows W3C `WheelEvent.deltaY`: positive = scroll down / away\n     * from user, negative = scroll up / toward user.\n     *\n     * Value is frozen at frame-start; reading it does not clear the\n     * accumulator. The next `world.update()` produces a fresh delta\n     * (zero when no wheel events arrived).\n     *\n     * Trade-off (plan-strategy R-7): trackpad high-resolution wheel\n     * events collapse to one notch per event, losing sub-notch fidelity.\n     * AI users who need analog magnitude must opt in via a future\n     * unitful surface (OOS-7 ScrollSnapshot is the deferred shape).\n     */\n    readonly wheelDelta: number;\n  };\n  /**\n   * Per-slot gamepad reader. Returns a reader object for the gamepad at\n   * slot `i` regardless of connection state: disconnected or out-of-range\n   * slots report `connected=false`, all button/axis readpoints return\n   * `false`/`0` (charter P3 empty signal). The slot index is intentionally\n   * not narrowed — platform slot counts vary, and bounds handling is a\n   * runtime concern.\n   */\n  gamepad(i: number): {\n    readonly feedbackTarget: GamepadFeedbackTarget | undefined;\n    readonly dualRumble: boolean;\n    readonly connected: boolean;\n    readonly standardMapping: boolean;\n    button(b: GamepadButtonIndex): boolean;\n    buttonValue(b: GamepadButtonIndex): number;\n    justPressed(b: GamepadButtonIndex): boolean;\n    justReleased(b: GamepadButtonIndex): boolean;\n    axis(a: GamepadAxisIndex): number;\n  };\n  /**\n   * Frozen capabilities snapshot, determined once at backend attach time.\n   * Consumers use this to decide whether gamepad/pointer readpoints will\n   * ever carry live data, without probing per-frame.\n   */\n  readonly capabilities: Capabilities;\n  /**\n   * Per-pointerId reader. Returns `{ active: true/false, x, y, pressure,\n   * pointerType, delta }` for the given pointerId. Unknown pointerIds\n   * return `{ active: false, ... }` without throwing.\n   */\n  pointer(\n    id: number,\n  ): PointerSample & { readonly delta: { readonly x: number; readonly y: number } };\n  /**\n   * Named virtual axis reader (joystick-derived). Returns `{ x, y }` for\n   * the given joystick config name. Unknown names return the zero-vector\n   * `{ x: 0, y: 0 }` without throwing.\n   */\n  virtualAxis(name: string): { readonly x: number; readonly y: number };\n  /**\n   * Per-frame phase event queue (down/move/up/cancel). One-frame\n   * lifecycle; drained by `sample()` at frame end. Empty array when no\n   * pointer events occurred this frame.\n   */\n  readonly pointerEvents: readonly PointerPhaseEvent[];\n  /**\n   * Continuous gesture values (pinch scale + rotation angle) for the\n   * active dual-finger gesture. Returns the identity empty signal\n   * (`pinchScale=1`, `rotationAngle=0`) when no gesture is active (AC-12);\n   * an active gesture retains its value on idle frames (fingers held still\n   * are not a gesture end). AC-11: reading the same frame's snapshot twice\n   * returns the identical object.\n   */\n  readonly gesture: GestureState;\n  /**\n   * Per-frame gesture lifecycle + instantaneous event queue (begin / end /\n   * cancel / swipe / long-press / double-tap). One-frame lifecycle, same\n   * pattern as `pointerEvents` (charter P4). Empty array when no gesture\n   * activity occurred this frame. Closed discriminant union (AC-13): a\n   * consumer exhaustively switches on `kind` without a default branch.\n   */\n  readonly gestureEvents: readonly GestureEvent[];\n  /**\n   * Action mapping readpoint. Returns a frozen reader for the named action.\n   * When `name` is registered in the InputMap, `isPressed()` / `justPressed()`\n   * / `justReleased()` / `strength` reflect the derived state. Unregistered\n   * action names return empty signal (false / 0 / false / false / 0) without\n   * throwing (charter P3: empty signal is the signal). AC-11: calling\n   * action() multiple times in the same frame returns identical values.\n   */\n  action(name: string): {\n    readonly isPressed: () => boolean;\n    readonly justPressed: () => boolean;\n    readonly justReleased: () => boolean;\n    readonly strength: number;\n  };\n  /**\n   * Compose a 1D axis value from two opposing actions.\n   *\n   * Returns `strength(pos) - strength(neg)`, range [-1, 1].\n   * Both registered: combines normally. One unregistered: contributes 0\n   * (E-3). Same action for both ends: always 0 (E-12).\n   *\n   * @param neg - Action name for the negative direction (e.g. 'moveLeft').\n   * @param pos - Action name for the positive direction (e.g. 'moveRight').\n   */\n  getAxis(neg: string, pos: string): number;\n  /**\n   * Compose a 2D vector from four directional actions with a single radial\n   * deadzone (Godot input.cpp three-branch formula). Uses `raw` (not\n   * `strength`) to avoid per-axis deadzone stacking into a square deadzone\n   * (AC-06).\n   *\n   * @param negX - Action name for negative X (e.g. 'moveLeft').\n   * @param posX - Action name for positive X (e.g. 'moveRight').\n   * @param negY - Action name for negative Y (e.g. 'moveUp').\n   * @param posY - Action name for positive Y (e.g. 'moveDown').\n   * @param opts - Optional override (deadzone).\n   */\n  getVector(\n    negX: string,\n    posX: string,\n    negY: string,\n    posY: string,\n    opts?: GetVectorOptions,\n  ): { readonly x: number; readonly y: number };\n}\n\n/**\n * Backend protocol consumed by the frame-start scan system. The browser\n * implementation (`browser-backend.ts`) is the production producer;\n * tests inject fakes that emit synthetic samples.\n */\nexport interface InputBackend {\n  readonly feedback?: GamepadFeedback;\n  dispatchFeedback?(intents: readonly GamepadFeedbackIntent[]): void;\n  /**\n   * Produce one frame's worth of input data and reset the per-frame\n   * accumulators (movement delta + edge sets). Held-key state and\n   * held-button state survive across calls. Browser producers latch edge\n   * transitions when events arrive, so a down+up sequence between two scans\n   * remains observable instead of being lost to the held-state projection.\n   *\n   * Contract notes:\n   * - `downKeys` is the held-key set as of the call (held across frames)\n   * - `upKeys` is the release-edge set since the previous sample (cleared\n   *   after the call so the edge appears in exactly one frame)\n   * - `buttons` is the held-button slot tuple `[b0, b1, b2]`\n   * - `movementX` / `movementY` are the accumulated PointerLock delta\n   *   since the previous sample (cleared after the call)\n   * - `focused` mirrors `document.hasFocus()` so the scan system can\n   *   suppress spurious up-edges across alt-tab transitions\n   */\n  sample(): InputBackendSample;\n  /**\n   * Command-set game gate for pointer-lock. When set to `false`, the\n   * backend will not request pointer-lock on click AND will immediately\n   * release any currently active lock (W3C path: `exitPointerLock`;\n   * provider path: `exitLock()`). When `true` (default), pointer-lock\n   * can be requested through the normal gate logic.\n   *\n   * Optional -- backends without pointer-lock support omit this method.\n   */\n  setPointerLockAllowed?(allowed: boolean): void;\n  /**\n   * Gate physical/synthetic acquisition for a host lifecycle boundary. A\n   * closed gate clears producer state and makes subsequent samples empty until\n   * the gate is reopened; it is independent of pointer-lock policy.\n   */\n  setInputAllowed?(allowed: boolean): void;\n  /**\n   * Atomically discard acquired state without detaching listeners. A host calls\n   * this when it revokes a control lease so held keys/buttons, contacts, frame\n   * edges, deltas and pointer lock cannot bleed into a later consumer. Optional\n   * keeps synthetic backends source-compatible.\n   */\n  clear?(): void;\n  /** Detach DOM listeners; called when the engine shuts down. */\n  detach(): void;\n}\n\n/** Snapshot value returned by `InputBackend.sample()` (POD). */\nexport interface InputBackendSample {\n  readonly feedbackResults?: readonly GamepadFeedbackResult[];\n  readonly feedbackLostResults?: number;\n  readonly downKeys: ReadonlySet<string>;\n  readonly upKeys: ReadonlySet<string>;\n  /** Physical code identity (KeyboardEvent.code), when the producer has it. */\n  readonly downCodes?: ReadonlySet<string>;\n  /** One-frame physical code release edges, when the producer has them. */\n  readonly upCodes?: ReadonlySet<string>;\n  /** Logical key press edges latched since the previous frame-start scan. */\n  readonly pressedKeys?: ReadonlySet<string>;\n  /** Physical code press edges latched since the previous frame-start scan. */\n  readonly pressedCodes?: ReadonlySet<string>;\n  readonly buttons: readonly [boolean, boolean, boolean];\n  /** Mouse button press edges latched since the previous frame-start scan. */\n  readonly pressedButtons?: readonly [boolean, boolean, boolean];\n  /** Mouse button release edges latched since the previous frame-start scan. */\n  readonly releasedButtons?: readonly [boolean, boolean, boolean];\n  readonly movementX: number;\n  readonly movementY: number;\n  /** Latest canvas-pixel mouse position; absent for non-pointer backends. */\n  readonly mouseX?: number;\n  readonly mouseY?: number;\n  /**\n   * Sign-discrete wheel notch accumulator since the previous sample\n   * (plan-strategy D-5). Browser backend writes `Math.sign(deltaY)` per\n   * `WheelEvent`; sample() drains the value and resets the producer\n   * accumulator (mirrors movementX/Y semantics).\n   */\n  readonly wheelDelta: number;\n  /** True for the first sample after blur/hidden state reset. */\n  readonly focusReset?: boolean;\n  readonly focused: boolean;\n  /** M1+ gamepad per-slot frame data (optional — absent when backend lacks gamepad support). */\n  readonly gamepads?: readonly GamepadSlotSample[];\n  /** M1+ frozen capability snapshot (optional — absent for pre-M1 backends). */\n  readonly capabilities?: Capabilities;\n  /** M2+ active pointer contacts (optional — absent for keyboard-only backends). */\n  readonly pointers?: readonly PointerSample[];\n  /** M2+ per-frame phase event queue (optional — absent when no pointer events occurred). */\n  readonly pointerEvents?: readonly PointerPhaseEvent[];\n  /** M3+ virtual joystick axis outputs (optional — absent when no virtual joysticks configured). */\n  readonly virtualAxes?: readonly VirtualAxisSample[];\n  /** M5+ continuous gesture values (optional — absent when no gesture is active). */\n  readonly gestures?: GestureState;\n  /** M5+ per-frame gesture event queue (optional — absent when no gesture activity occurred). */\n  readonly gestureEvents?: readonly GestureEvent[];\n  /**\n   * Merged pointer-lock state: true when either W3C pointer-lock is active\n   * (pointerLockElement === this backend's canvas) OR the lockProvider path\n   * has engaged (requestLock() was called and not yet released). Required\n   * field -- always present, defaults to false when no lock is active.\n   */\n  readonly pointerLocked: boolean;\n}\n\n/** Build the neutral backend sample used before or outside an active consumer. */\nexport function createEmptyInputBackendSample(): InputBackendSample {\n  return {\n    downKeys: new Set<string>(),\n    upKeys: new Set<string>(),\n    buttons: [false, false, false],\n    movementX: 0,\n    movementY: 0,\n    wheelDelta: 0,\n    focused: true,\n    pointerLocked: false,\n  };\n}\n\n/**\n * Build an `InputSnapshot` from a backend sample. The returned object is\n * frozen on construction: `down/up/button` are bound to the closed-over\n * sets, and `movementDelta` is a frozen literal. Subsequent backend\n * activity does not bleed into the snapshot.\n */\nfunction buildGamepadReader(\n  slot: GamepadSlotSample | undefined,\n): ReturnType<InputSnapshot['gamepad']> {\n  const standard = slot?.standardMapping === true;\n  return Object.freeze({\n    feedbackTarget: slot?.feedbackTarget,\n    dualRumble: slot?.dualRumble ?? false,\n    connected: slot !== undefined,\n    standardMapping: standard,\n    button(b: GamepadButtonIndex): boolean {\n      return standard && slot.pressed.has(b);\n    },\n    buttonValue(b: GamepadButtonIndex): number {\n      return standard ? (slot.buttonValues.get(b) ?? 0) : 0;\n    },\n    justPressed(b: GamepadButtonIndex): boolean {\n      return standard && slot.justPressed.has(b);\n    },\n    justReleased(b: GamepadButtonIndex): boolean {\n      return standard && slot.justReleased.has(b);\n    },\n    axis(a: GamepadAxisIndex): number {\n      return standard ? slot.axes[a] : 0;\n    },\n  });\n}\n\n/**\n * Build an `InputSnapshot` from a backend sample.\n *\n * @param sample - One frame's raw input backend sample (POD).\n * @param actionStates - Optional per-frame derived action states from\n *   deriveActionStates(). When provided, snap.action(name) returns mapped\n *   values; when absent or empty, all action readpoints return empty signal\n *   (charter P3: false/0, never throws). AC-11: actionStates is frozen into\n *   the snapshot so same-frame re-reads return identical values.\n */\nexport function snapshotFromSample(\n  sample: InputBackendSample,\n  actionStates?: readonly ActionState[],\n  previousSnapshot?: InputSnapshot,\n): InputSnapshot {\n  // structuralCopy: copying into local sets isolates the snapshot from\n  // any later backend mutation (the browser backend reuses its internal\n  // Set across frames). architecture-principles #2 derive: a Snapshot is\n  // a derived view of the producer's state at one instant.\n  const heldKeys = new Set<string>(sample.downKeys);\n  const upEdges = new Set<string>(sample.upKeys);\n  // Do not capture previousSnapshot in a callback: V8 can share that\n  // context with the returned readers and retain the entire frame history.\n  const justPressedKeys = new Set<string>(sample.pressedKeys);\n  if (sample.pressedKeys === undefined) {\n    for (const key of heldKeys) {\n      if (!previousSnapshot?.keyboard.down(key)) justPressedKeys.add(key);\n    }\n  }\n  const heldCodes = new Set<string>(sample.downCodes ?? []);\n  const upCodeEdges = new Set<string>(sample.upCodes ?? []);\n  const justPressedCodes = new Set<string>(sample.pressedCodes);\n  if (sample.pressedCodes === undefined) {\n    for (const code of heldCodes) {\n      if (!previousSnapshot?.keyboard.downCode(code)) justPressedCodes.add(code);\n    }\n  }\n  const buttons: readonly [boolean, boolean, boolean] = [\n    sample.buttons[0],\n    sample.buttons[1],\n    sample.buttons[2],\n  ];\n  const justPressedButtons: readonly [boolean, boolean, boolean] =\n    sample.pressedButtons === undefined\n      ? [\n          buttons[0] && (previousSnapshot === undefined || !previousSnapshot.mouse.button(0)),\n          buttons[1] && (previousSnapshot === undefined || !previousSnapshot.mouse.button(1)),\n          buttons[2] && (previousSnapshot === undefined || !previousSnapshot.mouse.button(2)),\n        ]\n      : [sample.pressedButtons[0], sample.pressedButtons[1], sample.pressedButtons[2]];\n  const justReleasedButtons: readonly [boolean, boolean, boolean] =\n    sample.releasedButtons === undefined\n      ? [\n          sample.focusReset !== true && previousSnapshot?.mouse.button(0) === true && !buttons[0],\n          sample.focusReset !== true && previousSnapshot?.mouse.button(1) === true && !buttons[1],\n          sample.focusReset !== true && previousSnapshot?.mouse.button(2) === true && !buttons[2],\n        ]\n      : [sample.releasedButtons[0], sample.releasedButtons[1], sample.releasedButtons[2]];\n  const movementDelta = Object.freeze({ x: sample.movementX, y: sample.movementY });\n  const mousePosition =\n    sample.mouseX === undefined || sample.mouseY === undefined\n      ? undefined\n      : Object.freeze({ x: sample.mouseX, y: sample.mouseY });\n  const wheelDelta = sample.wheelDelta;\n\n  // D-9: use `??` empty-signal defaults for all new optional fields.\n  const gamepadSlots: readonly GamepadSlotSample[] = sample.gamepads ?? [];\n  const caps: Capabilities =\n    sample.capabilities ?? Object.freeze({ gamepad: false, pointer: false });\n  const pointerEvts: readonly PointerPhaseEvent[] = sample.pointerEvents ?? [];\n  // D-4 / AC-12: no active gesture -> identity empty signal; gesture events\n  // default to an empty one-frame queue (mirrors pointerEvents).\n  const gesture: GestureState = sample.gestures ?? IDENTITY_GESTURE;\n  const gestureEvts: readonly GestureEvent[] = sample.gestureEvents ?? [];\n  // virtualAxes: consumed by M3 virtualAxis reader; stored as local for\n  // the snapshot closure below.\n  const _virtualAxes: readonly VirtualAxisSample[] = sample.virtualAxes ?? [];\n\n  const virtualAxesMap = new Map<string, VirtualAxisSample>();\n  for (const va of _virtualAxes) {\n    virtualAxesMap.set(va.name, va);\n  }\n\n  // Build index→slot map so gamepad(i) looks up by slot.index, not array position.\n  // The browser getGamepads() returns null-padded arrays where position IS the\n  // index, but the diffGamepadFrame output is a sparse list keyed by .index.\n  const gamepadSlotMap = new Map<number, GamepadSlotSample>();\n  for (const slot of gamepadSlots) {\n    gamepadSlotMap.set(slot.index, {\n      ...slot,\n      ...(slot.feedbackTarget ? { feedbackTarget: Object.freeze({ ...slot.feedbackTarget }) } : {}),\n    });\n  }\n\n  // Build action lookup map for snap.action(name) readpoint.\n  const actionMap = new Map<string, ActionState>();\n  if (actionStates) {\n    for (const a of actionStates) {\n      actionMap.set(a.action, a);\n    }\n  }\n\n  function emptyActionReader(): ReturnType<InputSnapshot['action']> {\n    return Object.freeze({\n      isPressed: () => false,\n      justPressed: () => false,\n      justReleased: () => false,\n      strength: 0,\n    });\n  }\n\n  const snapshot: InputSnapshot = {\n    keyboard: {\n      down(key) {\n        return heldKeys.has(key);\n      },\n      justPressed(key) {\n        return justPressedKeys.has(key);\n      },\n      up(key) {\n        return upEdges.has(key);\n      },\n      downCode(code) {\n        return heldCodes.has(code);\n      },\n      justPressedCode(code) {\n        return justPressedCodes.has(code);\n      },\n      upCode(code) {\n        return upCodeEdges.has(code);\n      },\n    },\n    mouse: {\n      position: mousePosition,\n      movementDelta,\n      pointerLocked: sample.pointerLocked,\n      button(i) {\n        // i is narrowed to 0 | 1 | 2 by the type system; the runtime\n        // index is therefore guaranteed to land in `buttons` (charter P3\n        // -- no defensive fallback necessary because the type narrows the\n        // input domain to the legal slots).\n        return buttons[i] === true;\n      },\n      justPressed(i) {\n        return justPressedButtons[i] === true;\n      },\n      justReleased(i) {\n        return justReleasedButtons[i] === true;\n      },\n      wheelDelta,\n    },\n    gamepad(i) {\n      const slot = gamepadSlotMap.get(i);\n      return buildGamepadReader(slot);\n    },\n    capabilities: caps,\n    pointer(id) {\n      const entry = (sample.pointers ?? []).find((p) => p.pointerId === id);\n      if (!entry) {\n        return Object.freeze({\n          active: false,\n          pointerId: -1,\n          x: 0,\n          y: 0,\n          pressure: 0,\n          pointerType: 'mouse' as PointerType,\n          delta: Object.freeze({ x: 0, y: 0 }),\n        });\n      }\n      return Object.freeze({\n        ...entry,\n        delta: Object.freeze({ x: entry.delta.x, y: entry.delta.y }),\n      });\n    },\n    virtualAxis(name) {\n      const va = virtualAxesMap.get(name);\n      if (!va) return Object.freeze({ x: 0, y: 0 });\n      return Object.freeze({ x: va.x, y: va.y });\n    },\n    action(name) {\n      const s = actionMap.get(name);\n      if (!s) return emptyActionReader();\n      return Object.freeze({\n        isPressed: () => s.pressed,\n        justPressed: () => s.justPressed,\n        justReleased: () => s.justReleased,\n        strength: s.strength,\n      });\n    },\n    getAxis(neg, pos) {\n      if (!actionStates) return 0;\n      return getAxis(actionStates, neg, pos);\n    },\n    getVector(negX, posX, negY, posY, opts) {\n      if (!actionStates) return { x: 0, y: 0 };\n      return getVector(actionStates, negX, posX, negY, posY, opts);\n    },\n    pointerEvents: pointerEvts,\n    gesture,\n    gestureEvents: gestureEvts,\n  };\n  (snapshot as unknown as Record<string, unknown>)._actionStates = actionStates;\n  return Object.freeze(snapshot);\n}\n\n/**\n * @internal Read previously derived action states from a snapshot for edge diff.\n * Used by the frame-start scan system (D-6: prev snapshot = edge baseline).\n */\nexport function readActionStatesForEdgeDiff(\n  snap: InputSnapshot,\n): readonly ActionState[] | undefined {\n  return (snap as unknown as { _actionStates?: readonly ActionState[] })._actionStates;\n}\n\n/**\n * Construct an empty snapshot for the pre-start window\n * (`engine.run()` has not yet attached a backend). Returns the full\n * multi-device shape as `snapshotFromSample`, with every accessor\n * returning `false` / `0` / zero-vector. AI users can put this into the\n * Resource store to satisfy `world.getResource('InputSnapshot')` calls\n * in fixtures or unit tests (charter P3: empty signal is the signal).\n * The underlying 7-field POD sample contract is unchanged (D-9).\n */\nexport function createInputSnapshot(): InputSnapshot {\n  return snapshotFromSample(createEmptyInputBackendSample());\n}\n\n/** Stable Resource key for `world.insertResource` / `world.getResource`. */\nexport const INPUT_SNAPSHOT_RESOURCE_KEY = 'InputSnapshot';\n","/** Event-path ownership and lifecycle reset primitives for browser hosts. */\n\nexport interface UiOwnershipResult {\n  readonly owned: boolean;\n  readonly source: 'composed-path' | 'target-fallback' | 'unknown';\n}\n\nexport interface UiInputResetBoundaryOptions {\n  readonly clear: () => void;\n  readonly signal?: AbortSignal;\n}\n\nexport interface UiInputResetBoundary {\n  readonly reset: () => void;\n  readonly dispose: () => void;\n}\n\nfunction contains(root: Node, value: EventTarget | null): boolean {\n  const NodeCtor = globalThis.Node;\n  return NodeCtor && value instanceof NodeCtor ? value === root || root.contains(value) : false;\n}\n\nexport function resolveUiOwnership(event: Event, host: Node): UiOwnershipResult {\n  const path = event.composedPath;\n  if (typeof path === 'function') {\n    const composed = path.call(event);\n    return {\n      owned:\n        composed.some((item) => contains(host, item)) ||\n        (composed.length === 0 && contains(host, event.target)),\n      source: composed.length === 0 ? 'target-fallback' : 'composed-path',\n    };\n  }\n  if ('target' in event) {\n    return { owned: contains(host, event.target), source: 'target-fallback' };\n  }\n  return { owned: false, source: 'unknown' };\n}\n\nexport function isUiOwnedEvent(event: Event, host: Node): boolean {\n  return resolveUiOwnership(event, host).owned;\n}\n\nexport function createUiInputResetBoundary(\n  options: UiInputResetBoundaryOptions,\n): UiInputResetBoundary {\n  let disposed = false;\n  const reset = (): void => {\n    if (!disposed) options.clear();\n  };\n  const onAbort = (): void => reset();\n  options.signal?.addEventListener('abort', onAbort, { once: true });\n  return {\n    reset,\n    dispose: () => {\n      if (disposed) return;\n      disposed = true;\n      options.signal?.removeEventListener('abort', onAbort);\n    },\n  };\n}\n","// virtual-joystick.ts -- pure-function virtual joystick derivation (M3).\n//\n// No DOM dependency; backend closure holds per-joystick bindState\n// and calls deriveVirtualAxes each sample() frame.\n//\n// @internal -- only the browser backend calls these functions; the\n// barrel does not re-export them.\n\nimport type { VirtualAxisSample, VirtualJoystickConfig } from './input-snapshot';\n\n/**\n * Per-joystick binding state. The backend closure owns a\n * Map<string, BindState> keyed by joystick config name.\n */\nexport interface BindState {\n  /** bound pointerId, or undefined if unbound */\n  pointerId?: number | undefined;\n  /** origin in canvas pixels (anchor for fixed, first-touch for floating) */\n  originX: number;\n  originY: number;\n}\n\nfunction computeVec(\n  ptrX: number,\n  ptrY: number,\n  originX: number,\n  originY: number,\n  radius: number,\n  deadzone: number,\n): { x: number; y: number } {\n  const rawX = (ptrX - originX) / radius;\n  const rawY = (ptrY - originY) / radius;\n  const mag = Math.sqrt(rawX * rawX + rawY * rawY);\n  if (mag < deadzone) return { x: 0, y: 0 };\n  if (mag > 1) {\n    // Clamp to unit vector: normalize direction, magnitude = 1.\n    return { x: rawX / mag, y: rawY / mag };\n  }\n  return { x: rawX, y: rawY };\n}\n\n/**\n * Derive one frame of virtual axis outputs from live pointer state and\n * per-joystick binding state.\n *\n * Pure function: no DOM access. The backend closure is the SSOT for\n * per-joystick state; binding + origin selection happens in\n * browser-backend.ts onPointerDown. This function only reads bindState\n * and computes per-frame vectors.\n *\n * Unbound joysticks always produce the zero vector.\n *\n * @param configs - configured virtual joysticks\n * @param pointerMap - live pointer positions keyed by pointerId\n * @param bindState - per-joystick binding state (read-only)\n * @returns one VirtualAxisSample per configured joystick\n */\nexport function deriveVirtualAxes(\n  configs: readonly VirtualJoystickConfig[],\n  pointerMap: Map<number, { readonly x: number; readonly y: number }>,\n  bindState: Map<string, BindState>,\n): VirtualAxisSample[] {\n  const results: VirtualAxisSample[] = [];\n\n  for (const cfg of configs) {\n    const bs = bindState.get(cfg.name);\n\n    if (bs?.pointerId !== undefined) {\n      // Bound: compute vector from current pointer position.\n      const ptr = pointerMap.get(bs.pointerId);\n      if (ptr) {\n        const vec = computeVec(ptr.x, ptr.y, bs.originX, bs.originY, cfg.radius, cfg.deadzone);\n        results.push({ name: cfg.name, x: vec.x, y: vec.y });\n      } else {\n        // Pointer disappeared (up/cancel handled by backend unbind,\n        // but this guards against pointer removal without unbind).\n        bs.pointerId = undefined;\n        results.push({ name: cfg.name, x: 0, y: 0 });\n      }\n    } else {\n      // Unbound: zero vector. Binding is the backend's responsibility.\n      results.push({ name: cfg.name, x: 0, y: 0 });\n    }\n  }\n\n  return results;\n}\n\n/**\n * Unbind a joystick when its bound pointer goes up or is cancelled.\n * Sets pointerId to undefined; the next deriveVirtualAxes call will\n * produce a zero vector for the unbound joystick.\n */\nexport function handleVirtualJoystickUnbind(\n  bindState: Map<string, BindState>,\n  pointerId: number,\n): void {\n  for (const bs of bindState.values()) {\n    if (bs.pointerId === pointerId) {\n      bs.pointerId = undefined;\n    }\n  }\n}\n","// browser-backend.ts -- DOM PointerLock + keyboard / mouse listener producer.\n//\n// charter awareness:\n//   F2 minimal surface -- exposes only `attachBrowserInputBackend(canvas)`\n//     returning a `(): void` detach handle; PointerLock + listener wiring\n//     is internal (plan OOS-1 explicit -- not part of the user-facing\n//     surface)\n//   P3 explicit failure -- detach is part of the contract; double-detach\n//     is a no-op (idempotent)\n//   P4 consistent abstraction -- the snapshot consumer does not see\n//     PointerLock state machine or `movementX/Y` units; only\n//     `mouse.movementDelta`\n//   P5 producer/consumer split -- this file is the only DOM-touching\n//     surface in the package; everything else operates on the\n//     `InputBackend` protocol (see input-snapshot.ts)\n//\n// Note: the actual PointerLock pump runs in a real browser; node-based\n// vitest unit tests inject fake backends through the `InputBackend`\n// protocol. The browser-mode coverage of this file is the M2b layer\n// (plan-strategy section 5.4 reason for the 70% floor).\n\nimport { attachBrowserGamepadFeedback } from './browser-gamepad-feedback';\nimport type { ControllerDb, MappingTokens } from './controller-db';\nimport { ButtonLatch, KeyLatch } from './digital-input';\nimport { diffGamepadFrame, type RawGamepadStub } from './gamepad-frame';\nimport {\n  createRecognizerState,\n  type GestureEvent,\n  type GestureState,\n  processGestureFrame,\n  type RecognizerPointer,\n  type RecognizerState,\n} from './gesture-recognizer';\nimport type {\n  Capabilities,\n  GamepadSlotSample,\n  InputBackend,\n  InputBackendSample,\n  PointerPhaseEvent,\n  PointerSample,\n  PointerType,\n  VirtualAxisSample,\n  VirtualJoystickConfig,\n} from './input-snapshot';\nimport { createEmptyInputBackendSample } from './input-snapshot';\nimport { isUiOwnedEvent } from './ui-ownership';\nimport { type BindState, deriveVirtualAxes, handleVirtualJoystickUnbind } from './virtual-joystick';\n\n// D-5: normalize W3C PointerEvent.pointerType to the canonical 3-literal union.\n// The spec allows '' when device type is undetectable; we map it to 'mouse' so\n// the snapshot consumers (action matchers, gesture recognizers) can exhaustively\n// switch on PointerType without a default branch (AC-19).\nexport function coercePointerType(raw: string): PointerType {\n  if (raw === 'pen') return 'pen';\n  if (raw === 'touch') return 'touch';\n  return 'mouse';\n}\n\n/**\n * Options accepted by `attachBrowserInputBackend`.\n */\nexport interface BrowserInputBackendOptions {\n  /** Optional host-owned UI root. Events in this root never reach gameplay. */\n  readonly uiRoot?: Node;\n  /**\n   * Optional document handle (testing override). Defaults to `document`.\n   * Plan-strategy section 9 row 7 (`document.hasFocus()` semantics)\n   * relies on this to decide whether the up-edge set should be cleared\n   * when focus is lost.\n   */\n  readonly document?: Document;\n  /**\n   * Optional window handle (testing override). Defaults to `window`.\n   * Used to attach key listeners (capturing focus loss) without\n   * requiring the canvas itself to receive keyboard events.\n   */\n  readonly window?: Window;\n  /**\n   * Neutral gate for the auto PointerLock-on-click. When provided and it\n   * returns false, the click handler skips `requestPointerLock()` — the host\n   * decides whether a click should capture the cursor right now. Defaults to\n   * always-locking (returns true), so the standalone game runtime keeps its\n   * MVP behaviour unchanged. This predicate is deliberately host-opaque: the\n   * backend never learns WHY locking is (dis)allowed — it only asks. A host\n   * that mounts this canvas in a non-game context (e.g. an editor viewport\n   * that owns the cursor for orbit/pick) supplies a predicate that returns\n   * false there. The input package carries zero knowledge of those contexts.\n   */\n  readonly pointerLockAllowed?: () => boolean;\n  /**\n   * Optional navigator handle (testing override). Defaults to\n   * `globalThis.navigator`. Used to poll `navigator.getGamepads()` each\n   * frame. Mirrors the `document`/`window` override pattern.\n   */\n  readonly navigator?: { getGamepads?(): (Gamepad | null)[] };\n  /**\n   * Optional virtual joystick configurations (M3). When provided, the\n   * backend auto-binds the first pointerdown within each config's region\n   * and derives per-frame VirtualAxisSample outputs via deriveVirtualAxes.\n   */\n  readonly virtualJoysticks?: readonly VirtualJoystickConfig[];\n  /**\n   * Optional SDL controller DB text loader (M3 D-13 test injection). When\n   * omitted, the backend dynamic-imports the vendored 554KB DB from\n   * `@forgeax/engine-input/controller-db-data` on first sight of a\n   * non-standard gamepad (D-2 lazy-load: the 554KB never sits in the\n   * default path). Tests inject a synthetic DB string to avoid loading the\n   * real vendored file. Returns the raw gamecontrollerdb.txt contents.\n   */\n  readonly loadControllerDb?: () => Promise<string>;\n  /**\n   * Optional monotonic clock (M5 D-3 test injection). Defaults to\n   * `() => performance.now()`. The gesture recognizer advances all timers\n   * (long-press duration, double-tap / swipe windows) off this clock, NOT\n   * off pointer-event arrival, so recognition stays decoupled from event\n   * frequency (AC-16). Tests inject a fake clock for deterministic timing,\n   * mirroring the `document` / `window` / `navigator` override pattern.\n   */\n  readonly now?: () => number;\n  /**\n   * Optional lock provider (D-2). When provided, pointer-lock requests\n   * route through requestLock() / exitLock() instead of the W3C\n   * requestPointerLock / exitPointerLock API. The backend remains\n   * host-opaque -- it never learns whether the provider wraps Tauri\n   * native-grab, postMessage, or any other mechanism.\n   */\n  readonly lockProvider?: PointerLockProvider;\n  /**\n   * Optional callback for lock request failures (D-4). When W3C\n   * requestPointerLock rejects or lockProvider.requestLock/exitLock\n   * throws/rejects, the backend calls this with a detail object.\n   * Without this callback, failures are silently caught (backward\n   * compatible but contrary to charter P3).\n   */\n  readonly onLockError?: (detail: { path: 'w3c' | 'provider'; cause: unknown }) => void;\n}\n\n/**\n * Lock provider interface (D-2). A host injects this to replace the\n * W3C Pointer Lock API path. requestLock() may return void (fire-and-forget,\n * D-7 optimistic placement) or Promise<void> (awaitable). exitLock() is\n * called when the backend needs to release the lock (ESC / blur / detach /\n * setPointerLockAllowed(false)).\n */\nexport interface PointerLockProvider {\n  /**\n   * Request pointer lock. The backend optimistically sets providerLocked=true\n   * when this is called (D-7). On throw/reject, the backend calls onLockError\n   * and rolls back providerLocked.\n   */\n  requestLock(): void | Promise<void>;\n  /** Release pointer lock. */\n  exitLock(): void;\n}\n\n/**\n * Attach DOM listeners (keydown / keyup / mousedown / mouseup /\n * pointerlockchange / mousemove inside lock / blur) to `canvas` and the\n * surrounding window. Returns a `detach` callable that:\n *\n *   - removes all listeners\n *   - exits PointerLock if currently locked\n *   - drops every internal accumulator\n *\n * The returned object also implements the `InputBackend` protocol -- the\n * runtime inserts it under `INPUT_BACKEND_KEY` and adds the\n * `InputFrameStartScan` system, which reads it back each tick.\n * Calling `detach()` and the protocol's `detach()` are equivalent\n * (idempotent; double-detach is safe -- charter P3).\n */\nexport function attachBrowserInputBackend(\n  canvas: HTMLCanvasElement,\n  options: BrowserInputBackendOptions = {},\n): (() => void) & { backend: InputBackend } {\n  const doc = options.document ?? globalThis.document;\n  const win = options.window ?? globalThis.window;\n\n  const keys = new KeyLatch();\n  const codes = new KeyLatch();\n  const mouseButtons = new ButtonLatch();\n  const { held: heldKeys, pressed: pressedKeys, released: upEdges } = keys;\n  const { held: heldCodes, pressed: pressedCodes, released: upCodeEdges } = codes;\n  const { held: buttons, pressed: pressedButtons, released: releasedButtons } = mouseButtons;\n  let mvx = 0;\n  let mvy = 0;\n  let wheelAccum = 0;\n  let detached = false;\n\n  const isUiEvent = (event: Event): boolean =>\n    options.uiRoot !== undefined && isUiOwnedEvent(event, options.uiRoot);\n\n  // w6: merged pointer-lock state tracking (D-1).\n  // w3cLocked is driven by document-level pointerlockchange events,\n  // isolated per-instance by comparing pointerLockElement === this canvas.\n  let w3cLocked = false;\n  // providerLocked is set optimistically when lockProvider.requestLock()\n  // is called (D-7); cleared by exitLock() or on rejection.\n  let providerLocked = false;\n  // gameGate is a command-set boolean (setPointerLockAllowed), default true.\n  let gameGate = true;\n  // Startup overlays and other host lifecycle boundaries gate acquisition at\n  // the producer, so events cannot become stale gameplay input at the next\n  // frame-start scan.\n  let inputAllowed = true;\n\n  function emitLockError(path: 'w3c' | 'provider', cause: unknown): void {\n    try {\n      options.onLockError?.({ path, cause });\n    } catch {\n      // Lock diagnostics are observational; a throwing host callback must not\n      // create a second unhandled rejection from the browser Promise path.\n    }\n  }\n\n  // w8 (D-1/D-3): release the provider lock idempotently. Calls the injected\n  // exitLock (routing any throw to onLockError as { path: 'provider' }) and\n  // clears providerLocked unconditionally. Shared by every provider-release\n  // site (ESC, blur, setPointerLockAllowed(false), detach) so the release\n  // semantics live in one place.\n  function releaseProviderLock(): void {\n    if (providerLocked && options.lockProvider?.exitLock) {\n      try {\n        options.lockProvider.exitLock();\n      } catch (err: unknown) {\n        emitLockError('provider', err);\n      }\n    }\n    providerLocked = false;\n  }\n\n  // D-4: capability detected once at attach time.\n  const nav =\n    options.navigator ?? (globalThis as { navigator?: { getGamepads?(): unknown } }).navigator;\n  const gamepadAvailable = typeof nav?.getGamepads === 'function';\n  const pointerAvailable = typeof globalThis.PointerEvent !== 'undefined';\n  const haptics = attachBrowserGamepadFeedback(doc, win);\n  const caps: Capabilities = { gamepad: gamepadAvailable, pointer: pointerAvailable };\n\n  // D-1: prevGamepadFrame is the only cross-frame state holder for gamepad diff.\n  // Stored in backend closure; diffGamepadFrame compares prev vs cur each sample().\n  let prevGamepadFrame = new Map<number, GamepadSlotSample>();\n  // Focus loss discards the old physical frame. The first successful sample\n  // afterwards establishes a new baseline instead of turning a still-held\n  // button into a synthetic justPressed edge.\n  let gamepadBaselinePending = false;\n  let focusResetPending = false;\n\n  // M3 D-2 lazy-load state. The SDL DB (554KB) is loaded once, on first sight\n  // of a non-standard gamepad, then cached here. `controllerDb` stays\n  // undefined until the async load resolves; frames before that keep the\n  // Feat1 empty signal (graceful degradation). `dbLoadStarted` prevents\n  // re-triggering the load on every frame while the promise is pending.\n  let controllerDb: ControllerDb | undefined;\n  let dbLoadStarted = false;\n  // Per-id GUID resolution cache (avoids re-parsing the same Gamepad.id).\n  const guidCache = new Map<string, string | undefined>();\n\n  // M3 D-13: the DB parser + GUID helpers live in the pure controller-db\n  // module. They are dynamic-imported alongside the data so neither the\n  // parser nor the 554KB vendored text enters the main-entry bundle.\n  let controllerDbApi:\n    | {\n        parseControllerDb: (txt: string) => ControllerDb;\n        extractGuidFromGamepadId: (id: string) => string | undefined;\n        selectBestMappingEntry: (\n          db: ControllerDb,\n          guid: string,\n          platform: string | undefined,\n        ) => { readonly tokens: MappingTokens } | undefined;\n        platformFromUserAgent: (ua: string) => string | undefined;\n      }\n    | undefined;\n\n  function kickOffDbLoad(): void {\n    if (dbLoadStarted) return;\n    dbLoadStarted = true;\n    const loadApi = controllerDbApi\n      ? Promise.resolve(controllerDbApi)\n      : import('@forgeax/engine-input/controller-db').then((m) => {\n          controllerDbApi = m;\n          return m;\n        });\n    const loadText = options.loadControllerDb\n      ? options.loadControllerDb()\n      : import('@forgeax/engine-input/controller-db-data').then((m) => m.loadBundledControllerDb());\n    Promise.all([loadApi, loadText])\n      .then(([api, txt]) => {\n        controllerDb = api.parseControllerDb(txt);\n      })\n      .catch(() => {\n        // Load failed (offline chunk / bad text): keep the Feat1 empty\n        // signal. Reset so a later frame may retry.\n        dbLoadStarted = false;\n      });\n  }\n\n  // Acquisition-layer remap lookup passed to diffGamepadFrame. Returns the\n  // standard-layout mapping tokens for a Gamepad.id, or null when the DB is\n  // not yet loaded / the GUID is unextractable / no DB entry matches.\n  function remapLookup(gamepadId: string): MappingTokens | null {\n    if (!controllerDb || !controllerDbApi) return null;\n    let guid = guidCache.get(gamepadId);\n    if (!guidCache.has(gamepadId)) {\n      guid = controllerDbApi.extractGuidFromGamepadId(gamepadId);\n      guidCache.set(gamepadId, guid);\n    }\n    if (!guid) return null;\n    const ua =\n      typeof globalThis.navigator?.userAgent === 'string' ? globalThis.navigator.userAgent : '';\n    const platform = controllerDbApi.platformFromUserAgent(ua);\n    const entry = controllerDbApi.selectBestMappingEntry(controllerDb, guid, platform);\n    return entry ? entry.tokens : null;\n  }\n\n  // w15: pointer map (pointerId → live position), phase queue (one-frame lifecycle),\n  // and per-pointer previous position for cross-frame delta.\n  const pointerMap = new Map<\n    number,\n    {\n      x: number;\n      y: number;\n      pressure: number;\n      pointerType: PointerType;\n      prevX: number;\n      prevY: number;\n    }\n  >();\n  const phaseQueue: PointerPhaseEvent[] = [];\n  let mouseX: number | undefined;\n  let mouseY: number | undefined;\n\n  // w21: virtual joystick binding state (per-joystick name → BindState).\n  const vjConfigs = options.virtualJoysticks ?? [];\n  const vjBindState = new Map<string, BindState>();\n\n  // M5 D-3/D-4: gesture recognizer cross-frame state lives in this closure\n  // (C-3: the only sanctioned cross-frame gesture holder, alongside\n  // prevGamepadFrame / pointerMap / vjBindState). `now` is injectable for\n  // deterministic test timing; production uses performance.now().\n  const now = options.now ?? (() => performance.now());\n  let recognizerState: RecognizerState = createRecognizerState();\n\n  // DPR coordinate helpers. computePointerCoords applies the standard DPR-correct\n  // canvas-pixel formula; falls back to clientX/clientY when getBoundingClientRect\n  // is missing (fake canvas in unit tests).\n  function computePointerCoords(ev: PointerEvent): { x: number; y: number } {\n    const rect = canvas.getBoundingClientRect?.();\n    if (!rect) return { x: ev.clientX, y: ev.clientY };\n    const scaleX = canvas.width / rect.width;\n    const scaleY = canvas.height / rect.height;\n    return {\n      x: (ev.clientX - rect.left) * scaleX,\n      y: (ev.clientY - rect.top) * scaleY,\n    };\n  }\n\n  function isFocused(): boolean {\n    // `document.hasFocus()` indicates whether the tab is foreground;\n    // when unfocused we suppress up-edges so stale releases do not fire\n    // after alt-tabbing back (section 9 row 7).\n    return typeof doc?.hasFocus === 'function' ? doc.hasFocus() : true;\n  }\n\n  function onKeyDown(ev: KeyboardEvent): void {\n    if (!inputAllowed) return;\n    if (isUiEvent(ev)) {\n      clear();\n      return;\n    }\n    keys.press(ev.key);\n    if (ev.code) codes.press(ev.code);\n    // w8 (D-1): ESC releases provider lock (W3C path handles ESC via browser\n    // pointerlockchange). Only acts when providerLocked is true.\n    if (ev.key === 'Escape' && providerLocked) {\n      releaseProviderLock();\n    }\n  }\n  function onKeyUp(ev: KeyboardEvent): void {\n    if (!inputAllowed) return;\n    if (isUiEvent(ev)) return;\n    if (isFocused()) {\n      keys.release(ev.key);\n      if (ev.code) codes.release(ev.code);\n    } else {\n      heldKeys.delete(ev.key);\n      if (ev.code) heldCodes.delete(ev.code);\n    }\n  }\n  function updateMouseButton(button: 0 | 1 | 2, held: boolean): void {\n    mouseButtons.set(button, held);\n  }\n\n  function onPointerDown(ev: PointerEvent): void {\n    if (!inputAllowed) return;\n    if (isUiEvent(ev)) {\n      clear();\n      return;\n    }\n    // Only mouse-type pointers affect the mouse button cluster (D-3).\n    if (ev.pointerType === 'mouse') {\n      if (ev.button === 0 || ev.button === 1 || ev.button === 2) {\n        updateMouseButton(ev.button, true);\n      }\n    }\n    // D-5: setPointerCapture for coherent pointer event dispatching — but NOT\n    // while pointer lock is active. Pointer capture and pointer lock are mutually\n    // exclusive (W3C): setPointerCapture throws InvalidStateError when the element\n    // already holds the lock. Under lock the cursor is confined and every pointer\n    // event already targets the locked element, so capture is redundant anyway.\n    // The try/catch is belt-and-suspenders for the race where lock/capture state\n    // flips between the pointerlockchange event and this handler.\n    if (!w3cLocked && !providerLocked && typeof canvas.setPointerCapture === 'function') {\n      try {\n        canvas.setPointerCapture(ev.pointerId);\n      } catch {\n        /* capture illegal in the current pointer state (e.g. just-acquired lock) — safe to skip */\n      }\n    }\n    // Track pointer in map for multi-pointer + delta (w15).\n    const coords = computePointerCoords(ev);\n    if (ev.pointerType === 'mouse') {\n      mouseX = coords.x;\n      mouseY = coords.y;\n    }\n    pointerMap.set(ev.pointerId, {\n      x: coords.x,\n      y: coords.y,\n      pressure: ev.pressure,\n      pointerType: coercePointerType(ev.pointerType),\n      prevX: coords.x,\n      prevY: coords.y,\n    });\n    phaseQueue.push({\n      pointerId: ev.pointerId,\n      phase: 'down',\n      x: coords.x,\n      y: coords.y,\n      pressure: ev.pressure,\n      pointerType: coercePointerType(ev.pointerType),\n    });\n    // w21: virtual joystick auto-bind -- first config whose region contains\n    // the pointerdown position, if not already bound to another pointer.\n    if (vjConfigs.length > 0) {\n      for (const cfg of vjConfigs) {\n        const { region } = cfg;\n        if (\n          coords.x >= region.x &&\n          coords.x <= region.x + region.width &&\n          coords.y >= region.y &&\n          coords.y <= region.y + region.height\n        ) {\n          const existing = vjBindState.get(cfg.name);\n          if (!existing?.pointerId) {\n            const originX =\n              cfg.mode === 'fixed' ? (cfg.anchor?.x ?? region.x + region.width / 2) : coords.x;\n            const originY =\n              cfg.mode === 'fixed' ? (cfg.anchor?.y ?? region.y + region.height / 2) : coords.y;\n            if (existing) {\n              existing.pointerId = ev.pointerId;\n              existing.originX = originX;\n              existing.originY = originY;\n            } else {\n              vjBindState.set(cfg.name, { pointerId: ev.pointerId, originX, originY });\n            }\n            // Only bind the first matching config per pointerdown.\n            break;\n          }\n        }\n      }\n    }\n  }\n  function onPointerUp(ev: PointerEvent): void {\n    if (!inputAllowed) return;\n    if (isUiEvent(ev)) return;\n    if (ev.pointerType === 'mouse') {\n      if (ev.button === 0 || ev.button === 1 || ev.button === 2) {\n        updateMouseButton(ev.button, false);\n      }\n    }\n    const entry = pointerMap.get(ev.pointerId);\n    if (entry) {\n      phaseQueue.push({\n        pointerId: ev.pointerId,\n        phase: 'up',\n        x: entry.x,\n        y: entry.y,\n        pressure: ev.pressure,\n        pointerType: coercePointerType(ev.pointerType),\n      });\n      pointerMap.delete(ev.pointerId);\n    }\n    // w21: unbind virtual joystick bound to this pointer.\n    if (vjBindState.size > 0) {\n      handleVirtualJoystickUnbind(vjBindState, ev.pointerId);\n    }\n  }\n  function onPointerMove(ev: PointerEvent): void {\n    if (!inputAllowed) return;\n    if (isUiEvent(ev)) return;\n    // D-3: movementDelta from pointermove (PointerEvent extends MouseEvent).\n    if (ev.pointerType === 'mouse') {\n      // Intermediate chord presses/releases are pointermove events. DOM masks\n      // order right before middle; the normalized tuple orders middle first.\n      updateMouseButton(0, (ev.buttons & 1) !== 0);\n      updateMouseButton(1, (ev.buttons & 4) !== 0);\n      updateMouseButton(2, (ev.buttons & 2) !== 0);\n      mvx += ev.movementX;\n      mvy += ev.movementY;\n    }\n    // Update live position; prevX/prevY NOT updated here (AC-09: prev only\n    // snapshots at sample() time, preventing Bevy #12442 zero-delta bug).\n    const coords = computePointerCoords(ev);\n    if (ev.pointerType === 'mouse') {\n      mouseX = coords.x;\n      mouseY = coords.y;\n    }\n    const entry = pointerMap.get(ev.pointerId);\n    if (entry) {\n      entry.x = coords.x;\n      entry.y = coords.y;\n      entry.pressure = ev.pressure;\n      phaseQueue.push({\n        pointerId: ev.pointerId,\n        phase: 'move',\n        x: coords.x,\n        y: coords.y,\n        pressure: ev.pressure,\n        pointerType: coercePointerType(ev.pointerType),\n      });\n    }\n  }\n  function onPointerCancel(ev: PointerEvent): void {\n    if (!inputAllowed) return;\n    if (isUiEvent(ev)) return;\n    const entry = pointerMap.get(ev.pointerId);\n    if (entry) {\n      phaseQueue.push({\n        pointerId: ev.pointerId,\n        phase: 'cancel',\n        x: entry.x,\n        y: entry.y,\n        pressure: ev.pressure,\n        pointerType: coercePointerType(ev.pointerType),\n      });\n      pointerMap.delete(ev.pointerId);\n    }\n    // w21: unbind virtual joystick on pointer cancel.\n    if (vjBindState.size > 0) {\n      handleVirtualJoystickUnbind(vjBindState, ev.pointerId);\n    }\n  }\n  function onVisibilityChange(): void {\n    if (doc.visibilityState === 'hidden') {\n      onBlur();\n    }\n  }\n  function onWheel(ev: WheelEvent): void {\n    if (!inputAllowed) return;\n    if (isUiEvent(ev)) {\n      clear();\n      return;\n    }\n    // plan-strategy D-5 sign-discrete normalization: collapse `WheelEvent`\n    // across the three `deltaMode` units (PIXEL / LINE / PAGE) by taking\n    // `Math.sign(deltaY)` per event. Trade-off documented at the\n    // InputSnapshot.mouse.wheelDelta JSDoc + plan-strategy R-7.\n    const dy = ev.deltaY;\n    if (typeof dy === 'number' && dy !== 0) {\n      wheelAccum += dy > 0 ? 1 : -1;\n    }\n  }\n  function onBlur(): void {\n    // A standalone backend preserves its current-frame cancellation semantics.\n    // A host control boundary calls clear() separately on the same blur event so\n    // no state crosses a lease; the source itself still emits cancellation to its\n    // sole consumer as it did before ownership routing existed.\n    keys.clear();\n    codes.clear();\n    mouseButtons.clear();\n    mvx = 0;\n    mvy = 0;\n    wheelAccum = 0;\n    // Pointer lock is not allowed to survive a focus boundary. Publish the\n    // unlocked state synchronously; pointerlockchange may arrive later (or\n    // be suppressed by the browser while the document is hidden).\n    if (typeof doc.exitPointerLock === 'function' && doc.pointerLockElement === canvas) {\n      doc.exitPointerLock();\n    }\n    w3cLocked = false;\n    releaseProviderLock();\n    if (pointerMap.size > 0) {\n      for (const [id, entry] of pointerMap) {\n        phaseQueue.push({\n          pointerId: id,\n          phase: 'cancel',\n          x: entry.x,\n          y: entry.y,\n          pressure: entry.pressure,\n          pointerType: entry.pointerType,\n        });\n      }\n      pointerMap.clear();\n    }\n    prevGamepadFrame.clear();\n    gamepadBaselinePending = true;\n    focusResetPending = true;\n    vjBindState.clear();\n  }\n\n  // Use try-blocks: jsdom / fake canvases passed by tests may lack\n  // `addEventListener`. We probe and skip silently to keep the unit-test\n  // surface workable (charter P3: detach must always succeed even if\n  // attach was a partial wiring).\n  const safeAdd = <K extends string>(\n    target: { addEventListener?: (k: K, h: EventListener) => void } | undefined,\n    kind: K,\n    handler: EventListener,\n  ): void => {\n    target?.addEventListener?.(kind, handler);\n  };\n  const safeRemove = <K extends string>(\n    target: { removeEventListener?: (k: K, h: EventListener) => void } | undefined,\n    kind: K,\n    handler: EventListener,\n  ): void => {\n    target?.removeEventListener?.(kind, handler);\n  };\n\n  safeAdd(win, 'keydown', onKeyDown as EventListener);\n  safeAdd(win, 'keyup', onKeyUp as EventListener);\n  safeAdd(win, 'blur', onBlur as EventListener);\n  safeAdd(canvas, 'pointerdown', onPointerDown as EventListener);\n  safeAdd(canvas, 'pointerup', onPointerUp as EventListener);\n  safeAdd(canvas, 'pointermove', onPointerMove as EventListener);\n  safeAdd(canvas, 'pointercancel', onPointerCancel as EventListener);\n  safeAdd(canvas, 'wheel', onWheel as EventListener);\n  safeAdd(doc, 'visibilitychange', onVisibilityChange as EventListener);\n\n  // w6 (D-1): track W3C pointer-lock state via document-level pointerlockchange.\n  // Per-instance isolation: only update w3cLocked when pointerLockElement matches\n  // this backend's canvas. A native unlock is also a lifecycle boundary: browsers\n  // do not all pair an OS focus transition with a DOM blur event, so clear the\n  // physical frame when an owned lock exits after being acquired.\n  function onPointerLockChange(): void {\n    const wasLocked = w3cLocked;\n    w3cLocked = doc.pointerLockElement === canvas;\n    // A delayed scan must not publish pre-lock movement as locked look input.\n    if (!wasLocked && w3cLocked && !providerLocked) {\n      mvx = 0;\n      mvy = 0;\n    }\n    if (wasLocked && !w3cLocked && !providerLocked) onBlur();\n  }\n  safeAdd(doc, 'pointerlockchange', onPointerLockChange as EventListener);\n\n  function onPointerLockError(event: Event): void {\n    emitLockError('w3c', event);\n  }\n  safeAdd(doc, 'pointerlockerror', onPointerLockError as EventListener);\n\n  // PointerLock entry must be triggered by user activation (W3C requires\n  // a click / keydown handler to call `requestPointerLock()`). The MVP\n  // wires a click listener on the canvas as the activation surface;\n  // OOS-1 keeps any explicit \"request lock\" / \"exit lock\" surface out\n  // of the snapshot itself.\n  // D-5: touch-action:none on the canvas so the browser does not interpret\n  // touch gestures (scroll/pinch/zoom) and deprioritizes pointer events.\n  // Presence-detect .style (fake canvas in unit tests may lack it).\n  let _prevTouchAction: string | undefined;\n  if (canvas.style) {\n    _prevTouchAction = canvas.style.touchAction;\n    canvas.style.touchAction = 'none';\n  }\n\n  function onCanvasClick(): void {\n    if (!inputAllowed) return;\n    // D-3: dual gate synthesis -- gameGate (command-set by template) AND\n    // hostPredicate (per-click evaluated by host). Both must pass to proceed.\n    if (!gameGate) return;\n    // Host gate: when the host says \"not now\" (e.g. an editor viewport that owns\n    // the cursor outside the play-game quadrant) skip the lock entirely. Default\n    // is always-allow, so the standalone game runtime is unchanged.\n    if (options.pointerLockAllowed && !options.pointerLockAllowed()) return;\n    // D-2 / D-7: lockProvider path takes priority over W3C.\n    if (options.lockProvider) {\n      if (!providerLocked && !w3cLocked) {\n        mvx = 0;\n        mvy = 0;\n      }\n      providerLocked = true; // D-7 optimistic placement\n      try {\n        const result = options.lockProvider.requestLock();\n        if (result && typeof (result as Promise<void>).catch === 'function') {\n          (result as Promise<void>).catch((cause: unknown) => {\n            providerLocked = false;\n            emitLockError('provider', cause);\n          });\n        }\n      } catch (cause: unknown) {\n        // Synchronous throw from requestLock.\n        providerLocked = false;\n        emitLockError('provider', cause);\n      }\n      return;\n    }\n\n    // W3C path: standard requestPointerLock.\n    const fn = canvas.requestPointerLock;\n    if (typeof fn !== 'function') return;\n    try {\n      const r = fn.call(canvas) as unknown;\n      if (r && typeof (r as Promise<void>).catch === 'function') {\n        (r as Promise<void>).catch((cause: unknown) => {\n          emitLockError('w3c', cause);\n        });\n      }\n    } catch (cause: unknown) {\n      emitLockError('w3c', cause);\n    }\n  }\n  safeAdd(canvas, 'click', onCanvasClick as EventListener);\n\n  function sample(): InputBackendSample {\n    if (!inputAllowed) {\n      clear();\n      return createEmptyInputBackendSample();\n    }\n    // D-1: gamepad edge diff derived inside sample() — the only\n    // cross-frame state holder. getGamepads() is polled once per frame;\n    // null-padded arrays use gamepad.index as slot key.\n    let gamepads: GamepadSlotSample[] | undefined;\n    if (gamepadAvailable) {\n      try {\n        const rawGamepads = (nav.getGamepads?.() ?? []) as (RawGamepadStub | null)[];\n        const valid: RawGamepadStub[] = [];\n        let hasNonStandard = false;\n        for (const gp of rawGamepads) {\n          if (!gp?.connected) continue;\n          valid.push(gp);\n          if (gp.mapping !== 'standard') hasNonStandard = true;\n        }\n        // M3 D-2 / C-5: only a real non-standard gamepad triggers the DB\n        // load. Standard pads never pull in the 554KB DB.\n        if (hasNonStandard) kickOffDbLoad();\n        haptics.observe(valid);\n        gamepads = diffGamepadFrame(prevGamepadFrame, valid, remapLookup).map((slot) => {\n          const target = haptics.target(slot.index);\n          return {\n            ...slot,\n            ...(target ? { feedbackTarget: target } : {}),\n            dualRumble: haptics.supported(slot.index),\n          };\n        });\n        if (gamepadBaselinePending) {\n          gamepads = gamepads.map((slot) => ({\n            ...slot,\n            justPressed: new Set<number>(),\n            justReleased: new Set<number>(),\n          }));\n          gamepadBaselinePending = false;\n        }\n        // Store this frame's state for next frame's diff.\n        const nextFrame = new Map<number, GamepadSlotSample>();\n        for (const slot of gamepads) nextFrame.set(slot.index, slot);\n        prevGamepadFrame = nextFrame;\n      } catch {\n        haptics.release();\n        // getGamepads() threw — treat as if no gamepad API.\n        // AC-05: API unstable environment does not crash.\n      }\n    }\n\n    // w15: freeze pointer map → PointerSample[] with cross-frame delta.\n    // Delta = current frozen position − previous frozen position (AC-09).\n    let pointers: PointerSample[] | undefined;\n    if (pointerMap.size > 0) {\n      pointers = [];\n      for (const [id, entry] of pointerMap) {\n        const deltaX = entry.x - entry.prevX;\n        const deltaY = entry.y - entry.prevY;\n        pointers.push({\n          pointerId: id,\n          x: entry.x,\n          y: entry.y,\n          pressure: entry.pressure,\n          pointerType: entry.pointerType,\n          active: true,\n          delta: Object.freeze({ x: deltaX, y: deltaY }),\n        });\n        // Update prev position for next frame's delta (D-1 frame-end freeze).\n        entry.prevX = entry.x;\n        entry.prevY = entry.y;\n      }\n    }\n\n    // w15: snapshot the phase queue for this frame.\n    const pointerEvents: PointerPhaseEvent[] | undefined =\n      phaseQueue.length > 0 ? [...phaseQueue] : undefined;\n\n    // w21: derive virtual joystick axes from live pointer positions.\n    let virtualAxes: VirtualAxisSample[] | undefined;\n    if (vjConfigs.length > 0) {\n      virtualAxes = deriveVirtualAxes(vjConfigs, pointerMap, vjBindState);\n    }\n\n    // M5 D-4: run the gesture recognizer over this frame's phase queue BEFORE\n    // it is drained below. onBlur / pointercancel pushed cancel phases into\n    // the same queue, so the recognizer naturally resets active gestures +\n    // emits cancel events (AC-18) without a separate reset path. All timers\n    // advance off `now()` (D-3), decoupled from event frequency (AC-16).\n    const gestureResult = processGestureFrame(\n      phaseQueue,\n      pointerMap as ReadonlyMap<number, RecognizerPointer>,\n      recognizerState,\n      now(),\n    );\n    recognizerState = gestureResult.newState;\n    // Emit optional fields only when there is gesture signal to carry: an\n    // active/frozen continuous value (non-identity) or lifecycle events.\n    const gestureEvents: readonly GestureEvent[] | undefined =\n      gestureResult.gestureEvents.length > 0 ? gestureResult.gestureEvents : undefined;\n    const gs = gestureResult.gestureState;\n    const gestures: GestureState | undefined =\n      gs.pinchScale !== 1 || gs.rotationAngle !== 0 ? gs : undefined;\n\n    const out: InputBackendSample = {\n      downKeys: new Set(heldKeys),\n      upKeys: new Set(upEdges),\n      downCodes: new Set(heldCodes),\n      upCodes: new Set(upCodeEdges),\n      pressedKeys: new Set(pressedKeys),\n      pressedCodes: new Set(pressedCodes),\n      buttons: [buttons[0], buttons[1], buttons[2]] as readonly [boolean, boolean, boolean],\n      pressedButtons: [pressedButtons[0], pressedButtons[1], pressedButtons[2]] as readonly [\n        boolean,\n        boolean,\n        boolean,\n      ],\n      releasedButtons: [releasedButtons[0], releasedButtons[1], releasedButtons[2]] as readonly [\n        boolean,\n        boolean,\n        boolean,\n      ],\n      movementX: mvx,\n      movementY: mvy,\n      ...(mouseX !== undefined && mouseY !== undefined ? { mouseX, mouseY } : {}),\n      wheelDelta: wheelAccum,\n      focused: isFocused(),\n      capabilities: caps,\n      pointerLocked: w3cLocked || providerLocked,\n      ...haptics.sampleResults(),\n      ...(gamepads ? { gamepads } : {}),\n      ...(pointers ? { pointers } : {}),\n      ...(pointerEvents ? { pointerEvents } : {}),\n      ...(virtualAxes ? { virtualAxes } : {}),\n      ...(gestures ? { gestures } : {}),\n      ...(gestureEvents ? { gestureEvents } : {}),\n      ...(focusResetPending ? { focusReset: true } : {}),\n    };\n    // Reset per-frame accumulators (movement delta + key edges + wheel notches + phase queue).\n    keys.clearFrame();\n    codes.clearFrame();\n    mouseButtons.clearFrame();\n    mvx = 0;\n    mvy = 0;\n    wheelAccum = 0;\n    phaseQueue.length = 0;\n    focusResetPending = false;\n    return out;\n  }\n\n  // w8 (D-3): command-set game gate for pointer-lock. set(false) immediately\n  // releases any active lock on both W3C and provider paths.\n  function setPointerLockAllowed(allowed: boolean): void {\n    gameGate = allowed;\n    if (!allowed) {\n      // W3C path: exit pointer-lock if currently locked on this canvas.\n      if (typeof doc.exitPointerLock === 'function' && doc.pointerLockElement === canvas) {\n        doc.exitPointerLock();\n      }\n      // Provider path: call exitLock and clear providerLocked.\n      releaseProviderLock();\n    }\n  }\n\n  function setInputAllowed(allowed: boolean): void {\n    inputAllowed = allowed;\n    // Both closing and reopening are lease boundaries. Clearing on reopen\n    // fences any event that raced the closed gate before the next scan.\n    clear();\n  }\n\n  function clear(): void {\n    haptics.release();\n    keys.clear();\n    codes.clear();\n    mouseButtons.clear();\n    pointerMap.clear();\n    phaseQueue.length = 0;\n    prevGamepadFrame.clear();\n    vjBindState.clear();\n    recognizerState = createRecognizerState();\n    mvx = 0;\n    mvy = 0;\n    wheelAccum = 0;\n    if (typeof doc?.exitPointerLock === 'function' && doc.pointerLockElement === canvas) {\n      doc.exitPointerLock();\n    }\n    // `pointerlockchange` is asynchronous. The boundary must nevertheless\n    // publish an unlocked frame immediately after revocation.\n    w3cLocked = false;\n    releaseProviderLock();\n  }\n\n  function detach(): void {\n    if (detached) return;\n    detached = true;\n    haptics.detach();\n    safeRemove(win, 'keydown', onKeyDown as EventListener);\n    safeRemove(win, 'keyup', onKeyUp as EventListener);\n    safeRemove(win, 'blur', onBlur as EventListener);\n    safeRemove(canvas, 'pointerdown', onPointerDown as EventListener);\n    safeRemove(canvas, 'pointerup', onPointerUp as EventListener);\n    safeRemove(canvas, 'pointermove', onPointerMove as EventListener);\n    safeRemove(canvas, 'pointercancel', onPointerCancel as EventListener);\n    safeRemove(canvas, 'wheel', onWheel as EventListener);\n    safeRemove(doc, 'visibilitychange', onVisibilityChange as EventListener);\n    safeRemove(doc, 'pointerlockchange', onPointerLockChange as EventListener);\n    safeRemove(doc, 'pointerlockerror', onPointerLockError as EventListener);\n    safeRemove(canvas, 'click', onCanvasClick as EventListener);\n    clear();\n    // D-5: restore original touch-action value.\n    if (canvas.style && _prevTouchAction !== undefined) {\n      canvas.style.touchAction = _prevTouchAction;\n    }\n  }\n\n  const backend: InputBackend = {\n    feedback: haptics.feedback,\n    dispatchFeedback: haptics.dispatch,\n    sample,\n    clear,\n    detach,\n    setPointerLockAllowed,\n    setInputAllowed,\n  };\n\n  // Returned callable doubles as the InputBackend (detach + sample). AI\n  // users see one symbol with both shapes, mirroring the\n  // produces-detach-and-protocol convention of `effect`-style libraries.\n  const handle = Object.assign(detach, { backend });\n  return handle;\n}\n","// @forgeax/engine-input -- exclusive host-owned canvas input boundary.\n//\n// A physical canvas has one DOM acquisition backend. Hosts with two worlds (for\n// example editor + transient Play) route that one producer through these two\n// InputBackend views. This is exclusive ownership, deliberately separate from\n// synthetic/replay input composition.\n\nimport {\n  createEmptyInputBackendSample,\n  type InputBackend,\n  type InputBackendSample,\n} from './input-snapshot';\nimport { isUiOwnedEvent } from './ui-ownership';\n\nexport interface CanvasInputBoundary {\n  readonly editor: InputBackend;\n  readonly game: InputBackend;\n  owner(): 'editor' | 'game';\n  grantGame(): void;\n  revokeGame(): void;\n  /** Clear the active consumer when an event originated in the host UI. */\n  handleUiEvent(event: Event, host: Node): boolean;\n  detach(): void;\n}\n\ntype CanvasInputOwner = ReturnType<CanvasInputBoundary['owner']>;\n\nexport function createCanvasInputBoundary(source: InputBackend): CanvasInputBoundary {\n  let active: CanvasInputOwner = 'editor';\n  let gamePointerLockAllowed = false;\n  let editorInputAllowed = true;\n  let gameInputAllowed = true;\n  source.setPointerLockAllowed?.(false);\n\n  const empty = (): InputBackendSample => createEmptyInputBackendSample();\n\n  const clear = (): void => {\n    source.clear?.();\n    source.setPointerLockAllowed?.(false);\n  };\n\n  const routed = (consumer: CanvasInputOwner): InputBackend => ({\n    sample: () => (consumer === active ? source.sample() : empty()),\n    setPointerLockAllowed: (allowed) => {\n      if (consumer === 'game') {\n        gamePointerLockAllowed = allowed;\n        source.setPointerLockAllowed?.(active === 'game' && allowed);\n      } else {\n        source.setPointerLockAllowed?.(false);\n      }\n    },\n    setInputAllowed: (allowed) => {\n      if (consumer === 'game') gameInputAllowed = allowed;\n      else editorInputAllowed = allowed;\n      source.setInputAllowed?.(active === 'game' ? gameInputAllowed : editorInputAllowed);\n    },\n    clear: () => {\n      if (consumer === active) clear();\n    },\n    detach: () => source.detach(),\n  });\n\n  const grantGame = (): void => {\n    if (active === 'game') return;\n    clear();\n    active = 'game';\n    source.setPointerLockAllowed?.(gamePointerLockAllowed);\n    source.setInputAllowed?.(gameInputAllowed);\n  };\n\n  const revokeGame = (): void => {\n    clear();\n    active = 'editor';\n    source.setInputAllowed?.(editorInputAllowed);\n  };\n\n  return {\n    editor: routed('editor'),\n    game: routed('game'),\n    owner: () => active,\n    grantGame,\n    revokeGame,\n    handleUiEvent: (event, host) => {\n      if (!isUiOwnedEvent(event, host)) return false;\n      clear();\n      return true;\n    },\n    detach: () => source.detach(),\n  };\n}\n","// @forgeax/engine-input -- CompositeInputBackend (synthetic-input decorator).\n//\n// PROBLEM. The scan system reads ONE `InputBackend` from `INPUT_BACKEND_KEY`\n// each frame. An AI / record-replay harness needs to feed synthetic input into\n// that same slot WITHOUT evicting the human's browser backend -- because a human\n// may take over at any instant (PIE two-world model + charter §8 human-as-final-\n// authority). Overwriting the resource locks the human out; wrapping it does not.\n//\n// SOLUTION. `makeCompositeBackend(inner)` returns an `InputBackend` that HOLDS\n// the human backend as `inner` and layers a programmatic injection surface\n// (`press` / `release` / `setButton` / `addMovement` / `addWheel`) on top. The\n// scan system stays variant-agnostic: it still calls `sample()` on one backend\n// (Depend-on-Abstractions -- the consumer never learns a composite exists).\n//\n// SIDE-EFFECT CONTRACT. `inner.sample()` DRAINS its per-frame accumulators\n// (up-edges, movement delta, wheel notches) on read, so the composite calls it\n// EXACTLY ONCE per `sample()` and drains its OWN injected accumulators in the\n// same pass. Field-by-field merge honoring each field's lifecycle:\n//\n//   downKeys   held across frames    -> UNION(inner, injected.held)\n//   upKeys     lives one frame        -> UNION; injected up-edge set drained here\n//   buttons    held tuple             -> OR per slot\n//   movementX/Y, wheelDelta            -> SUM; injected side reset to 0 here\n//   focused    gates up-edge suppress -> inner.focused || injectionActive\n//   pointerLocked                      -> inner (AI must not fabricate a lock)\n//   optional (pointers/gamepads/...)   -> pass through from inner untouched\n//\n// YIELD-TO-HUMAN (default on). A human-held key on `inner` suppresses only the\n// injected state for that SAME key in that frame. Other AI keys continue, so a\n// human can take a key without silencing unrelated synthetic input. This is the\n// structural realization of \"human wins\" without a global takeover policy.\n\nimport { ButtonLatch, KeyLatch } from './digital-input';\nimport type { InputBackend, InputBackendSample } from './input-snapshot';\n\nfunction mergeKeyState(\n  base: ReadonlySet<string> | undefined,\n  injected: ReadonlySet<string>,\n  humanOwns: (key: string) => boolean,\n): Set<string> {\n  const merged = new Set(base);\n  for (const key of injected) if (!humanOwns(key)) merged.add(key);\n  return merged;\n}\n\n/** Options controlling the composite merge policy. */\nexport interface CompositeBackendOptions {\n  /**\n   * When `true` (default), a key held on the inner (human) backend suppresses\n   * injected state only for that same key in that frame. Set `false` for\n   * record/replay or AI-solo scenarios where both sources should coexist even\n   * on key overlap.\n   */\n  readonly yieldToHuman?: boolean;\n}\n\n/**\n * A composite backend: an `InputBackend` (drop-in for `INPUT_BACKEND_KEY`) plus\n * a programmatic injection surface. All injection is additive over the wrapped\n * human backend.\n */\nexport interface CompositeInputBackend extends InputBackend {\n  /** Hold `key` down (mirrors a keydown). Idempotent. */\n  press(key: string): void;\n  /** Release `key` (mirrors a keyup); emits a one-frame up-edge on next sample. */\n  release(key: string): void;\n  /** Set an injected mouse-button slot (0/1/2) held-state. */\n  setButton(slot: 0 | 1 | 2, down: boolean): void;\n  /** Accumulate injected pointer-lock movement delta (drained on next sample). */\n  addMovement(dx: number, dy: number): void;\n  /** Accumulate injected wheel notches (drained on next sample). */\n  addWheel(notches: number): void;\n  /**\n   * Drop all injected state and pending frame edges; currently-held keys/buttons\n   * emit one clean release edge so a previously observed hold is closed.\n   */\n  clearInjected(): void;\n  /** Open a fresh synthetic-input lease after a previous revoke boundary. */\n  beginInjectedLease(): void;\n  /** Revoke the current lease and fence later injections until reopened. */\n  revokeInjectedLease(): void;\n  /**\n   * Create the one execution-scoped injection view. Creating a lease\n   * invalidates every previously-created view; an invalid view remains a\n   * no-op even after a later lease is opened.\n   */\n  createInjectedLease(): CompositeInputLease;\n  /** Toggle the yield-to-human gate at runtime. */\n  setYieldToHuman(yield_: boolean): void;\n}\n\n/**\n * Synthetic input exposed to one eval/execution. It deliberately has no\n * `beginInjectedLease` method: a script can release its own lease, but it\n * cannot reopen an old reference after the host has moved to another job.\n */\nexport interface CompositeInputLease extends InputBackend {\n  press(key: string): void;\n  release(key: string): void;\n  setButton(slot: 0 | 1 | 2, down: boolean): void;\n  addMovement(dx: number, dy: number): void;\n  addWheel(notches: number): void;\n  clearInjected(): void;\n  revokeInjectedLease(): void;\n}\n\n// The public injection surface accepts either the logical KeyboardEvent.key\n// (`w`, ` `, `ArrowUp`) or the physical KeyboardEvent.code (`KeyW`, `Space`).\n// Keep both projections populated so code-first control drives games that read\n// either keyboard.down(...) or keyboard.downCode(...).\nconst CODE_TO_KEY: Readonly<Record<string, string>> = {\n  Space: ' ',\n  ShiftLeft: 'Shift',\n  ShiftRight: 'Shift',\n  ControlLeft: 'Control',\n  ControlRight: 'Control',\n  AltLeft: 'Alt',\n  AltRight: 'Alt',\n  MetaLeft: 'Meta',\n  MetaRight: 'Meta',\n  BracketLeft: '[',\n  BracketRight: ']',\n  Backslash: '\\\\',\n  Semicolon: ';',\n  Quote: \"'\",\n  Comma: ',',\n  Period: '.',\n  Slash: '/',\n  Minus: '-',\n  Equal: '=',\n  Backquote: '`',\n};\n\nfunction keyForCode(code: string): string | undefined {\n  if (CODE_TO_KEY[code] !== undefined) return CODE_TO_KEY[code];\n  if (/^Key[A-Z]$/.test(code)) return code.slice(3).toLowerCase();\n  if (/^Digit[0-9]$/.test(code)) return code.slice(5);\n  if (/^Numpad[0-9]$/.test(code)) return code.slice(6);\n  if (/^F(?:[1-9]|1[0-2])$/.test(code)) return code;\n  if (/^Arrow(?:Up|Down|Left|Right)$/.test(code)) return code;\n  if (/^(?:Escape|Enter|Tab|Backspace|Delete|Home|End|PageUp|PageDown|Insert)$/.test(code))\n    return code;\n  return undefined;\n}\n\nfunction codeForKey(key: string): string | undefined {\n  if (/^[a-zA-Z]$/.test(key)) return `Key${key.toUpperCase()}`;\n  if (/^[0-9]$/.test(key)) return `Digit${key}`;\n  if (key === ' ') return 'Space';\n  if (\n    /^(?:Arrow(?:Up|Down|Left|Right)|Escape|Enter|Tab|Backspace|Delete|Home|End|PageUp|PageDown|Insert)$/.test(\n      key,\n    )\n  )\n    return key;\n  if (/^F(?:[1-9]|1[0-2])$/.test(key)) return key;\n  const entry = Object.entries(CODE_TO_KEY).find(([, value]) => value === key);\n  return entry?.[0];\n}\n\nfunction normalizeKey(value: string): { readonly key: string; readonly code: string | undefined } {\n  const logical = keyForCode(value);\n  return logical === undefined\n    ? { key: value, code: codeForKey(value) }\n    : { key: logical, code: value };\n}\n\nexport function makeCompositeBackend(\n  inner: InputBackend,\n  options?: CompositeBackendOptions,\n): CompositeInputBackend {\n  let yieldToHuman = options?.yieldToHuman ?? true;\n  let inputAllowed = true;\n  let leaseRevoked = false;\n  let leaseGeneration = 0;\n\n  // Injected held-state (survives across frames).\n  const keys = new KeyLatch();\n  const codes = new KeyLatch();\n  const mouseButtons = new ButtonLatch();\n  const { held: heldKeys, pressed: pressedKeys, released: upEdges } = keys;\n  const { held: heldCodes, pressed: pressedCodes, released: upCodeEdges } = codes;\n  const { held: buttons, pressed: pressedButtons, released: releasedButtons } = mouseButtons;\n  let mvx = 0;\n  let mvy = 0;\n  let wheel = 0;\n\n  function drainInjectedFrame(): void {\n    keys.clearFrame();\n    codes.clearFrame();\n    mouseButtons.clearFrame();\n    mvx = 0;\n    mvy = 0;\n    wheel = 0;\n  }\n\n  function injectionActive(): boolean {\n    return (\n      heldKeys.size > 0 ||\n      heldCodes.size > 0 ||\n      upEdges.size > 0 ||\n      upCodeEdges.size > 0 ||\n      pressedKeys.size > 0 ||\n      pressedCodes.size > 0 ||\n      buttons.some((b) => b) ||\n      pressedButtons.some((b) => b) ||\n      releasedButtons.some((b) => b)\n    );\n  }\n\n  function humanOwnsKey(base: InputBackendSample, key: string, code: string | undefined): boolean {\n    return (\n      yieldToHuman &&\n      (base.downKeys.has(key) || (code !== undefined && base.downCodes?.has(code) === true))\n    );\n  }\n\n  function humanOwnsCode(base: InputBackendSample, code: string): boolean {\n    const key = keyForCode(code);\n    return (\n      yieldToHuman &&\n      (base.downCodes?.has(code) === true || (key !== undefined && base.downKeys.has(key)))\n    );\n  }\n\n  function sample(): InputBackendSample {\n    // Call inner EXACTLY once -- it drains its own accumulators here.\n    const base = inner.sample();\n    if (!inputAllowed) {\n      clearInjected();\n      return {\n        ...base,\n        downKeys: new Set(),\n        upKeys: new Set(),\n        downCodes: new Set(),\n        upCodes: new Set(),\n        pressedKeys: new Set(),\n        pressedCodes: new Set(),\n        buttons: [false, false, false],\n        pressedButtons: [false, false, false],\n        releasedButtons: [false, false, false],\n        movementX: 0,\n        movementY: 0,\n        wheelDelta: 0,\n        pointerLocked: false,\n      };\n    }\n\n    // yield-to-human is PER-KEY: an injected key is suppressed only when the human\n    // is holding the SAME key this frame. This is the minimal realization of\n    // charter §8 (the human always wins a key they touch) WITHOUT the collateral of\n    // a global gate — a human strafing D does not silence an AI holding W, so the\n    // two genuinely coexist (that is the whole point of a composite; a caller who\n    // wants \"human takes over everything\" can clearInjected() at the policy layer).\n    // downKeys: union of human-held and injected-held, minus injected keys the human\n    // is also pressing. A yielded injected release is likewise a no-op: emitting its\n    // up-edge would incorrectly release the human-held key in the scan system.\n    const ownsKey = (key: string) => humanOwnsKey(base, key, codeForKey(key));\n    const ownsCode = (code: string) => humanOwnsCode(base, code);\n    const downKeys = mergeKeyState(base.downKeys, heldKeys, ownsKey);\n    const downCodes =\n      base.downCodes === undefined && heldCodes.size === 0\n        ? undefined\n        : mergeKeyState(base.downCodes, heldCodes, ownsCode);\n    const mergedUp = mergeKeyState(base.upKeys, upEdges, ownsKey);\n    const mergedUpCodes =\n      base.upCodes === undefined && upCodeEdges.size === 0\n        ? undefined\n        : mergeKeyState(base.upCodes, upCodeEdges, ownsCode);\n    const mergedPressed =\n      base.pressedKeys === undefined && pressedKeys.size === 0\n        ? undefined\n        : mergeKeyState(base.pressedKeys, pressedKeys, ownsKey);\n    const mergedPressedCodes =\n      base.pressedCodes === undefined && pressedCodes.size === 0\n        ? undefined\n        : mergeKeyState(base.pressedCodes, pressedCodes, ownsCode);\n\n    // buttons: OR per slot.\n    const mergedButtons: readonly [boolean, boolean, boolean] = [\n      base.buttons[0] || buttons[0],\n      base.buttons[1] || buttons[1],\n      base.buttons[2] || buttons[2],\n    ];\n    const mergedPressedButtons =\n      base.pressedButtons === undefined && !pressedButtons.some(Boolean)\n        ? undefined\n        : ([\n            (base.pressedButtons?.[0] ?? false) || pressedButtons[0],\n            (base.pressedButtons?.[1] ?? false) || pressedButtons[1],\n            (base.pressedButtons?.[2] ?? false) || pressedButtons[2],\n          ] as const);\n    const mergedReleasedButtons =\n      base.releasedButtons === undefined && !releasedButtons.some(Boolean)\n        ? undefined\n        : ([\n            (base.releasedButtons?.[0] ?? false) || releasedButtons[0],\n            (base.releasedButtons?.[1] ?? false) || releasedButtons[1],\n            (base.releasedButtons?.[2] ?? false) || releasedButtons[2],\n          ] as const);\n\n    // focused: keep true while WE are injecting, so the scan system does not\n    // treat a headless/backgrounded tab (inner.focused === false) as a reason\n    // to suppress our up-edges. Otherwise mirror inner.\n    const focused = base.focused || injectionActive();\n\n    const out: InputBackendSample = {\n      ...base, // carry inner optional fields (pointers/gamepads/gestures/...) untouched\n      downKeys,\n      upKeys: mergedUp,\n      ...(downCodes === undefined ? {} : { downCodes }),\n      ...(mergedUpCodes === undefined ? {} : { upCodes: mergedUpCodes }),\n      ...(mergedPressed === undefined ? {} : { pressedKeys: mergedPressed }),\n      ...(mergedPressedCodes === undefined ? {} : { pressedCodes: mergedPressedCodes }),\n      buttons: mergedButtons,\n      ...(mergedPressedButtons === undefined ? {} : { pressedButtons: mergedPressedButtons }),\n      ...(mergedReleasedButtons === undefined ? {} : { releasedButtons: mergedReleasedButtons }),\n      movementX: base.movementX + mvx,\n      movementY: base.movementY + mvy,\n      wheelDelta: base.wheelDelta + wheel,\n      focused,\n      pointerLocked: base.pointerLocked, // AI never fabricates a lock\n    };\n\n    drainInjectedFrame();\n\n    return out;\n  }\n\n  // Only surface setPointerLockAllowed when the inner backend supports it, so\n  // the optional method is truly absent (not `undefined`) under\n  // exactOptionalPropertyTypes -- and forwards to the human backend when present.\n  const lockGate: Pick<InputBackend, 'setPointerLockAllowed'> = inner.setPointerLockAllowed\n    ? { setPointerLockAllowed: (allowed: boolean) => inner.setPointerLockAllowed?.(allowed) }\n    : {};\n  const inputGate: Pick<InputBackend, 'setInputAllowed'> = {\n    setInputAllowed: (allowed: boolean) => {\n      inputAllowed = allowed;\n      inner.setInputAllowed?.(allowed);\n      // Closing and reopening are both lease boundaries. Clear after either\n      // transition so synthetic edges cannot cross a startup/input fence.\n      clearInjected();\n    },\n  };\n\n  const clearInjected = (): void => {\n    // Clearing is a lease boundary: discard every pending frame edge first,\n    // then emit only the releases required to close state that was held\n    // across the boundary. This prevents a press/release queued before a\n    // revoke from becoming a ghost edge for the next consumer.\n    drainInjectedFrame();\n    keys.releaseAll();\n    codes.releaseAll();\n    mouseButtons.releaseAll();\n  };\n\n  const beginInjectedLease = (): void => {\n    // A new boundary must invalidate old references. Merely flipping a global\n    // boolean would let an async script keep writing after a later job opens.\n    leaseGeneration += 1;\n    leaseRevoked = false;\n    clearInjected();\n  };\n  const revokeInjectedLease = (): void => {\n    leaseGeneration += 1;\n    leaseRevoked = true;\n    clearInjected();\n  };\n\n  // Both owner and execution views write the same injected state. Only the\n  // admission predicate differs: execution views also capture a generation.\n  const injectionWriter = (\n    active: () => boolean,\n  ): Pick<CompositeInputLease, 'press' | 'release' | 'setButton' | 'addMovement' | 'addWheel'> => ({\n    press(key) {\n      if (!active()) return;\n      const normalized = normalizeKey(key);\n      keys.press(normalized.key);\n      if (normalized.code !== undefined) codes.press(normalized.code);\n    },\n    release(key) {\n      if (!active()) return;\n      const normalized = normalizeKey(key);\n      if (heldKeys.has(normalized.key)) keys.release(normalized.key);\n      if (normalized.code !== undefined && heldCodes.has(normalized.code))\n        codes.release(normalized.code);\n    },\n    setButton(slot, down) {\n      if (!active()) return;\n      mouseButtons.set(slot, down);\n    },\n    addMovement(dx, dy) {\n      if (!active()) return;\n      mvx += dx;\n      mvy += dy;\n    },\n    addWheel(notches) {\n      if (!active()) return;\n      wheel += notches;\n    },\n  });\n\n  const createInjectedLease = (): CompositeInputLease => {\n    beginInjectedLease();\n    const generation = leaseGeneration;\n    const active = (): boolean => inputAllowed && !leaseRevoked && generation === leaseGeneration;\n    return {\n      sample,\n      detach: () => {},\n      ...injectionWriter(active),\n      clearInjected() {\n        if (active()) clearInjected();\n      },\n      revokeInjectedLease() {\n        if (active()) revokeInjectedLease();\n      },\n    };\n  };\n\n  return {\n    ...(inner.feedback ? { feedback: inner.feedback } : {}),\n    ...(inner.dispatchFeedback ? { dispatchFeedback: inner.dispatchFeedback.bind(inner) } : {}),\n    sample,\n    ...lockGate,\n    ...inputGate,\n    // Teardown belongs to the human backend -- revoke the synthetic lease\n    // first, then forward the physical listener teardown.  `clear()` is also\n    // exposed so an owner can revoke input without detaching the browser.\n    clear: () => {\n      clearInjected();\n      inner.clear?.();\n    },\n    detach: () => {\n      clearInjected();\n      inner.detach();\n    },\n\n    ...injectionWriter(() => inputAllowed && !leaseRevoked),\n    clearInjected,\n    beginInjectedLease,\n    revokeInjectedLease,\n    createInjectedLease,\n    setYieldToHuman(yield_) {\n      yieldToHuman = yield_;\n    },\n  };\n}\n","// frame-start-scan-system.ts -- bridges an `InputBackend` producer into\n// the `InputSnapshot` Resource consumed by user systems (charter P5).\n//\n// Plan-strategy section 2.10 D-5 locks the system to a frame-start position\n// in the schedule: user systems declare `after: ['input-frame-start-scan']`\n// to read the snapshot. The system itself holds zero queries; it only\n// pulls one sample from the backend and writes the Resource.\n//\n// The backend is supplied via the `InputBackend` World resource rather than a\n// captured closure. Resource reads remain explicit in the system body.\n\nimport { defineSystem, defineSystemSet, type SystemHandle } from '@forgeax/engine-ecs';\nimport {\n  type ActionConfig,\n  type ActionState,\n  deriveActionStates,\n  INPUT_MAP_KEY,\n} from './action-state';\nimport {\n  INPUT_SNAPSHOT_RESOURCE_KEY,\n  type InputBackend,\n  type InputSnapshot,\n  readActionStatesForEdgeDiff,\n  snapshotFromSample,\n} from './input-snapshot';\n\n/**\n * Stable system name (locked by `frame-start-scan-system.test.ts`). User\n * systems reference it through `after: [FRAME_START_SCAN_SYSTEM_NAME]`\n * to ensure they observe the freshly written snapshot.\n */\nexport const FRAME_START_SCAN_SYSTEM_NAME = 'input-frame-start-scan';\nexport const InputSet = defineSystemSet({ name: 'input' });\n\n/**\n * Resource key under which the {@link InputBackend} producer is inserted\n * (M2 — full resource-ification, D-2 / D-7). The frame-start scan system\n * declares it in `resources`; the fn body reads it back via\n * `world.getResource(INPUT_BACKEND_KEY)`.\n *\n * Aligns with the `INPUT_SNAPSHOT_RESOURCE_KEY` naming. Consumers import the\n * constant rather than the bare string so a typo degrades to an import error\n * (charter P3).\n */\nexport const INPUT_BACKEND_KEY = 'InputBackend' as const;\n\n/**\n * The frame-start scan system token (M2 — full resource-ification, D-4).\n *\n * Module-level `defineSystem` with the real fn body — no factory, no closure.\n * Each `world.update()` tick:\n *   1. reads the {@link InputBackend} from `INPUT_BACKEND_KEY` and calls\n *      `backend.sample()` once to atomically drain the per-frame accumulators\n *      (movement delta plus key/code/button press and release edge sets);\n *   2. derives a fresh `InputSnapshot` via `snapshotFromSample`;\n *   3. writes it under `INPUT_SNAPSHOT_RESOURCE_KEY` via\n *      `world.insertResource` -- idempotent overwrite, charter P4\n *      consistent abstraction (consumers always read the same Resource key\n *      regardless of which backend produced the sample).\n *\n * Labelled `'input'` (spec §6.2 label-anchor map).\n */\nexport const InputFrameStartScan: SystemHandle<readonly []> = defineSystem({\n  name: FRAME_START_SCAN_SYSTEM_NAME,\n  queries: [],\n  fn: (world) => {\n    const backend = world.getResource<InputBackend>(INPUT_BACKEND_KEY);\n    const sample = backend.sample();\n    backend.feedback?.acceptResults(sample.feedbackResults ?? [], sample.feedbackLostResults ?? 0);\n\n    // Action mapping: derive states from InputMap Resource + prev snapshot edges.\n    // D-6: edge baseline reuses existing prev InputSnapshot Resource (Derive,\n    // Don't Duplicate — zero new cross-frame state carrier).\n    let actionStates: ReturnType<typeof deriveActionStates> | undefined;\n    let inputMap: readonly ActionConfig[] | undefined;\n    if (world.hasResource(INPUT_MAP_KEY)) {\n      inputMap = world.getResource<readonly ActionConfig[]>(INPUT_MAP_KEY);\n      // Read prev snapshot's internal action states for edge diff.\n      // First frame: no prev snapshot → justPressed = pressed (same as Feat1 gamepad).\n      let prevActionStates: readonly ActionState[] | undefined;\n      if (world.hasResource(INPUT_SNAPSHOT_RESOURCE_KEY)) {\n        const prevSnap = world.getResource<InputSnapshot>(INPUT_SNAPSHOT_RESOURCE_KEY);\n        prevActionStates = readActionStatesForEdgeDiff(prevSnap);\n      }\n      actionStates = deriveActionStates(sample, inputMap, prevActionStates);\n    }\n\n    const previousSnapshot = world.hasResource(INPUT_SNAPSHOT_RESOURCE_KEY)\n      ? world.getResource<InputSnapshot>(INPUT_SNAPSHOT_RESOURCE_KEY)\n      : undefined;\n    const snapshot = snapshotFromSample(sample, actionStates, previousSnapshot);\n    world.insertResource(INPUT_SNAPSHOT_RESOURCE_KEY, snapshot);\n  },\n});\n","import type { Plugin } from '@forgeax/engine-plugin';\n\nimport type { InputBackend } from './input-snapshot';\n\ndeclare module '@forgeax/engine-plugin' {\n  interface EngineContextServices {\n    input?: InputBackend;\n  }\n}\n\nexport function inputBackendPlugin(backend: InputBackend): Plugin {\n  return {\n    name: 'input-backend',\n    provide: 'input',\n    apply(ctx) {\n      ctx.provide('input', backend);\n    },\n  };\n}\n\n/** Provide an App-acquired input backend and release its Host listeners with the Fiber. */\nexport function ownedInputBackendPlugin(backend: InputBackend, dispose: () => void): Plugin {\n  return {\n    name: 'input-backend',\n    provide: 'input',\n    apply(ctx) {\n      ctx.provide('input', backend);\n      ctx.effect(() => dispose, 'input/backend');\n    },\n  };\n}\n"]}