@termuijs/core 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -25
- package/dist/index.cjs +188 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -6
- package/dist/index.d.ts +69 -6
- package/dist/index.js +178 -22
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/style/Color.ts","../src/utils/ansi.ts","../src/terminal/Terminal.ts","../src/terminal/Screen.ts","../src/terminal/Renderer.ts","../src/terminal/LayerManager.ts","../src/events/types.ts","../src/input/KeyMap.ts","../src/input/MouseParser.ts","../src/events/EventEmitter.ts","../src/input/InputParser.ts","../src/style/Style.ts","../src/style/Border.ts","../src/layout/LayoutEngine.ts","../src/layout/Rect.ts","../src/layout/ConstraintLayout.ts","../src/events/FocusManager.ts","../src/style/symbols.ts","../src/terminal/TestBackend.ts","../src/app/Fallback.ts","../src/app/App.ts","../src/utils/unicode.ts"],"sourcesContent":["// ─────────────────────────────────────────────────────\n// @termuijs/core — Color types and color profile detection\n// ─────────────────────────────────────────────────────\n\n/**\n * Supported color depth levels, ordered from least to most capable.\n */\nexport enum ColorDepth {\n /** No color support (e.g. NO_COLOR env var set) */\n None = 0,\n /** 4-bit, 16 colors (standard ANSI) */\n Basic = 4,\n /** 8-bit, 256 colors */\n Ansi256 = 8,\n /** 24-bit, 16.7 million colors (true color) */\n TrueColor = 24,\n}\n\n/**\n * Represents a color value in the terminal.\n * Supports named ANSI colors, 256-color palette, and RGB true color.\n */\nexport type Color =\n | { type: 'named'; name: NamedColor }\n | { type: 'ansi256'; code: number }\n | { type: 'rgb'; r: number; g: number; b: number }\n | { type: 'hex'; hex: string }\n | { type: 'none' };\n\nexport type NamedColor =\n | 'black' | 'red' | 'green' | 'yellow'\n | 'blue' | 'magenta' | 'cyan' | 'white'\n | 'brightBlack' | 'brightRed' | 'brightGreen' | 'brightYellow'\n | 'brightBlue' | 'brightMagenta' | 'brightCyan' | 'brightWhite';\n\n/** Maps named colors to their ANSI 4-bit foreground code offsets (30-37, 90-97). */\nconst NAMED_TO_ANSI: Record<NamedColor, number> = {\n black: 0, red: 1, green: 2, yellow: 3,\n blue: 4, magenta: 5, cyan: 6, white: 7,\n brightBlack: 8, brightRed: 9, brightGreen: 10, brightYellow: 11,\n brightBlue: 12, brightMagenta: 13, brightCyan: 14, brightWhite: 15,\n};\n\n/** Maps named colors to approximate RGB for downgrading. */\nconst NAMED_TO_RGB: Record<NamedColor, [number, number, number]> = {\n black: [0, 0, 0], red: [170, 0, 0], green: [0, 170, 0], yellow: [170, 170, 0],\n blue: [0, 0, 170], magenta: [170, 0, 170], cyan: [0, 170, 170], white: [170, 170, 170],\n brightBlack: [85, 85, 85], brightRed: [255, 85, 85], brightGreen: [85, 255, 85], brightYellow: [255, 255, 85],\n brightBlue: [85, 85, 255], brightMagenta: [255, 85, 255], brightCyan: [85, 255, 255], brightWhite: [255, 255, 255],\n};\n\n/**\n * Parse a color string into a Color object.\n *\n * Accepts:\n * - Named colors: 'red', 'brightBlue', etc.\n * - Hex: '#ff0000', '#f00'\n * - RGB: 'rgb(255, 0, 0)'\n * - ANSI 256: 'ansi256(196)'\n */\nexport function parseColor(input: string): Color {\n if (input === 'none' || input === '') {\n return { type: 'none' };\n }\n\n // Named color\n if (input in NAMED_TO_ANSI) {\n return { type: 'named', name: input as NamedColor };\n }\n\n // Hex color\n if (input.startsWith('#')) {\n let hex = input.slice(1);\n if (hex.length === 3) {\n hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];\n }\n if (hex.length === 6 && /^[0-9a-fA-F]{6}$/.test(hex)) {\n return { type: 'hex', hex: '#' + hex.toLowerCase() };\n }\n // Invalid hex — return none instead of crashing\n return { type: 'none' };\n }\n\n // RGB color\n const rgbMatch = input.match(/^rgb\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*\\)$/);\n if (rgbMatch) {\n const r = Math.min(255, parseInt(rgbMatch[1], 10));\n const g = Math.min(255, parseInt(rgbMatch[2], 10));\n const b = Math.min(255, parseInt(rgbMatch[3], 10));\n return { type: 'rgb', r, g, b };\n }\n\n // ANSI 256\n const ansi256Match = input.match(/^ansi256\\(\\s*(\\d{1,3})\\s*\\)$/);\n if (ansi256Match) {\n const code = Math.min(255, parseInt(ansi256Match[1], 10));\n return { type: 'ansi256', code };\n }\n\n // Unknown format — return none instead of crashing\n return { type: 'none' };\n}\n\n/**\n * Convert any Color to its RGB representation.\n */\nexport function colorToRgb(color: Color): [number, number, number] {\n switch (color.type) {\n case 'none':\n return [0, 0, 0];\n case 'named':\n return NAMED_TO_RGB[color.name];\n case 'rgb':\n return [color.r, color.g, color.b];\n case 'hex': {\n const hex = color.hex.slice(1);\n return [\n parseInt(hex.slice(0, 2), 16),\n parseInt(hex.slice(2, 4), 16),\n parseInt(hex.slice(4, 6), 16),\n ];\n }\n case 'ansi256':\n return ansi256ToRgb(color.code);\n }\n}\n\n/**\n * Convert an ANSI 256 code to approximate RGB.\n */\nfunction ansi256ToRgb(code: number): [number, number, number] {\n // Standard colors (0-15) — use named mapping\n if (code < 16) {\n const names = Object.keys(NAMED_TO_RGB) as NamedColor[];\n return NAMED_TO_RGB[names[code]];\n }\n // Extended 216-color cube (16-231)\n if (code < 232) {\n const idx = code - 16;\n const b = (idx % 6) * 51;\n const g = (Math.floor(idx / 6) % 6) * 51;\n const r = Math.floor(idx / 36) * 51;\n return [r, g, b];\n }\n // Grayscale ramp (232-255)\n const gray = (code - 232) * 10 + 8;\n return [gray, gray, gray];\n}\n\n/**\n * Find the nearest ANSI 256 color code for a given RGB.\n */\nfunction rgbToAnsi256(r: number, g: number, b: number): number {\n // Check if it's a grayscale\n if (r === g && g === b) {\n if (r < 8) return 16;\n if (r > 248) return 231;\n return Math.round((r - 8) / 247 * 24) + 232;\n }\n return 16\n + 36 * Math.round(r / 255 * 5)\n + 6 * Math.round(g / 255 * 5)\n + Math.round(b / 255 * 5);\n}\n\n/**\n * Find the nearest ANSI 4-bit basic color for a given RGB.\n */\nfunction rgbToBasic(r: number, g: number, b: number): number {\n let minDist = Infinity;\n let best = 0;\n const names = Object.keys(NAMED_TO_RGB) as NamedColor[];\n for (let i = 0; i < names.length; i++) {\n const [cr, cg, cb] = NAMED_TO_RGB[names[i]];\n const dist = (r - cr) ** 2 + (g - cg) ** 2 + (b - cb) ** 2;\n if (dist < minDist) {\n minDist = dist;\n best = i;\n }\n }\n return best;\n}\n\n/**\n * Detect the terminal's color depth from environment variables.\n */\nexport function detectColorDepth(): ColorDepth {\n const env = process.env;\n\n // Respect NO_COLOR convention (https://no-color.org/)\n if (env['NO_COLOR'] !== undefined) {\n return ColorDepth.None;\n }\n\n // Force color via FORCE_COLOR\n if (env['FORCE_COLOR'] !== undefined) {\n const level = parseInt(env['FORCE_COLOR'], 10);\n if (level === 0) return ColorDepth.None;\n if (level === 1) return ColorDepth.Basic;\n if (level === 2) return ColorDepth.Ansi256;\n if (level >= 3) return ColorDepth.TrueColor;\n }\n\n // Check COLORTERM for true color\n const colorterm = env['COLORTERM'];\n if (colorterm === 'truecolor' || colorterm === '24bit') {\n return ColorDepth.TrueColor;\n }\n\n // Check TERM for 256 color\n const term = env['TERM'] || '';\n if (term === 'dumb') {\n return ColorDepth.None;\n }\n if (term.includes('256color') || term.includes('256')) {\n return ColorDepth.Ansi256;\n }\n\n // Check for common color-capable terminals\n if (env['TERM_PROGRAM'] === 'iTerm.app' || env['TERM_PROGRAM'] === 'Hyper') {\n return ColorDepth.TrueColor;\n }\n\n // Default to basic if stdout is a TTY\n if (process.stdout?.isTTY) {\n return ColorDepth.Basic;\n }\n\n return ColorDepth.None;\n}\n\n/**\n * Generate the ANSI escape codes for a foreground color at the given depth.\n */\nexport function colorToAnsiFg(color: Color, depth: ColorDepth): string {\n if (color.type === 'none' || depth === ColorDepth.None) return '';\n const [r, g, b] = colorToRgb(color);\n\n switch (depth) {\n case ColorDepth.TrueColor:\n return `\\x1b[38;2;${r};${g};${b}m`;\n case ColorDepth.Ansi256:\n return `\\x1b[38;5;${rgbToAnsi256(r, g, b)}m`;\n case ColorDepth.Basic: {\n const idx = rgbToBasic(r, g, b);\n return idx < 8 ? `\\x1b[${30 + idx}m` : `\\x1b[${90 + idx - 8}m`;\n }\n default:\n return '';\n }\n}\n\n/**\n * Generate the ANSI escape codes for a background color at the given depth.\n */\nexport function colorToAnsiBg(color: Color, depth: ColorDepth): string {\n if (color.type === 'none' || depth === ColorDepth.None) return '';\n const [r, g, b] = colorToRgb(color);\n\n switch (depth) {\n case ColorDepth.TrueColor:\n return `\\x1b[48;2;${r};${g};${b}m`;\n case ColorDepth.Ansi256:\n return `\\x1b[48;5;${rgbToAnsi256(r, g, b)}m`;\n case ColorDepth.Basic: {\n const idx = rgbToBasic(r, g, b);\n return idx < 8 ? `\\x1b[${40 + idx}m` : `\\x1b[${100 + idx - 8}m`;\n }\n default:\n return '';\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — ANSI escape sequence helpers\n// ─────────────────────────────────────────────────────\n\n/** CSI (Control Sequence Introducer) prefix */\nexport const CSI = '\\x1b[';\n/** OSC (Operating System Command) prefix */\nexport const OSC = '\\x1b]';\n/** ESC character */\nexport const ESC = '\\x1b';\n\n// ── Cursor Control ──────────────────────────────────\n\nexport const hideCursor = `${CSI}?25l`;\nexport const showCursor = `${CSI}?25h`;\nexport const saveCursorPosition = `${CSI}s`;\nexport const restoreCursorPosition = `${CSI}u`;\n\nexport function moveTo(col: number, row: number): string {\n return `${CSI}${row + 1};${col + 1}H`;\n}\n\nexport function moveUp(n = 1): string { return `${CSI}${n}A`; }\nexport function moveDown(n = 1): string { return `${CSI}${n}B`; }\nexport function moveRight(n = 1): string { return `${CSI}${n}C`; }\nexport function moveLeft(n = 1): string { return `${CSI}${n}D`; }\n\n// ── Screen Control ──────────────────────────────────\n\nexport const clearScreen = `${CSI}2J`;\nexport const clearLine = `${CSI}2K`;\nexport const clearLineToEnd = `${CSI}0K`;\nexport const clearLineToStart = `${CSI}1K`;\nexport const clearDown = `${CSI}J`;\nexport const clearUp = `${CSI}1J`;\n\n// ── Alternate Screen Buffer ─────────────────────────\n\nexport const enterAltScreen = `${CSI}?1049h`;\nexport const exitAltScreen = `${CSI}?1049l`;\n\n// ── Synchronized Output (CSI 2026) ──────────────────\n\n/** Begin synchronized update — terminal holds display until end marker */\nexport const beginSyncUpdate = `${CSI}?2026h`;\n/** End synchronized update — terminal flushes all pending changes atomically */\nexport const endSyncUpdate = `${CSI}?2026l`;\n\n// ── Mouse Tracking ──────────────────────────────────\n\n/** Enable SGR mouse tracking (most compatible modern mode) */\nexport const enableMouse = `${CSI}?1000h${CSI}?1002h${CSI}?1006h`;\n/** Disable mouse tracking */\nexport const disableMouse = `${CSI}?1000l${CSI}?1002l${CSI}?1006l`;\n\n// ── Bracketed Paste ─────────────────────────────────\n\nexport const enableBracketedPaste = `${CSI}?2004h`;\nexport const disableBracketedPaste = `${CSI}?2004l`;\n\n// ── Text Styling ────────────────────────────────────\n\nexport const reset = `${CSI}0m`;\nexport const bold = `${CSI}1m`;\nexport const dim = `${CSI}2m`;\nexport const italic = `${CSI}3m`;\nexport const underline = `${CSI}4m`;\nexport const blink = `${CSI}5m`;\nexport const inverse = `${CSI}7m`;\nexport const strikethrough = `${CSI}9m`;\n\nexport const resetBold = `${CSI}22m`;\nexport const resetDim = `${CSI}22m`;\nexport const resetItalic = `${CSI}23m`;\nexport const resetUnderline = `${CSI}24m`;\nexport const resetBlink = `${CSI}25m`;\nexport const resetInverse = `${CSI}27m`;\nexport const resetStrikethrough = `${CSI}29m`;\n\n// ── Scrolling Region ────────────────────────────────\n\nexport function setScrollRegion(top: number, bottom: number): string {\n return `${CSI}${top + 1};${bottom + 1}r`;\n}\nexport const resetScrollRegion = `${CSI}r`;\n\n// ── Title ───────────────────────────────────────────\n\nexport function setTitle(title: string): string {\n return `${OSC}0;${title}\\x07`;\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Terminal adapter\n// ─────────────────────────────────────────────────────\n\nimport { ColorDepth, detectColorDepth } from '../style/Color.js';\nimport * as ansi from '../utils/ansi.js';\n\nexport interface TerminalOptions {\n /** Override stdout stream (useful for testing) */\n stdout?: NodeJS.WriteStream;\n /** Override stdin stream (useful for testing) */\n stdin?: NodeJS.ReadStream;\n /** Force a specific color depth */\n colorDepth?: ColorDepth;\n /** Enable mouse tracking */\n mouse?: boolean;\n /** Use alternate screen buffer for full-screen apps */\n altScreen?: boolean;\n}\n\n/**\n * Terminal adapter — wraps process.stdout/stdin and manages\n * terminal state (raw mode, cursor, mouse, alternate screen).\n */\nexport class Terminal {\n readonly stdout: NodeJS.WriteStream;\n readonly stdin: NodeJS.ReadStream;\n readonly colorDepth: ColorDepth;\n\n private _cols: number;\n private _rows: number;\n private _isRawMode = false;\n private _isAltScreen = false;\n private _isMouseEnabled = false;\n private _resizeHandlers: Array<(cols: number, rows: number) => void> = [];\n private _cleanupHandlers: Array<() => void> = [];\n private _originalRawMode: boolean | undefined;\n\n // Stored handler references for proper cleanup\n private _resizeHandler: (() => void) | null = null;\n private _exitHandler: (() => void) | null = null;\n private _sigintHandler: (() => void) | null = null;\n private _sigtermHandler: (() => void) | null = null;\n private _restored = false;\n\n constructor(options: TerminalOptions = {}) {\n this.stdout = options.stdout ?? process.stdout;\n this.stdin = options.stdin ?? process.stdin;\n this.colorDepth = options.colorDepth ?? detectColorDepth();\n\n this._cols = this.stdout.columns ?? 80;\n this._rows = this.stdout.rows ?? 24;\n\n // Listen for terminal resize (store ref for cleanup)\n this._resizeHandler = () => {\n this._cols = this.stdout.columns ?? 80;\n this._rows = this.stdout.rows ?? 24;\n for (const handler of this._resizeHandlers) {\n handler(this._cols, this._rows);\n }\n };\n this.stdout.on('resize', this._resizeHandler);\n\n // Set up cleanup on process exit\n this._setupCleanup();\n }\n\n /** Current terminal width in columns */\n get cols(): number { return this._cols; }\n /** Current terminal height in rows */\n get rows(): number { return this._rows; }\n\n /** Whether stdin is a TTY (interactive) */\n isInteractive(): boolean {\n return Boolean(this.stdin.isTTY) && !process.env['CI'];\n }\n\n /** Whether the terminal supports raw mode */\n supportsRawMode(): boolean {\n return Boolean(this.stdin.isTTY && typeof this.stdin.setRawMode === 'function');\n }\n\n // ── Raw Mode ────────────────────────────────────────\n\n enterRawMode(): void {\n if (this._isRawMode || !this.supportsRawMode()) return;\n this._originalRawMode = this.stdin.isRaw;\n this.stdin.setRawMode(true);\n this.stdin.resume();\n this._isRawMode = true;\n }\n\n exitRawMode(): void {\n if (!this._isRawMode) return;\n this.stdin.setRawMode(this._originalRawMode ?? false);\n this.stdin.pause();\n this._isRawMode = false;\n }\n\n // ── Alternate Screen ────────────────────────────────\n\n enterAltScreen(): void {\n if (this._isAltScreen) return;\n this.write(ansi.enterAltScreen);\n this._isAltScreen = true;\n }\n\n exitAltScreen(): void {\n if (!this._isAltScreen) return;\n this.write(ansi.exitAltScreen);\n this._isAltScreen = false;\n }\n\n // ── Mouse ───────────────────────────────────────────\n\n enableMouse(): void {\n if (this._isMouseEnabled) return;\n this.write(ansi.enableMouse);\n this._isMouseEnabled = true;\n }\n\n disableMouse(): void {\n if (!this._isMouseEnabled) return;\n this.write(ansi.disableMouse);\n this._isMouseEnabled = false;\n }\n\n // ── Cursor ──────────────────────────────────────────\n\n hideCursor(): void { this.write(ansi.hideCursor); }\n showCursor(): void { this.write(ansi.showCursor); }\n\n // ── Output ──────────────────────────────────────────\n\n write(data: string): void {\n this.stdout.write(data);\n }\n\n // ── Resize ──────────────────────────────────────────\n\n onResize(handler: (cols: number, rows: number) => void): () => void {\n this._resizeHandlers.push(handler);\n return () => {\n const idx = this._resizeHandlers.indexOf(handler);\n if (idx >= 0) this._resizeHandlers.splice(idx, 1);\n };\n }\n\n // ── Cleanup ─────────────────────────────────────────\n\n /**\n * Restore terminal to its original state.\n * Removes all process signal handlers to prevent leaks.\n * Called automatically on SIGINT, SIGTERM, process exit.\n */\n restore(): void {\n if (this._restored) return; // Prevent double-restore\n this._restored = true;\n\n // Remove process-level signal handlers to prevent leaks\n if (this._exitHandler) process.off('exit', this._exitHandler);\n if (this._sigintHandler) process.off('SIGINT', this._sigintHandler);\n if (this._sigtermHandler) process.off('SIGTERM', this._sigtermHandler);\n\n // Remove resize listener\n if (this._resizeHandler) {\n this.stdout.off('resize', this._resizeHandler);\n }\n\n this.disableMouse();\n this.exitAltScreen();\n this.exitRawMode();\n this.showCursor();\n this.write(ansi.reset);\n }\n\n /**\n * Register a custom cleanup handler that runs on terminal restore.\n */\n onCleanup(handler: () => void): void {\n this._cleanupHandlers.push(handler);\n }\n\n private _setupCleanup(): void {\n const runCleanupHandlers = () => {\n for (const handler of this._cleanupHandlers) {\n try { handler(); } catch { /* swallow */ }\n }\n this.restore();\n };\n\n this._exitHandler = runCleanupHandlers;\n this._sigintHandler = () => { runCleanupHandlers(); process.exit(130); };\n this._sigtermHandler = () => { runCleanupHandlers(); process.exit(143); };\n\n process.on('exit', this._exitHandler);\n process.on('SIGINT', this._sigintHandler);\n process.on('SIGTERM', this._sigtermHandler);\n // NOTE: No uncaughtException handler — let errors propagate naturally\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Screen buffer (double-buffered cell grid)\n// ─────────────────────────────────────────────────────\n\nimport type { Color } from '../style/Color.js';\n\n/**\n * A single cell in the terminal grid.\n */\nexport interface Cell {\n /** The character displayed (single grapheme cluster) */\n char: string;\n /** Foreground color */\n fg: Color;\n /** Background color */\n bg: Color;\n /** Bold text */\n bold: boolean;\n /** Italic text */\n italic: boolean;\n /** Underline text */\n underline: boolean;\n /** Dim text */\n dim: boolean;\n /** Strikethrough text */\n strikethrough: boolean;\n /** Inverse colors */\n inverse: boolean;\n /**\n * Visual width of this cell.\n * - 1 for normal characters\n * - 2 for wide chars (CJK/emoji) — the next cell is a \"continuation\" cell\n * - 0 for continuation cells (second half of a wide char)\n */\n width: number;\n}\n\n/** Create a blank cell with default attributes */\nexport function emptyCell(): Cell {\n return {\n char: ' ',\n fg: { type: 'none' },\n bg: { type: 'none' },\n bold: false,\n italic: false,\n underline: false,\n dim: false,\n strikethrough: false,\n inverse: false,\n width: 1,\n };\n}\n\n/** Reset a cell in-place to default attributes (avoids allocation). */\nexport function resetCell(cell: Cell): void {\n cell.char = ' ';\n cell.fg = { type: 'none' };\n cell.bg = { type: 'none' };\n cell.bold = false;\n cell.italic = false;\n cell.underline = false;\n cell.dim = false;\n cell.strikethrough = false;\n cell.inverse = false;\n cell.width = 1;\n}\n\n/** Check if two cells are visually identical */\nexport function cellsEqual(a: Cell, b: Cell): boolean {\n return (\n a.char === b.char &&\n a.bold === b.bold &&\n a.italic === b.italic &&\n a.underline === b.underline &&\n a.dim === b.dim &&\n a.strikethrough === b.strikethrough &&\n a.inverse === b.inverse &&\n a.width === b.width &&\n colorsEqual(a.fg, b.fg) &&\n colorsEqual(a.bg, b.bg)\n );\n}\n\nfunction colorsEqual(a: Color, b: Color): boolean {\n if (a.type !== b.type) return false;\n switch (a.type) {\n case 'none': return true;\n case 'named': return a.name === (b as typeof a).name;\n case 'ansi256': return a.code === (b as typeof a).code;\n case 'rgb': return a.r === (b as typeof a).r && a.g === (b as typeof a).g && a.b === (b as typeof a).b;\n case 'hex': return a.hex === (b as typeof a).hex;\n }\n}\n\n/**\n * Double-buffered 2D cell grid for the terminal.\n *\n * - `front` = what's currently displayed on screen\n * - `back` = what we're building for the next frame\n *\n * After rendering, the renderer diffs `front` vs `back` and only emits\n * changes, then swaps the buffers.\n */\nexport class Screen {\n private _cols: number;\n private _rows: number;\n front: Cell[][];\n back: Cell[][];\n\n /**\n * Stack of clipping regions. When non-empty, setCell/writeString\n * only write to cells within the topmost clip rectangle.\n */\n private _clipStack: Array<{ x: number; y: number; width: number; height: number }> = [];\n\n constructor(cols: number, rows: number) {\n this._cols = cols;\n this._rows = rows;\n this.front = this._createGrid(cols, rows);\n this.back = this._createGrid(cols, rows);\n }\n\n get cols(): number { return this._cols; }\n get rows(): number { return this._rows; }\n\n /**\n * Push a clipping region onto the stack.\n * All subsequent setCell/writeString calls will be constrained\n * to cells within this rectangle. Clips are intersected with\n * any parent clip already on the stack (nested clipping).\n */\n pushClip(region: { x: number; y: number; width: number; height: number }): void {\n if (this._clipStack.length > 0) {\n // Intersect with the current clip\n const parent = this._clipStack[this._clipStack.length - 1];\n const x = Math.max(region.x, parent.x);\n const y = Math.max(region.y, parent.y);\n const right = Math.min(region.x + region.width, parent.x + parent.width);\n const bottom = Math.min(region.y + region.height, parent.y + parent.height);\n if (right <= x || bottom <= y) {\n // Fully clipped — push a zero-size region\n this._clipStack.push({ x: 0, y: 0, width: 0, height: 0 });\n } else {\n this._clipStack.push({ x, y, width: right - x, height: bottom - y });\n }\n } else {\n this._clipStack.push({ ...region });\n }\n }\n\n /**\n * Pop the most recent clipping region from the stack.\n */\n popClip(): void {\n this._clipStack.pop();\n }\n\n /**\n * Get the current active clip region, or null if no clip is active.\n */\n get activeClip(): { x: number; y: number; width: number; height: number } | null {\n return this._clipStack.length > 0\n ? this._clipStack[this._clipStack.length - 1]\n : null;\n }\n\n /**\n * Write a cell to the back buffer at position (col, row).\n */\n setCell(col: number, row: number, cell: Partial<Cell>): void {\n // Floor to integers — layout engine may produce fractional values\n col = Math.floor(col);\n row = Math.floor(row);\n // Use positive range check (NaN fails >= 0, preventing NaN indices)\n if (!(col >= 0 && col < this._cols && row >= 0 && row < this._rows)) return;\n\n // Enforce clip region\n if (this._clipStack.length > 0) {\n const clip = this._clipStack[this._clipStack.length - 1];\n if (col < clip.x || col >= clip.x + clip.width ||\n row < clip.y || row >= clip.y + clip.height) {\n return; // Outside active clip — silently discard\n }\n }\n\n const existing = this.back[row][col];\n Object.assign(existing, cell);\n }\n\n /**\n * Write a string to the back buffer starting at (col, row).\n * Applies the provided style attributes to each character.\n */\n writeString(\n col: number,\n row: number,\n str: string,\n style: Partial<Omit<Cell, 'char' | 'width'>> = {},\n ): void {\n row = Math.floor(row);\n col = Math.floor(col);\n if (!(row >= 0 && row < this._rows)) return;\n\n let x = col;\n for (const char of str) {\n if (x >= this._cols) break;\n if (x < 0) { x++; continue; }\n\n const cp = char.codePointAt(0)!;\n const isWide = this._isWideCodePoint(cp);\n const width = isWide ? 2 : 1;\n\n this.setCell(x, row, {\n char,\n width,\n ...style,\n });\n\n // If wide char, mark the next cell as a continuation\n if (isWide && x + 1 < this._cols) {\n this.setCell(x + 1, row, {\n char: '',\n width: 0,\n ...style,\n });\n x += 2;\n } else {\n x += 1;\n }\n }\n }\n\n /**\n * Clear the back buffer to all empty cells.\n */\n clear(): void {\n for (let r = 0; r < this._rows; r++) {\n for (let c = 0; c < this._cols; c++) {\n resetCell(this.back[r][c]);\n }\n }\n }\n\n /**\n * Swap front and back buffers. Called after rendering diffs.\n */\n swap(): void {\n const temp = this.front;\n this.front = this.back;\n this.back = temp;\n }\n\n /**\n * Resize the screen. Clears both buffers.\n */\n resize(cols: number, rows: number): void {\n this._cols = cols;\n this._rows = rows;\n this.front = this._createGrid(cols, rows);\n this.back = this._createGrid(cols, rows);\n }\n\n /**\n * Clear the front buffer (marks everything as \"needs redraw\").\n */\n invalidate(): void {\n for (let r = 0; r < this._rows; r++) {\n for (let c = 0; c < this._cols; c++) {\n this.front[r][c] = { ...emptyCell(), char: '\\0' }; // force diff\n }\n }\n }\n\n private _createGrid(cols: number, rows: number): Cell[][] {\n const grid: Cell[][] = [];\n for (let r = 0; r < rows; r++) {\n const row: Cell[] = [];\n for (let c = 0; c < cols; c++) {\n row.push(emptyCell());\n }\n grid.push(row);\n }\n return grid;\n }\n\n private _isWideCodePoint(cp: number): boolean {\n return (\n (cp >= 0x4E00 && cp <= 0x9FFF) ||\n (cp >= 0x3400 && cp <= 0x4DBF) ||\n (cp >= 0xF900 && cp <= 0xFAFF) ||\n (cp >= 0xAC00 && cp <= 0xD7AF) ||\n (cp >= 0x30A0 && cp <= 0x30FF) ||\n (cp >= 0x3000 && cp <= 0x303F) ||\n (cp >= 0x3040 && cp <= 0x309F) ||\n (cp >= 0xFF01 && cp <= 0xFF60) ||\n (cp >= 0xFFE0 && cp <= 0xFFE6) ||\n (cp >= 0x1F600 && cp <= 0x1F64F) ||\n (cp >= 0x1F300 && cp <= 0x1F5FF) ||\n (cp >= 0x1F680 && cp <= 0x1F6FF) ||\n (cp >= 0x1F900 && cp <= 0x1F9FF) ||\n (cp >= 0x20000 && cp <= 0x2A6DF)\n );\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Differential Renderer\n// ─────────────────────────────────────────────────────\n\nimport type { Terminal } from './Terminal.js';\nimport { type Cell, cellsEqual, type Screen } from './Screen.js';\nimport { type ColorDepth, colorToAnsiFg, colorToAnsiBg } from '../style/Color.js';\nimport { moveTo, beginSyncUpdate, endSyncUpdate, reset as ansiReset } from '../utils/ansi.js';\n\n/**\n * Differential renderer — compares front/back screen buffers and\n * outputs only the changed cells. Uses synchronized output (CSI 2026)\n * for atomic, flicker-free updates.\n */\nexport class Renderer {\n private _terminal: Terminal;\n private _screen: Screen;\n private _fps: number;\n private _frameTimer: ReturnType<typeof setInterval> | null = null;\n private _renderRequested = false;\n private _colorDepth: ColorDepth;\n\n constructor(terminal: Terminal, screen: Screen, fps = 30) {\n this._terminal = terminal;\n this._screen = screen;\n this._fps = fps;\n this._colorDepth = terminal.colorDepth;\n }\n\n /** Change the rendering frame rate cap */\n setFPS(fps: number): void {\n this._fps = fps;\n if (this._frameTimer) {\n this.stop();\n this.start();\n }\n }\n\n /** Start the render loop */\n start(): void {\n if (this._frameTimer) return;\n const interval = Math.floor(1000 / this._fps);\n this._frameTimer = setInterval(() => {\n if (this._renderRequested) {\n this._renderRequested = false;\n this._flush();\n }\n }, interval);\n }\n\n /** Stop the render loop */\n stop(): void {\n if (this._frameTimer) {\n clearInterval(this._frameTimer);\n this._frameTimer = null;\n }\n }\n\n /** Request a render on the next frame */\n requestFrame(): void {\n this._renderRequested = true;\n }\n\n /** Force an immediate render (bypass frame rate) */\n renderNow(): void {\n this._flush();\n }\n\n /**\n * Full-screen clear and redraw (first render or after resize).\n */\n fullRender(): void {\n this._screen.invalidate();\n this._flush();\n }\n\n /**\n * Core diff and flush: compare front vs back buffer,\n * emit only changed cells.\n */\n private _flush(): void {\n const { front, back, cols, rows } = this._screen;\n let output = beginSyncUpdate;\n let lastRow = -1;\n let lastCol = -1;\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const frontCell = front[r][c];\n const backCell = back[r][c];\n\n if (cellsEqual(frontCell, backCell)) continue;\n\n // Skip continuation cells (second half of wide chars)\n if (backCell.width === 0) continue;\n\n // Move cursor only if not already at the right position\n if (r !== lastRow || c !== lastCol) {\n output += moveTo(c, r);\n }\n\n output += this._renderCell(backCell);\n lastRow = r;\n lastCol = c + (backCell.width === 2 ? 2 : 1);\n }\n }\n\n output += ansiReset;\n output += endSyncUpdate;\n\n this._terminal.write(output);\n this._screen.swap();\n }\n\n /**\n * Generate the ANSI escape sequence to render a single cell.\n */\n private _renderCell(cell: Cell): string {\n let seq = '';\n\n // Reset before applying new attributes\n seq += ansiReset;\n\n // Apply text decorations\n if (cell.bold) seq += '\\x1b[1m';\n if (cell.dim) seq += '\\x1b[2m';\n if (cell.italic) seq += '\\x1b[3m';\n if (cell.underline) seq += '\\x1b[4m';\n if (cell.strikethrough) seq += '\\x1b[9m';\n if (cell.inverse) seq += '\\x1b[7m';\n\n // Apply colors\n seq += colorToAnsiFg(cell.fg, this._colorDepth);\n seq += colorToAnsiBg(cell.bg, this._colorDepth);\n\n // Write the character\n seq += cell.char || ' ';\n\n return seq;\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Layer Manager for overlay rendering\n// ─────────────────────────────────────────────────────\n\nimport type { Cell } from './Screen.js';\nimport { emptyCell, type Screen } from './Screen.js';\nimport type { Color } from '../style/Color.js';\nimport type { Rect } from '../layout/Rect.js';\n\n/**\n * A rendering layer. Each layer has its own cell grid and z-index.\n * Higher z-index layers render on top of lower ones during compositing.\n */\nexport interface Layer {\n /** Unique identifier for this layer */\n id: string;\n /** Stacking order — higher renders on top */\n zIndex: number;\n /** Cell grid (same dimensions as Screen) */\n cells: Cell[][];\n /** Whether this layer is visible */\n visible: boolean;\n /** Bounding box of cells written since last clear (null = nothing dirty) */\n dirtyRegion: Rect | null;\n}\n\n/**\n * Check if a cell is \"transparent\" (should show through to the layer below).\n * An empty cell with no explicit colors is considered transparent.\n */\nfunction isCellTransparent(cell: Cell): boolean {\n return (\n cell.char === ' ' &&\n cell.fg.type === 'none' &&\n cell.bg.type === 'none' &&\n !cell.bold &&\n !cell.italic &&\n !cell.underline &&\n !cell.dim &&\n !cell.strikethrough &&\n !cell.inverse\n );\n}\n\n/**\n * Manages multiple rendering layers for overlay support.\n *\n * The base layer (z=0) is the primary widget layer — always opaque.\n * Overlay layers (z>0) support transparency: only cells explicitly\n * written to them overwrite the base layer during compositing.\n *\n * Typical z-index values:\n * - 0: Base widget layer\n * - 10: Dropdown menus\n * - 100: Modal dialogs\n * - 1000: Toasts / notifications\n */\nexport class LayerManager {\n private _layers: Map<string, Layer> = new Map();\n private _cols: number;\n private _rows: number;\n\n constructor(cols: number, rows: number) {\n this._cols = cols;\n this._rows = rows;\n }\n\n get cols(): number { return this._cols; }\n get rows(): number { return this._rows; }\n\n /**\n * Create a new overlay layer.\n * @param id Unique identifier (e.g. 'modal', 'select-dropdown', 'toast')\n * @param zIndex Stacking order (higher = rendered on top)\n */\n createLayer(id: string, zIndex: number): Layer {\n if (this._layers.has(id)) {\n return this._layers.get(id)!;\n }\n\n const layer: Layer = {\n id,\n zIndex,\n cells: this._createGrid(),\n visible: true,\n dirtyRegion: null,\n };\n\n this._layers.set(id, layer);\n return layer;\n }\n\n /**\n * Remove an overlay layer and clean up its resources.\n */\n removeLayer(id: string): void {\n this._layers.delete(id);\n }\n\n /**\n * Get a layer by ID.\n */\n getLayer(id: string): Layer | undefined {\n return this._layers.get(id);\n }\n\n /**\n * Check if a layer exists.\n */\n hasLayer(id: string): boolean {\n return this._layers.has(id);\n }\n\n /**\n * Get all layers sorted by z-index (ascending).\n */\n getSortedLayers(): Layer[] {\n return Array.from(this._layers.values())\n .filter(l => l.visible)\n .sort((a, b) => a.zIndex - b.zIndex);\n }\n\n /**\n * Write a cell to a specific layer.\n */\n setCell(layerId: string, col: number, row: number, cell: Partial<Cell>): void {\n const layer = this._layers.get(layerId);\n if (!layer) return;\n\n col = Math.floor(col);\n row = Math.floor(row);\n if (!(col >= 0 && col < this._cols && row >= 0 && row < this._rows)) return;\n\n const existing = layer.cells[row][col];\n Object.assign(existing, cell);\n\n // Expand dirty region\n this._expandDirty(layer, col, row);\n }\n\n /**\n * Write a string to a specific layer at position (col, row).\n */\n writeString(\n layerId: string,\n col: number,\n row: number,\n str: string,\n style: Partial<Omit<Cell, 'char' | 'width'>> = {},\n ): void {\n const layer = this._layers.get(layerId);\n if (!layer) return;\n\n row = Math.floor(row);\n col = Math.floor(col);\n if (!(row >= 0 && row < this._rows)) return;\n\n let x = col;\n for (const char of str) {\n if (x >= this._cols) break;\n if (x < 0) { x++; continue; }\n\n this.setCell(layerId, x, row, { char, width: 1, ...style });\n x++;\n }\n }\n\n /**\n * Clear all cells in a specific layer.\n */\n clearLayer(id: string): void {\n const layer = this._layers.get(id);\n if (!layer) return;\n\n for (let r = 0; r < this._rows; r++) {\n for (let c = 0; c < this._cols; c++) {\n layer.cells[r][c] = emptyCell();\n }\n }\n layer.dirtyRegion = null;\n }\n\n /**\n * Clear all overlay layers.\n */\n clearAll(): void {\n for (const layer of this._layers.values()) {\n this.clearLayer(layer.id);\n }\n }\n\n /**\n * Composite all overlay layers onto the Screen's back buffer.\n * Layers are applied in z-index order (lowest first).\n * Transparent cells (empty with no colors) are skipped.\n */\n composite(screen: Screen): void {\n const sorted = this.getSortedLayers();\n\n for (const layer of sorted) {\n if (!layer.dirtyRegion) continue; // Nothing to composite\n\n const { x: dx, y: dy, width: dw, height: dh } = layer.dirtyRegion;\n\n for (let r = dy; r < dy + dh && r < this._rows; r++) {\n for (let c = dx; c < dx + dw && c < this._cols; c++) {\n const cell = layer.cells[r][c];\n if (isCellTransparent(cell)) continue;\n\n // Write non-transparent overlay cell to the screen's back buffer\n screen.setCell(c, r, {\n char: cell.char,\n fg: cell.fg,\n bg: cell.bg,\n bold: cell.bold,\n italic: cell.italic,\n underline: cell.underline,\n dim: cell.dim,\n strikethrough: cell.strikethrough,\n inverse: cell.inverse,\n width: cell.width,\n });\n }\n }\n }\n }\n\n /**\n * Resize all layers when the terminal is resized.\n */\n resize(cols: number, rows: number): void {\n this._cols = cols;\n this._rows = rows;\n\n for (const layer of this._layers.values()) {\n layer.cells = this._createGrid();\n layer.dirtyRegion = null;\n }\n }\n\n /**\n * Create an empty cell grid.\n */\n private _createGrid(): Cell[][] {\n const grid: Cell[][] = [];\n for (let r = 0; r < this._rows; r++) {\n const row: Cell[] = [];\n for (let c = 0; c < this._cols; c++) {\n row.push(emptyCell());\n }\n grid.push(row);\n }\n return grid;\n }\n\n /**\n * Expand the dirty region of a layer to include the given cell.\n */\n private _expandDirty(layer: Layer, col: number, row: number): void {\n if (!layer.dirtyRegion) {\n layer.dirtyRegion = { x: col, y: row, width: 1, height: 1 };\n return;\n }\n\n const r = layer.dirtyRegion;\n const newX = Math.min(r.x, col);\n const newY = Math.min(r.y, row);\n const newRight = Math.max(r.x + r.width, col + 1);\n const newBottom = Math.max(r.y + r.height, row + 1);\n r.x = newX;\n r.y = newY;\n r.width = newRight - newX;\n r.height = newBottom - newY;\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Event types\n// ─────────────────────────────────────────────────────\n\n/**\n * Keyboard event emitted when a key is pressed.\n */\nexport interface KeyEvent {\n /** Human-readable key name: 'a', 'enter', 'up', 'f1', 'tab', etc. */\n key: string;\n /** Raw byte sequence from stdin */\n raw: Buffer;\n /** Ctrl modifier held */\n ctrl: boolean;\n /** Alt/Meta modifier held */\n alt: boolean;\n /** Shift modifier held */\n shift: boolean;\n /** The widget ID that currently has focus (target of the event) */\n targetId?: string;\n /** Whether propagation has been stopped */\n _propagationStopped?: boolean;\n /** Whether the default action has been prevented */\n _defaultPrevented?: boolean;\n /** Stop this event from bubbling to parent widgets */\n stopPropagation(): void;\n /** Prevent the default action for this event */\n preventDefault(): void;\n}\n\n/**\n * Create a KeyEvent with propagation control methods attached.\n */\nexport function createKeyEvent(base: {\n key: string;\n raw: Buffer;\n ctrl: boolean;\n alt: boolean;\n shift: boolean;\n targetId?: string;\n}): KeyEvent {\n const event: KeyEvent = {\n ...base,\n _propagationStopped: false,\n _defaultPrevented: false,\n stopPropagation() { this._propagationStopped = true; },\n preventDefault() { this._defaultPrevented = true; },\n };\n return event;\n}\n\n/**\n * Mouse event types.\n */\nexport type MouseEventType = 'mousedown' | 'mouseup' | 'mousemove' | 'scroll';\nexport type MouseButton = 'left' | 'middle' | 'right' | 'none';\n\n/**\n * Mouse event emitted when mouse activity is detected.\n */\nexport interface MouseEvent {\n /** x (column) position, 0-indexed */\n x: number;\n /** y (row) position, 0-indexed */\n y: number;\n /** Which mouse button */\n button: MouseButton;\n /** Type of mouse event */\n type: MouseEventType;\n /** Scroll direction (-1 = up, 1 = down) */\n scrollDelta?: number;\n}\n\n/**\n * Resize event emitted when the terminal is resized.\n */\nexport interface ResizeEvent {\n cols: number;\n rows: number;\n}\n\n/**\n * Focus event emitted when a widget gains or loses focus.\n */\nexport interface FocusEvent {\n /** Widget ID that is gaining or losing focus */\n targetId: string;\n /** Type of focus event */\n type: 'focus' | 'blur';\n}\n\n/**\n * Map of all event types to their data shapes.\n */\nexport interface EventMap {\n 'key': KeyEvent;\n 'mouse': MouseEvent;\n 'resize': ResizeEvent;\n 'focus': FocusEvent;\n 'blur': FocusEvent;\n 'render': void;\n 'mount': void;\n 'unmount': void;\n 'tick': number; // delta ms\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Key mapping constants\n// ─────────────────────────────────────────────────────\n\n/**\n * Maps raw byte sequences to human-readable key names.\n * These are standard VT100/xterm escape sequences.\n */\nexport const ESCAPE_SEQUENCES: Record<string, string> = {\n // Arrow keys\n '\\x1b[A': 'up',\n '\\x1b[B': 'down',\n '\\x1b[C': 'right',\n '\\x1b[D': 'left',\n\n // Shift+Arrow\n '\\x1b[1;2A': 'shift+up',\n '\\x1b[1;2B': 'shift+down',\n '\\x1b[1;2C': 'shift+right',\n '\\x1b[1;2D': 'shift+left',\n\n // Ctrl+Arrow\n '\\x1b[1;5A': 'ctrl+up',\n '\\x1b[1;5B': 'ctrl+down',\n '\\x1b[1;5C': 'ctrl+right',\n '\\x1b[1;5D': 'ctrl+left',\n\n // Alt+Arrow\n '\\x1b[1;3A': 'alt+up',\n '\\x1b[1;3B': 'alt+down',\n '\\x1b[1;3C': 'alt+right',\n '\\x1b[1;3D': 'alt+left',\n\n // Home/End/Insert/Delete/PageUp/PageDown\n '\\x1b[H': 'home',\n '\\x1b[F': 'end',\n '\\x1b[2~': 'insert',\n '\\x1b[3~': 'delete',\n '\\x1b[5~': 'pageup',\n '\\x1b[6~': 'pagedown',\n\n // Alternate Home/End (some terminals)\n '\\x1b[1~': 'home',\n '\\x1b[4~': 'end',\n '\\x1bOH': 'home',\n '\\x1bOF': 'end',\n\n // Function keys\n '\\x1bOP': 'f1',\n '\\x1bOQ': 'f2',\n '\\x1bOR': 'f3',\n '\\x1bOS': 'f4',\n '\\x1b[15~': 'f5',\n '\\x1b[17~': 'f6',\n '\\x1b[18~': 'f7',\n '\\x1b[19~': 'f8',\n '\\x1b[20~': 'f9',\n '\\x1b[21~': 'f10',\n '\\x1b[23~': 'f11',\n '\\x1b[24~': 'f12',\n\n // Special keys\n '\\x1b[Z': 'shift+tab',\n};\n\n/**\n * Maps control character codes (0x01-0x1A) to key names.\n * Ctrl+A = 0x01, Ctrl+B = 0x02, ... Ctrl+Z = 0x1A\n */\nexport const CTRL_KEYS: Record<number, string> = {\n 0x01: 'a', 0x02: 'b', 0x03: 'c', 0x04: 'd',\n 0x05: 'e', 0x06: 'f', 0x07: 'g', 0x08: 'backspace',\n 0x09: 'tab', 0x0A: 'enter', 0x0B: 'k', 0x0C: 'l',\n 0x0D: 'enter', 0x0E: 'n', 0x0F: 'o', 0x10: 'p',\n 0x11: 'q', 0x12: 'r', 0x13: 's', 0x14: 't',\n 0x15: 'u', 0x16: 'v', 0x17: 'w', 0x18: 'x',\n 0x19: 'y', 0x1A: 'z',\n};\n\n/**\n * Special single-byte key codes.\n */\nexport const SPECIAL_KEYS: Record<number, string> = {\n 0x1B: 'escape',\n 0x7F: 'backspace',\n 0x09: 'tab',\n 0x0D: 'enter',\n 0x0A: 'enter',\n 0x20: 'space',\n};\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Mouse event parser (SGR mode)\n// ─────────────────────────────────────────────────────\n\nimport type { MouseEvent, MouseButton, MouseEventType } from '../events/types.js';\n\n/**\n * Parse an SGR mouse event escape sequence.\n *\n * SGR format: ESC [ < Cb ; Cx ; Cy M (button press)\n * ESC [ < Cb ; Cx ; Cy m (button release)\n *\n * Where Cb encodes the button and modifiers, Cx/Cy are 1-based coordinates.\n *\n * @returns Parsed MouseEvent or null if not a mouse sequence.\n */\nexport function parseMouseEvent(data: string): MouseEvent | null {\n // SGR mouse: \\x1b[<Cb;Cx;Cy[Mm]\n const match = data.match(/^\\x1b\\[<(\\d+);(\\d+);(\\d+)([Mm])$/);\n if (!match) return null;\n\n const cb = parseInt(match[1], 10);\n const cx = parseInt(match[2], 10) - 1; // Convert to 0-based\n const cy = parseInt(match[3], 10) - 1;\n const isRelease = match[4] === 'm';\n\n let button: MouseButton;\n let type: MouseEventType;\n let scrollDelta: number | undefined;\n\n // Decode button from low 2 bits\n const buttonBits = cb & 0b11;\n const motion = (cb & 0b100000) !== 0;\n const isScroll = (cb & 0b1000000) !== 0;\n\n if (isScroll) {\n button = 'none';\n type = 'scroll';\n scrollDelta = buttonBits === 0 ? -1 : 1; // 0 = scroll up, 1 = scroll down\n } else if (motion) {\n type = 'mousemove';\n button = decodeButton(buttonBits);\n } else if (isRelease) {\n type = 'mouseup';\n button = decodeButton(buttonBits);\n } else {\n type = 'mousedown';\n button = decodeButton(buttonBits);\n }\n\n return {\n x: cx,\n y: cy,\n button,\n type,\n scrollDelta,\n };\n}\n\nfunction decodeButton(bits: number): MouseButton {\n switch (bits) {\n case 0: return 'left';\n case 1: return 'middle';\n case 2: return 'right';\n default: return 'none';\n }\n}\n\n/**\n * Check if a string looks like it could be a mouse sequence.\n */\nexport function isMouseSequence(data: string): boolean {\n return data.startsWith('\\x1b[<');\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Typed Event Emitter\n// ─────────────────────────────────────────────────────\n\n/**\n * Strongly-typed event emitter using TypeScript generics.\n * Supports `on`, `off`, `once`, `emit` with type-safe event maps.\n */\nexport class EventEmitter<TEventMap extends Record<string, any>> {\n private _handlers: Map<keyof TEventMap, Set<(data: any) => void>> = new Map();\n private _onceHandlers: Map<keyof TEventMap, Set<(data: any) => void>> = new Map();\n\n /**\n * Subscribe to an event.\n * @returns Unsubscribe function.\n */\n on<K extends keyof TEventMap>(event: K, handler: (data: TEventMap[K]) => void): () => void {\n if (!this._handlers.has(event)) {\n this._handlers.set(event, new Set());\n }\n this._handlers.get(event)!.add(handler);\n\n return () => this.off(event, handler);\n }\n\n /**\n * Subscribe to an event, but only fire once.\n */\n once<K extends keyof TEventMap>(event: K, handler: (data: TEventMap[K]) => void): () => void {\n if (!this._onceHandlers.has(event)) {\n this._onceHandlers.set(event, new Set());\n }\n this._onceHandlers.get(event)!.add(handler);\n\n return () => {\n this._onceHandlers.get(event)?.delete(handler);\n };\n }\n\n /**\n * Unsubscribe from an event.\n */\n off<K extends keyof TEventMap>(event: K, handler: (data: TEventMap[K]) => void): void {\n this._handlers.get(event)?.delete(handler);\n this._onceHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emit an event to all subscribed handlers.\n */\n emit<K extends keyof TEventMap>(event: K, data: TEventMap[K]): void {\n // Regular handlers\n const handlers = this._handlers.get(event);\n if (handlers) {\n for (const handler of handlers) {\n try { handler(data); } catch { /* prevent one handler from breaking others */ }\n }\n }\n\n // Once handlers — fire and remove\n const onceHandlers = this._onceHandlers.get(event);\n if (onceHandlers) {\n for (const handler of onceHandlers) {\n try { handler(data); } catch { /* prevent one handler from breaking others */ }\n }\n onceHandlers.clear();\n }\n }\n\n /**\n * Remove all handlers for a specific event, or all events if no event specified.\n */\n removeAll(event?: keyof TEventMap): void {\n if (event) {\n this._handlers.delete(event);\n this._onceHandlers.delete(event);\n } else {\n this._handlers.clear();\n this._onceHandlers.clear();\n }\n }\n\n /**\n * Check if there are any handlers for an event.\n */\n hasListeners(event: keyof TEventMap): boolean {\n return (\n (this._handlers.get(event)?.size ?? 0) > 0 ||\n (this._onceHandlers.get(event)?.size ?? 0) > 0\n );\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Input Parser\n// ─────────────────────────────────────────────────────\n\nimport type { KeyEvent, MouseEvent } from '../events/types.js';\nimport { createKeyEvent } from '../events/types.js';\nimport { ESCAPE_SEQUENCES, CTRL_KEYS, SPECIAL_KEYS } from './KeyMap.js';\nimport { parseMouseEvent, isMouseSequence } from './MouseParser.js';\nimport { EventEmitter } from '../events/EventEmitter.js';\n\ninterface InputEvents {\n key: KeyEvent;\n mouse: MouseEvent;\n}\n\n/**\n * Reads raw stdin bytes and parses them into typed KeyEvent / MouseEvent objects.\n * Handles escape sequences, multi-byte keys, ctrl+key, and SGR mouse events.\n */\nexport class InputParser {\n private _events = new EventEmitter<InputEvents>();\n private _stdin: NodeJS.ReadStream;\n private _handler: ((data: Buffer) => void) | null = null;\n private _escapeTimeout: ReturnType<typeof setTimeout> | null = null;\n private _escapeBuffer = '';\n\n constructor(stdin: NodeJS.ReadStream) {\n this._stdin = stdin;\n }\n\n /** Subscribe to key events */\n onKey(handler: (event: KeyEvent) => void): () => void {\n return this._events.on('key', handler);\n }\n\n /** Subscribe to mouse events */\n onMouse(handler: (event: MouseEvent) => void): () => void {\n return this._events.on('mouse', handler);\n }\n\n /** Start listening for input */\n start(): void {\n if (this._handler) return;\n\n this._handler = (data: Buffer) => {\n this._processInput(data);\n };\n\n this._stdin.on('data', this._handler);\n }\n\n /** Stop listening for input */\n stop(): void {\n if (this._handler) {\n this._stdin.off('data', this._handler);\n this._handler = null;\n }\n if (this._escapeTimeout) {\n clearTimeout(this._escapeTimeout);\n this._escapeTimeout = null;\n }\n this._escapeBuffer = '';\n }\n\n /**\n * Process a chunk of raw input bytes.\n */\n private _processInput(data: Buffer): void {\n const str = data.toString('utf8');\n\n // If we're collecting an escape sequence\n if (this._escapeBuffer) {\n this._escapeBuffer += str;\n if (this._escapeTimeout) {\n clearTimeout(this._escapeTimeout);\n this._escapeTimeout = null;\n }\n this._tryParseEscape(data);\n return;\n }\n\n // Check if this starts an escape sequence\n if (str.startsWith('\\x1b') && str.length === 1) {\n // Lone ESC — wait a bit to see if more bytes follow\n this._escapeBuffer = str;\n this._escapeTimeout = setTimeout(() => {\n // Timeout — it was a standalone Escape key\n this._events.emit('key', createKeyEvent({\n key: 'escape',\n raw: Buffer.from(this._escapeBuffer),\n ctrl: false,\n alt: false,\n shift: false,\n }));\n this._escapeBuffer = '';\n this._escapeTimeout = null;\n }, 50); // 50ms debounce for escape sequences\n return;\n }\n\n if (str.startsWith('\\x1b')) {\n this._escapeBuffer = str;\n this._tryParseEscape(data);\n return;\n }\n\n // Process each byte for non-escape input\n for (let i = 0; i < str.length; i++) {\n const ch = str[i];\n const code = str.charCodeAt(i);\n const raw = Buffer.from(ch, 'utf8');\n\n // Ctrl+key (0x01-0x1A, excluding tab/enter/backspace)\n if (code >= 0x01 && code <= 0x1A) {\n const keyName = CTRL_KEYS[code];\n const isCtrl = code !== 0x09 && code !== 0x0D && code !== 0x0A;\n this._events.emit('key', createKeyEvent({\n key: keyName || String.fromCharCode(code + 96),\n raw,\n ctrl: isCtrl,\n alt: false,\n shift: false,\n }));\n continue;\n }\n\n // Special keys\n if (code in SPECIAL_KEYS) {\n this._events.emit('key', createKeyEvent({\n key: SPECIAL_KEYS[code],\n raw,\n ctrl: false,\n alt: false,\n shift: false,\n }));\n continue;\n }\n\n // Regular printable character\n if (code >= 0x20) {\n this._events.emit('key', createKeyEvent({\n key: ch,\n raw,\n ctrl: false,\n alt: false,\n shift: ch !== ch.toLowerCase() && ch === ch.toUpperCase(),\n }));\n }\n }\n }\n\n /**\n * Try to parse buffered escape sequence.\n */\n private _tryParseEscape(rawData: Buffer): void {\n const seq = this._escapeBuffer;\n\n // Check for mouse event first\n if (isMouseSequence(seq)) {\n const mouseEvt = parseMouseEvent(seq);\n if (mouseEvt) {\n this._events.emit('mouse', mouseEvt);\n this._escapeBuffer = '';\n return;\n }\n // Might be incomplete mouse sequence — wait for more data\n if (seq.length < 20) { // safety cap\n this._escapeTimeout = setTimeout(() => {\n this._escapeBuffer = '';\n this._escapeTimeout = null;\n }, 100);\n return;\n }\n }\n\n // Check known escape sequences\n if (seq in ESCAPE_SEQUENCES) {\n const keyName = ESCAPE_SEQUENCES[seq];\n const isShift = keyName.startsWith('shift+');\n const isCtrl = keyName.startsWith('ctrl+');\n const isAlt = keyName.startsWith('alt+');\n const cleanKey = keyName.replace(/^(shift|ctrl|alt)\\+/, '');\n\n this._events.emit('key', createKeyEvent({\n key: cleanKey,\n raw: rawData,\n ctrl: isCtrl,\n alt: isAlt,\n shift: isShift,\n }));\n this._escapeBuffer = '';\n return;\n }\n\n // Alt+key: ESC followed by a regular character\n if (seq.length === 2 && seq[0] === '\\x1b') {\n const ch = seq[1];\n this._events.emit('key', createKeyEvent({\n key: ch,\n raw: rawData,\n ctrl: false,\n alt: true,\n shift: ch !== ch.toLowerCase() && ch === ch.toUpperCase(),\n }));\n this._escapeBuffer = '';\n return;\n }\n\n // If the sequence is getting too long, give up\n if (seq.length > 20) {\n this._escapeBuffer = '';\n return;\n }\n\n // Wait for more bytes (might be an incomplete sequence)\n this._escapeTimeout = setTimeout(() => {\n // Timeout — emit as unknown escape and clear\n this._escapeBuffer = '';\n this._escapeTimeout = null;\n }, 100);\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Style definition and merging\n// ─────────────────────────────────────────────────────\n\nimport type { Color } from './Color.js';\nimport type { BorderStyle } from './Border.js';\n\n/**\n * Edge values (padding, margin) — top, right, bottom, left.\n */\nexport interface Edges {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\n/**\n * Complete style definition for a widget.\n */\nexport interface Style {\n // ── Colors ──────────────\n fg?: Color;\n bg?: Color;\n\n // ── Text Decoration ─────\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n dim?: boolean;\n strikethrough?: boolean;\n inverse?: boolean;\n\n // ── Box Model ───────────\n padding?: Partial<Edges> | number;\n margin?: Partial<Edges> | number;\n border?: BorderStyle;\n borderColor?: Color;\n\n // ── Dimensions ──────────\n width?: number | string; // number = fixed chars, string = '50%'\n height?: number | string;\n minWidth?: number;\n minHeight?: number;\n maxWidth?: number;\n maxHeight?: number;\n\n // ── Flex Layout ─────────\n flexDirection?: 'row' | 'column';\n justifyContent?: 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around';\n alignItems?: 'flex-start' | 'flex-end' | 'center' | 'stretch';\n flexGrow?: number;\n flexShrink?: number;\n flexWrap?: 'nowrap' | 'wrap';\n gap?: number;\n\n // ── Overflow ────────────\n overflow?: 'visible' | 'hidden' | 'scroll';\n\n // ── Stacking ────────────\n /** Z-index for layer ordering. Higher values render on top. */\n zIndex?: number;\n\n // ── Focus ────────────────\n /** Color of the focus ring when this widget has focus */\n focusRingColor?: Color;\n /** Style of the focus ring indicator */\n focusRingStyle?: 'border' | 'corners' | 'glow' | 'none';\n\n // ── Visibility ──────────\n visible?: boolean;\n}\n\n/**\n * Normalize a shorthand edge value (number) into the full Edges object.\n */\nexport function normalizeEdges(value: Partial<Edges> | number | undefined): Edges {\n if (value === undefined) return { top: 0, right: 0, bottom: 0, left: 0 };\n if (typeof value === 'number') {\n return { top: value, right: value, bottom: value, left: value };\n }\n return {\n top: value.top ?? 0,\n right: value.right ?? 0,\n bottom: value.bottom ?? 0,\n left: value.left ?? 0,\n };\n}\n\n/**\n * Merge two styles. `override` values take precedence.\n * Undefined values in override do not overwrite base values.\n */\nexport function mergeStyles(base: Style, override: Style): Style {\n const result: Style = { ...base };\n\n for (const key of Object.keys(override) as Array<keyof Style>) {\n const val = override[key];\n if (val !== undefined) {\n (result as any)[key] = val;\n }\n }\n\n return result;\n}\n\n/**\n * Create a default (empty) style.\n */\nexport function defaultStyle(): Style {\n return {\n visible: true,\n flexDirection: 'column',\n justifyContent: 'flex-start',\n alignItems: 'stretch',\n flexGrow: 0,\n flexShrink: 1,\n flexWrap: 'nowrap',\n overflow: 'hidden',\n gap: 0,\n };\n}\n\n/**\n * Extract the cell-level style attributes from a Style object.\n * Used when rendering text into the screen buffer.\n */\nexport function styleToCellAttrs(style: Style): {\n fg: Color;\n bg: Color;\n bold: boolean;\n italic: boolean;\n underline: boolean;\n dim: boolean;\n strikethrough: boolean;\n inverse: boolean;\n} {\n return {\n fg: style.fg ?? { type: 'none' },\n bg: style.bg ?? { type: 'none' },\n bold: style.bold ?? false,\n italic: style.italic ?? false,\n underline: style.underline ?? false,\n dim: style.dim ?? false,\n strikethrough: style.strikethrough ?? false,\n inverse: style.inverse ?? false,\n };\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Border styles and rendering\n// ─────────────────────────────────────────────────────\n\n/**\n * Supported border styles.\n */\nexport type BorderStyle =\n | 'none'\n | 'single'\n | 'double'\n | 'round'\n | 'heavy'\n | 'dashed'\n | 'custom';\n\n/**\n * The characters used to draw a border.\n * Layout:\n * ```\n * topLeft ─── top ─── topRight\n * │ │\n * left content right\n * │ │\n * bottomLeft ─ bottom ─ bottomRight\n * ```\n */\nexport interface BorderChars {\n topLeft: string;\n top: string;\n topRight: string;\n right: string;\n bottomRight: string;\n bottom: string;\n bottomLeft: string;\n left: string;\n}\n\n/** Character maps for each border style */\nexport const BORDER_CHARS: Record<Exclude<BorderStyle, 'none' | 'custom'>, BorderChars> = {\n single: {\n topLeft: '┌', top: '─', topRight: '┐',\n right: '│', bottomRight: '┘', bottom: '─',\n bottomLeft: '└', left: '│',\n },\n double: {\n topLeft: '╔', top: '═', topRight: '╗',\n right: '║', bottomRight: '╝', bottom: '═',\n bottomLeft: '╚', left: '║',\n },\n round: {\n topLeft: '╭', top: '─', topRight: '╮',\n right: '│', bottomRight: '╯', bottom: '─',\n bottomLeft: '╰', left: '│',\n },\n heavy: {\n topLeft: '┏', top: '━', topRight: '┓',\n right: '┃', bottomRight: '┛', bottom: '━',\n bottomLeft: '┗', left: '┃',\n },\n dashed: {\n topLeft: '┌', top: '┄', topRight: '┐',\n right: '┆', bottomRight: '┘', bottom: '┄',\n bottomLeft: '└', left: '┆',\n },\n};\n\n/**\n * Get the border characters for a given style.\n */\nexport function getBorderChars(style: BorderStyle, customChars?: Partial<BorderChars>): BorderChars | null {\n if (style === 'none') return null;\n if (style === 'custom') {\n const base = BORDER_CHARS.single;\n return { ...base, ...customChars };\n }\n return BORDER_CHARS[style];\n}\n\n/**\n * Calculate the total space a border takes up.\n * Returns { horizontal, vertical } representing how many columns/rows\n * the border consumes (0 for none, 2 for any visible border — 1 on each side).\n */\nexport function borderSize(style: BorderStyle): { horizontal: number; vertical: number } {\n if (style === 'none') return { horizontal: 0, vertical: 0 };\n return { horizontal: 2, vertical: 2 };\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Flexbox-like Layout Engine\n// ─────────────────────────────────────────────────────\n\nimport type { Style } from '../style/Style.js';\nimport { normalizeEdges } from '../style/Style.js';\nimport { borderSize } from '../style/Border.js';\nimport type { Rect } from './Rect.js';\n\n/**\n * A node in the layout tree. Each widget produces one LayoutNode.\n */\nexport interface LayoutNode {\n /** Reference back to the widget/element that created this node */\n id: string;\n /** Style properties that affect layout */\n style: Style;\n /** Child nodes */\n children: LayoutNode[];\n /** Computed position and size — filled in by computeLayout() */\n computed: Rect;\n}\n\n/**\n * Create a LayoutNode with default values.\n */\nexport function createLayoutNode(id: string, style: Style, children: LayoutNode[] = []): LayoutNode {\n return {\n id,\n style,\n children,\n computed: { x: 0, y: 0, width: 0, height: 0 },\n };\n}\n\n/**\n * Compute the layout of a tree of LayoutNodes.\n *\n * This is a simplified Flexbox implementation that handles:\n * - flexDirection: row | column\n * - justifyContent: flex-start | flex-end | center | space-between | space-around\n * - alignItems: flex-start | flex-end | center | stretch\n * - flexGrow / flexShrink\n * - padding, margin, border\n * - fixed width/height, percentage width/height\n * - minWidth, maxWidth, minHeight, maxHeight\n * - gap between children\n */\nexport function computeLayout(root: LayoutNode, containerWidth: number, containerHeight: number): void {\n root.computed = { x: 0, y: 0, width: containerWidth, height: containerHeight };\n layoutNode(root, containerWidth, containerHeight);\n}\n\nfunction layoutNode(node: LayoutNode, availWidth: number, availHeight: number, precomputed = false): void {\n const style = node.style;\n const padding = normalizeEdges(style.padding);\n const margin = normalizeEdges(style.margin);\n const border = borderSize(style.border ?? 'none');\n\n if (!precomputed) {\n // Calculate this node's dimensions\n let nodeWidth = resolveSize(style.width, availWidth);\n let nodeHeight = resolveSize(style.height, availHeight);\n\n // Apply constraints\n if (nodeWidth === undefined) nodeWidth = availWidth - margin.left - margin.right;\n if (nodeHeight === undefined) nodeHeight = availHeight - margin.top - margin.bottom;\n\n nodeWidth = clampSize(nodeWidth, style.minWidth, style.maxWidth);\n nodeHeight = clampSize(nodeHeight, style.minHeight, style.maxHeight);\n\n node.computed.width = nodeWidth;\n node.computed.height = nodeHeight;\n }\n\n if (node.children.length === 0) return;\n\n const nodeWidth = node.computed.width;\n const nodeHeight = node.computed.height;\n\n // Inner content area (after padding + border)\n const innerX = padding.left + (border.horizontal / 2);\n const innerY = padding.top + (border.vertical / 2);\n const innerWidth = Math.max(0, nodeWidth - padding.left - padding.right - border.horizontal);\n const innerHeight = Math.max(0, nodeHeight - padding.top - padding.bottom - border.vertical);\n\n const direction = style.flexDirection ?? 'column';\n const isRow = direction === 'row';\n const gap = style.gap ?? 0;\n\n // ── Phase 1: Measure children's desired sizes ──────\n\n const childInfos: Array<{\n node: LayoutNode;\n mainSize: number;\n crossSize: number;\n flexGrow: number;\n flexShrink: number;\n margin: { top: number; right: number; bottom: number; left: number };\n }> = [];\n\n let totalFixed = 0;\n let totalGrow = 0;\n let totalShrink = 0;\n\n for (const child of node.children) {\n if (child.style.visible === false) continue;\n\n const childMargin = normalizeEdges(child.style.margin);\n const childBorder = borderSize(child.style.border ?? 'none');\n const grow = child.style.flexGrow ?? 0;\n const shrink = child.style.flexShrink ?? 1;\n\n let mainSize: number;\n let crossSize: number;\n\n if (isRow) {\n mainSize = resolveSize(child.style.width, innerWidth) ?? 0;\n crossSize = resolveSize(child.style.height, innerHeight) ?? innerHeight;\n mainSize += childMargin.left + childMargin.right;\n crossSize = clampSize(crossSize, child.style.minHeight, child.style.maxHeight);\n } else {\n mainSize = resolveSize(child.style.height, innerHeight) ?? 0;\n crossSize = resolveSize(child.style.width, innerWidth) ?? innerWidth;\n mainSize += childMargin.top + childMargin.bottom;\n crossSize = clampSize(crossSize, child.style.minWidth, child.style.maxWidth);\n }\n\n totalFixed += mainSize;\n totalGrow += grow;\n totalShrink += shrink;\n\n childInfos.push({ node: child, mainSize, crossSize, flexGrow: grow, flexShrink: shrink, margin: childMargin });\n }\n\n const totalGaps = Math.max(0, childInfos.length - 1) * gap;\n const mainAvail = isRow ? innerWidth : innerHeight;\n const freeSpace = mainAvail - totalFixed - totalGaps;\n\n // ── Phase 2: Distribute free space (grow/shrink) ───\n\n if (freeSpace > 0 && totalGrow > 0) {\n for (const info of childInfos) {\n if (info.flexGrow > 0) {\n info.mainSize += (info.flexGrow / totalGrow) * freeSpace;\n }\n }\n } else if (freeSpace < 0 && totalShrink > 0) {\n for (const info of childInfos) {\n if (info.flexShrink > 0) {\n info.mainSize += (info.flexShrink / totalShrink) * freeSpace;\n info.mainSize = Math.max(0, info.mainSize);\n }\n }\n }\n\n // ── Phase 3: Position children ─────────────────────\n\n const totalMainUsed = childInfos.reduce((sum, i) => sum + i.mainSize, 0) + totalGaps;\n const remainingSpace = Math.max(0, mainAvail - totalMainUsed);\n\n let mainOffset: number;\n let spaceBetween = 0;\n\n const justify = style.justifyContent ?? 'flex-start';\n switch (justify) {\n case 'flex-start':\n mainOffset = 0;\n break;\n case 'flex-end':\n mainOffset = remainingSpace;\n break;\n case 'center':\n mainOffset = remainingSpace / 2;\n break;\n case 'space-between':\n mainOffset = 0;\n spaceBetween = childInfos.length > 1 ? remainingSpace / (childInfos.length - 1) : 0;\n break;\n case 'space-around':\n spaceBetween = childInfos.length > 0 ? remainingSpace / childInfos.length : 0;\n mainOffset = spaceBetween / 2;\n break;\n default:\n mainOffset = 0;\n }\n\n const crossAvail = isRow ? innerHeight : innerWidth;\n const align = style.alignItems ?? 'stretch';\n\n for (const info of childInfos) {\n // Cross axis alignment\n let crossOffset: number;\n let finalCrossSize = info.crossSize;\n\n switch (align) {\n case 'flex-start':\n crossOffset = 0;\n break;\n case 'flex-end':\n crossOffset = crossAvail - finalCrossSize;\n break;\n case 'center':\n crossOffset = (crossAvail - finalCrossSize) / 2;\n break;\n case 'stretch':\n crossOffset = 0;\n finalCrossSize = crossAvail;\n break;\n default:\n crossOffset = 0;\n }\n\n // Set computed rect\n if (isRow) {\n info.node.computed = {\n x: Math.floor(node.computed.x + innerX + mainOffset + info.margin.left),\n y: Math.floor(node.computed.y + innerY + crossOffset + info.margin.top),\n width: Math.round(Math.max(0, info.mainSize - info.margin.left - info.margin.right)),\n height: Math.round(Math.max(0, finalCrossSize - info.margin.top - info.margin.bottom)),\n };\n } else {\n info.node.computed = {\n x: Math.floor(node.computed.x + innerX + crossOffset + info.margin.left),\n y: Math.floor(node.computed.y + innerY + mainOffset + info.margin.top),\n width: Math.round(Math.max(0, finalCrossSize - info.margin.left - info.margin.right)),\n height: Math.round(Math.max(0, info.mainSize - info.margin.top - info.margin.bottom)),\n };\n }\n\n mainOffset += info.mainSize + gap + spaceBetween;\n\n // Recursively layout children — dimensions already set by parent\n layoutNode(info.node, info.node.computed.width, info.node.computed.height, true);\n }\n}\n\n/**\n * Resolve a size value (fixed number or percentage string) to pixels.\n * Returns undefined if the value is not set.\n */\nfunction resolveSize(value: number | string | undefined, available: number): number | undefined {\n if (value === undefined) return undefined;\n if (typeof value === 'number') return value;\n if (typeof value === 'string' && value.endsWith('%')) {\n const pct = parseFloat(value) / 100;\n return Math.floor(available * pct);\n }\n return undefined;\n}\n\n/**\n * Clamp a size to min/max bounds.\n */\nfunction clampSize(value: number, min?: number, max?: number): number {\n let result = value;\n if (min !== undefined) result = Math.max(result, min);\n if (max !== undefined) result = Math.min(result, max);\n return result;\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Layout types (Rect, Size, Edges)\n// ─────────────────────────────────────────────────────\n\n/**\n * A computed rectangle with position and size.\n */\nexport interface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * A 2D size.\n */\nexport interface Size {\n width: number;\n height: number;\n}\n\n/**\n * Create an empty rect at origin.\n */\nexport function emptyRect(): Rect {\n return { x: 0, y: 0, width: 0, height: 0 };\n}\n\n/**\n * Check if a point is inside a rect.\n */\nexport function containsPoint(rect: Rect, x: number, y: number): boolean {\n return x >= rect.x && x < rect.x + rect.width &&\n y >= rect.y && y < rect.y + rect.height;\n}\n\n/**\n * Shrink a rect by the given edges (inset).\n */\nexport function shrinkRect(rect: Rect, top: number, right: number, bottom: number, left: number): Rect {\n return {\n x: rect.x + left,\n y: rect.y + top,\n width: Math.max(0, rect.width - left - right),\n height: Math.max(0, rect.height - top - bottom),\n };\n}\n\n/**\n * Intersect two rects. Returns the overlapping region, or null if disjoint.\n */\nexport function intersectRect(a: Rect, b: Rect): Rect | null {\n const x = Math.max(a.x, b.x);\n const y = Math.max(a.y, b.y);\n const r = Math.min(a.x + a.width, b.x + b.width);\n const bot = Math.min(a.y + a.height, b.y + b.height);\n if (r <= x || bot <= y) return null;\n return { x, y, width: r - x, height: bot - y };\n}\n\n/**\n * Union two rects into the smallest bounding rect that contains both.\n */\nexport function unionRect(a: Rect, b: Rect): Rect {\n const x = Math.min(a.x, b.x);\n const y = Math.min(a.y, b.y);\n const r = Math.max(a.x + a.width, b.x + b.width);\n const bot = Math.max(a.y + a.height, b.y + b.height);\n return { x, y, width: r - x, height: bot - y };\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Constraint-based Layout\n// Alternative to flexbox for dashboard-style splits.\n// ─────────────────────────────────────────────────────\n\nimport type { Rect } from './Rect.js';\n\n// ── Constraint Types ─────────────────────────────────\n\nexport type Constraint =\n | { type: 'length'; value: number }\n | { type: 'percentage'; value: number }\n | { type: 'ratio'; num: number; den: number }\n | { type: 'min'; value: number }\n | { type: 'max'; value: number }\n | { type: 'fill'; weight: number };\n\n// ── Constraint Factories ─────────────────────────────\n\n/** Exactly n cells. */\nexport const length = (n: number): Constraint => ({ type: 'length', value: n });\n\n/** n% of available space. */\nexport const percentage = (n: number): Constraint => ({ type: 'percentage', value: n });\n\n/** num/den of available space. */\nexport const ratio = (num: number, den: number): Constraint => ({ type: 'ratio', num, den });\n\n/** At least n cells. */\nexport const min = (n: number): Constraint => ({ type: 'min', value: n });\n\n/** At most n cells. */\nexport const max = (n: number): Constraint => ({ type: 'max', value: n });\n\n/** Fill remaining space with the given weight. Default weight: 1. */\nexport const fill = (weight: number = 1): Constraint => ({ type: 'fill', weight });\n\n// ── Solver ───────────────────────────────────────────\n\nfunction resolveSize(constraint: Constraint, available: number): number {\n switch (constraint.type) {\n case 'length': return Math.min(constraint.value, available);\n case 'percentage': return Math.min(Math.floor((available * constraint.value) / 100), available);\n case 'ratio': return constraint.den === 0 ? 0 : Math.min(\n Math.floor((available * constraint.num) / constraint.den), available\n );\n case 'min': return constraint.value;\n case 'max': return Math.min(constraint.value, available);\n case 'fill': return 0; // resolved in second pass\n }\n}\n\n/**\n * Split a rectangle into sub-rectangles using constraints.\n *\n * Example:\n * ```ts\n * const [header, body, footer] = splitRect(\n * area,\n * [length(3), fill(), length(1)],\n * 'vertical',\n * );\n * ```\n */\nexport function splitRect(\n rect: Rect,\n constraints: Constraint[],\n direction: 'horizontal' | 'vertical' = 'vertical',\n gap: number = 0,\n): Rect[] {\n if (constraints.length === 0) return [];\n\n const totalAvailable = direction === 'horizontal' ? rect.width : rect.height;\n const count = constraints.length;\n const totalGaps = count > 1 ? gap * (count - 1) : 0;\n const availableForConstraints = Math.max(0, totalAvailable - totalGaps);\n\n // First pass: resolve non-fill constraints\n const sizes: number[] = [];\n let usedSpace = 0;\n let fillWeightSum = 0;\n\n for (const constraint of constraints) {\n if (constraint.type === 'fill') {\n sizes.push(0);\n fillWeightSum += Math.max(1, constraint.weight);\n } else {\n const size = resolveSize(constraint, availableForConstraints);\n sizes.push(size);\n usedSpace += size;\n }\n }\n\n // Second pass: distribute remaining space to fill constraints\n if (fillWeightSum > 0) {\n const remaining = Math.max(0, availableForConstraints - usedSpace);\n let distributed = 0;\n\n for (let i = 0; i < count; i++) {\n const constraint = constraints[i];\n if (!constraint || constraint.type !== 'fill') continue;\n\n const weight = Math.max(1, constraint.weight);\n const share = Math.floor((remaining * weight) / fillWeightSum);\n sizes[i] = share;\n distributed += share;\n }\n\n // Give leftover pixels to the last fill constraint\n const leftover = remaining - distributed;\n if (leftover > 0) {\n for (let i = count - 1; i >= 0; i--) {\n const constraint = constraints[i];\n if (constraint && constraint.type === 'fill') {\n sizes[i] = (sizes[i] ?? 0) + leftover;\n break;\n }\n }\n }\n }\n\n // Clamp so total doesn't exceed available\n let totalUsed = 0;\n for (let i = 0; i < count; i++) {\n const size = sizes[i] ?? 0;\n const clamped = Math.max(0, Math.min(size, availableForConstraints - totalUsed));\n sizes[i] = clamped;\n totalUsed += clamped;\n }\n\n // Build result rects\n const results: Rect[] = [];\n let offset = 0;\n\n for (let i = 0; i < count; i++) {\n const size = sizes[i] ?? 0;\n\n if (direction === 'horizontal') {\n results.push({ x: rect.x + offset, y: rect.y, width: size, height: rect.height });\n } else {\n results.push({ x: rect.x, y: rect.y + offset, width: rect.width, height: size });\n }\n\n offset += size + gap;\n }\n\n return results;\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Focus Manager\n// ─────────────────────────────────────────────────────\n\nimport { EventEmitter } from './EventEmitter.js';\nimport type { FocusEvent } from './types.js';\n\nexport interface Focusable {\n id: string;\n tabIndex: number;\n focusable: boolean;\n}\n\n/**\n * Manages tab-order focus cycling between focusable widgets.\n * Dispatches focus/blur events when focus changes.\n *\n * Supports:\n * - Tab-order cycling (focusNext/focusPrev)\n * - Focus trapping (for modals — limits Tab to a container)\n * - Focus groups (for arrow-key navigation within a group)\n */\nexport class FocusManager {\n private _focusables: Focusable[] = [];\n private _currentIndex = -1;\n private _events = new EventEmitter<{ focus: FocusEvent; blur: FocusEvent }>();\n\n /**\n * Stack of trap container IDs. When non-empty, only focusables\n * that belong to the topmost trap container are reachable via Tab.\n */\n private _trapStack: string[] = [];\n\n /**\n * Map of container ID → child widget IDs that belong to it.\n * Used for trap membership lookup.\n */\n private _containerMembers: Map<string, Set<string>> = new Map();\n\n /**\n * Named focus groups. Arrow keys move within a group, Tab moves between groups.\n * Maps groupId → ordered list of widget IDs.\n */\n private _groups: Map<string, string[]> = new Map();\n\n /** Currently focused widget ID, or null if none */\n get currentId(): string | null {\n if (this._currentIndex < 0 || this._currentIndex >= this._focusables.length) {\n return null;\n }\n return this._focusables[this._currentIndex].id;\n }\n\n /** Subscribe to focus/blur events */\n on<K extends 'focus' | 'blur'>(event: K, handler: (data: FocusEvent) => void): () => void {\n return this._events.on(event, handler);\n }\n\n /**\n * Register a focusable widget.\n * Widgets are ordered by tabIndex (ascending), then insertion order.\n */\n register(focusable: Focusable): void {\n this._focusables.push(focusable);\n this._focusables.sort((a, b) => a.tabIndex - b.tabIndex);\n\n // Auto-focus the first widget if nothing is focused\n if (this._currentIndex < 0 && focusable.focusable) {\n this._currentIndex = this._focusables.indexOf(focusable);\n this._events.emit('focus', { targetId: focusable.id, type: 'focus' });\n }\n }\n\n /**\n * Unregister a focusable widget.\n */\n unregister(id: string): void {\n const idx = this._focusables.findIndex(f => f.id === id);\n if (idx < 0) return;\n\n const wasFocused = idx === this._currentIndex;\n this._focusables.splice(idx, 1);\n\n if (wasFocused) {\n this._events.emit('blur', { targetId: id, type: 'blur' });\n // Try to focus the next widget\n if (this._focusables.length > 0) {\n this._currentIndex = Math.min(this._currentIndex, this._focusables.length - 1);\n this._events.emit('focus', {\n targetId: this._focusables[this._currentIndex].id,\n type: 'focus',\n });\n } else {\n this._currentIndex = -1;\n }\n } else if (idx < this._currentIndex) {\n this._currentIndex--;\n }\n }\n\n /**\n * Move focus to the next focusable widget (wraps around).\n * Respects focus traps — if a trap is active, only cycles within it.\n */\n focusNext(): void {\n const candidates = this._getActiveFocusables();\n if (candidates.length === 0) return;\n\n const currentInCandidates = this.currentId\n ? candidates.findIndex(f => f.id === this.currentId)\n : -1;\n\n let next = (currentInCandidates + 1) % candidates.length;\n const start = next;\n\n // Skip non-focusable widgets\n while (!candidates[next].focusable) {\n next = (next + 1) % candidates.length;\n if (next === start) return; // All non-focusable\n }\n\n // Find this candidate's index in the master list\n const masterIdx = this._focusables.findIndex(f => f.id === candidates[next].id);\n if (masterIdx >= 0) this._changeFocus(masterIdx);\n }\n\n /**\n * Move focus to the previous focusable widget (wraps around).\n * Respects focus traps.\n */\n focusPrev(): void {\n const candidates = this._getActiveFocusables();\n if (candidates.length === 0) return;\n\n const currentInCandidates = this.currentId\n ? candidates.findIndex(f => f.id === this.currentId)\n : 0;\n\n let prev = (currentInCandidates - 1 + candidates.length) % candidates.length;\n const start = prev;\n\n while (!candidates[prev].focusable) {\n prev = (prev - 1 + candidates.length) % candidates.length;\n if (prev === start) return;\n }\n\n const masterIdx = this._focusables.findIndex(f => f.id === candidates[prev].id);\n if (masterIdx >= 0) this._changeFocus(masterIdx);\n }\n\n /**\n * Focus a specific widget by ID.\n */\n focusWidget(id: string): void {\n const idx = this._focusables.findIndex(f => f.id === id);\n if (idx < 0 || !this._focusables[idx].focusable) return;\n this._changeFocus(idx);\n }\n\n /**\n * Check if a specific widget currently has focus.\n */\n isFocused(id: string): boolean {\n return this.currentId === id;\n }\n\n // ── Focus Trap ──────────────────────────────────────\n\n /**\n * Register widget IDs as members of a container (for trap lookup).\n */\n registerContainerMembers(containerId: string, memberIds: string[]): void {\n const set = this._containerMembers.get(containerId) ?? new Set();\n for (const id of memberIds) set.add(id);\n this._containerMembers.set(containerId, set);\n }\n\n /**\n * Unregister a container's member list.\n */\n unregisterContainerMembers(containerId: string): void {\n this._containerMembers.delete(containerId);\n }\n\n /**\n * Trap focus within a container. Only focusables inside the\n * container are reachable via Tab. Traps are stacked —\n * nested modals create nested traps.\n */\n trap(containerId: string): void {\n this._trapStack.push(containerId);\n\n // Focus the first focusable inside the trap\n const trapped = this._getActiveFocusables();\n if (trapped.length > 0) {\n const first = trapped.find(f => f.focusable);\n if (first) {\n const idx = this._focusables.findIndex(f => f.id === first.id);\n if (idx >= 0) this._changeFocus(idx);\n }\n }\n }\n\n /**\n * Release the current focus trap. Restores previous trap or free navigation.\n */\n release(): void {\n this._trapStack.pop();\n }\n\n /** Whether a focus trap is currently active */\n get isTrapped(): boolean {\n return this._trapStack.length > 0;\n }\n\n /** ID of the current trap container, or null */\n get currentTrapId(): string | null {\n return this._trapStack.length > 0\n ? this._trapStack[this._trapStack.length - 1]\n : null;\n }\n\n // ── Focus Groups ────────────────────────────────────\n\n /**\n * Register a focus group. Arrow keys move within the group.\n * @param groupId Unique group identifier\n * @param widgetIds Ordered list of widget IDs in the group\n */\n registerGroup(groupId: string, widgetIds: string[]): void {\n this._groups.set(groupId, widgetIds);\n }\n\n /**\n * Unregister a focus group.\n */\n unregisterGroup(groupId: string): void {\n this._groups.delete(groupId);\n }\n\n /**\n * Move focus to the next widget within the same group.\n * Returns true if focus was moved, false if the widget isn't in a group.\n */\n focusNextInGroup(): boolean {\n const currentId = this.currentId;\n if (!currentId) return false;\n\n for (const [, ids] of this._groups) {\n const idx = ids.indexOf(currentId);\n if (idx >= 0) {\n const nextIdx = (idx + 1) % ids.length;\n this.focusWidget(ids[nextIdx]);\n return true;\n }\n }\n return false;\n }\n\n /**\n * Move focus to the previous widget within the same group.\n */\n focusPrevInGroup(): boolean {\n const currentId = this.currentId;\n if (!currentId) return false;\n\n for (const [, ids] of this._groups) {\n const idx = ids.indexOf(currentId);\n if (idx >= 0) {\n const prevIdx = (idx - 1 + ids.length) % ids.length;\n this.focusWidget(ids[prevIdx]);\n return true;\n }\n }\n return false;\n }\n\n // ── Private ──────────────────────────────────────────\n\n /**\n * Get the active focusables, filtered by the current trap if any.\n */\n private _getActiveFocusables(): Focusable[] {\n if (this._trapStack.length === 0) return this._focusables;\n\n const containerId = this._trapStack[this._trapStack.length - 1];\n const members = this._containerMembers.get(containerId);\n if (!members) return this._focusables;\n\n return this._focusables.filter(f => members.has(f.id));\n }\n\n private _changeFocus(newIndex: number): void {\n const oldId = this.currentId;\n if (oldId) {\n this._events.emit('blur', { targetId: oldId, type: 'blur' });\n }\n this._currentIndex = newIndex;\n this._events.emit('focus', {\n targetId: this._focusables[newIndex].id,\n type: 'focus',\n });\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Unicode Symbol Sets\n// ─────────────────────────────────────────────────────\n\n// ── Border Sets ──────────────────────────────────────\n\nexport interface BorderSet {\n topLeft: string;\n topRight: string;\n bottomLeft: string;\n bottomRight: string;\n horizontal: string;\n vertical: string;\n cross: string;\n}\n\nexport const BorderSets = {\n PLAIN: {\n topLeft: '┌', topRight: '┐', bottomLeft: '└', bottomRight: '┘',\n horizontal: '─', vertical: '│', cross: '┼',\n },\n ROUNDED: {\n topLeft: '╭', topRight: '╮', bottomLeft: '╰', bottomRight: '╯',\n horizontal: '─', vertical: '│', cross: '┼',\n },\n DOUBLE: {\n topLeft: '╔', topRight: '╗', bottomLeft: '╚', bottomRight: '╝',\n horizontal: '═', vertical: '║', cross: '╬',\n },\n THICK: {\n topLeft: '┏', topRight: '┓', bottomLeft: '┗', bottomRight: '┛',\n horizontal: '━', vertical: '┃', cross: '╋',\n },\n QUADRANT_INSIDE: {\n topLeft: '▗', topRight: '▖', bottomLeft: '▝', bottomRight: '▘',\n horizontal: '▀', vertical: '▐', cross: '█',\n },\n QUADRANT_OUTSIDE: {\n topLeft: '▛', topRight: '▜', bottomLeft: '▙', bottomRight: '▟',\n horizontal: '▀', vertical: '▌', cross: '█',\n },\n EMPTY: {\n topLeft: ' ', topRight: ' ', bottomLeft: ' ', bottomRight: ' ',\n horizontal: ' ', vertical: ' ', cross: ' ',\n },\n} as const satisfies Record<string, BorderSet>;\n\n// ── Bar Chart Symbol Sets ────────────────────────────\n\nexport interface BarSet {\n full: string;\n sevenEighths: string;\n threeQuarters: string;\n fiveEighths: string;\n half: string;\n threeEighths: string;\n oneQuarter: string;\n oneEighth: string;\n empty: string;\n}\n\n/**\n * Vertical bar symbols: bottom-up block characters ▁▂▃▄▅▆▇█\n * 9 levels (including empty) for sub-cell precision.\n */\nexport const BarSets = {\n NINE_LEVELS: {\n full: '█', sevenEighths: '▇', threeQuarters: '▆', fiveEighths: '▅',\n half: '▄', threeEighths: '▃', oneQuarter: '▂', oneEighth: '▁', empty: ' ',\n },\n THREE_LEVELS: {\n full: '█', sevenEighths: '░', threeQuarters: '░', fiveEighths: '░',\n half: '▄', threeEighths: '░', oneQuarter: '░', oneEighth: '░', empty: ' ',\n },\n ASCII: {\n full: '#', sevenEighths: '#', threeQuarters: '#', fiveEighths: '#',\n half: '#', threeEighths: '-', oneQuarter: '-', oneEighth: '-', empty: ' ',\n },\n} as const satisfies Record<string, BarSet>;\n\n/** Ordered vertical bar symbols from empty to full (9 levels). */\nexport const VERTICAL_BAR_SYMBOLS: readonly string[] = [\n ' ', '▁', '▂', '▃', '▄', '▅', '▆', '▇', '█',\n];\n\n/** Ordered horizontal bar symbols from empty to full (9 levels). */\nexport const HORIZONTAL_BAR_SYMBOLS: readonly string[] = [\n ' ', '\\u258F', '\\u258E', '\\u258D', '\\u258C', '\\u258B', '\\u258A', '\\u2589', '\\u2588',\n];\n\n// ── Scrollbar Symbol Sets ────────────────────────────\n\nexport interface ScrollbarSet {\n track: string;\n thumb: string;\n begin: string;\n end: string;\n}\n\nexport const ScrollbarSets = {\n VERTICAL: { track: '│', thumb: '█', begin: '↑', end: '↓' },\n HORIZONTAL: { track: '─', thumb: '█', begin: '←', end: '→' },\n DOUBLE_VERTICAL: { track: '║', thumb: '▐', begin: '▲', end: '▼' },\n DOUBLE_HORIZONTAL: { track: '═', thumb: '▌', begin: '◄', end: '►' },\n} as const satisfies Record<string, ScrollbarSet>;\n\n// ── Line Symbol Sets ─────────────────────────────────\n\nexport interface LineSet {\n horizontal: string;\n vertical: string;\n cross: string;\n}\n\nexport const LineSets = {\n NORMAL: { horizontal: '─', vertical: '│', cross: '┼' },\n THICK: { horizontal: '━', vertical: '┃', cross: '╋' },\n DOUBLE: { horizontal: '═', vertical: '║', cross: '╬' },\n} as const satisfies Record<string, LineSet>;\n\n// ── Shade Symbols ────────────────────────────────────\n\nexport const Shade = {\n FULL: '█',\n DARK: '▓',\n MEDIUM: '▒',\n LIGHT: '░',\n EMPTY: ' ',\n} as const;\n\n// ── Braille Constants ────────────────────────────────\n\n/** Unicode braille range offset (U+2800). */\nexport const BRAILLE_OFFSET = 0x2800;\n\n/**\n * Braille dot bit positions.\n * Each row is [leftBit, rightBit] for a 2-wide, 4-tall braille cell.\n */\nexport const BRAILLE_DOTS: readonly (readonly [number, number])[] = [\n [0x01, 0x08],\n [0x02, 0x10],\n [0x04, 0x20],\n [0x40, 0x80],\n] as const;\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Test Backend\n// In-memory rendering for snapshot testing.\n// ─────────────────────────────────────────────────────\n\nimport type { Cell } from './Screen.js';\nimport { emptyCell } from './Screen.js';\n\n/**\n * In-memory grid that captures rendered output.\n * Use `createTestScreen()` to create one, render widgets into it,\n * then call `testScreenToString()` to get a plain-text snapshot.\n */\nexport interface TestScreen {\n readonly width: number;\n readonly height: number;\n cells: Cell[][];\n}\n\n/**\n * Create an in-memory test screen of the given dimensions.\n * Every cell starts as empty (space character, default colors).\n */\nexport function createTestScreen(width: number, height: number): TestScreen {\n const cells: Cell[][] = [];\n for (let row = 0; row < height; row++) {\n const rowCells: Cell[] = [];\n for (let col = 0; col < width; col++) {\n rowCells.push(emptyCell());\n }\n cells.push(rowCells);\n }\n return { width, height, cells };\n}\n\n/**\n * Set a cell in the test screen at (x, y).\n * Out-of-bounds writes are silently ignored.\n */\nexport function testScreenSetCell(screen: TestScreen, x: number, y: number, cell: Cell): void {\n if (x < 0 || x >= screen.width || y < 0 || y >= screen.height) {\n return;\n }\n const row = screen.cells[y];\n if (row) {\n row[x] = cell;\n }\n}\n\n/**\n * Get the cell at (x, y) in the test screen.\n * Returns undefined for out-of-bounds coordinates.\n */\nexport function testScreenGetCell(screen: TestScreen, x: number, y: number): Cell | undefined {\n if (x < 0 || x >= screen.width || y < 0 || y >= screen.height) {\n return undefined;\n }\n const row = screen.cells[y];\n return row ? row[x] : undefined;\n}\n\n/**\n * Convert the test screen to a plain-text string.\n * Each row becomes a line. Trailing spaces on each line are preserved.\n *\n * Example output:\n * ```\n * ┌Hello──┐\n * │World │\n * └───────┘\n * ```\n */\nexport function testScreenToString(screen: TestScreen): string {\n return screen.cells\n .map(row => row.map(cell => cell.char).join(''))\n .join('\\n');\n}\n\n/**\n * Clear the test screen, resetting all cells to empty.\n */\nexport function testScreenClear(screen: TestScreen): void {\n for (let y = 0; y < screen.height; y++) {\n const row = screen.cells[y];\n if (row) {\n for (let x = 0; x < screen.width; x++) {\n row[x] = emptyCell();\n }\n }\n }\n}\n\n/**\n * Write a string into the test screen starting at (x, y).\n * Characters that fall outside the screen bounds are clipped.\n */\nexport function testScreenSetString(\n screen: TestScreen,\n x: number,\n y: number,\n str: string,\n): void {\n let cx = x;\n for (const ch of str) {\n if (cx >= screen.width) break;\n if (cx >= 0 && y >= 0 && y < screen.height) {\n const row = screen.cells[y];\n if (row) {\n const cell = emptyCell();\n cell.char = ch;\n row[cx] = cell;\n }\n }\n cx++;\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Fallback (static) renderer for CI/pipes\n// ─────────────────────────────────────────────────────\n\nimport type { Screen } from '../terminal/Screen.js';\nimport { stripAnsi } from '../utils/unicode.js';\n\n/**\n * Detect if the terminal should use fallback (non-interactive) rendering.\n *\n * Returns true when:\n * - stdout is not a TTY (piped)\n * - CI environment variable is set\n * - TERM is 'dumb'\n * - NO_COLOR is set\n */\nexport function shouldUseFallback(): boolean {\n if (!process.stdout.isTTY) return true;\n if (process.env['CI']) return true;\n if (process.env['TERM'] === 'dumb') return true;\n return false;\n}\n\n/**\n * Render a Screen buffer as plain text (no ANSI, no interactivity).\n *\n * Reads all cells from the screen and produces a simple text representation.\n * Strips trailing whitespace from each line and removes empty trailing lines.\n */\nexport function renderFallback(screen: Screen): string {\n const lines: string[] = [];\n\n for (let r = 0; r < screen.rows; r++) {\n let line = '';\n for (let c = 0; c < screen.cols; c++) {\n const cell = screen.back[r][c];\n if (cell.width === 0) continue; // Skip continuation cells\n line += cell.char || ' ';\n }\n lines.push(line.trimEnd());\n }\n\n // Remove empty trailing lines\n while (lines.length > 0 && lines[lines.length - 1] === '') {\n lines.pop();\n }\n\n return lines.join('\\n');\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Application lifecycle manager\n// ─────────────────────────────────────────────────────\n\nimport { Terminal, type TerminalOptions } from '../terminal/Terminal.js';\nimport { Screen } from '../terminal/Screen.js';\nimport { Renderer } from '../terminal/Renderer.js';\nimport { LayerManager } from '../terminal/LayerManager.js';\nimport { InputParser } from '../input/InputParser.js';\nimport { FocusManager } from '../events/FocusManager.js';\nimport { EventEmitter } from '../events/EventEmitter.js';\nimport { computeLayout, type LayoutNode } from '../layout/LayoutEngine.js';\nimport type { EventMap } from '../events/types.js';\nimport { createKeyEvent } from '../events/types.js';\nimport { renderFallback, shouldUseFallback } from './Fallback.js';\n\nexport interface AppOptions extends TerminalOptions {\n /** Frames per second for the render loop */\n fps?: number;\n /** Use alternate screen (full-screen mode). Default: true */\n fullscreen?: boolean;\n /** Enable mouse support. Default: false */\n mouse?: boolean;\n /** Force fallback (static) rendering */\n forceFallback?: boolean;\n /** Skip fallback detection — always run interactively. Default: false */\n skipFallback?: boolean;\n /** Title to set on the terminal window */\n title?: string;\n}\n\n/**\n * Widget interface that App expects for the root widget.\n * This is the minimum contract — the full Widget class in @termuijs/widgets extends this.\n */\nexport interface RootWidget {\n id: string;\n getLayoutNode(): LayoutNode;\n syncLayout?(): void;\n render(screen: Screen): void;\n mount?(): void;\n unmount?(): void;\n /** Check if this widget needs re-rendering (dirty flag) */\n isDirty?: boolean;\n /** Clear the dirty flag after rendering */\n clearDirty?(): void;\n}\n\n/**\n * Application lifecycle manager.\n *\n * Manages:\n * - Terminal setup/teardown (alt screen, raw mode, cursor, mouse)\n * - Screen buffer and renderer initialization\n * - Input parsing and event dispatch\n * - Layout computation and rect sync\n * - Render loop\n * - Graceful shutdown\n */\nexport class App {\n readonly terminal: Terminal;\n readonly screen: Screen;\n readonly renderer: Renderer;\n readonly input: InputParser;\n readonly focus: FocusManager;\n readonly events: EventEmitter<EventMap>;\n readonly layers: LayerManager;\n\n private _rootWidget: RootWidget;\n private _options: AppOptions;\n private _mounted = false;\n private _exitResolve: ((code: number) => void) | null = null;\n\n constructor(rootWidget: RootWidget, options: AppOptions = {}) {\n this._rootWidget = rootWidget;\n this._options = {\n fullscreen: true,\n mouse: false,\n fps: 30,\n ...options,\n };\n\n this.terminal = new Terminal(options);\n this.screen = new Screen(this.terminal.cols, this.terminal.rows);\n this.renderer = new Renderer(this.terminal, this.screen, this._options.fps);\n this.input = new InputParser(this.terminal.stdin);\n this.focus = new FocusManager();\n this.events = new EventEmitter();\n this.layers = new LayerManager(this.terminal.cols, this.terminal.rows);\n }\n\n /**\n * Start the application.\n * Sets up the terminal, starts the render loop, and mounts the root widget.\n * Returns a promise that resolves when exit() is called.\n */\n async mount(): Promise<number> {\n if (this._mounted) return 0;\n\n // Check if we should use fallback mode\n if (this._options.forceFallback || (!this._options.skipFallback && shouldUseFallback())) {\n this._renderFallback();\n return 0;\n }\n\n this._mounted = true;\n\n // Set up terminal\n this.terminal.enterRawMode();\n if (this._options.fullscreen) {\n this.terminal.enterAltScreen();\n }\n this.terminal.hideCursor();\n\n if (this._options.mouse) {\n this.terminal.enableMouse();\n }\n\n if (this._options.title) {\n this.terminal.write(`\\x1b]0;${this._options.title}\\x07`);\n }\n\n // Handle resize\n this.terminal.onResize((cols, rows) => {\n this.screen.resize(cols, rows);\n this.screen.invalidate();\n this.layers.resize(cols, rows);\n this.events.emit('resize', { cols, rows });\n this.requestRender();\n });\n\n // Set up input handling\n this.input.start();\n\n // Forward key events with bubble dispatch\n this.input.onKey((rawEvent) => {\n const event = createKeyEvent({\n ...rawEvent,\n targetId: this.focus.currentId ?? undefined,\n });\n\n // Phase 1: Bubble dispatch — focused widget → parent → root\n const focusedId = this.focus.currentId;\n if (focusedId) {\n const chain = this._buildBubbleChain(focusedId);\n for (const widget of chain) {\n widget.events.emit('key', event);\n if (event._propagationStopped) break;\n }\n }\n\n // Phase 2: Default actions (Tab for focus cycling)\n if (!event._defaultPrevented) {\n if (event.key === 'tab' && !event.ctrl && !event.alt) {\n if (event.shift) {\n this.focus.focusPrev();\n } else {\n this.focus.focusNext();\n }\n }\n }\n\n // Phase 3: App-level broadcast (always fires unless stopped)\n if (!event._propagationStopped) {\n this.events.emit('key', event);\n }\n });\n\n // Forward mouse events\n this.input.onMouse((event) => {\n this.events.emit('mouse', event);\n });\n\n // Start render loop\n this.renderer.start();\n\n // Mount root widget\n this._rootWidget.mount?.();\n this.events.emit('mount', undefined as any);\n\n // Initial render — invalidate front buffer to force full redraw\n this.screen.invalidate();\n this.requestRender();\n\n // Block until exit() is called\n return new Promise<number>((resolve) => {\n this._exitResolve = resolve;\n });\n }\n\n /**\n * Stop the application and restore terminal state.\n */\n unmount(): void {\n if (!this._mounted) return;\n this._mounted = false;\n\n this._rootWidget.unmount?.();\n this.events.emit('unmount', undefined as any);\n\n this.renderer.stop();\n this.input.stop();\n this.terminal.restore();\n this.events.removeAll();\n }\n\n /**\n * Create an overlay layer for rendering above normal widgets.\n * @param id Unique layer identifier (e.g. 'modal', 'select-dropdown', 'toast')\n * @param zIndex Stacking order (higher = rendered on top). Default: 100\n */\n addOverlay(id: string, zIndex = 100): void {\n this.layers.createLayer(id, zIndex);\n }\n\n /**\n * Remove an overlay layer.\n */\n removeOverlay(id: string): void {\n this.layers.removeLayer(id);\n }\n\n /**\n * Request a re-render on the next frame.\n */\n requestRender(): void {\n if (!this._mounted) return;\n\n // Compute layout\n const layoutRoot = this._rootWidget.getLayoutNode();\n computeLayout(layoutRoot, this.terminal.cols, this.terminal.rows);\n\n // Sync computed rects from layout tree back to widgets\n this._rootWidget.syncLayout?.();\n\n // Clear the back buffer and render widgets into it\n this.screen.clear();\n this._rootWidget.render(this.screen);\n\n // Composite overlay layers on top of the base rendering\n this.layers.composite(this.screen);\n\n this.renderer.requestFrame();\n }\n\n /**\n * Exit the app (convenience method).\n */\n exit(code = 0): void {\n this.unmount();\n if (this._exitResolve) {\n this._exitResolve(code);\n this._exitResolve = null;\n }\n }\n\n /**\n * Render in fallback (static) mode for non-interactive environments.\n */\n private _renderFallback(): void {\n const layoutRoot = this._rootWidget.getLayoutNode();\n computeLayout(layoutRoot, this.terminal.cols, this.terminal.rows);\n\n this._rootWidget.syncLayout?.();\n\n this.screen.clear();\n this._rootWidget.render(this.screen);\n\n const output = renderFallback(this.screen);\n this.terminal.write(output + '\\n');\n }\n\n /**\n * Build the bubble chain for keyboard events.\n * Returns an array: [focused widget, parent, grandparent, ..., root]\n */\n private _buildBubbleChain(widgetId: string): Array<{ events: { emit: (event: string, data: any) => void } }> {\n const chain: Array<{ events: { emit: (event: string, data: any) => void } }> = [];\n const widget = this._findWidgetById(this._rootWidget as any, widgetId);\n if (!widget) return chain;\n\n let current: any = widget;\n while (current) {\n if (current.events) {\n chain.push(current);\n }\n current = current.parent ?? null;\n }\n return chain;\n }\n\n /**\n * Find a widget by ID in the widget tree (DFS).\n * Uses duck-typing to work with any object that has id/children.\n */\n private _findWidgetById(root: any, id: string): any | null {\n if (root.id === id) return root;\n\n // Check children if the widget has them\n const children = root._children ?? root.children ?? [];\n if (Array.isArray(children)) {\n for (const child of children) {\n const found = this._findWidgetById(child, id);\n if (found) return found;\n }\n }\n\n return null;\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Unicode string width utilities\n// ─────────────────────────────────────────────────────\n\n/**\n * Check if a code point is a CJK (East Asian Wide/Fullwidth) character.\n * These characters occupy 2 terminal columns.\n *\n * Covers: CJK Unified Ideographs, Hangul Syllables, Katakana, Fullwidth Latin, etc.\n */\nfunction isWideChar(codePoint: number): boolean {\n return (\n // CJK Unified Ideographs (common Chinese/Japanese/Korean)\n (codePoint >= 0x4E00 && codePoint <= 0x9FFF) ||\n // CJK Unified Ideographs Extension A\n (codePoint >= 0x3400 && codePoint <= 0x4DBF) ||\n // CJK Compatibility Ideographs\n (codePoint >= 0xF900 && codePoint <= 0xFAFF) ||\n // Hangul Syllables\n (codePoint >= 0xAC00 && codePoint <= 0xD7AF) ||\n // Katakana\n (codePoint >= 0x30A0 && codePoint <= 0x30FF) ||\n // CJK Symbols and Punctuation\n (codePoint >= 0x3000 && codePoint <= 0x303F) ||\n // Hiragana\n (codePoint >= 0x3040 && codePoint <= 0x309F) ||\n // Fullwidth Forms\n (codePoint >= 0xFF01 && codePoint <= 0xFF60) ||\n (codePoint >= 0xFFE0 && codePoint <= 0xFFE6) ||\n // CJK Unified Ideographs Extension B\n (codePoint >= 0x20000 && codePoint <= 0x2A6DF) ||\n // CJK Unified Ideographs Extension C,D,E,F\n (codePoint >= 0x2A700 && codePoint <= 0x2EBEF) ||\n // CJK Compatibility Ideographs Supplement\n (codePoint >= 0x2F800 && codePoint <= 0x2FA1F)\n );\n}\n\n/**\n * Check if a code point is a combining character (zero-width).\n * These characters do not occupy any terminal column by themselves.\n */\nfunction isCombining(codePoint: number): boolean {\n return (\n // Combining Diacritical Marks\n (codePoint >= 0x0300 && codePoint <= 0x036F) ||\n // Combining Diacritical Marks Extended\n (codePoint >= 0x1AB0 && codePoint <= 0x1AFF) ||\n // Combining Diacritical Marks Supplement\n (codePoint >= 0x1DC0 && codePoint <= 0x1DFF) ||\n // Combining Diacritical Marks for Symbols\n (codePoint >= 0x20D0 && codePoint <= 0x20FF) ||\n // Combining Half Marks\n (codePoint >= 0xFE20 && codePoint <= 0xFE2F) ||\n // Variation selectors\n (codePoint >= 0xFE00 && codePoint <= 0xFE0F) ||\n // Zero-width joiner / non-joiner\n codePoint === 0x200B || codePoint === 0x200C || codePoint === 0x200D ||\n codePoint === 0xFEFF\n );\n}\n\n/**\n * Check if a character is an emoji that typically occupies 2 columns.\n * Simplified heuristic covering common emoji ranges.\n */\nfunction isEmoji(codePoint: number): boolean {\n return (\n // Emoticons\n (codePoint >= 0x1F600 && codePoint <= 0x1F64F) ||\n // Misc Symbols and Pictographs\n (codePoint >= 0x1F300 && codePoint <= 0x1F5FF) ||\n // Transport and Map\n (codePoint >= 0x1F680 && codePoint <= 0x1F6FF) ||\n // Supplemental Symbols\n (codePoint >= 0x1F900 && codePoint <= 0x1F9FF) ||\n // Misc symbols\n (codePoint >= 0x2600 && codePoint <= 0x26FF) ||\n // Dingbats\n (codePoint >= 0x2700 && codePoint <= 0x27BF) ||\n // Flags\n (codePoint >= 0x1F1E0 && codePoint <= 0x1F1FF)\n );\n}\n\n/**\n * Calculate the visual width of a string in terminal columns.\n *\n * - CJK characters count as 2 columns\n * - Emoji count as 2 columns\n * - Combining/zero-width characters count as 0\n * - ANSI escape sequences count as 0\n * - Regular characters count as 1\n */\nexport function stringWidth(str: string): number {\n let width = 0;\n let inEscape = false;\n\n for (const char of str) {\n const cp = char.codePointAt(0)!;\n\n // Skip ANSI escape sequences\n if (cp === 0x1B) { // ESC\n inEscape = true;\n continue;\n }\n if (inEscape) {\n // End of CSI sequence (letter after ESC[...m)\n if ((cp >= 0x40 && cp <= 0x7E) && cp !== 0x5B) {\n inEscape = false;\n }\n continue;\n }\n\n // Skip control characters\n if (cp < 0x20 || (cp >= 0x7F && cp < 0xA0)) {\n continue;\n }\n\n // Zero-width\n if (isCombining(cp)) {\n continue;\n }\n\n // Double-width\n if (isWideChar(cp) || isEmoji(cp)) {\n width += 2;\n continue;\n }\n\n width += 1;\n }\n\n return width;\n}\n\n/**\n * Truncate a string to the given visual width, preserving ANSI codes.\n * Appends an ellipsis character if truncated.\n */\nexport function truncate(str: string, maxWidth: number, ellipsis = '…'): string {\n if (maxWidth <= 0) return '';\n const strW = stringWidth(str);\n if (strW <= maxWidth) return str;\n\n const ellipsisW = stringWidth(ellipsis);\n const targetW = maxWidth - ellipsisW;\n if (targetW <= 0) return ellipsis.slice(0, maxWidth);\n\n let width = 0;\n let result = '';\n let inEscape = false;\n let escapeBuffer = '';\n\n for (const char of str) {\n const cp = char.codePointAt(0)!;\n\n if (cp === 0x1B) {\n inEscape = true;\n escapeBuffer += char;\n continue;\n }\n if (inEscape) {\n escapeBuffer += char;\n if ((cp >= 0x40 && cp <= 0x7E) && cp !== 0x5B) {\n inEscape = false;\n result += escapeBuffer;\n escapeBuffer = '';\n }\n continue;\n }\n\n let charW = 1;\n if (isCombining(cp)) {\n charW = 0;\n } else if (isWideChar(cp) || isEmoji(cp)) {\n charW = 2;\n } else if (cp < 0x20 || (cp >= 0x7F && cp < 0xA0)) {\n charW = 0;\n }\n\n if (width + charW > targetW) break;\n width += charW;\n result += char;\n }\n\n return result + ellipsis;\n}\n\n/**\n * Strip all ANSI escape sequences from a string.\n */\nexport function stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1b\\[[0-9;]*[a-zA-Z]/g, '');\n}\n\n/**\n * Word-wrap text to a given width, respecting existing newlines.\n * Does not handle ANSI codes within words (wraps at the character level).\n */\nexport function wordWrap(str: string, width: number): string {\n if (width <= 0) return str;\n\n const lines = str.split('\\n');\n const result: string[] = [];\n\n for (const line of lines) {\n if (stringWidth(line) <= width) {\n result.push(line);\n continue;\n }\n\n let currentLine = '';\n let currentWidth = 0;\n const words = line.split(/(\\s+)/);\n\n for (const word of words) {\n const wordW = stringWidth(word);\n\n if (currentWidth + wordW <= width) {\n currentLine += word;\n currentWidth += wordW;\n } else if (wordW > width) {\n // Word is longer than width — break it\n if (currentLine) {\n result.push(currentLine);\n currentLine = '';\n currentWidth = 0;\n }\n for (const char of word) {\n const cp = char.codePointAt(0)!;\n const charW = (isWideChar(cp) || isEmoji(cp)) ? 2 : (isCombining(cp) ? 0 : 1);\n if (currentWidth + charW > width) {\n result.push(currentLine);\n currentLine = '';\n currentWidth = 0;\n }\n currentLine += char;\n currentWidth += charW;\n }\n } else {\n result.push(currentLine);\n currentLine = word.trimStart();\n currentWidth = stringWidth(currentLine);\n }\n }\n\n if (currentLine) {\n result.push(currentLine);\n }\n }\n\n return result.join('\\n');\n}\n"],"mappings":"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","names":["ColorDepth","nodeWidth","nodeHeight","min","max","resolveSize"]}
|
|
1
|
+
{"version":3,"sources":["../src/style/Color.ts","../src/utils/ansi.ts","../src/terminal/Terminal.ts","../src/terminal/Screen.ts","../src/terminal/Renderer.ts","../src/terminal/LayerManager.ts","../src/terminal/env-caps.ts","../src/terminal/ascii-map.ts","../src/events/types.ts","../src/input/KeyMap.ts","../src/input/MouseParser.ts","../src/events/EventEmitter.ts","../src/input/InputParser.ts","../src/style/Style.ts","../src/style/Border.ts","../src/layout/LayoutEngine.ts","../src/layout/Rect.ts","../src/layout/ConstraintLayout.ts","../src/events/FocusManager.ts","../src/style/symbols.ts","../src/terminal/TestBackend.ts","../src/app/Fallback.ts","../src/app/App.ts","../src/utils/unicode.ts"],"sourcesContent":["// ─────────────────────────────────────────────────────\n// @termuijs/core — Color types and color profile detection\n// ─────────────────────────────────────────────────────\n\n/**\n * Supported color depth levels, ordered from least to most capable.\n */\nexport enum ColorDepth {\n /** No color support (e.g. NO_COLOR env var set) */\n None = 0,\n /** 4-bit, 16 colors (standard ANSI) */\n Basic = 4,\n /** 8-bit, 256 colors */\n Ansi256 = 8,\n /** 24-bit, 16.7 million colors (true color) */\n TrueColor = 24,\n}\n\n/**\n * Represents a color value in the terminal.\n * Supports named ANSI colors, 256-color palette, and RGB true color.\n */\nexport type Color =\n | { type: 'named'; name: NamedColor }\n | { type: 'ansi256'; code: number }\n | { type: 'rgb'; r: number; g: number; b: number }\n | { type: 'hex'; hex: string }\n | { type: 'none' };\n\nexport type NamedColor =\n | 'black' | 'red' | 'green' | 'yellow'\n | 'blue' | 'magenta' | 'cyan' | 'white'\n | 'brightBlack' | 'brightRed' | 'brightGreen' | 'brightYellow'\n | 'brightBlue' | 'brightMagenta' | 'brightCyan' | 'brightWhite';\n\n/** Maps named colors to their ANSI 4-bit foreground code offsets (30-37, 90-97). */\nconst NAMED_TO_ANSI: Record<NamedColor, number> = {\n black: 0, red: 1, green: 2, yellow: 3,\n blue: 4, magenta: 5, cyan: 6, white: 7,\n brightBlack: 8, brightRed: 9, brightGreen: 10, brightYellow: 11,\n brightBlue: 12, brightMagenta: 13, brightCyan: 14, brightWhite: 15,\n};\n\n/** Maps named colors to approximate RGB for downgrading. */\nconst NAMED_TO_RGB: Record<NamedColor, [number, number, number]> = {\n black: [0, 0, 0], red: [170, 0, 0], green: [0, 170, 0], yellow: [170, 170, 0],\n blue: [0, 0, 170], magenta: [170, 0, 170], cyan: [0, 170, 170], white: [170, 170, 170],\n brightBlack: [85, 85, 85], brightRed: [255, 85, 85], brightGreen: [85, 255, 85], brightYellow: [255, 255, 85],\n brightBlue: [85, 85, 255], brightMagenta: [255, 85, 255], brightCyan: [85, 255, 255], brightWhite: [255, 255, 255],\n};\n\n/**\n * Parse a color string into a Color object.\n *\n * Accepts:\n * - Named colors: 'red', 'brightBlue', etc.\n * - Hex: '#ff0000', '#f00'\n * - RGB: 'rgb(255, 0, 0)'\n * - ANSI 256: 'ansi256(196)'\n */\nexport function parseColor(input: string): Color {\n if (input === 'none' || input === '') {\n return { type: 'none' };\n }\n\n // Named color\n if (input in NAMED_TO_ANSI) {\n return { type: 'named', name: input as NamedColor };\n }\n\n // Hex color\n if (input.startsWith('#')) {\n let hex = input.slice(1);\n if (hex.length === 3) {\n hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];\n }\n if (hex.length === 6 && /^[0-9a-fA-F]{6}$/.test(hex)) {\n return { type: 'hex', hex: '#' + hex.toLowerCase() };\n }\n // Invalid hex — return none instead of crashing\n return { type: 'none' };\n }\n\n // RGB color\n const rgbMatch = input.match(/^rgb\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*\\)$/);\n if (rgbMatch) {\n const r = Math.min(255, parseInt(rgbMatch[1], 10));\n const g = Math.min(255, parseInt(rgbMatch[2], 10));\n const b = Math.min(255, parseInt(rgbMatch[3], 10));\n return { type: 'rgb', r, g, b };\n }\n\n // ANSI 256\n const ansi256Match = input.match(/^ansi256\\(\\s*(\\d{1,3})\\s*\\)$/);\n if (ansi256Match) {\n const code = Math.min(255, parseInt(ansi256Match[1], 10));\n return { type: 'ansi256', code };\n }\n\n // Unknown format — return none instead of crashing\n return { type: 'none' };\n}\n\n/**\n * Convert any Color to its RGB representation.\n */\nexport function colorToRgb(color: Color): [number, number, number] {\n switch (color.type) {\n case 'none':\n return [0, 0, 0];\n case 'named':\n return NAMED_TO_RGB[color.name];\n case 'rgb':\n return [color.r, color.g, color.b];\n case 'hex': {\n const hex = color.hex.slice(1);\n return [\n parseInt(hex.slice(0, 2), 16),\n parseInt(hex.slice(2, 4), 16),\n parseInt(hex.slice(4, 6), 16),\n ];\n }\n case 'ansi256':\n return ansi256ToRgb(color.code);\n }\n}\n\n/**\n * Convert an ANSI 256 code to approximate RGB.\n */\nfunction ansi256ToRgb(code: number): [number, number, number] {\n // Standard colors (0-15) — use named mapping\n if (code < 16) {\n const names = Object.keys(NAMED_TO_RGB) as NamedColor[];\n return NAMED_TO_RGB[names[code]];\n }\n // Extended 216-color cube (16-231)\n if (code < 232) {\n const idx = code - 16;\n const b = (idx % 6) * 51;\n const g = (Math.floor(idx / 6) % 6) * 51;\n const r = Math.floor(idx / 36) * 51;\n return [r, g, b];\n }\n // Grayscale ramp (232-255)\n const gray = (code - 232) * 10 + 8;\n return [gray, gray, gray];\n}\n\n/**\n * Find the nearest ANSI 256 color code for a given RGB.\n */\nfunction rgbToAnsi256(r: number, g: number, b: number): number {\n // Check if it's a grayscale\n if (r === g && g === b) {\n if (r < 8) return 16;\n if (r > 248) return 231;\n return Math.round((r - 8) / 247 * 24) + 232;\n }\n return 16\n + 36 * Math.round(r / 255 * 5)\n + 6 * Math.round(g / 255 * 5)\n + Math.round(b / 255 * 5);\n}\n\n/**\n * Find the nearest ANSI 4-bit basic color for a given RGB.\n */\nfunction rgbToBasic(r: number, g: number, b: number): number {\n let minDist = Infinity;\n let best = 0;\n const names = Object.keys(NAMED_TO_RGB) as NamedColor[];\n for (let i = 0; i < names.length; i++) {\n const [cr, cg, cb] = NAMED_TO_RGB[names[i]];\n const dist = (r - cr) ** 2 + (g - cg) ** 2 + (b - cb) ** 2;\n if (dist < minDist) {\n minDist = dist;\n best = i;\n }\n }\n return best;\n}\n\n/**\n * Detect the terminal's color depth from environment variables.\n */\nexport function detectColorDepth(): ColorDepth {\n const env = process.env;\n\n // Respect NO_COLOR convention (https://no-color.org/)\n if (env['NO_COLOR'] !== undefined) {\n return ColorDepth.None;\n }\n\n // Force color via FORCE_COLOR\n if (env['FORCE_COLOR'] !== undefined) {\n const level = parseInt(env['FORCE_COLOR'], 10);\n if (level === 0) return ColorDepth.None;\n if (level === 1) return ColorDepth.Basic;\n if (level === 2) return ColorDepth.Ansi256;\n if (level >= 3) return ColorDepth.TrueColor;\n }\n\n // Check COLORTERM for true color\n const colorterm = env['COLORTERM'];\n if (colorterm === 'truecolor' || colorterm === '24bit') {\n return ColorDepth.TrueColor;\n }\n\n // Check TERM for 256 color\n const term = env['TERM'] || '';\n if (term === 'dumb') {\n return ColorDepth.None;\n }\n if (term.includes('256color') || term.includes('256')) {\n return ColorDepth.Ansi256;\n }\n\n // Check for common color-capable terminals\n if (env['TERM_PROGRAM'] === 'iTerm.app' || env['TERM_PROGRAM'] === 'Hyper') {\n return ColorDepth.TrueColor;\n }\n\n // Default to basic if stdout is a TTY\n if (process.stdout?.isTTY) {\n return ColorDepth.Basic;\n }\n\n return ColorDepth.None;\n}\n\n/**\n * Generate the ANSI escape codes for a foreground color at the given depth.\n */\nexport function colorToAnsiFg(color: Color, depth: ColorDepth): string {\n if (color.type === 'none' || depth === ColorDepth.None) return '';\n const [r, g, b] = colorToRgb(color);\n\n switch (depth) {\n case ColorDepth.TrueColor:\n return `\\x1b[38;2;${r};${g};${b}m`;\n case ColorDepth.Ansi256:\n return `\\x1b[38;5;${rgbToAnsi256(r, g, b)}m`;\n case ColorDepth.Basic: {\n const idx = rgbToBasic(r, g, b);\n return idx < 8 ? `\\x1b[${30 + idx}m` : `\\x1b[${90 + idx - 8}m`;\n }\n default:\n return '';\n }\n}\n\n/**\n * Generate the ANSI escape codes for a background color at the given depth.\n */\nexport function colorToAnsiBg(color: Color, depth: ColorDepth): string {\n if (color.type === 'none' || depth === ColorDepth.None) return '';\n const [r, g, b] = colorToRgb(color);\n\n switch (depth) {\n case ColorDepth.TrueColor:\n return `\\x1b[48;2;${r};${g};${b}m`;\n case ColorDepth.Ansi256:\n return `\\x1b[48;5;${rgbToAnsi256(r, g, b)}m`;\n case ColorDepth.Basic: {\n const idx = rgbToBasic(r, g, b);\n return idx < 8 ? `\\x1b[${40 + idx}m` : `\\x1b[${100 + idx - 8}m`;\n }\n default:\n return '';\n }\n}\n\n// ── WCAG Contrast Utilities ──────────────────────────\n\n/**\n * Compute relative luminance per WCAG 2.1.\n * Returns value in [0, 1] where 0 = black, 1 = white.\n */\nexport function relativeLuminance(color: Color): number {\n const [r, g, b] = colorToRgb(color);\n const linearize = (c: number): number => {\n const sRGB = c / 255;\n return sRGB <= 0.03928 ? sRGB / 12.92 : Math.pow((sRGB + 0.055) / 1.055, 2.4);\n };\n return 0.2126 * linearize(r) + 0.7152 * linearize(g) + 0.0722 * linearize(b);\n}\n\n/**\n * Compute WCAG 2.1 contrast ratio between foreground and background colors.\n * Returns value in [1, 21] where 21 is maximum contrast (black on white).\n */\nexport function contrastRatio(fg: Color, bg: Color): number {\n const l1 = relativeLuminance(fg);\n const l2 = relativeLuminance(bg);\n const lighter = Math.max(l1, l2);\n const darker = Math.min(l1, l2);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * Determine WCAG 2.1 conformance level for a contrast ratio.\n * @param ratio Result of contrastRatio()\n * @param large True if text is large (18pt+ regular or 14pt+ bold). Default: false.\n */\nexport function wcagLevel(ratio: number, large = false): 'AAA' | 'AA' | 'A' | 'fail' {\n if (large) {\n if (ratio >= 4.5) return 'AAA';\n if (ratio >= 3.0) return 'AA';\n return 'fail';\n }\n if (ratio >= 7.0) return 'AAA';\n if (ratio >= 4.5) return 'AA';\n if (ratio >= 3.0) return 'A';\n return 'fail';\n}\n\nexport interface ContrastFailure {\n /** Description of the color pair, e.g. 'fg on bg' */\n pair: string;\n ratio: number;\n level: 'A' | 'fail';\n required: 'AA';\n}\n\n/**\n * Validate contrast for key pairs in a theme (hex string map).\n * Checks: fg/bg, primary/bg, error/bg, success/bg, warning/bg, muted/bg.\n * Returns failures (pairs below AA = 4.5:1 for normal text).\n */\nexport function validateThemeContrast(theme: Record<string, string>): ContrastFailure[] {\n const failures: ContrastFailure[] = [];\n const bg = theme['bg'];\n if (!bg) return failures;\n\n const bgColor = parseColor(bg);\n const pairs: Array<[string, string | undefined]> = [\n ['fg on bg', theme['fg']],\n ['primary on bg', theme['primary']],\n ['error on bg', theme['error']],\n ['success on bg', theme['success']],\n ['warning on bg', theme['warning']],\n ['muted on bg', theme['muted']],\n ];\n\n for (const [label, hex] of pairs) {\n if (!hex) continue;\n const fgColor = parseColor(hex);\n const ratio = contrastRatio(fgColor, bgColor);\n const level = wcagLevel(ratio);\n if (level !== 'AAA' && level !== 'AA') {\n failures.push({ pair: label, ratio: Math.round(ratio * 100) / 100, level: level as 'A' | 'fail', required: 'AA' });\n }\n }\n\n return failures;\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — ANSI escape sequence helpers\n// ─────────────────────────────────────────────────────\n\n/** CSI (Control Sequence Introducer) prefix */\nexport const CSI = '\\x1b[';\n/** OSC (Operating System Command) prefix */\nexport const OSC = '\\x1b]';\n/** ESC character */\nexport const ESC = '\\x1b';\n\n// ── Cursor Control ──────────────────────────────────\n\nexport const hideCursor = `${CSI}?25l`;\nexport const showCursor = `${CSI}?25h`;\nexport const saveCursorPosition = `${CSI}s`;\nexport const restoreCursorPosition = `${CSI}u`;\n\nexport function moveTo(col: number, row: number): string {\n return `${CSI}${row + 1};${col + 1}H`;\n}\n\nexport function moveUp(n = 1): string { return `${CSI}${n}A`; }\nexport function moveDown(n = 1): string { return `${CSI}${n}B`; }\nexport function moveRight(n = 1): string { return `${CSI}${n}C`; }\nexport function moveLeft(n = 1): string { return `${CSI}${n}D`; }\n\n// ── Screen Control ──────────────────────────────────\n\nexport const clearScreen = `${CSI}2J`;\nexport const clearLine = `${CSI}2K`;\nexport const clearLineToEnd = `${CSI}0K`;\nexport const clearLineToStart = `${CSI}1K`;\nexport const clearDown = `${CSI}J`;\nexport const clearUp = `${CSI}1J`;\n\n// ── Alternate Screen Buffer ─────────────────────────\n\nexport const enterAltScreen = `${CSI}?1049h`;\nexport const exitAltScreen = `${CSI}?1049l`;\n\n// ── Synchronized Output (CSI 2026) ──────────────────\n\n/** Begin synchronized update — terminal holds display until end marker */\nexport const beginSyncUpdate = `${CSI}?2026h`;\n/** End synchronized update — terminal flushes all pending changes atomically */\nexport const endSyncUpdate = `${CSI}?2026l`;\n\n// ── Mouse Tracking ──────────────────────────────────\n\n/** Enable SGR mouse tracking (most compatible modern mode) */\nexport const enableMouse = `${CSI}?1000h${CSI}?1002h${CSI}?1006h`;\n/** Disable mouse tracking */\nexport const disableMouse = `${CSI}?1000l${CSI}?1002l${CSI}?1006l`;\n\n// ── Bracketed Paste ─────────────────────────────────\n\nexport const enableBracketedPaste = `${CSI}?2004h`;\nexport const disableBracketedPaste = `${CSI}?2004l`;\n\n// ── Text Styling ────────────────────────────────────\n\nexport const reset = `${CSI}0m`;\nexport const bold = `${CSI}1m`;\nexport const dim = `${CSI}2m`;\nexport const italic = `${CSI}3m`;\nexport const underline = `${CSI}4m`;\nexport const blink = `${CSI}5m`;\nexport const inverse = `${CSI}7m`;\nexport const strikethrough = `${CSI}9m`;\n\nexport const resetBold = `${CSI}22m`;\nexport const resetDim = `${CSI}22m`;\nexport const resetItalic = `${CSI}23m`;\nexport const resetUnderline = `${CSI}24m`;\nexport const resetBlink = `${CSI}25m`;\nexport const resetInverse = `${CSI}27m`;\nexport const resetStrikethrough = `${CSI}29m`;\n\n// ── Scrolling Region ────────────────────────────────\n\nexport function setScrollRegion(top: number, bottom: number): string {\n return `${CSI}${top + 1};${bottom + 1}r`;\n}\nexport const resetScrollRegion = `${CSI}r`;\n\n// ── Title ───────────────────────────────────────────\n\nexport function setTitle(title: string): string {\n return `${OSC}0;${title}\\x07`;\n}\n\n// ── Clipboard ───────────────────────────────────────\n\n/**\n * Write text to the system clipboard via OSC 52.\n * Supported by: xterm, iTerm2, Kitty, WezTerm, Alacritty, Windows Terminal.\n * @param text Plain text to copy to clipboard\n * @param stdout Target stream (default: process.stdout)\n */\nexport function writeClipboard(text: string, stdout: NodeJS.WriteStream = process.stdout): void {\n const encoded = Buffer.from(text, 'utf8').toString('base64');\n stdout.write(`${OSC}52;c;${encoded}\\x07`);\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Terminal adapter\n// ─────────────────────────────────────────────────────\n\nimport { ColorDepth, detectColorDepth } from '../style/Color.js';\nimport * as ansi from '../utils/ansi.js';\n\nexport interface TerminalOptions {\n /** Override stdout stream (useful for testing) */\n stdout?: NodeJS.WriteStream;\n /** Override stdin stream (useful for testing) */\n stdin?: NodeJS.ReadStream;\n /** Force a specific color depth */\n colorDepth?: ColorDepth;\n /** Enable mouse tracking */\n mouse?: boolean;\n /** Use alternate screen buffer for full-screen apps */\n altScreen?: boolean;\n}\n\n/**\n * Terminal adapter — wraps process.stdout/stdin and manages\n * terminal state (raw mode, cursor, mouse, alternate screen).\n */\nexport class Terminal {\n readonly stdout: NodeJS.WriteStream;\n readonly stdin: NodeJS.ReadStream;\n readonly colorDepth: ColorDepth;\n\n private _cols: number;\n private _rows: number;\n private _isRawMode = false;\n private _isAltScreen = false;\n private _isMouseEnabled = false;\n private _resizeHandlers: Array<(cols: number, rows: number) => void> = [];\n private _cleanupHandlers: Array<() => void> = [];\n private _originalRawMode: boolean | undefined;\n\n // Stored handler references for proper cleanup\n private _resizeHandler: (() => void) | null = null;\n private _exitHandler: (() => void) | null = null;\n private _sigintHandler: (() => void) | null = null;\n private _sigtermHandler: (() => void) | null = null;\n private _uncaughtExceptionHandler: ((err: Error) => void) | null = null;\n private _unhandledRejectionHandler: (() => void) | null = null;\n private _restored = false;\n\n constructor(options: TerminalOptions = {}) {\n this.stdout = options.stdout ?? process.stdout;\n this.stdin = options.stdin ?? process.stdin;\n this.colorDepth = options.colorDepth ?? detectColorDepth();\n\n this._cols = this.stdout.columns ?? 80;\n this._rows = this.stdout.rows ?? 24;\n\n // Listen for terminal resize (store ref for cleanup)\n this._resizeHandler = () => {\n this._cols = this.stdout.columns ?? 80;\n this._rows = this.stdout.rows ?? 24;\n for (const handler of this._resizeHandlers) {\n handler(this._cols, this._rows);\n }\n };\n this.stdout.on('resize', this._resizeHandler);\n\n // Set up cleanup on process exit\n this._setupCleanup();\n }\n\n /** Current terminal width in columns */\n get cols(): number { return this._cols; }\n /** Current terminal height in rows */\n get rows(): number { return this._rows; }\n\n /** Whether stdin is a TTY (interactive) */\n isInteractive(): boolean {\n return Boolean(this.stdin.isTTY) && !process.env['CI'];\n }\n\n /** Whether the terminal supports raw mode */\n supportsRawMode(): boolean {\n return Boolean(this.stdin.isTTY && typeof this.stdin.setRawMode === 'function');\n }\n\n // ── Raw Mode ────────────────────────────────────────\n\n enterRawMode(): void {\n if (this._isRawMode || !this.supportsRawMode()) return;\n this._originalRawMode = this.stdin.isRaw;\n this.stdin.setRawMode(true);\n this.stdin.resume();\n this._isRawMode = true;\n }\n\n exitRawMode(): void {\n if (!this._isRawMode) return;\n this.stdin.setRawMode(this._originalRawMode ?? false);\n this.stdin.pause();\n this._isRawMode = false;\n }\n\n // ── Alternate Screen ────────────────────────────────\n\n enterAltScreen(): void {\n if (this._isAltScreen) return;\n this.write(ansi.enterAltScreen);\n this._isAltScreen = true;\n }\n\n exitAltScreen(): void {\n if (!this._isAltScreen) return;\n this.write(ansi.exitAltScreen);\n this._isAltScreen = false;\n }\n\n // ── Mouse ───────────────────────────────────────────\n\n enableMouse(): void {\n if (this._isMouseEnabled) return;\n this.write(ansi.enableMouse);\n this._isMouseEnabled = true;\n }\n\n disableMouse(): void {\n if (!this._isMouseEnabled) return;\n this.write(ansi.disableMouse);\n this._isMouseEnabled = false;\n }\n\n // ── Cursor ──────────────────────────────────────────\n\n hideCursor(): void { this.write(ansi.hideCursor); }\n showCursor(): void { this.write(ansi.showCursor); }\n\n // ── Output ──────────────────────────────────────────\n\n write(data: string): void {\n this.stdout.write(data);\n }\n\n // ── Resize ──────────────────────────────────────────\n\n onResize(handler: (cols: number, rows: number) => void): () => void {\n this._resizeHandlers.push(handler);\n return () => {\n const idx = this._resizeHandlers.indexOf(handler);\n if (idx >= 0) this._resizeHandlers.splice(idx, 1);\n };\n }\n\n // ── Cleanup ─────────────────────────────────────────\n\n /**\n * Restore terminal to its original state.\n * Removes all process signal handlers to prevent leaks.\n * Called automatically on SIGINT, SIGTERM, process exit.\n */\n restore(): void {\n if (this._restored) return; // Prevent double-restore\n this._restored = true;\n\n // Remove process-level signal handlers to prevent leaks\n if (this._exitHandler) process.off('exit', this._exitHandler);\n if (this._sigintHandler) process.off('SIGINT', this._sigintHandler);\n if (this._sigtermHandler) process.off('SIGTERM', this._sigtermHandler);\n if (this._uncaughtExceptionHandler) {\n process.off('uncaughtException', this._uncaughtExceptionHandler);\n this._uncaughtExceptionHandler = null;\n }\n if (this._unhandledRejectionHandler) {\n process.off('unhandledRejection', this._unhandledRejectionHandler);\n this._unhandledRejectionHandler = null;\n }\n\n // Remove resize listener\n if (this._resizeHandler) {\n this.stdout.off('resize', this._resizeHandler);\n }\n\n this.disableMouse();\n this.exitAltScreen();\n this.exitRawMode();\n this.showCursor();\n this.write(ansi.reset);\n }\n\n /**\n * Register a custom cleanup handler that runs on terminal restore.\n */\n onCleanup(handler: () => void): void {\n this._cleanupHandlers.push(handler);\n }\n\n private _setupCleanup(): void {\n const runCleanupHandlers = () => {\n for (const handler of this._cleanupHandlers) {\n try { handler(); } catch { /* swallow */ }\n }\n this.restore();\n };\n\n this._exitHandler = runCleanupHandlers;\n this._sigintHandler = () => { runCleanupHandlers(); process.exit(130); };\n this._sigtermHandler = () => { runCleanupHandlers(); process.exit(143); };\n\n process.on('exit', this._exitHandler);\n process.on('SIGINT', this._sigintHandler);\n process.on('SIGTERM', this._sigtermHandler);\n\n this._uncaughtExceptionHandler = (err: Error) => {\n this.restore();\n process.exit(1);\n };\n this._unhandledRejectionHandler = () => {\n this.restore();\n process.exit(1);\n };\n // Use .on() (not .once()) so restore() can explicitly remove these handlers\n // via process.off(). With .once(), the reference is removed after first fire,\n // making process.off() in restore() a no-op on subsequent exceptions.\n process.on('uncaughtException', this._uncaughtExceptionHandler);\n process.on('unhandledRejection', this._unhandledRejectionHandler);\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Screen buffer (double-buffered cell grid)\n// ─────────────────────────────────────────────────────\n\nimport type { Color } from '../style/Color.js';\n\nconst EMPTY_COLOR: Color = Object.freeze({ type: 'none' } as const);\n\n/**\n * A single cell in the terminal grid.\n */\nexport interface Cell {\n /** The character displayed (single grapheme cluster) */\n char: string;\n /** Foreground color */\n fg: Color;\n /** Background color */\n bg: Color;\n /** Bold text */\n bold: boolean;\n /** Italic text */\n italic: boolean;\n /** Underline text */\n underline: boolean;\n /** Dim text */\n dim: boolean;\n /** Strikethrough text */\n strikethrough: boolean;\n /** Inverse colors */\n inverse: boolean;\n /**\n * Visual width of this cell.\n * - 1 for normal characters\n * - 2 for wide chars (CJK/emoji) — the next cell is a \"continuation\" cell\n * - 0 for continuation cells (second half of a wide char)\n */\n width: number;\n}\n\n/** Create a blank cell with default attributes */\nexport function emptyCell(): Cell {\n return {\n char: ' ',\n fg: EMPTY_COLOR,\n bg: EMPTY_COLOR,\n bold: false,\n italic: false,\n underline: false,\n dim: false,\n strikethrough: false,\n inverse: false,\n width: 1,\n };\n}\n\n/** Reset a cell in-place to default attributes (avoids allocation). */\nexport function resetCell(cell: Cell): void {\n cell.char = ' ';\n cell.fg = EMPTY_COLOR;\n cell.bg = EMPTY_COLOR;\n cell.bold = false;\n cell.italic = false;\n cell.underline = false;\n cell.dim = false;\n cell.strikethrough = false;\n cell.inverse = false;\n cell.width = 1;\n}\n\n/** Check if two cells are visually identical */\nexport function cellsEqual(a: Cell, b: Cell): boolean {\n return (\n a.char === b.char &&\n a.bold === b.bold &&\n a.italic === b.italic &&\n a.underline === b.underline &&\n a.dim === b.dim &&\n a.strikethrough === b.strikethrough &&\n a.inverse === b.inverse &&\n a.width === b.width &&\n colorsEqual(a.fg, b.fg) &&\n colorsEqual(a.bg, b.bg)\n );\n}\n\nfunction colorsEqual(a: Color, b: Color): boolean {\n if (a.type !== b.type) return false;\n switch (a.type) {\n case 'none': return true;\n case 'named': return a.name === (b as typeof a).name;\n case 'ansi256': return a.code === (b as typeof a).code;\n case 'rgb': return a.r === (b as typeof a).r && a.g === (b as typeof a).g && a.b === (b as typeof a).b;\n case 'hex': return a.hex === (b as typeof a).hex;\n }\n}\n\n/**\n * Double-buffered 2D cell grid for the terminal.\n *\n * - `front` = what's currently displayed on screen\n * - `back` = what we're building for the next frame\n *\n * After rendering, the renderer diffs `front` vs `back` and only emits\n * changes, then swaps the buffers.\n */\nexport class Screen {\n private _cols: number;\n private _rows: number;\n front: Cell[][];\n back: Cell[][];\n\n /**\n * Stack of clipping regions. When non-empty, setCell/writeString\n * only write to cells within the topmost clip rectangle.\n */\n private _clipStack: Array<{ x: number; y: number; width: number; height: number }> = [];\n\n constructor(cols: number, rows: number) {\n this._cols = cols;\n this._rows = rows;\n this.front = this._createGrid(cols, rows);\n this.back = this._createGrid(cols, rows);\n }\n\n get cols(): number { return this._cols; }\n get rows(): number { return this._rows; }\n\n /**\n * Push a clipping region onto the stack.\n * All subsequent setCell/writeString calls will be constrained\n * to cells within this rectangle. Clips are intersected with\n * any parent clip already on the stack (nested clipping).\n */\n pushClip(region: { x: number; y: number; width: number; height: number }): void {\n if (this._clipStack.length > 0) {\n // Intersect with the current clip\n const parent = this._clipStack[this._clipStack.length - 1];\n const x = Math.max(region.x, parent.x);\n const y = Math.max(region.y, parent.y);\n const right = Math.min(region.x + region.width, parent.x + parent.width);\n const bottom = Math.min(region.y + region.height, parent.y + parent.height);\n if (right <= x || bottom <= y) {\n // Fully clipped — push a zero-size region\n this._clipStack.push({ x: 0, y: 0, width: 0, height: 0 });\n } else {\n this._clipStack.push({ x, y, width: right - x, height: bottom - y });\n }\n } else {\n this._clipStack.push({ ...region });\n }\n }\n\n /**\n * Pop the most recent clipping region from the stack.\n */\n popClip(): void {\n this._clipStack.pop();\n }\n\n /**\n * Get the current active clip region, or null if no clip is active.\n */\n get activeClip(): { x: number; y: number; width: number; height: number } | null {\n return this._clipStack.length > 0\n ? this._clipStack[this._clipStack.length - 1]\n : null;\n }\n\n /**\n * Write a cell to the back buffer at position (col, row).\n */\n setCell(col: number, row: number, cell: Partial<Cell>): void {\n // Floor to integers — layout engine may produce fractional values\n col = Math.floor(col);\n row = Math.floor(row);\n // Use positive range check (NaN fails >= 0, preventing NaN indices)\n if (!(col >= 0 && col < this._cols && row >= 0 && row < this._rows)) return;\n\n // Enforce clip region\n if (this._clipStack.length > 0) {\n const clip = this._clipStack[this._clipStack.length - 1];\n if (col < clip.x || col >= clip.x + clip.width ||\n row < clip.y || row >= clip.y + clip.height) {\n return; // Outside active clip — silently discard\n }\n }\n\n const existing = this.back[row][col];\n Object.assign(existing, cell);\n }\n\n /**\n * Write a string to the back buffer starting at (col, row).\n * Applies the provided style attributes to each character.\n */\n writeString(\n col: number,\n row: number,\n str: string,\n style: Partial<Omit<Cell, 'char' | 'width'>> = {},\n ): void {\n row = Math.floor(row);\n col = Math.floor(col);\n if (!(row >= 0 && row < this._rows)) return;\n\n let x = col;\n for (const char of str) {\n if (x >= this._cols) break;\n if (x < 0) { x++; continue; }\n\n const cp = char.codePointAt(0)!;\n const isWide = this._isWideCodePoint(cp);\n const width = isWide ? 2 : 1;\n\n this.setCell(x, row, {\n char,\n width,\n ...style,\n });\n\n // If wide char, mark the next cell as a continuation\n if (isWide && x + 1 < this._cols) {\n this.setCell(x + 1, row, {\n char: '',\n width: 0,\n ...style,\n });\n x += 2;\n } else {\n x += 1;\n }\n }\n }\n\n /**\n * Clear the back buffer to all empty cells.\n */\n clear(): void {\n this._clipStack = [];\n for (let r = 0; r < this._rows; r++) {\n for (let c = 0; c < this._cols; c++) {\n resetCell(this.back[r][c]);\n }\n }\n }\n\n /**\n * Swap front and back buffers. Called after rendering diffs.\n */\n swap(): void {\n const temp = this.front;\n this.front = this.back;\n this.back = temp;\n }\n\n /**\n * Resize the screen. Clears both buffers.\n */\n resize(cols: number, rows: number): void {\n this._cols = cols;\n this._rows = rows;\n this.front = this._createGrid(cols, rows);\n this.back = this._createGrid(cols, rows);\n }\n\n /**\n * Clear the front buffer (marks everything as \"needs redraw\").\n */\n invalidate(): void {\n for (let r = 0; r < this._rows; r++) {\n for (let c = 0; c < this._cols; c++) {\n this.front[r][c] = { ...emptyCell(), char: '\\0' }; // force diff\n }\n }\n }\n\n private _createGrid(cols: number, rows: number): Cell[][] {\n const grid: Cell[][] = [];\n for (let r = 0; r < rows; r++) {\n const row: Cell[] = [];\n for (let c = 0; c < cols; c++) {\n row.push(emptyCell());\n }\n grid.push(row);\n }\n return grid;\n }\n\n private _isWideCodePoint(cp: number): boolean {\n return (\n (cp >= 0x4E00 && cp <= 0x9FFF) ||\n (cp >= 0x3400 && cp <= 0x4DBF) ||\n (cp >= 0xF900 && cp <= 0xFAFF) ||\n (cp >= 0xAC00 && cp <= 0xD7AF) ||\n (cp >= 0x30A0 && cp <= 0x30FF) ||\n (cp >= 0x3000 && cp <= 0x303F) ||\n (cp >= 0x3040 && cp <= 0x309F) ||\n (cp >= 0xFF01 && cp <= 0xFF60) ||\n (cp >= 0xFFE0 && cp <= 0xFFE6) ||\n (cp >= 0x1F600 && cp <= 0x1F64F) ||\n (cp >= 0x1F300 && cp <= 0x1F5FF) ||\n (cp >= 0x1F680 && cp <= 0x1F6FF) ||\n (cp >= 0x1F900 && cp <= 0x1F9FF) ||\n (cp >= 0x20000 && cp <= 0x2A6DF)\n );\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Differential Renderer\n// ─────────────────────────────────────────────────────\n\nimport type { Terminal } from './Terminal.js';\nimport { type Cell, cellsEqual, type Screen } from './Screen.js';\nimport { type ColorDepth, colorToAnsiFg, colorToAnsiBg } from '../style/Color.js';\nimport { moveTo, beginSyncUpdate, endSyncUpdate, reset as ansiReset } from '../utils/ansi.js';\n\n/**\n * Differential renderer — compares front/back screen buffers and\n * outputs only the changed cells. Uses synchronized output (CSI 2026)\n * for atomic, flicker-free updates.\n */\nexport class Renderer {\n private _terminal: Terminal;\n private _screen: Screen;\n private _fps: number;\n private _frameTimer: ReturnType<typeof setInterval> | null = null;\n private _renderRequested = false;\n private _colorDepth: ColorDepth;\n private _onTick: (() => void) | null = null;\n\n constructor(terminal: Terminal, screen: Screen, fps = 30) {\n this._terminal = terminal;\n this._screen = screen;\n this._fps = fps;\n this._colorDepth = terminal.colorDepth;\n }\n\n /** Change the rendering frame rate cap */\n setFPS(fps: number): void {\n this._fps = fps;\n if (this._frameTimer) {\n this.stop();\n this.start(this._onTick ?? undefined);\n }\n }\n\n /** Start the render loop */\n start(onTick?: () => void): void {\n if (this._frameTimer) return;\n this._onTick = onTick ?? null;\n const interval = Math.floor(1000 / this._fps);\n this._frameTimer = setInterval(() => {\n this._onTick?.();\n if (this._renderRequested) {\n this._renderRequested = false;\n this._flush();\n }\n }, interval);\n }\n\n /** Stop the render loop */\n stop(): void {\n if (this._frameTimer) {\n clearInterval(this._frameTimer);\n this._frameTimer = null;\n }\n }\n\n /** Request a render on the next frame */\n requestFrame(): void {\n this._renderRequested = true;\n }\n\n /** Force an immediate render (bypass frame rate) */\n renderNow(): void {\n this._flush();\n }\n\n /**\n * Full-screen clear and redraw (first render or after resize).\n */\n fullRender(): void {\n this._screen.invalidate();\n this._flush();\n }\n\n /**\n * Core diff and flush: compare front vs back buffer,\n * emit only changed cells.\n */\n private _flush(): void {\n const { front, back, cols, rows } = this._screen;\n let output = beginSyncUpdate;\n let lastRow = -1;\n let lastCol = -1;\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const frontCell = front[r][c];\n const backCell = back[r][c];\n\n if (cellsEqual(frontCell, backCell)) continue;\n\n // Skip continuation cells (second half of wide chars)\n if (backCell.width === 0) continue;\n\n // Move cursor only if not already at the right position\n if (r !== lastRow || c !== lastCol) {\n output += moveTo(c, r);\n }\n\n output += this._renderCell(backCell);\n lastRow = r;\n lastCol = c + (backCell.width === 2 ? 2 : 1);\n }\n }\n\n output += ansiReset;\n output += endSyncUpdate;\n\n this._terminal.write(output);\n this._screen.swap();\n }\n\n /**\n * Generate the ANSI escape sequence to render a single cell.\n */\n private _renderCell(cell: Cell): string {\n let seq = '';\n\n // Reset before applying new attributes\n seq += ansiReset;\n\n // Apply text decorations\n if (cell.bold) seq += '\\x1b[1m';\n if (cell.dim) seq += '\\x1b[2m';\n if (cell.italic) seq += '\\x1b[3m';\n if (cell.underline) seq += '\\x1b[4m';\n if (cell.strikethrough) seq += '\\x1b[9m';\n if (cell.inverse) seq += '\\x1b[7m';\n\n // Apply colors\n seq += colorToAnsiFg(cell.fg, this._colorDepth);\n seq += colorToAnsiBg(cell.bg, this._colorDepth);\n\n // Write the character\n seq += cell.char || ' ';\n\n return seq;\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Layer Manager for overlay rendering\n// ─────────────────────────────────────────────────────\n\nimport type { Cell } from './Screen.js';\nimport { emptyCell, type Screen } from './Screen.js';\nimport type { Color } from '../style/Color.js';\nimport type { Rect } from '../layout/Rect.js';\n\n/**\n * A rendering layer. Each layer has its own cell grid and z-index.\n * Higher z-index layers render on top of lower ones during compositing.\n */\nexport interface Layer {\n /** Unique identifier for this layer */\n id: string;\n /** Stacking order — higher renders on top */\n zIndex: number;\n /** Cell grid (same dimensions as Screen) */\n cells: Cell[][];\n /** Whether this layer is visible */\n visible: boolean;\n /** Bounding box of cells written since last clear (null = nothing dirty) */\n dirtyRegion: Rect | null;\n}\n\n/**\n * Check if a cell is \"transparent\" (should show through to the layer below).\n * An empty cell with no explicit colors is considered transparent.\n */\nfunction isCellTransparent(cell: Cell): boolean {\n return (\n cell.char === ' ' &&\n cell.fg.type === 'none' &&\n cell.bg.type === 'none' &&\n !cell.bold &&\n !cell.italic &&\n !cell.underline &&\n !cell.dim &&\n !cell.strikethrough &&\n !cell.inverse\n );\n}\n\n/**\n * Manages multiple rendering layers for overlay support.\n *\n * The base layer (z=0) is the primary widget layer — always opaque.\n * Overlay layers (z>0) support transparency: only cells explicitly\n * written to them overwrite the base layer during compositing.\n *\n * Typical z-index values:\n * - 0: Base widget layer\n * - 10: Dropdown menus\n * - 100: Modal dialogs\n * - 1000: Toasts / notifications\n */\nexport class LayerManager {\n private _layers: Map<string, Layer> = new Map();\n private _cols: number;\n private _rows: number;\n\n constructor(cols: number, rows: number) {\n this._cols = cols;\n this._rows = rows;\n }\n\n get cols(): number { return this._cols; }\n get rows(): number { return this._rows; }\n\n /**\n * Create a new overlay layer.\n * @param id Unique identifier (e.g. 'modal', 'select-dropdown', 'toast')\n * @param zIndex Stacking order (higher = rendered on top)\n */\n createLayer(id: string, zIndex: number): Layer {\n if (this._layers.has(id)) {\n return this._layers.get(id)!;\n }\n\n const layer: Layer = {\n id,\n zIndex,\n cells: this._createGrid(),\n visible: true,\n dirtyRegion: null,\n };\n\n this._layers.set(id, layer);\n return layer;\n }\n\n /**\n * Remove an overlay layer and clean up its resources.\n */\n removeLayer(id: string): void {\n this._layers.delete(id);\n }\n\n /**\n * Get a layer by ID.\n */\n getLayer(id: string): Layer | undefined {\n return this._layers.get(id);\n }\n\n /**\n * Check if a layer exists.\n */\n hasLayer(id: string): boolean {\n return this._layers.has(id);\n }\n\n /**\n * Get all layers sorted by z-index (ascending).\n */\n getSortedLayers(): Layer[] {\n return Array.from(this._layers.values())\n .filter(l => l.visible)\n .sort((a, b) => a.zIndex - b.zIndex);\n }\n\n /**\n * Write a cell to a specific layer.\n */\n setCell(layerId: string, col: number, row: number, cell: Partial<Cell>): void {\n const layer = this._layers.get(layerId);\n if (!layer) return;\n\n col = Math.floor(col);\n row = Math.floor(row);\n if (!(col >= 0 && col < this._cols && row >= 0 && row < this._rows)) return;\n\n const existing = layer.cells[row][col];\n Object.assign(existing, cell);\n\n // Expand dirty region\n this._expandDirty(layer, col, row);\n }\n\n /**\n * Write a string to a specific layer at position (col, row).\n */\n writeString(\n layerId: string,\n col: number,\n row: number,\n str: string,\n style: Partial<Omit<Cell, 'char' | 'width'>> = {},\n ): void {\n const layer = this._layers.get(layerId);\n if (!layer) return;\n\n row = Math.floor(row);\n col = Math.floor(col);\n if (!(row >= 0 && row < this._rows)) return;\n\n let x = col;\n for (const char of str) {\n if (x >= this._cols) break;\n if (x < 0) { x++; continue; }\n\n this.setCell(layerId, x, row, { char, width: 1, ...style });\n x++;\n }\n }\n\n /**\n * Clear all cells in a specific layer.\n */\n clearLayer(id: string): void {\n const layer = this._layers.get(id);\n if (!layer) return;\n\n for (let r = 0; r < this._rows; r++) {\n for (let c = 0; c < this._cols; c++) {\n layer.cells[r][c] = emptyCell();\n }\n }\n layer.dirtyRegion = null;\n }\n\n /**\n * Clear all overlay layers.\n */\n clearAll(): void {\n for (const layer of this._layers.values()) {\n this.clearLayer(layer.id);\n }\n }\n\n /**\n * Composite all overlay layers onto the Screen's back buffer.\n * Layers are applied in z-index order (lowest first).\n * Transparent cells (empty with no colors) are skipped.\n */\n composite(screen: Screen): void {\n const sorted = this.getSortedLayers();\n\n for (const layer of sorted) {\n if (!layer.dirtyRegion) continue; // Nothing to composite\n\n const { x: dx, y: dy, width: dw, height: dh } = layer.dirtyRegion;\n\n for (let r = dy; r < dy + dh && r < this._rows; r++) {\n for (let c = dx; c < dx + dw && c < this._cols; c++) {\n const cell = layer.cells[r][c];\n if (isCellTransparent(cell)) continue;\n\n // Write non-transparent overlay cell to the screen's back buffer\n screen.setCell(c, r, {\n char: cell.char,\n fg: cell.fg,\n bg: cell.bg,\n bold: cell.bold,\n italic: cell.italic,\n underline: cell.underline,\n dim: cell.dim,\n strikethrough: cell.strikethrough,\n inverse: cell.inverse,\n width: cell.width,\n });\n }\n }\n }\n }\n\n /**\n * Resize all layers when the terminal is resized.\n */\n resize(cols: number, rows: number): void {\n this._cols = cols;\n this._rows = rows;\n\n for (const layer of this._layers.values()) {\n layer.cells = this._createGrid();\n layer.dirtyRegion = null;\n }\n }\n\n /**\n * Create an empty cell grid.\n */\n private _createGrid(): Cell[][] {\n const grid: Cell[][] = [];\n for (let r = 0; r < this._rows; r++) {\n const row: Cell[] = [];\n for (let c = 0; c < this._cols; c++) {\n row.push(emptyCell());\n }\n grid.push(row);\n }\n return grid;\n }\n\n /**\n * Expand the dirty region of a layer to include the given cell.\n */\n private _expandDirty(layer: Layer, col: number, row: number): void {\n if (!layer.dirtyRegion) {\n layer.dirtyRegion = { x: col, y: row, width: 1, height: 1 };\n return;\n }\n\n const r = layer.dirtyRegion;\n const newX = Math.min(r.x, col);\n const newY = Math.min(r.y, row);\n const newRight = Math.max(r.x + r.width, col + 1);\n const newBottom = Math.max(r.y + r.height, row + 1);\n r.x = newX;\n r.y = newY;\n r.width = newRight - newX;\n r.height = newBottom - newY;\n }\n}\n","export const caps = {\n color: !process.env.NO_COLOR && process.env.TERM !== 'dumb',\n unicode: !process.env.NO_UNICODE && process.env.TERM !== 'dumb',\n motion: !process.env.NO_MOTION && !process.env.CI,\n ci: !!process.env.CI,\n} as const;\n","// Box-drawing unicode → ASCII fallback map\nexport const BOX: Record<string, string> = {\n '┌': '+', '┐': '+', '└': '+', '┘': '+',\n '─': '-', '│': '|', '├': '+', '┤': '+',\n '┬': '+', '┴': '+', '┼': '+',\n '═': '=', '║': '|', '╔': '+', '╗': '+', '╚': '+', '╝': '+',\n '╠': '+', '╣': '+', '╦': '+', '╩': '+', '╬': '+',\n};\n\n// Spinner fallback frames when unicode not available\nexport const BRAILLE_SPIN = ['|', '/', '-', '\\\\'] as const;\n\n// Block characters for progress bars\nexport const BLOCK = { full: '#', empty: ' ', partial: '-' } as const;\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Event types\n// ─────────────────────────────────────────────────────\n\n/**\n * Keyboard event emitted when a key is pressed.\n */\nexport interface KeyEvent {\n /** Human-readable key name: 'a', 'enter', 'up', 'f1', 'tab', etc. */\n key: string;\n /** Raw byte sequence from stdin */\n raw: Buffer;\n /** Ctrl modifier held */\n ctrl: boolean;\n /** Alt/Meta modifier held */\n alt: boolean;\n /** Shift modifier held */\n shift: boolean;\n /** The widget ID that currently has focus (target of the event) */\n targetId?: string;\n /** Whether propagation has been stopped */\n _propagationStopped?: boolean;\n /** Whether the default action has been prevented */\n _defaultPrevented?: boolean;\n /** Stop this event from bubbling to parent widgets */\n stopPropagation(): void;\n /** Prevent the default action for this event */\n preventDefault(): void;\n}\n\n/**\n * Create a KeyEvent with propagation control methods attached.\n */\nexport function createKeyEvent(base: {\n key: string;\n raw: Buffer;\n ctrl: boolean;\n alt: boolean;\n shift: boolean;\n targetId?: string;\n}): KeyEvent {\n const event: KeyEvent = {\n ...base,\n _propagationStopped: false,\n _defaultPrevented: false,\n stopPropagation() { this._propagationStopped = true; },\n preventDefault() { this._defaultPrevented = true; },\n };\n return event;\n}\n\n/**\n * Mouse event types.\n */\nexport type MouseEventType = 'mousedown' | 'mouseup' | 'mousemove' | 'scroll';\nexport type MouseButton = 'left' | 'middle' | 'right' | 'none';\n\n/**\n * Mouse event emitted when mouse activity is detected.\n */\nexport interface MouseEvent {\n /** x (column) position, 0-indexed */\n x: number;\n /** y (row) position, 0-indexed */\n y: number;\n /** Which mouse button */\n button: MouseButton;\n /** Type of mouse event */\n type: MouseEventType;\n /** Scroll direction (-1 = up, 1 = down) */\n scrollDelta?: number;\n}\n\n/**\n * Resize event emitted when the terminal is resized.\n */\nexport interface ResizeEvent {\n cols: number;\n rows: number;\n}\n\n/**\n * Focus event emitted when a widget gains or loses focus.\n */\nexport interface FocusEvent {\n /** Widget ID that is gaining or losing focus */\n targetId: string;\n /** Type of focus event */\n type: 'focus' | 'blur';\n}\n\n/**\n * Map of all event types to their data shapes.\n */\nexport interface EventMap {\n 'key': KeyEvent;\n 'mouse': MouseEvent;\n 'resize': ResizeEvent;\n 'focus': FocusEvent;\n 'blur': FocusEvent;\n 'render': void;\n 'mount': void;\n 'unmount': void;\n 'tick': number; // delta ms\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Key mapping constants\n// ─────────────────────────────────────────────────────\n\n/**\n * Maps raw byte sequences to human-readable key names.\n * These are standard VT100/xterm escape sequences.\n */\nexport const ESCAPE_SEQUENCES: Record<string, string> = {\n // Arrow keys\n '\\x1b[A': 'up',\n '\\x1b[B': 'down',\n '\\x1b[C': 'right',\n '\\x1b[D': 'left',\n\n // Shift+Arrow\n '\\x1b[1;2A': 'shift+up',\n '\\x1b[1;2B': 'shift+down',\n '\\x1b[1;2C': 'shift+right',\n '\\x1b[1;2D': 'shift+left',\n\n // Ctrl+Arrow\n '\\x1b[1;5A': 'ctrl+up',\n '\\x1b[1;5B': 'ctrl+down',\n '\\x1b[1;5C': 'ctrl+right',\n '\\x1b[1;5D': 'ctrl+left',\n\n // Alt+Arrow\n '\\x1b[1;3A': 'alt+up',\n '\\x1b[1;3B': 'alt+down',\n '\\x1b[1;3C': 'alt+right',\n '\\x1b[1;3D': 'alt+left',\n\n // Home/End/Insert/Delete/PageUp/PageDown\n '\\x1b[H': 'home',\n '\\x1b[F': 'end',\n '\\x1b[2~': 'insert',\n '\\x1b[3~': 'delete',\n '\\x1b[5~': 'pageup',\n '\\x1b[6~': 'pagedown',\n\n // Alternate Home/End (some terminals)\n '\\x1b[1~': 'home',\n '\\x1b[4~': 'end',\n '\\x1bOH': 'home',\n '\\x1bOF': 'end',\n\n // Function keys\n '\\x1bOP': 'f1',\n '\\x1bOQ': 'f2',\n '\\x1bOR': 'f3',\n '\\x1bOS': 'f4',\n '\\x1b[15~': 'f5',\n '\\x1b[17~': 'f6',\n '\\x1b[18~': 'f7',\n '\\x1b[19~': 'f8',\n '\\x1b[20~': 'f9',\n '\\x1b[21~': 'f10',\n '\\x1b[23~': 'f11',\n '\\x1b[24~': 'f12',\n\n // Special keys\n '\\x1b[Z': 'shift+tab',\n};\n\n/**\n * Maps control character codes (0x01-0x1A) to key names.\n * Ctrl+A = 0x01, Ctrl+B = 0x02, ... Ctrl+Z = 0x1A\n */\nexport const CTRL_KEYS: Record<number, string> = {\n 0x01: 'a', 0x02: 'b', 0x03: 'c', 0x04: 'd',\n 0x05: 'e', 0x06: 'f', 0x07: 'g', 0x08: 'backspace',\n 0x09: 'tab', 0x0A: 'enter', 0x0B: 'k', 0x0C: 'l',\n 0x0D: 'enter', 0x0E: 'n', 0x0F: 'o', 0x10: 'p',\n 0x11: 'q', 0x12: 'r', 0x13: 's', 0x14: 't',\n 0x15: 'u', 0x16: 'v', 0x17: 'w', 0x18: 'x',\n 0x19: 'y', 0x1A: 'z',\n};\n\n/**\n * Special single-byte key codes.\n */\nexport const SPECIAL_KEYS: Record<number, string> = {\n 0x1B: 'escape',\n 0x7F: 'backspace',\n 0x09: 'tab',\n 0x0D: 'enter',\n 0x0A: 'enter',\n 0x20: 'space',\n};\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Mouse event parser (SGR mode)\n// ─────────────────────────────────────────────────────\n\nimport type { MouseEvent, MouseButton, MouseEventType } from '../events/types.js';\n\n/**\n * Parse an SGR mouse event escape sequence.\n *\n * SGR format: ESC [ < Cb ; Cx ; Cy M (button press)\n * ESC [ < Cb ; Cx ; Cy m (button release)\n *\n * Where Cb encodes the button and modifiers, Cx/Cy are 1-based coordinates.\n *\n * @returns Parsed MouseEvent or null if not a mouse sequence.\n */\nexport function parseMouseEvent(data: string): MouseEvent | null {\n // SGR mouse: \\x1b[<Cb;Cx;Cy[Mm]\n const match = data.match(/^\\x1b\\[<(\\d+);(\\d+);(\\d+)([Mm])$/);\n if (!match) return null;\n\n const cb = parseInt(match[1], 10);\n const cx = parseInt(match[2], 10) - 1; // Convert to 0-based\n const cy = parseInt(match[3], 10) - 1;\n const isRelease = match[4] === 'm';\n\n let button: MouseButton;\n let type: MouseEventType;\n let scrollDelta: number | undefined;\n\n // Decode button from low 2 bits\n const buttonBits = cb & 0b11;\n const motion = (cb & 0b100000) !== 0;\n const isScroll = (cb & 0b1000000) !== 0;\n\n if (isScroll) {\n button = 'none';\n type = 'scroll';\n scrollDelta = buttonBits === 0 ? -1 : 1; // 0 = scroll up, 1 = scroll down\n } else if (motion) {\n type = 'mousemove';\n button = decodeButton(buttonBits);\n } else if (isRelease) {\n type = 'mouseup';\n button = decodeButton(buttonBits);\n } else {\n type = 'mousedown';\n button = decodeButton(buttonBits);\n }\n\n return {\n x: cx,\n y: cy,\n button,\n type,\n scrollDelta,\n };\n}\n\nfunction decodeButton(bits: number): MouseButton {\n switch (bits) {\n case 0: return 'left';\n case 1: return 'middle';\n case 2: return 'right';\n default: return 'none';\n }\n}\n\n/**\n * Check if a string looks like it could be a mouse sequence.\n */\nexport function isMouseSequence(data: string): boolean {\n return data.startsWith('\\x1b[<');\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Typed Event Emitter\n// ─────────────────────────────────────────────────────\n\n/**\n * Strongly-typed event emitter using TypeScript generics.\n * Supports `on`, `off`, `once`, `emit` with type-safe event maps.\n */\nexport class EventEmitter<TEventMap extends Record<string, any>> {\n private _handlers: Map<keyof TEventMap, Set<(data: any) => void>> = new Map();\n private _onceHandlers: Map<keyof TEventMap, Set<(data: any) => void>> = new Map();\n\n /**\n * Subscribe to an event.\n * @returns Unsubscribe function.\n */\n on<K extends keyof TEventMap>(event: K, handler: (data: TEventMap[K]) => void): () => void {\n if (!this._handlers.has(event)) {\n this._handlers.set(event, new Set());\n }\n this._handlers.get(event)!.add(handler);\n\n return () => this.off(event, handler);\n }\n\n /**\n * Subscribe to an event, but only fire once.\n */\n once<K extends keyof TEventMap>(event: K, handler: (data: TEventMap[K]) => void): () => void {\n if (!this._onceHandlers.has(event)) {\n this._onceHandlers.set(event, new Set());\n }\n this._onceHandlers.get(event)!.add(handler);\n\n return () => {\n this._onceHandlers.get(event)?.delete(handler);\n };\n }\n\n /**\n * Unsubscribe from an event.\n */\n off<K extends keyof TEventMap>(event: K, handler: (data: TEventMap[K]) => void): void {\n this._handlers.get(event)?.delete(handler);\n this._onceHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emit an event to all subscribed handlers.\n */\n emit<K extends keyof TEventMap>(event: K, data: TEventMap[K]): void {\n // Regular handlers\n const handlers = this._handlers.get(event);\n if (handlers) {\n for (const handler of handlers) {\n try { handler(data); } catch { /* prevent one handler from breaking others */ }\n }\n }\n\n // Once handlers — fire and remove\n const onceHandlers = this._onceHandlers.get(event);\n if (onceHandlers) {\n for (const handler of onceHandlers) {\n try { handler(data); } catch { /* prevent one handler from breaking others */ }\n }\n onceHandlers.clear();\n }\n }\n\n /**\n * Remove all handlers for a specific event, or all events if no event specified.\n */\n removeAll(event?: keyof TEventMap): void {\n if (event) {\n this._handlers.delete(event);\n this._onceHandlers.delete(event);\n } else {\n this._handlers.clear();\n this._onceHandlers.clear();\n }\n }\n\n /**\n * Check if there are any handlers for an event.\n */\n hasListeners(event: keyof TEventMap): boolean {\n return (\n (this._handlers.get(event)?.size ?? 0) > 0 ||\n (this._onceHandlers.get(event)?.size ?? 0) > 0\n );\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Input Parser\n// ─────────────────────────────────────────────────────\n\nimport type { KeyEvent, MouseEvent } from '../events/types.js';\nimport { createKeyEvent } from '../events/types.js';\nimport { ESCAPE_SEQUENCES, CTRL_KEYS, SPECIAL_KEYS } from './KeyMap.js';\nimport { parseMouseEvent, isMouseSequence } from './MouseParser.js';\nimport { EventEmitter } from '../events/EventEmitter.js';\n\ninterface InputEvents {\n key: KeyEvent;\n mouse: MouseEvent;\n}\n\n/**\n * Reads raw stdin bytes and parses them into typed KeyEvent / MouseEvent objects.\n * Handles escape sequences, multi-byte keys, ctrl+key, and SGR mouse events.\n */\nexport class InputParser {\n private _events = new EventEmitter<InputEvents>();\n private _stdin: NodeJS.ReadStream;\n private _handler: ((data: Buffer) => void) | null = null;\n private _escapeTimeout: ReturnType<typeof setTimeout> | null = null;\n private _escapeBuffer = '';\n\n constructor(stdin: NodeJS.ReadStream) {\n this._stdin = stdin;\n }\n\n /** Subscribe to key events */\n onKey(handler: (event: KeyEvent) => void): () => void {\n return this._events.on('key', handler);\n }\n\n /** Subscribe to mouse events */\n onMouse(handler: (event: MouseEvent) => void): () => void {\n return this._events.on('mouse', handler);\n }\n\n /** Start listening for input */\n start(): void {\n if (this._handler) return;\n\n this._handler = (data: Buffer) => {\n this._processInput(data);\n };\n\n this._stdin.on('data', this._handler);\n }\n\n /** Stop listening for input */\n stop(): void {\n if (this._handler) {\n this._stdin.off('data', this._handler);\n this._handler = null;\n }\n if (this._escapeTimeout) {\n clearTimeout(this._escapeTimeout);\n this._escapeTimeout = null;\n }\n this._escapeBuffer = '';\n }\n\n /**\n * Process a chunk of raw input bytes.\n */\n private _processInput(data: Buffer): void {\n const str = data.toString('utf8');\n\n // If we're collecting an escape sequence\n if (this._escapeBuffer) {\n this._escapeBuffer += str;\n if (this._escapeTimeout) {\n clearTimeout(this._escapeTimeout);\n this._escapeTimeout = null;\n }\n this._tryParseEscape(data);\n return;\n }\n\n // Check if this starts an escape sequence\n if (str.startsWith('\\x1b') && str.length === 1) {\n // Lone ESC — wait a bit to see if more bytes follow\n this._escapeBuffer = str;\n this._escapeTimeout = setTimeout(() => {\n // Timeout — it was a standalone Escape key\n this._events.emit('key', createKeyEvent({\n key: 'escape',\n raw: Buffer.from(this._escapeBuffer),\n ctrl: false,\n alt: false,\n shift: false,\n }));\n this._escapeBuffer = '';\n this._escapeTimeout = null;\n }, 50); // 50ms debounce for escape sequences\n return;\n }\n\n if (str.startsWith('\\x1b')) {\n this._escapeBuffer = str;\n this._tryParseEscape(data);\n return;\n }\n\n // Process each byte for non-escape input\n for (let i = 0; i < str.length; i++) {\n const ch = str[i];\n const code = str.charCodeAt(i);\n const raw = Buffer.from(ch, 'utf8');\n\n // Ctrl+key (0x01-0x1A, excluding tab/enter/backspace)\n if (code >= 0x01 && code <= 0x1A) {\n const keyName = CTRL_KEYS[code];\n const isCtrl = code !== 0x09 && code !== 0x0D && code !== 0x0A;\n this._events.emit('key', createKeyEvent({\n key: keyName || String.fromCharCode(code + 96),\n raw,\n ctrl: isCtrl,\n alt: false,\n shift: false,\n }));\n continue;\n }\n\n // Special keys\n if (code in SPECIAL_KEYS) {\n this._events.emit('key', createKeyEvent({\n key: SPECIAL_KEYS[code],\n raw,\n ctrl: false,\n alt: false,\n shift: false,\n }));\n continue;\n }\n\n // Regular printable character\n if (code >= 0x20) {\n this._events.emit('key', createKeyEvent({\n key: ch,\n raw,\n ctrl: false,\n alt: false,\n shift: ch !== ch.toLowerCase() && ch === ch.toUpperCase(),\n }));\n }\n }\n }\n\n /**\n * Try to parse buffered escape sequence.\n */\n private _tryParseEscape(rawData: Buffer): void {\n const seq = this._escapeBuffer;\n\n // Check for mouse event first\n if (isMouseSequence(seq)) {\n const mouseEvt = parseMouseEvent(seq);\n if (mouseEvt) {\n this._events.emit('mouse', mouseEvt);\n this._escapeBuffer = '';\n return;\n }\n // Might be incomplete mouse sequence — wait for more data\n if (seq.length < 20) { // safety cap\n if (this._escapeTimeout) {\n clearTimeout(this._escapeTimeout);\n this._escapeTimeout = null;\n }\n this._escapeTimeout = setTimeout(() => {\n this._escapeBuffer = '';\n this._escapeTimeout = null;\n }, 100);\n return;\n }\n }\n\n // Check known escape sequences\n if (seq in ESCAPE_SEQUENCES) {\n const keyName = ESCAPE_SEQUENCES[seq];\n const isShift = keyName.startsWith('shift+');\n const isCtrl = keyName.startsWith('ctrl+');\n const isAlt = keyName.startsWith('alt+');\n const cleanKey = keyName.replace(/^(shift|ctrl|alt)\\+/, '');\n\n this._events.emit('key', createKeyEvent({\n key: cleanKey,\n raw: rawData,\n ctrl: isCtrl,\n alt: isAlt,\n shift: isShift,\n }));\n this._escapeBuffer = '';\n return;\n }\n\n // Alt+key: ESC followed by a regular character\n if (seq.length === 2 && seq[0] === '\\x1b') {\n const ch = seq[1];\n this._events.emit('key', createKeyEvent({\n key: ch,\n raw: rawData,\n ctrl: false,\n alt: true,\n shift: ch !== ch.toLowerCase() && ch === ch.toUpperCase(),\n }));\n this._escapeBuffer = '';\n return;\n }\n\n // If the sequence is getting too long, give up\n if (seq.length > 20) {\n this._escapeBuffer = '';\n return;\n }\n\n // Wait for more bytes (might be an incomplete sequence)\n if (this._escapeTimeout) {\n clearTimeout(this._escapeTimeout);\n this._escapeTimeout = null;\n }\n this._escapeTimeout = setTimeout(() => {\n // Timeout — emit as unknown escape and clear\n this._escapeBuffer = '';\n this._escapeTimeout = null;\n }, 100);\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Style definition and merging\n// ─────────────────────────────────────────────────────\n\nimport type { Color } from './Color.js';\nimport type { BorderStyle } from './Border.js';\n\n/**\n * Edge values (padding, margin) — top, right, bottom, left.\n */\nexport interface Edges {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\n/**\n * Complete style definition for a widget.\n */\nexport interface Style {\n // ── Colors ──────────────\n fg?: Color;\n bg?: Color;\n\n // ── Text Decoration ─────\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n dim?: boolean;\n strikethrough?: boolean;\n inverse?: boolean;\n\n // ── Box Model ───────────\n padding?: Partial<Edges> | number;\n margin?: Partial<Edges> | number;\n border?: BorderStyle;\n borderColor?: Color;\n\n // ── Dimensions ──────────\n width?: number | string; // number = fixed chars, string = '50%'\n height?: number | string;\n minWidth?: number;\n minHeight?: number;\n maxWidth?: number;\n maxHeight?: number;\n\n // ── Flex Layout ─────────\n flexDirection?: 'row' | 'column';\n justifyContent?: 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around';\n alignItems?: 'flex-start' | 'flex-end' | 'center' | 'stretch';\n flexGrow?: number;\n flexShrink?: number;\n flexWrap?: 'nowrap' | 'wrap';\n gap?: number;\n\n // ── Overflow ────────────\n overflow?: 'visible' | 'hidden' | 'scroll';\n\n // ── Stacking ────────────\n /** Z-index for layer ordering. Higher values render on top. */\n zIndex?: number;\n\n // ── Focus ────────────────\n /** Color of the focus ring when this widget has focus */\n focusRingColor?: Color;\n /** Style of the focus ring indicator */\n focusRingStyle?: 'border' | 'corners' | 'glow' | 'none';\n\n // ── Visibility ──────────\n visible?: boolean;\n}\n\n/**\n * Normalize a shorthand edge value (number) into the full Edges object.\n */\nexport function normalizeEdges(value: Partial<Edges> | number | undefined): Edges {\n if (value === undefined) return { top: 0, right: 0, bottom: 0, left: 0 };\n if (typeof value === 'number') {\n return { top: value, right: value, bottom: value, left: value };\n }\n return {\n top: value.top ?? 0,\n right: value.right ?? 0,\n bottom: value.bottom ?? 0,\n left: value.left ?? 0,\n };\n}\n\n/**\n * Merge two styles. `override` values take precedence.\n * Undefined values in override do not overwrite base values.\n */\nexport function mergeStyles(base: Style, override: Style): Style {\n const result: Style = { ...base };\n\n for (const key of Object.keys(override) as Array<keyof Style>) {\n const val = override[key];\n if (val !== undefined) {\n (result as any)[key] = val;\n }\n }\n\n return result;\n}\n\n/**\n * Create a default (empty) style.\n */\nexport function defaultStyle(): Style {\n return {\n visible: true,\n flexDirection: 'column',\n justifyContent: 'flex-start',\n alignItems: 'stretch',\n flexGrow: 0,\n flexShrink: 1,\n flexWrap: 'nowrap',\n overflow: 'hidden',\n gap: 0,\n };\n}\n\n/**\n * Extract the cell-level style attributes from a Style object.\n * Used when rendering text into the screen buffer.\n */\nexport function styleToCellAttrs(style: Style): {\n fg: Color;\n bg: Color;\n bold: boolean;\n italic: boolean;\n underline: boolean;\n dim: boolean;\n strikethrough: boolean;\n inverse: boolean;\n} {\n return {\n fg: style.fg ?? { type: 'none' },\n bg: style.bg ?? { type: 'none' },\n bold: style.bold ?? false,\n italic: style.italic ?? false,\n underline: style.underline ?? false,\n dim: style.dim ?? false,\n strikethrough: style.strikethrough ?? false,\n inverse: style.inverse ?? false,\n };\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Border styles and rendering\n// ─────────────────────────────────────────────────────\n\n/**\n * Supported border styles.\n */\nexport type BorderStyle =\n | 'none'\n | 'single'\n | 'double'\n | 'round'\n | 'heavy'\n | 'dashed'\n | 'custom';\n\n/**\n * The characters used to draw a border.\n * Layout:\n * ```\n * topLeft ─── top ─── topRight\n * │ │\n * left content right\n * │ │\n * bottomLeft ─ bottom ─ bottomRight\n * ```\n */\nexport interface BorderChars {\n topLeft: string;\n top: string;\n topRight: string;\n right: string;\n bottomRight: string;\n bottom: string;\n bottomLeft: string;\n left: string;\n}\n\n/** Character maps for each border style */\nexport const BORDER_CHARS: Record<Exclude<BorderStyle, 'none' | 'custom'>, BorderChars> = {\n single: {\n topLeft: '┌', top: '─', topRight: '┐',\n right: '│', bottomRight: '┘', bottom: '─',\n bottomLeft: '└', left: '│',\n },\n double: {\n topLeft: '╔', top: '═', topRight: '╗',\n right: '║', bottomRight: '╝', bottom: '═',\n bottomLeft: '╚', left: '║',\n },\n round: {\n topLeft: '╭', top: '─', topRight: '╮',\n right: '│', bottomRight: '╯', bottom: '─',\n bottomLeft: '╰', left: '│',\n },\n heavy: {\n topLeft: '┏', top: '━', topRight: '┓',\n right: '┃', bottomRight: '┛', bottom: '━',\n bottomLeft: '┗', left: '┃',\n },\n dashed: {\n topLeft: '┌', top: '┄', topRight: '┐',\n right: '┆', bottomRight: '┘', bottom: '┄',\n bottomLeft: '└', left: '┆',\n },\n};\n\n/**\n * Get the border characters for a given style.\n */\nexport function getBorderChars(style: BorderStyle, customChars?: Partial<BorderChars>): BorderChars | null {\n if (style === 'none') return null;\n if (style === 'custom') {\n const base = BORDER_CHARS.single;\n return { ...base, ...customChars };\n }\n return BORDER_CHARS[style];\n}\n\n/**\n * Calculate the total space a border takes up.\n * Returns { horizontal, vertical } representing how many columns/rows\n * the border consumes (0 for none, 2 for any visible border — 1 on each side).\n */\nexport function borderSize(style: BorderStyle): { horizontal: number; vertical: number } {\n if (style === 'none') return { horizontal: 0, vertical: 0 };\n return { horizontal: 2, vertical: 2 };\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Flexbox-like Layout Engine\n// ─────────────────────────────────────────────────────\n\nimport type { Style } from '../style/Style.js';\nimport { normalizeEdges } from '../style/Style.js';\nimport { borderSize } from '../style/Border.js';\nimport type { Rect } from './Rect.js';\n\n/**\n * A node in the layout tree. Each widget produces one LayoutNode.\n */\nexport interface LayoutNode {\n /** Reference back to the widget/element that created this node */\n id: string;\n /** Style properties that affect layout */\n style: Style;\n /** Child nodes */\n children: LayoutNode[];\n /** Computed position and size — filled in by computeLayout() */\n computed: Rect;\n /** Dirty flag — true when this node needs to be re-laid-out. Foundation for layout caching. */\n _dirty: boolean;\n}\n\n/**\n * Create a LayoutNode with default values.\n */\nexport function createLayoutNode(id: string, style: Style, children: LayoutNode[] = []): LayoutNode {\n return {\n id,\n style,\n children,\n computed: { x: 0, y: 0, width: 0, height: 0 },\n _dirty: true,\n };\n}\n\n/**\n * Compute the layout of a tree of LayoutNodes.\n *\n * This is a simplified Flexbox implementation that handles:\n * - flexDirection: row | column\n * - justifyContent: flex-start | flex-end | center | space-between | space-around\n * - alignItems: flex-start | flex-end | center | stretch\n * - flexGrow / flexShrink\n * - padding, margin, border\n * - fixed width/height, percentage width/height\n * - minWidth, maxWidth, minHeight, maxHeight\n * - gap between children\n */\nexport function computeLayout(root: LayoutNode, containerWidth: number, containerHeight: number): void {\n root.computed = { x: 0, y: 0, width: containerWidth, height: containerHeight };\n layoutNode(root, containerWidth, containerHeight);\n}\n\nfunction layoutNode(node: LayoutNode, availWidth: number, availHeight: number, precomputed = false): void {\n const style = node.style;\n const padding = normalizeEdges(style.padding);\n const margin = normalizeEdges(style.margin);\n const border = borderSize(style.border ?? 'none');\n\n if (!precomputed) {\n // Calculate this node's dimensions\n let nodeWidth = resolveSize(style.width, availWidth);\n let nodeHeight = resolveSize(style.height, availHeight);\n\n // Apply constraints\n if (nodeWidth === undefined) nodeWidth = availWidth - margin.left - margin.right;\n if (nodeHeight === undefined) nodeHeight = availHeight - margin.top - margin.bottom;\n\n nodeWidth = clampSize(nodeWidth, style.minWidth, style.maxWidth);\n nodeHeight = clampSize(nodeHeight, style.minHeight, style.maxHeight);\n\n node.computed.width = nodeWidth;\n node.computed.height = nodeHeight;\n }\n\n if (node.children.length === 0) {\n node._dirty = false;\n return;\n }\n\n const nodeWidth = node.computed.width;\n const nodeHeight = node.computed.height;\n\n // Inner content area (after padding + border)\n const innerX = padding.left + (border.horizontal / 2);\n const innerY = padding.top + (border.vertical / 2);\n const innerWidth = Math.max(0, nodeWidth - padding.left - padding.right - border.horizontal);\n const innerHeight = Math.max(0, nodeHeight - padding.top - padding.bottom - border.vertical);\n\n const direction = style.flexDirection ?? 'column';\n const isRow = direction === 'row';\n const gap = style.gap ?? 0;\n\n // ── Phase 1: Measure children's desired sizes ──────\n\n const childInfos: Array<{\n node: LayoutNode;\n mainSize: number;\n crossSize: number;\n flexGrow: number;\n flexShrink: number;\n margin: { top: number; right: number; bottom: number; left: number };\n }> = [];\n\n let totalFixed = 0;\n let totalGrow = 0;\n let totalShrink = 0;\n\n for (const child of node.children) {\n if (child.style.visible === false) continue;\n\n const childMargin = normalizeEdges(child.style.margin);\n const childBorder = borderSize(child.style.border ?? 'none');\n const grow = child.style.flexGrow ?? 0;\n const shrink = child.style.flexShrink ?? 1;\n\n let mainSize: number;\n let crossSize: number;\n\n if (isRow) {\n mainSize = resolveSize(child.style.width, innerWidth) ?? 0;\n crossSize = resolveSize(child.style.height, innerHeight) ?? innerHeight;\n mainSize += childMargin.left + childMargin.right;\n crossSize = clampSize(crossSize, child.style.minHeight, child.style.maxHeight);\n } else {\n mainSize = resolveSize(child.style.height, innerHeight) ?? 0;\n crossSize = resolveSize(child.style.width, innerWidth) ?? innerWidth;\n mainSize += childMargin.top + childMargin.bottom;\n crossSize = clampSize(crossSize, child.style.minWidth, child.style.maxWidth);\n }\n\n totalFixed += mainSize;\n totalGrow += grow;\n totalShrink += shrink;\n\n childInfos.push({ node: child, mainSize, crossSize, flexGrow: grow, flexShrink: shrink, margin: childMargin });\n }\n\n const totalGaps = Math.max(0, childInfos.length - 1) * gap;\n const mainAvail = isRow ? innerWidth : innerHeight;\n const freeSpace = mainAvail - totalFixed - totalGaps;\n\n // ── Phase 2: Distribute free space (grow/shrink) ───\n\n if (freeSpace > 0 && totalGrow > 0) {\n for (const info of childInfos) {\n if (info.flexGrow > 0) {\n info.mainSize += (info.flexGrow / totalGrow) * freeSpace;\n }\n }\n } else if (freeSpace < 0 && totalShrink > 0) {\n for (const info of childInfos) {\n if (info.flexShrink > 0) {\n info.mainSize += (info.flexShrink / totalShrink) * freeSpace;\n info.mainSize = Math.max(0, info.mainSize);\n }\n }\n }\n\n // ── Phase 3: Position children ─────────────────────\n\n const totalMainUsed = childInfos.reduce((sum, i) => sum + i.mainSize, 0) + totalGaps;\n const remainingSpace = Math.max(0, mainAvail - totalMainUsed);\n\n let mainOffset: number;\n let spaceBetween = 0;\n\n const justify = style.justifyContent ?? 'flex-start';\n switch (justify) {\n case 'flex-start':\n mainOffset = 0;\n break;\n case 'flex-end':\n mainOffset = remainingSpace;\n break;\n case 'center':\n mainOffset = remainingSpace / 2;\n break;\n case 'space-between':\n mainOffset = 0;\n spaceBetween = childInfos.length > 1 ? remainingSpace / (childInfos.length - 1) : 0;\n break;\n case 'space-around':\n spaceBetween = childInfos.length > 0 ? remainingSpace / childInfos.length : 0;\n mainOffset = spaceBetween / 2;\n break;\n default:\n mainOffset = 0;\n }\n\n const crossAvail = isRow ? innerHeight : innerWidth;\n const align = style.alignItems ?? 'stretch';\n\n for (const info of childInfos) {\n // Cross axis alignment\n let crossOffset: number;\n let finalCrossSize = info.crossSize;\n\n switch (align) {\n case 'flex-start':\n crossOffset = 0;\n break;\n case 'flex-end':\n crossOffset = crossAvail - finalCrossSize;\n break;\n case 'center':\n crossOffset = (crossAvail - finalCrossSize) / 2;\n break;\n case 'stretch':\n crossOffset = 0;\n finalCrossSize = crossAvail;\n break;\n default:\n crossOffset = 0;\n }\n\n // Set computed rect\n if (isRow) {\n info.node.computed = {\n x: Math.floor(node.computed.x + innerX + mainOffset + info.margin.left),\n y: Math.floor(node.computed.y + innerY + crossOffset + info.margin.top),\n width: Math.round(Math.max(0, info.mainSize - info.margin.left - info.margin.right)),\n height: Math.round(Math.max(0, finalCrossSize - info.margin.top - info.margin.bottom)),\n };\n } else {\n info.node.computed = {\n x: Math.floor(node.computed.x + innerX + crossOffset + info.margin.left),\n y: Math.floor(node.computed.y + innerY + mainOffset + info.margin.top),\n width: Math.round(Math.max(0, finalCrossSize - info.margin.left - info.margin.right)),\n height: Math.round(Math.max(0, info.mainSize - info.margin.top - info.margin.bottom)),\n };\n }\n\n mainOffset += info.mainSize + gap + spaceBetween;\n\n // Recursively layout children — dimensions already set by parent\n layoutNode(info.node, info.node.computed.width, info.node.computed.height, true);\n }\n\n // Mark this node clean after layout is complete (used by future caching logic)\n node._dirty = false;\n}\n\n/**\n * Resolve a size value (fixed number or percentage string) to pixels.\n * Returns undefined if the value is not set.\n */\nfunction resolveSize(value: number | string | undefined, available: number): number | undefined {\n if (value === undefined) return undefined;\n if (typeof value === 'number') return value;\n if (typeof value === 'string' && value.endsWith('%')) {\n const pct = parseFloat(value) / 100;\n return Math.floor(available * pct);\n }\n return undefined;\n}\n\n/**\n * Clamp a size to min/max bounds.\n */\nfunction clampSize(value: number, min?: number, max?: number): number {\n let result = value;\n if (min !== undefined) result = Math.max(result, min);\n if (max !== undefined) result = Math.min(result, max);\n return result;\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Layout types (Rect, Size, Edges)\n// ─────────────────────────────────────────────────────\n\n/**\n * A computed rectangle with position and size.\n */\nexport interface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * A 2D size.\n */\nexport interface Size {\n width: number;\n height: number;\n}\n\n/**\n * Create an empty rect at origin.\n */\nexport function emptyRect(): Rect {\n return { x: 0, y: 0, width: 0, height: 0 };\n}\n\n/**\n * Check if a point is inside a rect.\n */\nexport function containsPoint(rect: Rect, x: number, y: number): boolean {\n return x >= rect.x && x < rect.x + rect.width &&\n y >= rect.y && y < rect.y + rect.height;\n}\n\n/**\n * Shrink a rect by the given edges (inset).\n */\nexport function shrinkRect(rect: Rect, top: number, right: number, bottom: number, left: number): Rect {\n return {\n x: rect.x + left,\n y: rect.y + top,\n width: Math.max(0, rect.width - left - right),\n height: Math.max(0, rect.height - top - bottom),\n };\n}\n\n/**\n * Intersect two rects. Returns the overlapping region, or null if disjoint.\n */\nexport function intersectRect(a: Rect, b: Rect): Rect | null {\n const x = Math.max(a.x, b.x);\n const y = Math.max(a.y, b.y);\n const r = Math.min(a.x + a.width, b.x + b.width);\n const bot = Math.min(a.y + a.height, b.y + b.height);\n if (r <= x || bot <= y) return null;\n return { x, y, width: r - x, height: bot - y };\n}\n\n/**\n * Union two rects into the smallest bounding rect that contains both.\n */\nexport function unionRect(a: Rect, b: Rect): Rect {\n const x = Math.min(a.x, b.x);\n const y = Math.min(a.y, b.y);\n const r = Math.max(a.x + a.width, b.x + b.width);\n const bot = Math.max(a.y + a.height, b.y + b.height);\n return { x, y, width: r - x, height: bot - y };\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Constraint-based Layout\n// Alternative to flexbox for dashboard-style splits.\n// ─────────────────────────────────────────────────────\n\nimport type { Rect } from './Rect.js';\n\n// ── Constraint Types ─────────────────────────────────\n\nexport type Constraint =\n | { type: 'length'; value: number }\n | { type: 'percentage'; value: number }\n | { type: 'ratio'; num: number; den: number }\n | { type: 'min'; value: number }\n | { type: 'max'; value: number }\n | { type: 'fill'; weight: number };\n\n// ── Constraint Factories ─────────────────────────────\n\n/** Exactly n cells. */\nexport const length = (n: number): Constraint => ({ type: 'length', value: n });\n\n/** n% of available space. */\nexport const percentage = (n: number): Constraint => ({ type: 'percentage', value: n });\n\n/** num/den of available space. */\nexport const ratio = (num: number, den: number): Constraint => ({ type: 'ratio', num, den });\n\n/** At least n cells. */\nexport const min = (n: number): Constraint => ({ type: 'min', value: n });\n\n/** At most n cells. */\nexport const max = (n: number): Constraint => ({ type: 'max', value: n });\n\n/** Fill remaining space with the given weight. Default weight: 1. */\nexport const fill = (weight: number = 1): Constraint => ({ type: 'fill', weight });\n\n// ── Solver ───────────────────────────────────────────\n\nfunction resolveSize(constraint: Constraint, available: number): number {\n switch (constraint.type) {\n case 'length': return Math.min(constraint.value, available);\n case 'percentage': return Math.min(Math.floor((available * constraint.value) / 100), available);\n case 'ratio': return constraint.den === 0 ? 0 : Math.min(\n Math.floor((available * constraint.num) / constraint.den), available\n );\n case 'min': return constraint.value;\n case 'max': return Math.min(constraint.value, available);\n case 'fill': return 0; // resolved in second pass\n }\n}\n\n/**\n * Split a rectangle into sub-rectangles using constraints.\n *\n * Example:\n * ```ts\n * const [header, body, footer] = splitRect(\n * area,\n * [length(3), fill(), length(1)],\n * 'vertical',\n * );\n * ```\n */\nexport function splitRect(\n rect: Rect,\n constraints: Constraint[],\n direction: 'horizontal' | 'vertical' = 'vertical',\n gap: number = 0,\n): Rect[] {\n if (constraints.length === 0) return [];\n\n const totalAvailable = direction === 'horizontal' ? rect.width : rect.height;\n const count = constraints.length;\n const totalGaps = count > 1 ? gap * (count - 1) : 0;\n const availableForConstraints = Math.max(0, totalAvailable - totalGaps);\n\n // First pass: resolve non-fill constraints\n const sizes: number[] = [];\n let usedSpace = 0;\n let fillWeightSum = 0;\n\n for (const constraint of constraints) {\n if (constraint.type === 'fill') {\n sizes.push(0);\n fillWeightSum += Math.max(1, constraint.weight);\n } else {\n const size = resolveSize(constraint, availableForConstraints);\n sizes.push(size);\n usedSpace += size;\n }\n }\n\n // Second pass: distribute remaining space to fill constraints\n if (fillWeightSum > 0) {\n const remaining = Math.max(0, availableForConstraints - usedSpace);\n let distributed = 0;\n\n for (let i = 0; i < count; i++) {\n const constraint = constraints[i];\n if (!constraint || constraint.type !== 'fill') continue;\n\n const weight = Math.max(1, constraint.weight);\n const share = Math.floor((remaining * weight) / fillWeightSum);\n sizes[i] = share;\n distributed += share;\n }\n\n // Give leftover pixels to the last fill constraint\n const leftover = remaining - distributed;\n if (leftover > 0) {\n for (let i = count - 1; i >= 0; i--) {\n const constraint = constraints[i];\n if (constraint && constraint.type === 'fill') {\n sizes[i] = (sizes[i] ?? 0) + leftover;\n break;\n }\n }\n }\n }\n\n // Clamp so total doesn't exceed available\n let totalUsed = 0;\n for (let i = 0; i < count; i++) {\n const size = sizes[i] ?? 0;\n const clamped = Math.max(0, Math.min(size, availableForConstraints - totalUsed));\n sizes[i] = clamped;\n totalUsed += clamped;\n }\n\n // Build result rects\n const results: Rect[] = [];\n let offset = 0;\n\n for (let i = 0; i < count; i++) {\n const size = sizes[i] ?? 0;\n\n if (direction === 'horizontal') {\n results.push({ x: rect.x + offset, y: rect.y, width: size, height: rect.height });\n } else {\n results.push({ x: rect.x, y: rect.y + offset, width: rect.width, height: size });\n }\n\n offset += size + gap;\n }\n\n return results;\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Focus Manager\n// ─────────────────────────────────────────────────────\n\nimport { EventEmitter } from './EventEmitter.js';\nimport type { FocusEvent } from './types.js';\n\nexport interface Focusable {\n id: string;\n tabIndex: number;\n focusable: boolean;\n}\n\n/**\n * Manages tab-order focus cycling between focusable widgets.\n * Dispatches focus/blur events when focus changes.\n *\n * Supports:\n * - Tab-order cycling (focusNext/focusPrev)\n * - Focus trapping (for modals — limits Tab to a container)\n * - Focus groups (for arrow-key navigation within a group)\n */\nexport class FocusManager {\n private _focusables: Focusable[] = [];\n private _currentIndex = -1;\n private _events = new EventEmitter<{ focus: FocusEvent; blur: FocusEvent }>();\n\n /**\n * Stack of trap container IDs. When non-empty, only focusables\n * that belong to the topmost trap container are reachable via Tab.\n */\n private _trapStack: string[] = [];\n\n /**\n * Map of container ID → child widget IDs that belong to it.\n * Used for trap membership lookup.\n */\n private _containerMembers: Map<string, Set<string>> = new Map();\n\n /**\n * Named focus groups. Arrow keys move within a group, Tab moves between groups.\n * Maps groupId → ordered list of widget IDs.\n */\n private _groups: Map<string, string[]> = new Map();\n\n /** Currently focused widget ID, or null if none */\n get currentId(): string | null {\n if (this._currentIndex < 0 || this._currentIndex >= this._focusables.length) {\n return null;\n }\n return this._focusables[this._currentIndex].id;\n }\n\n /** Subscribe to focus/blur events */\n on<K extends 'focus' | 'blur'>(event: K, handler: (data: FocusEvent) => void): () => void {\n return this._events.on(event, handler);\n }\n\n /**\n * Register a focusable widget.\n * Widgets are ordered by tabIndex (ascending), then insertion order.\n */\n register(focusable: Focusable): void {\n this._focusables.push(focusable);\n this._focusables.sort((a, b) => a.tabIndex - b.tabIndex);\n\n // Auto-focus the first widget if nothing is focused\n if (this._currentIndex < 0 && focusable.focusable) {\n this._currentIndex = this._focusables.indexOf(focusable);\n this._events.emit('focus', { targetId: focusable.id, type: 'focus' });\n }\n }\n\n /**\n * Unregister a focusable widget.\n */\n unregister(id: string): void {\n const idx = this._focusables.findIndex(f => f.id === id);\n if (idx < 0) return;\n\n const wasFocused = idx === this._currentIndex;\n this._focusables.splice(idx, 1);\n\n if (wasFocused) {\n this._events.emit('blur', { targetId: id, type: 'blur' });\n // Try to focus the next widget\n if (this._focusables.length > 0) {\n this._currentIndex = Math.min(this._currentIndex, this._focusables.length - 1);\n this._events.emit('focus', {\n targetId: this._focusables[this._currentIndex].id,\n type: 'focus',\n });\n } else {\n this._currentIndex = -1;\n }\n } else if (idx < this._currentIndex) {\n this._currentIndex--;\n }\n }\n\n /**\n * Move focus to the next focusable widget (wraps around).\n * Respects focus traps — if a trap is active, only cycles within it.\n */\n focusNext(): void {\n const candidates = this._getActiveFocusables();\n if (candidates.length === 0) return;\n\n const currentInCandidates = this.currentId\n ? candidates.findIndex(f => f.id === this.currentId)\n : -1;\n\n let next = (currentInCandidates + 1) % candidates.length;\n const start = next;\n\n // Skip non-focusable widgets\n while (!candidates[next].focusable) {\n next = (next + 1) % candidates.length;\n if (next === start) return; // All non-focusable\n }\n\n // Find this candidate's index in the master list\n const masterIdx = this._focusables.findIndex(f => f.id === candidates[next].id);\n if (masterIdx >= 0) this._changeFocus(masterIdx);\n }\n\n /**\n * Move focus to the previous focusable widget (wraps around).\n * Respects focus traps.\n */\n focusPrev(): void {\n const candidates = this._getActiveFocusables();\n if (candidates.length === 0) return;\n\n const currentInCandidates = this.currentId\n ? candidates.findIndex(f => f.id === this.currentId)\n : 0;\n\n let prev = (currentInCandidates - 1 + candidates.length) % candidates.length;\n const start = prev;\n\n while (!candidates[prev].focusable) {\n prev = (prev - 1 + candidates.length) % candidates.length;\n if (prev === start) return;\n }\n\n const masterIdx = this._focusables.findIndex(f => f.id === candidates[prev].id);\n if (masterIdx >= 0) this._changeFocus(masterIdx);\n }\n\n /**\n * Focus a specific widget by ID.\n */\n focusWidget(id: string): void {\n const idx = this._focusables.findIndex(f => f.id === id);\n if (idx < 0 || !this._focusables[idx].focusable) return;\n this._changeFocus(idx);\n }\n\n /**\n * Check if a specific widget currently has focus.\n */\n isFocused(id: string): boolean {\n return this.currentId === id;\n }\n\n // ── Focus Trap ──────────────────────────────────────\n\n /**\n * Register widget IDs as members of a container (for trap lookup).\n */\n registerContainerMembers(containerId: string, memberIds: string[]): void {\n const set = this._containerMembers.get(containerId) ?? new Set();\n for (const id of memberIds) set.add(id);\n this._containerMembers.set(containerId, set);\n }\n\n /**\n * Unregister a container's member list.\n */\n unregisterContainerMembers(containerId: string): void {\n this._containerMembers.delete(containerId);\n }\n\n /**\n * Trap focus within a container. Only focusables inside the\n * container are reachable via Tab. Traps are stacked —\n * nested modals create nested traps.\n */\n trap(containerId: string): void {\n this._trapStack.push(containerId);\n\n // Focus the first focusable inside the trap\n const trapped = this._getActiveFocusables();\n if (trapped.length > 0) {\n const first = trapped.find(f => f.focusable);\n if (first) {\n const idx = this._focusables.findIndex(f => f.id === first.id);\n if (idx >= 0) this._changeFocus(idx);\n }\n }\n }\n\n /**\n * Release the current focus trap. Restores previous trap or free navigation.\n */\n release(): void {\n this._trapStack.pop();\n }\n\n /** Whether a focus trap is currently active */\n get isTrapped(): boolean {\n return this._trapStack.length > 0;\n }\n\n /** ID of the current trap container, or null */\n get currentTrapId(): string | null {\n return this._trapStack.length > 0\n ? this._trapStack[this._trapStack.length - 1]\n : null;\n }\n\n // ── Focus Groups ────────────────────────────────────\n\n /**\n * Register a focus group. Arrow keys move within the group.\n * @param groupId Unique group identifier\n * @param widgetIds Ordered list of widget IDs in the group\n */\n registerGroup(groupId: string, widgetIds: string[]): void {\n this._groups.set(groupId, widgetIds);\n }\n\n /**\n * Unregister a focus group.\n */\n unregisterGroup(groupId: string): void {\n this._groups.delete(groupId);\n }\n\n /**\n * Move focus to the next widget within the same group.\n * Returns true if focus was moved, false if the widget isn't in a group.\n */\n focusNextInGroup(): boolean {\n const currentId = this.currentId;\n if (!currentId) return false;\n\n for (const [, ids] of this._groups) {\n const idx = ids.indexOf(currentId);\n if (idx >= 0) {\n const nextIdx = (idx + 1) % ids.length;\n this.focusWidget(ids[nextIdx]);\n return true;\n }\n }\n return false;\n }\n\n /**\n * Move focus to the previous widget within the same group.\n */\n focusPrevInGroup(): boolean {\n const currentId = this.currentId;\n if (!currentId) return false;\n\n for (const [, ids] of this._groups) {\n const idx = ids.indexOf(currentId);\n if (idx >= 0) {\n const prevIdx = (idx - 1 + ids.length) % ids.length;\n this.focusWidget(ids[prevIdx]);\n return true;\n }\n }\n return false;\n }\n\n // ── Private ──────────────────────────────────────────\n\n /**\n * Get the active focusables, filtered by the current trap if any.\n */\n private _getActiveFocusables(): Focusable[] {\n if (this._trapStack.length === 0) return this._focusables;\n\n const containerId = this._trapStack[this._trapStack.length - 1];\n const members = this._containerMembers.get(containerId);\n if (!members) return this._focusables;\n\n return this._focusables.filter(f => members.has(f.id));\n }\n\n private _changeFocus(newIndex: number): void {\n const oldId = this.currentId;\n if (oldId) {\n this._events.emit('blur', { targetId: oldId, type: 'blur' });\n }\n this._currentIndex = newIndex;\n this._events.emit('focus', {\n targetId: this._focusables[newIndex].id,\n type: 'focus',\n });\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Unicode Symbol Sets\n// ─────────────────────────────────────────────────────\n\n// ── Border Sets ──────────────────────────────────────\n\nexport interface BorderSet {\n topLeft: string;\n topRight: string;\n bottomLeft: string;\n bottomRight: string;\n horizontal: string;\n vertical: string;\n cross: string;\n}\n\nexport const BorderSets = {\n PLAIN: {\n topLeft: '┌', topRight: '┐', bottomLeft: '└', bottomRight: '┘',\n horizontal: '─', vertical: '│', cross: '┼',\n },\n ROUNDED: {\n topLeft: '╭', topRight: '╮', bottomLeft: '╰', bottomRight: '╯',\n horizontal: '─', vertical: '│', cross: '┼',\n },\n DOUBLE: {\n topLeft: '╔', topRight: '╗', bottomLeft: '╚', bottomRight: '╝',\n horizontal: '═', vertical: '║', cross: '╬',\n },\n THICK: {\n topLeft: '┏', topRight: '┓', bottomLeft: '┗', bottomRight: '┛',\n horizontal: '━', vertical: '┃', cross: '╋',\n },\n QUADRANT_INSIDE: {\n topLeft: '▗', topRight: '▖', bottomLeft: '▝', bottomRight: '▘',\n horizontal: '▀', vertical: '▐', cross: '█',\n },\n QUADRANT_OUTSIDE: {\n topLeft: '▛', topRight: '▜', bottomLeft: '▙', bottomRight: '▟',\n horizontal: '▀', vertical: '▌', cross: '█',\n },\n EMPTY: {\n topLeft: ' ', topRight: ' ', bottomLeft: ' ', bottomRight: ' ',\n horizontal: ' ', vertical: ' ', cross: ' ',\n },\n} as const satisfies Record<string, BorderSet>;\n\n// ── Bar Chart Symbol Sets ────────────────────────────\n\nexport interface BarSet {\n full: string;\n sevenEighths: string;\n threeQuarters: string;\n fiveEighths: string;\n half: string;\n threeEighths: string;\n oneQuarter: string;\n oneEighth: string;\n empty: string;\n}\n\n/**\n * Vertical bar symbols: bottom-up block characters ▁▂▃▄▅▆▇█\n * 9 levels (including empty) for sub-cell precision.\n */\nexport const BarSets = {\n NINE_LEVELS: {\n full: '█', sevenEighths: '▇', threeQuarters: '▆', fiveEighths: '▅',\n half: '▄', threeEighths: '▃', oneQuarter: '▂', oneEighth: '▁', empty: ' ',\n },\n THREE_LEVELS: {\n full: '█', sevenEighths: '░', threeQuarters: '░', fiveEighths: '░',\n half: '▄', threeEighths: '░', oneQuarter: '░', oneEighth: '░', empty: ' ',\n },\n ASCII: {\n full: '#', sevenEighths: '#', threeQuarters: '#', fiveEighths: '#',\n half: '#', threeEighths: '-', oneQuarter: '-', oneEighth: '-', empty: ' ',\n },\n} as const satisfies Record<string, BarSet>;\n\n/** Ordered vertical bar symbols from empty to full (9 levels). */\nexport const VERTICAL_BAR_SYMBOLS: readonly string[] = [\n ' ', '▁', '▂', '▃', '▄', '▅', '▆', '▇', '█',\n];\n\n/** Ordered horizontal bar symbols from empty to full (9 levels). */\nexport const HORIZONTAL_BAR_SYMBOLS: readonly string[] = [\n ' ', '\\u258F', '\\u258E', '\\u258D', '\\u258C', '\\u258B', '\\u258A', '\\u2589', '\\u2588',\n];\n\n// ── Scrollbar Symbol Sets ────────────────────────────\n\nexport interface ScrollbarSet {\n track: string;\n thumb: string;\n begin: string;\n end: string;\n}\n\nexport const ScrollbarSets = {\n VERTICAL: { track: '│', thumb: '█', begin: '↑', end: '↓' },\n HORIZONTAL: { track: '─', thumb: '█', begin: '←', end: '→' },\n DOUBLE_VERTICAL: { track: '║', thumb: '▐', begin: '▲', end: '▼' },\n DOUBLE_HORIZONTAL: { track: '═', thumb: '▌', begin: '◄', end: '►' },\n} as const satisfies Record<string, ScrollbarSet>;\n\n// ── Line Symbol Sets ─────────────────────────────────\n\nexport interface LineSet {\n horizontal: string;\n vertical: string;\n cross: string;\n}\n\nexport const LineSets = {\n NORMAL: { horizontal: '─', vertical: '│', cross: '┼' },\n THICK: { horizontal: '━', vertical: '┃', cross: '╋' },\n DOUBLE: { horizontal: '═', vertical: '║', cross: '╬' },\n} as const satisfies Record<string, LineSet>;\n\n// ── Shade Symbols ────────────────────────────────────\n\nexport const Shade = {\n FULL: '█',\n DARK: '▓',\n MEDIUM: '▒',\n LIGHT: '░',\n EMPTY: ' ',\n} as const;\n\n// ── Braille Constants ────────────────────────────────\n\n/** Unicode braille range offset (U+2800). */\nexport const BRAILLE_OFFSET = 0x2800;\n\n/**\n * Braille dot bit positions.\n * Each row is [leftBit, rightBit] for a 2-wide, 4-tall braille cell.\n */\nexport const BRAILLE_DOTS: readonly (readonly [number, number])[] = [\n [0x01, 0x08],\n [0x02, 0x10],\n [0x04, 0x20],\n [0x40, 0x80],\n] as const;\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Test Backend\n// In-memory rendering for snapshot testing.\n// ─────────────────────────────────────────────────────\n\nimport type { Cell } from './Screen.js';\nimport { emptyCell } from './Screen.js';\n\n/**\n * In-memory grid that captures rendered output.\n * Use `createTestScreen()` to create one, render widgets into it,\n * then call `testScreenToString()` to get a plain-text snapshot.\n */\nexport interface TestScreen {\n readonly width: number;\n readonly height: number;\n cells: Cell[][];\n}\n\n/**\n * Create an in-memory test screen of the given dimensions.\n * Every cell starts as empty (space character, default colors).\n */\nexport function createTestScreen(width: number, height: number): TestScreen {\n const cells: Cell[][] = [];\n for (let row = 0; row < height; row++) {\n const rowCells: Cell[] = [];\n for (let col = 0; col < width; col++) {\n rowCells.push(emptyCell());\n }\n cells.push(rowCells);\n }\n return { width, height, cells };\n}\n\n/**\n * Set a cell in the test screen at (x, y).\n * Out-of-bounds writes are silently ignored.\n */\nexport function testScreenSetCell(screen: TestScreen, x: number, y: number, cell: Cell): void {\n if (x < 0 || x >= screen.width || y < 0 || y >= screen.height) {\n return;\n }\n const row = screen.cells[y];\n if (row) {\n row[x] = cell;\n }\n}\n\n/**\n * Get the cell at (x, y) in the test screen.\n * Returns undefined for out-of-bounds coordinates.\n */\nexport function testScreenGetCell(screen: TestScreen, x: number, y: number): Cell | undefined {\n if (x < 0 || x >= screen.width || y < 0 || y >= screen.height) {\n return undefined;\n }\n const row = screen.cells[y];\n return row ? row[x] : undefined;\n}\n\n/**\n * Convert the test screen to a plain-text string.\n * Each row becomes a line. Trailing spaces on each line are preserved.\n *\n * Example output:\n * ```\n * ┌Hello──┐\n * │World │\n * └───────┘\n * ```\n */\nexport function testScreenToString(screen: TestScreen): string {\n return screen.cells\n .map(row => row.map(cell => cell.char).join(''))\n .join('\\n');\n}\n\n/**\n * Clear the test screen, resetting all cells to empty.\n */\nexport function testScreenClear(screen: TestScreen): void {\n for (let y = 0; y < screen.height; y++) {\n const row = screen.cells[y];\n if (row) {\n for (let x = 0; x < screen.width; x++) {\n row[x] = emptyCell();\n }\n }\n }\n}\n\n/**\n * Write a string into the test screen starting at (x, y).\n * Characters that fall outside the screen bounds are clipped.\n */\nexport function testScreenSetString(\n screen: TestScreen,\n x: number,\n y: number,\n str: string,\n): void {\n let cx = x;\n for (const ch of str) {\n if (cx >= screen.width) break;\n if (cx >= 0 && y >= 0 && y < screen.height) {\n const row = screen.cells[y];\n if (row) {\n const cell = emptyCell();\n cell.char = ch;\n row[cx] = cell;\n }\n }\n cx++;\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Fallback (static) renderer for CI/pipes\n// ─────────────────────────────────────────────────────\n\nimport type { Screen } from '../terminal/Screen.js';\nimport { stripAnsi } from '../utils/unicode.js';\n\n/**\n * Detect if the terminal should use fallback (non-interactive) rendering.\n *\n * Returns true when:\n * - stdout is not a TTY (piped)\n * - CI environment variable is set\n * - TERM is 'dumb'\n * - NO_COLOR is set\n */\nexport function shouldUseFallback(): boolean {\n if (!process.stdout.isTTY) return true;\n if (process.env['CI']) return true;\n if (process.env['TERM'] === 'dumb') return true;\n return false;\n}\n\n/**\n * Render a Screen buffer as plain text (no ANSI, no interactivity).\n *\n * Reads all cells from the screen and produces a simple text representation.\n * Strips trailing whitespace from each line and removes empty trailing lines.\n */\nexport function renderFallback(screen: Screen): string {\n const lines: string[] = [];\n\n for (let r = 0; r < screen.rows; r++) {\n let line = '';\n for (let c = 0; c < screen.cols; c++) {\n const cell = screen.back[r][c];\n if (cell.width === 0) continue; // Skip continuation cells\n line += cell.char || ' ';\n }\n lines.push(line.trimEnd());\n }\n\n // Remove empty trailing lines\n while (lines.length > 0 && lines[lines.length - 1] === '') {\n lines.pop();\n }\n\n return lines.join('\\n');\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Application lifecycle manager\n// ─────────────────────────────────────────────────────\n\nimport { Terminal, type TerminalOptions } from '../terminal/Terminal.js';\nimport { Screen } from '../terminal/Screen.js';\nimport { Renderer } from '../terminal/Renderer.js';\nimport { LayerManager } from '../terminal/LayerManager.js';\nimport { InputParser } from '../input/InputParser.js';\nimport { FocusManager } from '../events/FocusManager.js';\nimport { EventEmitter } from '../events/EventEmitter.js';\nimport { computeLayout, type LayoutNode } from '../layout/LayoutEngine.js';\nimport type { EventMap } from '../events/types.js';\nimport { createKeyEvent } from '../events/types.js';\nimport { renderFallback, shouldUseFallback } from './Fallback.js';\n\nexport interface AppOptions extends TerminalOptions {\n /** Frames per second for the render loop */\n fps?: number;\n /** Use alternate screen (full-screen mode). Default: true */\n fullscreen?: boolean;\n /** Enable mouse support. Default: false */\n mouse?: boolean;\n /** Force fallback (static) rendering */\n forceFallback?: boolean;\n /** Skip fallback detection — always run interactively. Default: false */\n skipFallback?: boolean;\n /** Title to set on the terminal window */\n title?: string;\n}\n\n/**\n * Widget interface that App expects for the root widget.\n * This is the minimum contract — the full Widget class in @termuijs/widgets extends this.\n */\nexport interface RootWidget {\n id: string;\n getLayoutNode(): LayoutNode;\n syncLayout?(): void;\n render(screen: Screen): void;\n mount?(): void;\n unmount?(): void;\n /** Check if this widget needs re-rendering (dirty flag) */\n isDirty?: boolean;\n /** Clear the dirty flag after rendering */\n clearDirty?(): void;\n}\n\n/**\n * Application lifecycle manager.\n *\n * Manages:\n * - Terminal setup/teardown (alt screen, raw mode, cursor, mouse)\n * - Screen buffer and renderer initialization\n * - Input parsing and event dispatch\n * - Layout computation and rect sync\n * - Render loop\n * - Graceful shutdown\n */\nexport class App {\n readonly terminal: Terminal;\n readonly screen: Screen;\n readonly renderer: Renderer;\n readonly input: InputParser;\n readonly focus: FocusManager;\n readonly events: EventEmitter<EventMap>;\n readonly layers: LayerManager;\n\n private _rootWidget: RootWidget;\n private _options: AppOptions;\n private _mounted = false;\n private _exitResolve: ((code: number) => void) | null = null;\n private _unsubKey: (() => void) | null = null;\n private _unsubMouse: (() => void) | null = null;\n private _widgetById = new Map<string, any>();\n\n constructor(rootWidget: RootWidget, options: AppOptions = {}) {\n this._rootWidget = rootWidget;\n this._options = {\n fullscreen: true,\n mouse: false,\n fps: 30,\n ...options,\n };\n\n this.terminal = new Terminal(options);\n this.screen = new Screen(this.terminal.cols, this.terminal.rows);\n this.renderer = new Renderer(this.terminal, this.screen, this._options.fps);\n this.input = new InputParser(this.terminal.stdin);\n this.focus = new FocusManager();\n this.events = new EventEmitter();\n this.layers = new LayerManager(this.terminal.cols, this.terminal.rows);\n }\n\n /**\n * Start the application.\n * Sets up the terminal, starts the render loop, and mounts the root widget.\n * Returns a promise that resolves when exit() is called.\n */\n async mount(): Promise<number> {\n if (this._mounted) return 0;\n\n // Check if we should use fallback mode\n if (this._options.forceFallback || (!this._options.skipFallback && shouldUseFallback())) {\n this._renderFallback();\n return 0;\n }\n\n this._mounted = true;\n\n // Set up terminal\n this.terminal.enterRawMode();\n if (this._options.fullscreen) {\n this.terminal.enterAltScreen();\n }\n this.terminal.hideCursor();\n\n if (this._options.mouse) {\n this.terminal.enableMouse();\n }\n\n if (this._options.title) {\n this.terminal.write(`\\x1b]0;${this._options.title}\\x07`);\n }\n\n // Handle resize\n this.terminal.onResize((cols, rows) => {\n this.screen.resize(cols, rows);\n this.screen.invalidate();\n this.layers.resize(cols, rows);\n this.events.emit('resize', { cols, rows });\n (this._rootWidget as any).markDirty?.();\n this.requestRender();\n });\n\n // Set up input handling\n this.input.start();\n\n // Forward key events with bubble dispatch\n this._unsubKey = this.input.onKey((rawEvent) => {\n const event = createKeyEvent({\n ...rawEvent,\n targetId: this.focus.currentId ?? undefined,\n });\n\n // Phase 1: Bubble dispatch — focused widget → parent → root\n const focusedId = this.focus.currentId;\n if (focusedId) {\n const chain = this._buildBubbleChain(focusedId);\n for (const widget of chain) {\n widget.events.emit('key', event);\n if (event._propagationStopped) break;\n }\n }\n\n // Phase 2: Default actions (Tab for focus cycling)\n if (!event._defaultPrevented) {\n if (event.key === 'tab' && !event.ctrl && !event.alt) {\n if (event.shift) {\n this.focus.focusPrev();\n } else {\n this.focus.focusNext();\n }\n }\n }\n\n // Phase 3: App-level broadcast (always fires unless stopped)\n if (!event._propagationStopped) {\n this.events.emit('key', event);\n }\n });\n\n // Forward mouse events\n this._unsubMouse = this.input.onMouse((event) => {\n this.events.emit('mouse', event);\n });\n\n // Start render loop — tick drives requestRender() so dirty widgets\n // (motion, timers) get redrawn without a separate setInterval.\n this.renderer.start(() => this.requestRender());\n\n // Mount root widget\n this._rootWidget.mount?.();\n this.events.emit('mount', undefined as any);\n\n // Initial render — invalidate front buffer to force full redraw\n this.screen.invalidate();\n this.requestRender();\n\n // Block until exit() is called\n return new Promise<number>((resolve) => {\n this._exitResolve = resolve;\n });\n }\n\n /**\n * Stop the application and restore terminal state.\n */\n unmount(): void {\n if (!this._mounted) return;\n this._mounted = false;\n\n this._rootWidget.unmount?.();\n this.events.emit('unmount', undefined as any);\n\n this._unsubKey?.();\n this._unsubKey = null;\n this._unsubMouse?.();\n this._unsubMouse = null;\n\n this.renderer.stop();\n this.input.stop();\n this.terminal.restore();\n this.events.removeAll();\n }\n\n /**\n * Create an overlay layer for rendering above normal widgets.\n * @param id Unique layer identifier (e.g. 'modal', 'select-dropdown', 'toast')\n * @param zIndex Stacking order (higher = rendered on top). Default: 100\n */\n addOverlay(id: string, zIndex = 100): void {\n this.layers.createLayer(id, zIndex);\n }\n\n /**\n * Remove an overlay layer.\n */\n removeOverlay(id: string): void {\n this.layers.removeLayer(id);\n }\n\n /**\n * Request a re-render on the next frame.\n * Skips layout + render pass when the root widget reports no dirty state.\n */\n requestRender(): void {\n if (!this._mounted) return;\n\n // Skip full layout pass if widget tree reports nothing has changed.\n // isDirty propagates upward via markDirty(), so the root being clean\n // means no descendant needs re-rendering either.\n // Do NOT call requestFrame() here — back buffer is stale after swap()\n // and flushing it would write old content over the current display.\n if (this._rootWidget.isDirty === false) {\n return;\n }\n\n // Compute layout\n const layoutRoot = this._rootWidget.getLayoutNode();\n computeLayout(layoutRoot, this.terminal.cols, this.terminal.rows);\n\n // Sync computed rects from layout tree back to widgets\n this._rootWidget.syncLayout?.();\n\n // Rebuild the widget ID cache so _buildBubbleChain can do O(1) lookups\n this._buildWidgetMap(this._rootWidget);\n\n // Clear the back buffer and render widgets into it\n this.screen.clear();\n this._rootWidget.render(this.screen);\n\n // Clear dirty flags now that we've rendered — future requestRender()\n // calls will skip layout until markDirty() is called again.\n this._rootWidget.clearDirty?.();\n\n // Composite overlay layers on top of the base rendering\n this.layers.composite(this.screen);\n\n this.renderer.requestFrame();\n }\n\n /**\n * Exit the app (convenience method).\n */\n exit(code = 0): void {\n this.unmount();\n if (this._exitResolve) {\n this._exitResolve(code);\n this._exitResolve = null;\n }\n }\n\n /**\n * Render in fallback (static) mode for non-interactive environments.\n */\n private _renderFallback(): void {\n const layoutRoot = this._rootWidget.getLayoutNode();\n computeLayout(layoutRoot, this.terminal.cols, this.terminal.rows);\n\n this._rootWidget.syncLayout?.();\n\n this.screen.clear();\n this._rootWidget.render(this.screen);\n\n const output = renderFallback(this.screen);\n this.terminal.write(output + '\\n');\n }\n\n /**\n * Build the bubble chain for keyboard events.\n * Returns an array: [focused widget, parent, grandparent, ..., root]\n * Uses the cached _widgetById map for O(1) lookup instead of DFS.\n */\n private _buildBubbleChain(widgetId: string): Array<{ events: { emit: (event: string, data: any) => void } }> {\n const chain: Array<{ events: { emit: (event: string, data: any) => void } }> = [];\n const widget = this._widgetById.get(widgetId); // O(1) lookup\n if (!widget) return chain;\n\n let current: any = widget;\n while (current) {\n if (current.events) {\n chain.push(current);\n }\n current = current.parent ?? null;\n }\n return chain;\n }\n\n /**\n * Rebuild the widget ID cache by walking the entire widget tree.\n * Called after syncLayout() so the map stays current.\n */\n private _buildWidgetMap(root: any): void {\n this._widgetById.clear();\n this._walkWidget(root);\n }\n\n private _walkWidget(widget: any): void {\n if (!widget) return;\n if (widget.id) this._widgetById.set(widget.id, widget);\n const children = widget._children ?? widget.children ?? [];\n if (Array.isArray(children)) {\n for (const child of children) {\n this._walkWidget(child);\n }\n }\n }\n}\n","// ─────────────────────────────────────────────────────\n// @termuijs/core — Unicode string width utilities\n// ─────────────────────────────────────────────────────\n\n/**\n * Check if a code point is a CJK (East Asian Wide/Fullwidth) character.\n * These characters occupy 2 terminal columns.\n *\n * Covers: CJK Unified Ideographs, Hangul Syllables, Katakana, Fullwidth Latin, etc.\n */\nfunction isWideChar(codePoint: number): boolean {\n return (\n // CJK Unified Ideographs (common Chinese/Japanese/Korean)\n (codePoint >= 0x4E00 && codePoint <= 0x9FFF) ||\n // CJK Unified Ideographs Extension A\n (codePoint >= 0x3400 && codePoint <= 0x4DBF) ||\n // CJK Compatibility Ideographs\n (codePoint >= 0xF900 && codePoint <= 0xFAFF) ||\n // Hangul Syllables\n (codePoint >= 0xAC00 && codePoint <= 0xD7AF) ||\n // Katakana\n (codePoint >= 0x30A0 && codePoint <= 0x30FF) ||\n // CJK Symbols and Punctuation\n (codePoint >= 0x3000 && codePoint <= 0x303F) ||\n // Hiragana\n (codePoint >= 0x3040 && codePoint <= 0x309F) ||\n // Fullwidth Forms\n (codePoint >= 0xFF01 && codePoint <= 0xFF60) ||\n (codePoint >= 0xFFE0 && codePoint <= 0xFFE6) ||\n // CJK Unified Ideographs Extension B\n (codePoint >= 0x20000 && codePoint <= 0x2A6DF) ||\n // CJK Unified Ideographs Extension C,D,E,F\n (codePoint >= 0x2A700 && codePoint <= 0x2EBEF) ||\n // CJK Compatibility Ideographs Supplement\n (codePoint >= 0x2F800 && codePoint <= 0x2FA1F)\n );\n}\n\n/**\n * Check if a code point is a combining character (zero-width).\n * These characters do not occupy any terminal column by themselves.\n */\nfunction isCombining(codePoint: number): boolean {\n return (\n // Combining Diacritical Marks\n (codePoint >= 0x0300 && codePoint <= 0x036F) ||\n // Combining Diacritical Marks Extended\n (codePoint >= 0x1AB0 && codePoint <= 0x1AFF) ||\n // Combining Diacritical Marks Supplement\n (codePoint >= 0x1DC0 && codePoint <= 0x1DFF) ||\n // Combining Diacritical Marks for Symbols\n (codePoint >= 0x20D0 && codePoint <= 0x20FF) ||\n // Combining Half Marks\n (codePoint >= 0xFE20 && codePoint <= 0xFE2F) ||\n // Variation selectors\n (codePoint >= 0xFE00 && codePoint <= 0xFE0F) ||\n // Zero-width joiner / non-joiner\n codePoint === 0x200B || codePoint === 0x200C || codePoint === 0x200D ||\n codePoint === 0xFEFF\n );\n}\n\n/**\n * Check if a character is an emoji that typically occupies 2 columns.\n * Simplified heuristic covering common emoji ranges.\n */\nfunction isEmoji(codePoint: number): boolean {\n return (\n // Emoticons\n (codePoint >= 0x1F600 && codePoint <= 0x1F64F) ||\n // Misc Symbols and Pictographs\n (codePoint >= 0x1F300 && codePoint <= 0x1F5FF) ||\n // Transport and Map\n (codePoint >= 0x1F680 && codePoint <= 0x1F6FF) ||\n // Supplemental Symbols\n (codePoint >= 0x1F900 && codePoint <= 0x1F9FF) ||\n // Misc symbols\n (codePoint >= 0x2600 && codePoint <= 0x26FF) ||\n // Dingbats\n (codePoint >= 0x2700 && codePoint <= 0x27BF) ||\n // Flags\n (codePoint >= 0x1F1E0 && codePoint <= 0x1F1FF)\n );\n}\n\n/**\n * Calculate the visual width of a string in terminal columns.\n *\n * - CJK characters count as 2 columns\n * - Emoji count as 2 columns\n * - Combining/zero-width characters count as 0\n * - ANSI escape sequences count as 0\n * - Regular characters count as 1\n */\nexport function stringWidth(str: string): number {\n let width = 0;\n let inEscape = false;\n\n for (const char of str) {\n const cp = char.codePointAt(0)!;\n\n // Skip ANSI escape sequences\n if (cp === 0x1B) { // ESC\n inEscape = true;\n continue;\n }\n if (inEscape) {\n // End of CSI sequence (letter after ESC[...m)\n if ((cp >= 0x40 && cp <= 0x7E) && cp !== 0x5B) {\n inEscape = false;\n }\n continue;\n }\n\n // Skip control characters\n if (cp < 0x20 || (cp >= 0x7F && cp < 0xA0)) {\n continue;\n }\n\n // Zero-width\n if (isCombining(cp)) {\n continue;\n }\n\n // Double-width\n if (isWideChar(cp) || isEmoji(cp)) {\n width += 2;\n continue;\n }\n\n width += 1;\n }\n\n return width;\n}\n\n/**\n * Truncate a string to the given visual width, preserving ANSI codes.\n * Appends an ellipsis character if truncated.\n */\nexport function truncate(str: string, maxWidth: number, ellipsis = '…'): string {\n if (maxWidth <= 0) return '';\n const strW = stringWidth(str);\n if (strW <= maxWidth) return str;\n\n const ellipsisW = stringWidth(ellipsis);\n const targetW = maxWidth - ellipsisW;\n if (targetW <= 0) return ellipsis.slice(0, maxWidth);\n\n let width = 0;\n let result = '';\n let inEscape = false;\n let escapeBuffer = '';\n\n for (const char of str) {\n const cp = char.codePointAt(0)!;\n\n if (cp === 0x1B) {\n inEscape = true;\n escapeBuffer += char;\n continue;\n }\n if (inEscape) {\n escapeBuffer += char;\n if ((cp >= 0x40 && cp <= 0x7E) && cp !== 0x5B) {\n inEscape = false;\n result += escapeBuffer;\n escapeBuffer = '';\n }\n continue;\n }\n\n let charW = 1;\n if (isCombining(cp)) {\n charW = 0;\n } else if (isWideChar(cp) || isEmoji(cp)) {\n charW = 2;\n } else if (cp < 0x20 || (cp >= 0x7F && cp < 0xA0)) {\n charW = 0;\n }\n\n if (width + charW > targetW) break;\n width += charW;\n result += char;\n }\n\n return result + ellipsis;\n}\n\n/**\n * Strip all ANSI escape sequences from a string.\n */\nexport function stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1b\\[[0-9;]*[a-zA-Z]/g, '');\n}\n\n/**\n * Word-wrap text to a given width, respecting existing newlines.\n * Does not handle ANSI codes within words (wraps at the character level).\n */\nexport function wordWrap(str: string, width: number): string {\n if (width <= 0) return str;\n\n const lines = str.split('\\n');\n const result: string[] = [];\n\n for (const line of lines) {\n if (stringWidth(line) <= width) {\n result.push(line);\n continue;\n }\n\n let currentLine = '';\n let currentWidth = 0;\n const words = line.split(/(\\s+)/);\n\n for (const word of words) {\n const wordW = stringWidth(word);\n\n if (currentWidth + wordW <= width) {\n currentLine += word;\n currentWidth += wordW;\n } else if (wordW > width) {\n // Word is longer than width — break it\n if (currentLine) {\n result.push(currentLine);\n currentLine = '';\n currentWidth = 0;\n }\n for (const char of word) {\n const cp = char.codePointAt(0)!;\n const charW = (isWideChar(cp) || isEmoji(cp)) ? 2 : (isCombining(cp) ? 0 : 1);\n if (currentWidth + charW > width) {\n result.push(currentLine);\n currentLine = '';\n currentWidth = 0;\n }\n currentLine += char;\n currentWidth += charW;\n }\n } else {\n result.push(currentLine);\n currentLine = word.trimStart();\n currentWidth = stringWidth(currentLine);\n }\n }\n\n if (currentLine) {\n result.push(currentLine);\n }\n }\n\n return result.join('\\n');\n}\n"],"mappings":"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","names":["ColorDepth","ratio","nodeWidth","nodeHeight","min","max","resolveSize"]}
|