class ThinkingPanel { constructor(thinkingEl) { this._el = thinkingEl; } get element() { return this._el; } render(turn, replay) { if (!turn) { this._el.innerHTML = "

Select a game to inspect reasoning.

"; this._syncMonoOffset(); return; } const reasoning = turn.my_thinking; const reasons = this._extractReasoningList(reasoning); const reasonList = reasons.map((item) => `
  • ${item}
  • `).join(""); const gameMeta = replay && replay.game ? replay.game : {}; const snakeType = Utils.safeString(gameMeta.your_snake_type); const snakeVersion = Utils.safeString(gameMeta.your_snake_version); this._el.innerHTML = `
    Chosen Move${Utils.safeString(turn.my_move)}
    Snake Type${snakeType}
    Snake Version${snakeVersion}
    Observed At${Utils.formatObservedAtLocal(turn.observed_at)}
    Food Count${Array.isArray(turn.food) ? turn.food.length : 0}
    Hazard Count${Array.isArray(turn.hazards) ? turn.hazards.length : 0}
    ${SnakeTable.buildSnakesRows(turn, replay)}
    SnakeLatencyMoveHealthLength

    Move Scores

    ${MoveTable.buildScoresRows(reasoning)}
    MoveScore

    Decision Summary

    Raw Reasoning Payload

    ${JSON.stringify(reasoning, null, 2)}
    `; this._syncMonoOffset(); } highlightSnake(snakeId) { const section = this._el.querySelector(".snakes-section"); if (!section) return; section.querySelectorAll(".snake-row.highlighted").forEach((r) => r.classList.remove("highlighted")); section.classList.remove("has-highlight"); if (!snakeId) return; const row = section.querySelector(`[data-snake-id="${CSS.escape(snakeId)}"]`); if (row) { row.classList.add("highlighted"); section.classList.add("has-highlight"); } } syncMonoOffset() { this._syncMonoOffset(); } _syncMonoOffset() { const mono = this._el.querySelector(".mono"); if (!mono) return; const rect = mono.getBoundingClientRect(); const bottomPaddingPx = 36; const offset = Math.max(120, Math.round(rect.top + bottomPaddingPx)); document.documentElement.style.setProperty("--mono-vh-offset", `${offset}px`); } _extractReasoningList(reasoning) { const parts = []; if (!reasoning || typeof reasoning !== "object") { return ["No reasoning recorded by this snake implementation."]; } if (reasoning.reason) parts.push(`Reason: ${reasoning.reason}`); if (reasoning.mode) parts.push(`Mode: ${reasoning.mode}`); if (reasoning.health !== undefined) parts.push(`Health: ${reasoning.health}`); if (reasoning.length !== undefined) parts.push(`Length: ${reasoning.length}`); if (reasoning.occupancy !== undefined) parts.push(`Occupancy: ${reasoning.occupancy}`); if (reasoning.ms_remaining !== undefined) parts.push(`Time left: ${reasoning.ms_remaining}ms`); if (parts.length === 0) parts.push("Structured reasoning not provided; showing raw payload below."); return parts; } }