export interface ScoreboardEntry { teamId: string; teamName: string; score: number; isPlayer: boolean; } export interface LayoutConfig { backgroundColor?: string; gridWidth?: number; gridHeight?: number; showScoreboard?: boolean; } export interface LayoutState { config: LayoutConfig; scoreboard: ScoreboardEntry[]; gridContent: string; } export class Layout { private state: LayoutState; constructor(config: LayoutConfig = {}) { this.state = { config: { backgroundColor: '#1a1a2e', gridWidth: 800, gridHeight: 600, showScoreboard: true, ...config }, scoreboard: [], gridContent: '' }; } public setGridContent(content: string): void { this.state.gridContent = content; } public updateScoreboard(entries: ScoreboardEntry[]): void { this.state.scoreboard = [...entries]; } public setPlayerTeam(teamId: string): void { this.state.scoreboard = this.state.scoreboard.map(entry => ({ ...entry, isPlayer: entry.teamId === teamId })); } public render(): string { const { config } = this.state; return `
${this.renderScoreboard()}
${this.state.gridContent}
`; } private renderScoreboard(): string { if (!this.state.config.showScoreboard || this.state.scoreboard.length === 0) { return ''; } const scoreboardEntries = this.state.scoreboard .sort((a, b) => b.score - a.score) .map(entry => this.renderScoreboardEntry(entry)) .join(''); return `

Scoreboard

${scoreboardEntries}
`; } private renderScoreboardEntry(entry: ScoreboardEntry): string { const isPlayerStyle = entry.isPlayer ? 'background-color: rgba(74, 144, 226, 0.3); border-left: 4px solid #4a90e2;' : 'background-color: rgba(255, 255, 255, 0.05);'; return `
${this.escapeHtml(entry.teamName)} ${entry.score}
`; } private escapeHtml(text: string): string { return text .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } public getState(): Readonly { return { ...this.state }; } public updateConfig(updates: Partial): void { this.state.config = { ...this.state.config, ...updates }; } } export function createLayout(config?: LayoutConfig): Layout { return new Layout(config); } export function renderCenteredGrid(content: string, width = 800, height = 600): string { const layout = createLayout({ gridWidth: width, gridHeight: height }); layout.setGridContent(content); return layout.render(); } /** @internal Phoenix VCS traceability — do not remove. */ export const _phoenix = { iu_id: '9a35a9f5ebc71f65e83ff408274437068be7102b862e2935ac1476754d238566', name: 'Layout', risk_tier: 'low', canon_ids: [2 as const], } as const;