/** * LANE-UI — inspector panel. Shows one entity: what it is, what the codex says about * it, what it's chewing, how far along, how hot, and why it has stopped. * * Holds an entity *id*, never an entity object — CONTRACTS says the sim may reuse * snapshot buffers between frames, so we re-look-up from the live snapshot each update * and close ourselves if the unit is gone. */ import type { EntityState, GameData, ItemDef, MachineDef, RecipeDef, SimSnapshot, UIBus, } from '../contracts'; import { createChipRow, type ChipRow } from './chips'; import { intakeChips, outputChips } from './chipspec'; import { attrs, cls, el, panel, style, text } from './dom'; import { COPY, jamText, machineFlavor } from './voice'; export interface Inspector { el: HTMLElement; open(entityId: number): void; close(): void; isOpen(): boolean; update(snap: SimSnapshot): void; /** Entity currently shown, for the renderer-side selection highlight later. */ openId(): number | null; } /** Heat above this throttles (CONTRACTS: "throttles >0.7, scrams at 1"). */ const THROTTLE_AT = 0.7; export function createInspector(data: GameData, bus: UIBus): Inspector { const machines = new Map(data.machines.map((m) => [m.id, m])); const recipes = new Map(data.recipes.map((r) => [r.id, r])); const items = new Map(data.items.map((i) => [i.id, i])); const root = panel(); root.id = 'fk-inspect'; const name = el('div', 'fk-ins-name'); const closeBtn = el('button', 'fk-ins-x', [COPY.inspectorClose]); attrs(closeBtn, { type: 'button', title: 'CLOSE (ESC)' }); const head = el('div', 'fk-ins-head', [name, closeBtn]); const flavor = el('div', 'fk-ins-flavor'); // ------------------------------------------------------------- recipe picker const recHead = el('div', 'fk-h', [COPY.inspectorRecipe]); const recSelect = el('select', 'fk-ins-recipe'); attrs(recSelect, { title: 'PROCESS SELECT' }); recSelect.addEventListener('change', () => { if (openId === null) return; const v = recSelect.value; bus.dispatch({ kind: 'setRecipe', entity: openId, recipe: v === '' ? null : v }); }); /** The def whose options are currently in the