@hypersocial/cli-games 0.1.0 → 0.2.0

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/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/themes/index.ts","../src/games/utils.ts","../src/games/gameTransitions.ts","../src/games/shared/menu.ts","../src/games/2048/slideLogic.ts","../src/games/2048/index.ts","../src/games/asteroids/index.ts","../src/games/breakout/index.ts","../src/games/chopper/levels.ts","../src/games/chopper/effects.ts","../src/games/chopper/index.ts","../src/games/crack/index.ts","../src/games/frogger/index.ts","../src/games/hangman/index.ts","../src/games/minesweeper/index.ts","../src/games/pong/index.ts","../src/games/runner/index.ts","../src/games/simon/index.ts","../src/games/snake/index.ts","../src/games/spaceinvaders/index.ts","../src/games/tetris/index.ts","../src/games/tower/index.ts","../src/games/tron/index.ts","../src/games/typingtest/index.ts","../src/games/wordle/index.ts","../src/games/gamesMenu.ts","../src/games/index.ts","../src/cli.ts"],"sourcesContent":["/**\n * Terminal color themes\n *\n * Provides both CSS colors (for UI) and ANSI escape codes (for terminal).\n */\n\n/**\n * Available theme identifiers\n */\nexport type PhosphorMode =\n | 'cyan'\n | 'cyanLight'\n | 'amber'\n | 'green'\n | 'white'\n | 'hotpink'\n | 'hotpinkLight'\n | 'blood'\n | 'ice'\n | 'iceLight'\n | 'bladerunner'\n | 'bladerunnerLight'\n | 'tron'\n | 'tronLight'\n | 'daylight'\n | 'kawaii'\n | 'kawaiiLight'\n | 'oled'\n | 'solarized'\n | 'solarizedLight'\n | 'nord'\n | 'nordLight'\n | 'highcontrast'\n | 'highcontrastLight'\n | 'banana'\n | 'cream';\n\n/**\n * Theme color definition for CSS/UI usage\n */\nexport interface ThemeColors {\n /** Display name */\n name: string;\n /** Emoji icon for quick switcher / UI */\n icon: string;\n /** Primary text/accent color (hex) */\n primary: string;\n /** Secondary accent color (hex) */\n secondary: string;\n /** Subtle glow effect (rgba) */\n glow: string;\n /** Intense glow effect (rgba) */\n glowIntense: string;\n /** Background color (hex) */\n bg: string;\n /** Status bar background - slightly elevated from bg */\n statusBarBg: string;\n /** Terminal foreground color - defaults to primary if not set */\n foreground?: string;\n}\n\n/**\n * All theme definitions with CSS colors\n */\nexport const themes: Record<PhosphorMode, ThemeColors> = {\n cyan: {\n name: 'Cyberpunk',\n icon: '🔵',\n primary: '#00D9FF',\n secondary: '#FF006E',\n glow: 'rgba(0, 217, 255, 0.5)',\n glowIntense: 'rgba(0, 217, 255, 0.8)',\n bg: '#0A1628',\n statusBarBg: '#0D1E38',\n },\n cyanLight: {\n name: 'Cyberpunk Light',\n icon: '💠',\n primary: '#0099CC',\n secondary: '#CC0066',\n glow: 'rgba(0, 153, 204, 0.15)',\n glowIntense: 'rgba(0, 153, 204, 0.3)',\n bg: '#F8FAFF',\n statusBarBg: '#EEF2FA',\n foreground: '#2d3640', // Dark text for terminal readability\n },\n amber: {\n name: 'Fallout',\n icon: '🟠',\n primary: '#FFB000',\n secondary: '#FF6600',\n glow: 'rgba(255, 176, 0, 0.5)',\n glowIntense: 'rgba(255, 176, 0, 0.8)',\n bg: '#1C1408',\n statusBarBg: '#2A1E0C',\n },\n green: {\n name: 'Matrix',\n icon: '🟢',\n primary: '#39FF14',\n secondary: '#00FF00',\n glow: 'rgba(57, 255, 20, 0.5)',\n glowIntense: 'rgba(57, 255, 20, 0.8)',\n bg: '#001A00',\n statusBarBg: '#002800',\n },\n white: {\n name: 'Ghost',\n icon: '⚪',\n primary: '#FFFFFF',\n secondary: '#88CCFF',\n glow: 'rgba(255, 255, 255, 0.3)',\n glowIntense: 'rgba(255, 255, 255, 0.5)',\n bg: '#0C0C0C',\n statusBarBg: '#1A1A1A',\n },\n hotpink: {\n name: 'Synthwave',\n icon: '🩷',\n primary: '#FF6AC1',\n secondary: '#00D9FF',\n glow: 'rgba(255, 106, 193, 0.5)',\n glowIntense: 'rgba(255, 106, 193, 0.8)',\n bg: '#0F0818',\n statusBarBg: '#1A0F28',\n },\n hotpinkLight: {\n name: 'Synthwave Light',\n icon: '🌷',\n primary: '#D84A9C',\n secondary: '#0099BB',\n glow: 'rgba(216, 74, 156, 0.15)',\n glowIntense: 'rgba(216, 74, 156, 0.3)',\n bg: '#FFF8FC',\n statusBarBg: '#F5EEF2',\n foreground: '#2d3640', // Dark text for terminal readability\n },\n blood: {\n name: 'Blood',\n icon: '🔴',\n primary: '#FF3333',\n secondary: '#AA0000',\n glow: 'rgba(255, 51, 51, 0.5)',\n glowIntense: 'rgba(255, 51, 51, 0.8)',\n bg: '#1A0505',\n statusBarBg: '#280808',\n },\n ice: {\n name: 'Ice',\n icon: '🩵',\n primary: '#88FFFF',\n secondary: '#4488FF',\n glow: 'rgba(136, 255, 255, 0.4)',\n glowIntense: 'rgba(136, 255, 255, 0.7)',\n bg: '#051520',\n statusBarBg: '#082030',\n },\n iceLight: {\n name: 'Ice Light',\n icon: '🧊',\n primary: '#0077AA',\n secondary: '#2255CC',\n glow: 'rgba(0, 119, 170, 0.12)',\n glowIntense: 'rgba(0, 119, 170, 0.25)',\n bg: '#F0FAFF',\n statusBarBg: '#E5F0F8',\n foreground: '#2d3640', // Dark text for terminal readability\n },\n bladerunner: {\n name: 'Blade Runner',\n icon: '🟧',\n primary: '#FF6B35',\n secondary: '#00CED1',\n glow: 'rgba(255, 107, 53, 0.6)',\n glowIntense: 'rgba(255, 107, 53, 0.9)',\n bg: '#1F0E08',\n statusBarBg: '#2D150C',\n },\n bladerunnerLight: {\n name: 'Blade Runner Light',\n icon: '🌅',\n primary: '#CC4400',\n secondary: '#008B8B',\n glow: 'rgba(204, 68, 0, 0.15)',\n glowIntense: 'rgba(204, 68, 0, 0.3)',\n bg: '#FFFAF5',\n statusBarBg: '#F5EFEA',\n foreground: '#2d3640', // Dark text for terminal readability\n },\n tron: {\n name: 'Tron',\n icon: '🔷',\n primary: '#6FFFE9',\n secondary: '#FF6B00',\n glow: 'rgba(111, 255, 233, 0.5)',\n glowIntense: 'rgba(111, 255, 233, 0.8)',\n bg: '#020815',\n statusBarBg: '#051020',\n },\n tronLight: {\n name: 'Tron Light',\n icon: '💎',\n primary: '#008080',\n secondary: '#CC5500',\n glow: 'rgba(0, 128, 128, 0.15)',\n glowIntense: 'rgba(0, 128, 128, 0.3)',\n bg: '#F5FFFF',\n statusBarBg: '#EAF5F5',\n foreground: '#2d3640', // Dark text for terminal readability\n },\n daylight: {\n name: 'Daylight',\n icon: '☀️',\n primary: '#1a1a1a',\n secondary: '#0066CC',\n glow: 'rgba(0, 102, 204, 0.1)',\n glowIntense: 'rgba(0, 102, 204, 0.2)',\n bg: '#FAFAF8',\n statusBarBg: '#EEEEEC',\n foreground: '#1a1a1a', // Matches primary for consistent dark text\n },\n kawaii: {\n name: 'Kawaii',\n icon: '🌸',\n primary: '#FF69B4',\n secondary: '#87CEEB',\n glow: 'rgba(255, 105, 180, 0.6)',\n glowIntense: 'rgba(255, 105, 180, 0.9)',\n bg: '#1E0818',\n statusBarBg: '#2D0F25',\n },\n kawaiiLight: {\n name: 'Kawaii Light',\n icon: '🎀',\n primary: '#D4458B',\n secondary: '#7B68EE',\n glow: 'rgba(255, 105, 180, 0.2)',\n glowIntense: 'rgba(255, 105, 180, 0.4)',\n bg: '#FFF5F8',\n statusBarBg: '#F5EAEE',\n foreground: '#2d3640', // Dark text for terminal readability\n },\n oled: {\n name: 'OLED Black',\n icon: '⚫',\n primary: '#FFFFFF',\n secondary: '#00D9FF',\n glow: 'rgba(255, 255, 255, 0.3)',\n glowIntense: 'rgba(255, 255, 255, 0.5)',\n bg: '#000000',\n statusBarBg: '#0A0A0A',\n },\n solarized: {\n name: 'Solarized',\n icon: '🌊',\n primary: '#2AA198',\n secondary: '#859900',\n glow: 'rgba(42, 161, 152, 0.4)',\n glowIntense: 'rgba(42, 161, 152, 0.6)',\n bg: '#002B36',\n statusBarBg: '#073642',\n foreground: '#D4D4D4', // Light gray for better readability\n },\n solarizedLight: {\n name: 'Solarized Light',\n icon: '🏖️',\n primary: '#657B83',\n secondary: '#268BD2',\n glow: 'rgba(38, 139, 210, 0.15)',\n glowIntense: 'rgba(38, 139, 210, 0.25)',\n bg: '#FDF6E3',\n statusBarBg: '#EEE8D5',\n foreground: '#586e75', // Solarized base01 for terminal text\n },\n nord: {\n name: 'Nord',\n icon: '❄️',\n primary: '#88C0D0',\n secondary: '#81A1C1',\n glow: 'rgba(136, 192, 208, 0.3)',\n glowIntense: 'rgba(136, 192, 208, 0.5)',\n bg: '#2E3440',\n statusBarBg: '#3B4252',\n },\n nordLight: {\n name: 'Nord Light',\n icon: '🏔️',\n primary: '#2E3440',\n secondary: '#5E81AC',\n glow: 'rgba(94, 129, 172, 0.15)',\n glowIntense: 'rgba(94, 129, 172, 0.25)',\n bg: '#ECEFF4',\n statusBarBg: '#E5E9F0',\n foreground: '#2E3440', // Nord polar night for terminal text\n },\n highcontrast: {\n name: 'High Contrast',\n icon: '◐',\n primary: '#FFFFFF',\n secondary: '#FFFF00',\n glow: 'rgba(255, 255, 255, 0.1)',\n glowIntense: 'rgba(255, 255, 255, 0.2)',\n bg: '#000000',\n statusBarBg: '#111111',\n },\n highcontrastLight: {\n name: 'High Contrast Light',\n icon: '◑',\n primary: '#000000',\n secondary: '#0000CC',\n glow: 'rgba(0, 0, 0, 0.05)',\n glowIntense: 'rgba(0, 0, 0, 0.1)',\n bg: '#FFFFFF',\n statusBarBg: '#EEEEEE',\n foreground: '#000000', // Maximum contrast for terminal text\n },\n banana: {\n name: 'Banana',\n icon: '🍌',\n primary: '#FFE135',\n secondary: '#8B7500',\n glow: 'rgba(255, 225, 53, 0.5)',\n glowIntense: 'rgba(255, 225, 53, 0.8)',\n bg: '#1A1800',\n statusBarBg: '#282400',\n },\n cream: {\n name: 'Cream',\n icon: '🍦',\n primary: '#4A3C2A',\n secondary: '#C17844',\n glow: 'rgba(193, 120, 68, 0.12)',\n glowIntense: 'rgba(193, 120, 68, 0.22)',\n bg: '#EDE5D4',\n statusBarBg: '#E3DBCA',\n foreground: '#4A3C2A',\n },\n};\n\n/**\n * ANSI escape codes for terminal text coloring\n */\nconst ansiCodes: Record<PhosphorMode, string> = {\n cyan: '\\x1b[96m',\n cyanLight: '\\x1b[38;5;31m',\n amber: '\\x1b[93m',\n green: '\\x1b[92m',\n white: '\\x1b[97m',\n hotpink: '\\x1b[95m',\n hotpinkLight: '\\x1b[38;5;169m',\n blood: '\\x1b[91m',\n ice: '\\x1b[96m',\n iceLight: '\\x1b[38;5;31m',\n bladerunner: '\\x1b[38;5;208m',\n bladerunnerLight: '\\x1b[38;5;166m',\n tron: '\\x1b[96m',\n tronLight: '\\x1b[38;5;30m',\n daylight: '\\x1b[34m',\n kawaii: '\\x1b[95m',\n kawaiiLight: '\\x1b[35m',\n oled: '\\x1b[97m',\n solarized: '\\x1b[36m',\n solarizedLight: '\\x1b[38;5;66m',\n nord: '\\x1b[96m',\n nordLight: '\\x1b[38;5;59m',\n highcontrast: '\\x1b[97m',\n highcontrastLight: '\\x1b[30m',\n banana: '\\x1b[93m',\n cream: '\\x1b[38;5;130m',\n};\n\n/**\n * Light themes that need dark text\n */\nconst lightThemes: Set<PhosphorMode> = new Set([\n 'cyanLight',\n 'hotpinkLight',\n 'iceLight',\n 'bladerunnerLight',\n 'tronLight',\n 'daylight',\n 'kawaiiLight',\n 'solarizedLight',\n 'nordLight',\n 'highcontrastLight',\n 'cream',\n]);\n\n/**\n * Subtle background colors for game elements\n */\nconst subtleColors: Partial<Record<PhosphorMode, string>> = {\n cyanLight: '\\x1b[38;5;153m',\n hotpinkLight: '\\x1b[38;5;225m',\n iceLight: '\\x1b[38;5;195m',\n bladerunnerLight: '\\x1b[38;5;223m',\n tronLight: '\\x1b[38;5;159m',\n daylight: '\\x1b[38;5;252m',\n kawaiiLight: '\\x1b[38;5;218m',\n solarizedLight: '\\x1b[38;5;187m',\n nordLight: '\\x1b[38;5;255m',\n highcontrastLight: '\\x1b[38;5;250m',\n cream: '\\x1b[38;5;223m',\n oled: '\\x1b[38;5;234m',\n highcontrast: '\\x1b[38;5;238m',\n};\n\n// ============================================================================\n// API Functions\n// ============================================================================\n\n/**\n * Get theme colors by mode\n */\nexport function getTheme(mode: PhosphorMode): ThemeColors {\n return themes[mode];\n}\n\n/**\n * Get ANSI escape code for a theme\n */\nexport function getAnsiColor(mode: PhosphorMode): string {\n return ansiCodes[mode] || '\\x1b[92m';\n}\n\n/**\n * Check if a theme is light (needs dark text)\n */\nexport function isLightTheme(mode: PhosphorMode): boolean {\n return lightThemes.has(mode);\n}\n\n/**\n * Get subtle background color for game elements\n */\nexport function getSubtleColor(mode: PhosphorMode): string {\n return subtleColors[mode] || '\\x1b[38;5;236m';\n}\n\n/**\n * Get all available theme modes\n */\nexport function getThemeModes(): PhosphorMode[] {\n return Object.keys(themes) as PhosphorMode[];\n}\n\nconst VALID_THEME_MODES = new Set<string>(Object.keys(themes));\n\n/**\n * Check if a string is a valid theme mode\n */\nexport function isValidThemeMode(value: string): value is PhosphorMode {\n return VALID_THEME_MODES.has(value);\n}\n\n/**\n * ANSI reset code\n */\nexport const ANSI_RESET = '\\x1b[0m';\n\n// ============================================================================\n// xterm.js Terminal Theme\n// ============================================================================\n\n/**\n * xterm.js ITheme-compatible color set.\n * Includes the 16 ANSI colors, selection, cursor, scrollbar, and foreground/background.\n */\nexport interface ITerminalTheme {\n background: string;\n foreground: string;\n cursor: string;\n cursorAccent: string;\n selectionBackground: string;\n selectionForeground: string;\n black: string;\n red: string;\n green: string;\n yellow: string;\n blue: string;\n magenta: string;\n cyan: string;\n white: string;\n brightBlack: string;\n brightRed: string;\n brightGreen: string;\n brightYellow: string;\n brightBlue: string;\n brightMagenta: string;\n brightCyan: string;\n brightWhite: string;\n scrollbarSliderBackground: string;\n scrollbarSliderHoverBackground: string;\n scrollbarSliderActiveBackground: string;\n}\n\n/**\n * Generate a full xterm.js theme from a PhosphorMode.\n *\n * Maps theme colors to the 16 ANSI colors, selection, cursor, and scrollbar.\n * Light themes get inverted black/white and muted ANSI colors for readability.\n */\nexport function getTerminalTheme(mode: PhosphorMode): ITerminalTheme {\n const theme = themes[mode];\n const isLight = lightThemes.has(mode);\n\n const selectionBg = isLight ? '#3399FF' : theme.primary;\n const selectionFg = isLight ? '#000000' : '#000000';\n\n // For light themes, invert black/white so apps that hard-code dark backgrounds\n // (e.g. Codex using \\033[40m) remain readable on light terminal backgrounds.\n let black, white, brightBlack, brightWhite;\n\n if (isLight) {\n black = theme.bg;\n white = '#1a1a1a';\n brightBlack = '#e0e0e0';\n brightWhite = '#2a2a2a';\n } else {\n black = theme.bg;\n white = '#FFFFFF';\n brightBlack = '#636B7C';\n brightWhite = '#FFFFFF';\n }\n\n const cursorAccent = isLight\n ? (theme.foreground ?? '#1a1a1a')\n : theme.bg;\n\n return {\n background: \"rgba(0, 0, 0, 0)\",\n foreground: theme.foreground ?? theme.primary,\n cursor: theme.secondary,\n cursorAccent,\n selectionBackground: selectionBg,\n selectionForeground: selectionFg,\n black,\n red: isLight ? \"#c41a16\" : \"#FF0040\",\n green: isLight ? \"#007400\" : \"#39FF14\",\n yellow: isLight ? \"#826b00\" : \"#E5C400\",\n blue: isLight ? \"#0451a5\" : \"#7AA2F7\",\n magenta: isLight ? \"#a626a4\" : theme.secondary,\n cyan: isLight ? \"#0598bc\" : theme.primary,\n white,\n brightBlack,\n brightRed: isLight ? \"#e45649\" : \"#FF006E\",\n brightGreen: isLight ? \"#50a14f\" : \"#39FF14\",\n brightYellow: isLight ? \"#c18401\" : \"#FFD400\",\n brightBlue: isLight ? \"#4078f2\" : \"#89B4FA\",\n brightMagenta: isLight ? \"#c678dd\" : theme.secondary,\n brightCyan: isLight ? \"#0184bc\" : theme.primary,\n brightWhite,\n scrollbarSliderBackground: isLight ? 'rgba(0, 0, 0, 0.12)' : 'rgba(255, 255, 255, 0.1)',\n scrollbarSliderHoverBackground: isLight ? 'rgba(0, 0, 0, 0.2)' : 'rgba(255, 255, 255, 0.18)',\n scrollbarSliderActiveBackground: isLight ? 'rgba(0, 0, 0, 0.28)' : 'rgba(255, 255, 255, 0.25)',\n };\n}\n\n// ============================================================================\n// Light Theme Escape Sequence Transformer\n// ============================================================================\n\nfunction srgbToLinear(channel: number): number {\n const normalized = channel / 255;\n return normalized <= 0.04045\n ? normalized / 12.92\n : Math.pow((normalized + 0.055) / 1.055, 2.4);\n}\n\nfunction relativeLuminance(r: number, g: number, b: number): number {\n return 0.2126 * srgbToLinear(r) + 0.7152 * srgbToLinear(g) + 0.0722 * srgbToLinear(b);\n}\n\nfunction contrastRatio(\n fgR: number,\n fgG: number,\n fgB: number,\n bgR: number,\n bgG: number,\n bgB: number\n): number {\n const fgLum = relativeLuminance(fgR, fgG, fgB);\n const bgLum = relativeLuminance(bgR, bgG, bgB);\n const lighter = Math.max(fgLum, bgLum);\n const darker = Math.min(fgLum, bgLum);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\nfunction ensureReadableForegroundOnLightTheme(\n red: number,\n green: number,\n blue: number,\n bgR: number,\n bgG: number,\n bgB: number,\n minContrast = 4.2\n): [number, number, number] {\n if (contrastRatio(red, green, blue, bgR, bgG, bgB) >= minContrast) {\n return [red, green, blue];\n }\n\n for (let step = 1; step <= 20; step += 1) {\n const factor = 1 - step / 20;\n const nextR = Math.round(red * factor);\n const nextG = Math.round(green * factor);\n const nextB = Math.round(blue * factor);\n if (contrastRatio(nextR, nextG, nextB, bgR, bgG, bgB) >= minContrast) {\n return [nextR, nextG, nextB];\n }\n }\n\n return [30, 30, 30];\n}\n\nfunction ansi256ToRgb(colorIndex: number): [number, number, number] | null {\n if (colorIndex < 0 || colorIndex > 255) return null;\n\n // Standard + bright ANSI palette.\n const basePalette: Array<[number, number, number]> = [\n [0, 0, 0],\n [205, 49, 49],\n [13, 188, 121],\n [229, 229, 16],\n [36, 114, 200],\n [188, 63, 188],\n [17, 168, 205],\n [229, 229, 229],\n [102, 102, 102],\n [241, 76, 76],\n [35, 209, 139],\n [245, 245, 67],\n [59, 142, 234],\n [214, 112, 214],\n [41, 184, 219],\n [255, 255, 255],\n ];\n\n if (colorIndex <= 15) return basePalette[colorIndex];\n\n if (colorIndex >= 16 && colorIndex <= 231) {\n const idx = colorIndex - 16;\n const red = Math.floor(idx / 36);\n const green = Math.floor((idx % 36) / 6);\n const blue = idx % 6;\n const level = [0, 95, 135, 175, 215, 255];\n return [level[red], level[green], level[blue]];\n }\n\n const gray = 8 + (colorIndex - 232) * 10;\n return [gray, gray, gray];\n}\n\n/**\n * Transform ANSI escape sequences for light themes.\n *\n * Apps like Codex use true color (24-bit) escape sequences that bypass our\n * theme's ANSI color settings. This intercepts dark backgrounds/foregrounds\n * and inverts them so TUI apps remain readable on light backgrounds.\n *\n * @param data - Raw terminal data with ANSI escape sequences\n * @param themeBg - The theme's background color hex (e.g., \"#F5E6D3\")\n * @returns Transformed data with inverted colors for light themes\n */\nexport function transformEscapeSequencesForLightTheme(data: string, themeBg: string): string {\n const bgR = parseInt(themeBg.slice(1, 3), 16);\n const bgG = parseInt(themeBg.slice(3, 5), 16);\n const bgB = parseInt(themeBg.slice(5, 7), 16);\n // Keep a small but visible contrast band so TUI input/panel regions\n // remain distinguishable on light themes.\n const highlightDelta = 22;\n const highlightR = Math.max(bgR - highlightDelta, 0);\n const highlightG = Math.max(bgG - highlightDelta, 0);\n const highlightB = Math.max(bgB - highlightDelta, 0);\n\n const transformSgr = (sequence: string) => {\n const body = sequence.slice(2, -1);\n if (body.length === 0) return sequence;\n\n const normalized = body.replace(/:/g, ';');\n const rawParams = normalized.split(';');\n const params: number[] = [];\n\n for (const raw of rawParams) {\n if (raw === '') {\n params.push(0);\n continue;\n }\n const value = Number(raw);\n if (!Number.isFinite(value)) {\n return sequence;\n }\n params.push(value);\n }\n\n let changed = false;\n const out: number[] = [];\n\n for (let i = 0; i < params.length; i += 1) {\n const code = params[i];\n\n // 24-bit background color (48;2;R;G;B)\n if (code === 48 && params[i + 1] === 2 && i + 4 < params.length) {\n const hasColorSpace = i + 5 < params.length\n && params[i + 2] === 0\n && params[i + 3] <= 255\n && params[i + 4] <= 255\n && params[i + 5] <= 255;\n const offset = hasColorSpace ? 3 : 2;\n const red = params[i + offset];\n const green = params[i + offset + 1];\n const blue = params[i + offset + 2];\n const sum = red + green + blue;\n\n if (sum < 600) {\n // Dark and mid-range backgrounds -> theme bg (invisible)\n out.push(48, 2, bgR, bgG, bgB);\n changed = true;\n } else {\n // Preserve bright panel/input backgrounds as subtle contrast.\n out.push(48, 2, highlightR, highlightG, highlightB);\n changed = true;\n }\n i += hasColorSpace ? 5 : 4;\n continue;\n }\n\n // 8-bit background color (48;5;N)\n if (code === 48 && params[i + 1] === 5 && i + 2 < params.length) {\n const colorIndex = params[i + 2];\n if (colorIndex === 7 || colorIndex === 8 || colorIndex === 15 || (colorIndex >= 247 && colorIndex <= 255)) {\n // White/bright backgrounds often represent panel surfaces in TUIs.\n // Keep them as a subtle highlight instead of fully flattening.\n out.push(48, 2, highlightR, highlightG, highlightB);\n changed = true;\n } else if (colorIndex === 0 || colorIndex === 16 || (colorIndex >= 232 && colorIndex <= 246)) {\n // Map black and dark-to-mid grays (232-246) to theme bg.\n out.push(48, 2, bgR, bgG, bgB);\n changed = true;\n } else {\n out.push(48, 5, colorIndex);\n }\n i += 2;\n continue;\n }\n\n // 24-bit foreground color (38;2;R;G;B)\n if (code === 38 && params[i + 1] === 2 && i + 4 < params.length) {\n const hasColorSpace = i + 5 < params.length\n && params[i + 2] === 0\n && params[i + 3] <= 255\n && params[i + 4] <= 255\n && params[i + 5] <= 255;\n const offset = hasColorSpace ? 3 : 2;\n const red = params[i + offset];\n const green = params[i + offset + 1];\n const blue = params[i + offset + 2];\n const [nextR, nextG, nextB] = ensureReadableForegroundOnLightTheme(red, green, blue, bgR, bgG, bgB);\n if (nextR !== red || nextG !== green || nextB !== blue) {\n out.push(38, 2, nextR, nextG, nextB);\n changed = true;\n } else {\n out.push(38, 2, red, green, blue);\n }\n i += hasColorSpace ? 5 : 4;\n continue;\n }\n\n // 8-bit foreground color (38;5;N)\n if (code === 38 && params[i + 1] === 5 && i + 2 < params.length) {\n const colorIndex = params[i + 2];\n const rgb = ansi256ToRgb(colorIndex);\n if (!rgb) {\n out.push(38, 5, colorIndex);\n i += 2;\n continue;\n }\n const [red, green, blue] = rgb;\n const [nextR, nextG, nextB] = ensureReadableForegroundOnLightTheme(red, green, blue, bgR, bgG, bgB);\n if (nextR !== red || nextG !== green || nextB !== blue) {\n out.push(38, 2, nextR, nextG, nextB);\n changed = true;\n } else {\n out.push(38, 5, colorIndex);\n }\n i += 2;\n continue;\n }\n\n // Faint text often becomes unreadable on light backgrounds.\n if (code === 2) {\n changed = true;\n continue;\n }\n\n // Standard ANSI background black (40)\n if (code === 40) {\n out.push(48, 2, bgR, bgG, bgB);\n changed = true;\n continue;\n }\n\n // ANSI white/bright white background (47, 107)\n if (code === 47 || code === 107) {\n out.push(48, 2, highlightR, highlightG, highlightB);\n changed = true;\n continue;\n }\n\n // Bright black background (100)\n if (code === 100) {\n out.push(48, 2, highlightR, highlightG, highlightB);\n changed = true;\n continue;\n }\n\n // ANSI black foreground (30)\n if (code === 30) {\n out.push(38, 2, 60, 60, 60);\n changed = true;\n continue;\n }\n\n // Bright black foreground (90)\n if (code === 90) {\n out.push(38, 2, 100, 100, 100);\n changed = true;\n continue;\n }\n\n // ANSI white foreground (37)\n if (code === 37) {\n out.push(38, 2, 40, 40, 40);\n changed = true;\n continue;\n }\n\n // Bright white foreground (97)\n if (code === 97) {\n out.push(38, 2, 30, 30, 30);\n changed = true;\n continue;\n }\n\n // Reverse video (7) can create harsh dark pills on light themes when\n // apps rely on default background swapping. Force a subtle theme-aware bg.\n if (code === 7) {\n out.push(48, 2, highlightR, highlightG, highlightB);\n changed = true;\n continue;\n }\n\n // Inverse-off (27) should clear the background we introduced for code 7.\n if (code === 27) {\n out.push(49);\n changed = true;\n continue;\n }\n\n out.push(code);\n }\n\n if (!changed) return sequence;\n return `\\x1b[${out.join(';')}m`;\n };\n\n return data.replace(/\\x1b\\[[0-9:;]*m/g, transformSgr);\n}\n\n/**\n * Transform ANSI escape sequences for dark themes with non-black backgrounds.\n *\n * Apps like Claude Code use true-color (24-bit) escape sequences for dark\n * backgrounds (e.g. \\033[48;2;0;0;0m) which bypass the ANSI color mapping.\n * On dark themes where the bg isn't pure black, these show as jarring strips.\n * This remaps near-black and near-white backgrounds to the theme bg.\n */\nexport function transformEscapeSequencesForDarkTheme(data: string, themeBg: string): string {\n const bgR = parseInt(themeBg.slice(1, 3), 16);\n const bgG = parseInt(themeBg.slice(3, 5), 16);\n const bgB = parseInt(themeBg.slice(5, 7), 16);\n\n const transformSgr = (sequence: string) => {\n const body = sequence.slice(2, -1);\n if (body.length === 0) return sequence;\n\n const normalized = body.replace(/:/g, ';');\n const rawParams = normalized.split(';');\n const params: number[] = [];\n\n for (const raw of rawParams) {\n if (raw === '') { params.push(0); continue; }\n const value = Number(raw);\n if (!Number.isFinite(value)) return sequence;\n params.push(value);\n }\n\n let changed = false;\n const out: number[] = [];\n\n for (let i = 0; i < params.length; i += 1) {\n const code = params[i];\n\n // 24-bit background color (48;2;R;G;B) — remap near-black/near-white\n if (code === 48 && params[i + 1] === 2 && i + 4 < params.length) {\n const hasColorSpace = i + 5 < params.length\n && params[i + 2] === 0\n && params[i + 3] <= 255\n && params[i + 4] <= 255\n && params[i + 5] <= 255;\n const offset = hasColorSpace ? 3 : 2;\n const red = params[i + offset];\n const green = params[i + offset + 1];\n const blue = params[i + offset + 2];\n const sum = red + green + blue;\n\n // Near-black and near-white backgrounds are usually hard-coded TUI\n // panel fills that clash with themed dark terminals.\n if (sum < 40 || sum > 700) {\n out.push(48, 2, bgR, bgG, bgB);\n changed = true;\n } else {\n out.push(48, 2, red, green, blue);\n }\n i += hasColorSpace ? 5 : 4;\n continue;\n }\n\n // 8-bit background color (48;5;N) — remap black/near-black and white\n if (code === 48 && params[i + 1] === 5 && i + 2 < params.length) {\n const colorIndex = params[i + 2];\n if (\n colorIndex === 0\n || colorIndex === 7\n || colorIndex === 8\n || colorIndex === 15\n || colorIndex === 16\n || colorIndex === 231\n || (colorIndex >= 232 && colorIndex <= 234)\n || (colorIndex >= 250 && colorIndex <= 255)\n ) {\n out.push(48, 2, bgR, bgG, bgB);\n changed = true;\n } else {\n out.push(48, 5, colorIndex);\n }\n i += 2;\n continue;\n }\n\n // Standard ANSI white/bright white background\n if (code === 47 || code === 107) {\n out.push(48, 2, bgR, bgG, bgB);\n changed = true;\n continue;\n }\n\n out.push(code);\n }\n\n if (!changed) return sequence;\n return `\\x1b[${out.join(';')}m`;\n };\n\n return data.replace(/\\x1b\\[[0-9:;]*m/g, transformSgr);\n}\n","/**\n * Shared utilities for games\n *\n * This module provides theme-aware utilities for games.\n * The theme must be configured by the consuming application via setTheme().\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport {\n type PhosphorMode,\n getAnsiColor,\n isLightTheme as checkLightTheme,\n getSubtleColor,\n} from '../themes';\n\n// ============================================================================\n// Theme Configuration\n// ============================================================================\n\n/**\n * Current theme mode - configured by the consuming application\n */\nlet currentTheme: PhosphorMode = 'cyan';\n\n/**\n * Set the current theme mode\n * Call this from your app when the theme changes\n */\nexport function setTheme(mode: PhosphorMode): void {\n currentTheme = mode;\n}\n\n/**\n * Get the current theme mode\n */\nexport function getTheme(): PhosphorMode {\n return currentTheme;\n}\n\n// ============================================================================\n// Alternate Buffer Management\n// ============================================================================\n\n/**\n * Track which terminals are currently in alternate buffer.\n * This prevents double-entry/exit issues and provides debugging info.\n */\nconst alternateBufferState = new WeakMap<Terminal, { reason: string; enteredAt: number }>();\n\n/**\n * Check if a terminal is valid and can accept writes\n */\nexport function isTerminalValid(terminal: Terminal | null | undefined): terminal is Terminal {\n if (!terminal) return false;\n // Check if terminal has been disposed (element becomes null)\n try {\n return terminal.element !== null;\n } catch {\n return false;\n }\n}\n\n/**\n * Enter alternate screen buffer with state tracking.\n * Safe to call multiple times - will log warning but not double-enter.\n *\n * @param terminal - The xterm terminal instance\n * @param reason - Description of why we're entering (for debugging)\n * @returns true if buffer was entered, false if already in buffer or terminal invalid\n */\nexport function enterAlternateBuffer(terminal: Terminal, reason: string): boolean {\n if (!isTerminalValid(terminal)) {\n console.warn(`[AlternateBuffer] Cannot enter: terminal invalid (reason: ${reason})`);\n return false;\n }\n\n if (alternateBufferState.has(terminal)) {\n const existing = alternateBufferState.get(terminal)!;\n console.warn(`[AlternateBuffer] Already in buffer (entered by: ${existing.reason}), requested by: ${reason}`);\n return false;\n }\n\n terminal.write('\\x1b[?1049h'); // Enter alternate screen buffer\n terminal.write('\\x1b[?25l'); // Hide cursor\n terminal.write('\\x1b[2J\\x1b[H'); // Clear screen\n\n alternateBufferState.set(terminal, { reason, enteredAt: Date.now() });\n return true;\n}\n\n/**\n * Exit alternate screen buffer with state tracking.\n * Safe to call multiple times - will log warning but not double-exit.\n *\n * @param terminal - The xterm terminal instance\n * @param reason - Description of why we're exiting (for debugging)\n * @returns true if buffer was exited, false if not in buffer or terminal invalid\n */\nexport function exitAlternateBuffer(terminal: Terminal, reason: string): boolean {\n if (!isTerminalValid(terminal)) {\n console.warn(`[AlternateBuffer] Cannot exit: terminal invalid (reason: ${reason})`);\n return false;\n }\n\n if (!alternateBufferState.has(terminal)) {\n console.warn(`[AlternateBuffer] Not in alternate buffer, exit requested by: ${reason}`);\n return false;\n }\n\n terminal.write('\\x1b[?1049l'); // Exit alternate screen buffer\n terminal.write('\\x1b[?25h'); // Show cursor\n\n alternateBufferState.delete(terminal);\n return true;\n}\n\n/**\n * Check if terminal is currently in alternate buffer\n */\nexport function isInAlternateBuffer(terminal: Terminal): boolean {\n return alternateBufferState.has(terminal);\n}\n\n/**\n * Force exit alternate buffer without state check (for error recovery)\n * Use sparingly - prefer exitAlternateBuffer for normal operations\n */\nexport function forceExitAlternateBuffer(terminal: Terminal, reason: string): void {\n if (!isTerminalValid(terminal)) {\n console.warn(`[AlternateBuffer] Cannot force exit: terminal invalid (reason: ${reason})`);\n return;\n }\n\n terminal.write('\\x1b[?1049l');\n terminal.write('\\x1b[?25h');\n alternateBufferState.delete(terminal);\n console.warn(`[AlternateBuffer] Force exited (reason: ${reason})`);\n}\n\n// ============================================================================\n// Theme Color Utilities\n// ============================================================================\n\n/**\n * Get theme-appropriate ANSI color escape code\n */\nexport function getThemeColorCode(mode: PhosphorMode): string {\n return getAnsiColor(mode);\n}\n\n/**\n * Get current theme color code\n */\nexport function getCurrentThemeColor(): string {\n return getAnsiColor(currentTheme);\n}\n\n/**\n * Check if current theme is a light theme (needs dark text)\n */\nexport function isLightTheme(): boolean {\n return checkLightTheme(currentTheme);\n}\n\n/**\n * Get a subtle/muted color that blends with the terminal background\n * Useful for background elements like doors, walls, etc.\n */\nexport function getSubtleBackgroundColor(): string {\n return getSubtleColor(currentTheme);\n}\n\n// ============================================================================\n// Layout Utilities\n// ============================================================================\n\ninterface VerticalAnchorOptions {\n headerRows?: number;\n footerRows?: number;\n minTop?: number;\n}\n\n/**\n * Compute a vertically-centered top row for content while reserving header/footer space.\n */\nexport function getVerticalAnchor(\n terminalRows: number,\n contentRows: number,\n options: VerticalAnchorOptions = {}\n): number {\n const headerRows = options.headerRows ?? 0;\n const footerRows = options.footerRows ?? 0;\n const minTop = Math.max(1, options.minTop ?? 1);\n\n const availableRows = terminalRows - headerRows - footerRows;\n const centeredTop = headerRows + Math.floor((availableRows - contentRows) / 2) + 1;\n\n return Math.max(minTop, centeredTop);\n}\n\n// Re-export PhosphorMode type for convenience\nexport type { PhosphorMode } from '../themes';\n","/**\n * Game Transitions - Centralized hacker-style transition effects\n *\n * Provides cinematic transitions for game entry, exit, and switching.\n * Games don't need to know about these - they just dispatch events.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from './utils';\n\n// Transition timing constants\nconst BOOT_DURATION = 800; // ms for boot sequence\nconst EXIT_DURATION = 400; // ms for exit sequence\nconst SWITCH_DURATION = 600; // ms for game switch\n\n// Boot messages - randomized hacker-style text\nconst BOOT_MESSAGES = [\n 'INITIALIZING NEURAL INTERFACE...',\n 'LOADING HYPER PROTOCOLS...',\n 'BYPASSING SECURITY LAYER...',\n 'ESTABLISHING UPLINK...',\n 'DECRYPTING GAME MODULE...',\n 'INJECTING PAYLOAD...',\n 'COMPILING RUNTIME...',\n 'SYNCHRONIZING CORES...',\n];\n\nconst EXIT_MESSAGES = [\n 'CONNECTION TERMINATED',\n 'SIGNAL LOST',\n 'LINK SEVERED',\n 'SESSION CLOSED',\n 'UPLINK DISCONNECTED',\n];\n\nconst SWITCH_MESSAGES = [\n 'REROUTING SIGNAL...',\n 'SWITCHING CHANNELS...',\n 'REALLOCATING RESOURCES...',\n 'LOADING NEW PROTOCOL...',\n];\n\n// ASCII art for transitions\nconst LOADING_FRAMES = [\n '[ ]',\n '[= ]',\n '[== ]',\n '[=== ]',\n '[====]',\n '[ ===]',\n '[ ==]',\n '[ =]',\n];\n\nconst GLITCH_CHARS = '!@#$%^&*()_+-=[]{}|;:,.<>?/~`░▒▓█▀▄';\n\n/**\n * Generate a random glitch string\n */\nfunction glitchText(length: number): string {\n let result = '';\n for (let i = 0; i < length; i++) {\n result += GLITCH_CHARS[Math.floor(Math.random() * GLITCH_CHARS.length)];\n }\n return result;\n}\n\n/**\n * Get random message from array\n */\nfunction randomMessage(messages: string[]): string {\n return messages[Math.floor(Math.random() * messages.length)];\n}\n\n/**\n * Sleep helper\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Boot transition - plays before game starts\n */\nexport async function playBootTransition(terminal: Terminal): Promise<void> {\n const themeColor = getCurrentThemeColor();\n const cols = terminal.cols;\n\n // Enter alternate buffer for clean transition\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l'); // Hide cursor\n terminal.write('\\x1b[2J\\x1b[H'); // Clear screen\n\n const centerX = Math.floor(cols / 2);\n\n // Quick glitch burst\n for (let i = 0; i < 3; i++) {\n const glitchLine = glitchText(cols);\n const glitchY = Math.floor(Math.random() * 10) + 5;\n terminal.write(`\\x1b[${glitchY};1H\\x1b[91m${glitchLine}\\x1b[0m`);\n await sleep(30);\n terminal.write(`\\x1b[${glitchY};1H${' '.repeat(cols)}`);\n }\n\n // Boot message\n const bootMsg = randomMessage(BOOT_MESSAGES);\n const msgX = Math.max(1, centerX - Math.floor(bootMsg.length / 2));\n terminal.write(`\\x1b[8;${msgX}H${themeColor}${bootMsg}\\x1b[0m`);\n\n // Loading bar animation\n const barY = 10;\n const loadingLabel = 'LOADING: ';\n const barX = Math.max(1, centerX - Math.floor((loadingLabel.length + 8) / 2));\n\n for (let i = 0; i < LOADING_FRAMES.length; i++) {\n const frame = LOADING_FRAMES[i];\n terminal.write(`\\x1b[${barY};${barX}H\\x1b[2m${themeColor}${loadingLabel}${frame}\\x1b[0m`);\n await sleep(BOOT_DURATION / LOADING_FRAMES.length);\n }\n\n // Final flash\n terminal.write(`\\x1b[${barY};${barX}H${themeColor}\\x1b[1m${loadingLabel}[DONE]\\x1b[0m`);\n await sleep(100);\n\n // Clear for game\n terminal.write('\\x1b[2J\\x1b[H');\n\n // Exit alternate buffer - game will re-enter\n terminal.write('\\x1b[?1049l');\n terminal.write('\\x1b[?25h');\n}\n\n/**\n * Exit transition - plays when game quits back to shell\n */\nexport async function playExitTransition(terminal: Terminal): Promise<void> {\n const themeColor = getCurrentThemeColor();\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // We're already in alternate buffer from the game\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n\n // Glitch effect - corrupt the screen\n for (let i = 0; i < 5; i++) {\n const glitchY = Math.floor(Math.random() * rows) + 1;\n const glitchLine = GLITCH_CHARS.repeat(Math.floor(cols / GLITCH_CHARS.length) + 1).slice(0, cols);\n terminal.write(`\\x1b[${glitchY};1H\\x1b[91m${glitchLine}\\x1b[0m`);\n await sleep(30);\n }\n\n // Exit message\n const exitMsg = randomMessage(EXIT_MESSAGES);\n const msgX = Math.max(1, centerX - Math.floor(exitMsg.length / 2));\n\n // Flash the message\n for (let i = 0; i < 3; i++) {\n terminal.write(`\\x1b[${centerY};${msgX}H\\x1b[1;91m${exitMsg}\\x1b[0m`);\n await sleep(60);\n terminal.write(`\\x1b[${centerY};${msgX}H${' '.repeat(exitMsg.length)}`);\n await sleep(40);\n }\n terminal.write(`\\x1b[${centerY};${msgX}H\\x1b[2m${themeColor}${exitMsg}\\x1b[0m`);\n await sleep(150);\n\n // Screen wipe down effect\n for (let y = 1; y <= rows; y += 2) {\n terminal.write(`\\x1b[${y};1H${' '.repeat(cols)}`);\n if (y + 1 <= rows) {\n terminal.write(`\\x1b[${y + 1};1H${' '.repeat(cols)}`);\n }\n await sleep(EXIT_DURATION / (rows / 2));\n }\n}\n\n/**\n * Switch transition - plays when switching to a new game\n */\nexport async function playSwitchTransition(terminal: Terminal): Promise<void> {\n const themeColor = getCurrentThemeColor();\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n\n // Quick screen corruption\n for (let i = 0; i < 4; i++) {\n const y1 = Math.floor(Math.random() * rows) + 1;\n const y2 = Math.floor(Math.random() * rows) + 1;\n terminal.write(`\\x1b[${y1};1H\\x1b[96m${glitchText(cols)}\\x1b[0m`);\n terminal.write(`\\x1b[${y2};1H\\x1b[95m${glitchText(cols)}\\x1b[0m`);\n await sleep(40);\n }\n\n // Clear center for message\n for (let y = centerY - 1; y <= centerY + 1; y++) {\n terminal.write(`\\x1b[${y};1H${' '.repeat(cols)}`);\n }\n\n // Switch message with spinner\n const switchMsg = randomMessage(SWITCH_MESSAGES);\n const msgX = Math.max(1, centerX - Math.floor(switchMsg.length / 2));\n const spinnerChars = ['|', '/', '-', '\\\\'];\n\n for (let i = 0; i < 8; i++) {\n const spinner = spinnerChars[i % spinnerChars.length];\n terminal.write(`\\x1b[${centerY};${msgX - 2}H${themeColor}${spinner}\\x1b[0m`);\n terminal.write(`\\x1b[${centerY};${msgX}H\\x1b[1m${themeColor}${switchMsg}\\x1b[0m`);\n await sleep(SWITCH_DURATION / 8);\n }\n\n // Quick fade out\n terminal.write('\\x1b[2J\\x1b[H');\n await sleep(50);\n}\n\n/**\n * Quick boot - shorter version for game switching (game-to-game)\n */\nexport async function playQuickBoot(terminal: Terminal): Promise<void> {\n const themeColor = getCurrentThemeColor();\n const cols = terminal.cols;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n terminal.write('\\x1b[2J\\x1b[H');\n\n const centerX = Math.floor(cols / 2);\n\n // Just a quick loading indicator\n const msg = 'LOADING...';\n const msgX = Math.max(1, centerX - Math.floor(msg.length / 2));\n\n terminal.write(`\\x1b[8;${msgX}H${themeColor}${msg}\\x1b[0m`);\n\n // Quick bar\n for (let i = 0; i < 5; i++) {\n const bar = '='.repeat(i + 1).padEnd(5, ' ');\n terminal.write(`\\x1b[10;${msgX}H${themeColor}[${bar}]\\x1b[0m`);\n await sleep(60);\n }\n\n await sleep(50);\n terminal.write('\\x1b[2J\\x1b[H');\n terminal.write('\\x1b[?1049l');\n terminal.write('\\x1b[?25h');\n}\n\n/**\n * Select transition - plays when selecting a game from the menu\n * Shows the game name with a cool reveal effect\n */\nexport async function playSelectTransition(terminal: Terminal, gameName: string): Promise<void> {\n const themeColor = getCurrentThemeColor();\n const cols = terminal.cols;\n const rows = terminal.rows;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n\n // Clear screen with a quick flash\n terminal.write('\\x1b[2J\\x1b[H');\n terminal.write(`\\x1b[48;5;255m${' '.repeat(cols * rows)}\\x1b[0m`);\n await sleep(30);\n terminal.write('\\x1b[2J\\x1b[H');\n await sleep(50);\n\n // Draw scan lines converging to center\n for (let i = 0; i < 6; i++) {\n const offset = 6 - i;\n // Top and bottom lines moving to center\n if (centerY - offset > 0) {\n terminal.write(`\\x1b[${centerY - offset};1H${themeColor}${'─'.repeat(cols)}\\x1b[0m`);\n }\n if (centerY + offset <= rows) {\n terminal.write(`\\x1b[${centerY + offset};1H${themeColor}${'─'.repeat(cols)}\\x1b[0m`);\n }\n await sleep(30);\n // Clear previous lines\n if (i > 0) {\n const prevOffset = 7 - i;\n if (centerY - prevOffset > 0) {\n terminal.write(`\\x1b[${centerY - prevOffset};1H${' '.repeat(cols)}`);\n }\n if (centerY + prevOffset <= rows) {\n terminal.write(`\\x1b[${centerY + prevOffset};1H${' '.repeat(cols)}`);\n }\n }\n }\n\n // Clear for game name reveal\n terminal.write('\\x1b[2J\\x1b[H');\n\n // Glitch reveal of game name\n const displayName = `▶ ${gameName} ◀`;\n const nameX = Math.max(1, centerX - Math.floor(displayName.length / 2));\n\n // Glitch through random characters then reveal\n for (let frame = 0; frame < 8; frame++) {\n let revealed = '';\n for (let i = 0; i < displayName.length; i++) {\n if (frame >= 6 || Math.random() < frame / 8) {\n revealed += displayName[i];\n } else {\n revealed += GLITCH_CHARS[Math.floor(Math.random() * GLITCH_CHARS.length)];\n }\n }\n terminal.write(`\\x1b[${centerY};${nameX}H\\x1b[1m${themeColor}${revealed}\\x1b[0m`);\n await sleep(50);\n }\n\n // Final clean display with glow effect (bright)\n terminal.write(`\\x1b[${centerY};${nameX}H\\x1b[1;7m${themeColor}${displayName}\\x1b[0m`);\n await sleep(150);\n\n // Subtitle\n const loadingMsg = 'INITIALIZING...';\n const loadingX = Math.max(1, centerX - Math.floor(loadingMsg.length / 2));\n terminal.write(`\\x1b[${centerY + 2};${loadingX}H\\x1b[2m${themeColor}${loadingMsg}\\x1b[0m`);\n\n // Quick loading bar\n const barWidth = 20;\n const barX = Math.max(1, centerX - Math.floor(barWidth / 2) - 1);\n for (let i = 0; i <= barWidth; i++) {\n const filled = '█'.repeat(i);\n const empty = '░'.repeat(barWidth - i);\n terminal.write(`\\x1b[${centerY + 4};${barX}H${themeColor}[${filled}${empty}]\\x1b[0m`);\n await sleep(20);\n }\n\n await sleep(100);\n\n // Wipe out effect\n for (let i = 0; i < 3; i++) {\n terminal.write('\\x1b[2J\\x1b[H');\n await sleep(30);\n terminal.write(`\\x1b[${centerY};${nameX}H\\x1b[1m${themeColor}${displayName}\\x1b[0m`);\n await sleep(30);\n }\n\n terminal.write('\\x1b[2J\\x1b[H');\n await sleep(50);\n}\n\n// Export event types for games to dispatch\nexport const GAME_EVENTS = {\n // Game wants to quit back to shell\n QUIT: 'hypersurge:game-quit',\n // Game wants to switch to another random game\n SWITCH: 'hypersurge:random-game',\n // Game wants to show the games menu\n GAMES_MENU: 'hypersurge:games-menu',\n // Launch a specific game by id\n LAUNCH_GAME: 'hypersurge:launch-game',\n} as const;\n\n/**\n * Helper for games to dispatch quit event\n * This triggers the exit transition before returning to shell\n */\nexport function dispatchGameQuit(terminal: Terminal): void {\n window.dispatchEvent(new CustomEvent(GAME_EVENTS.QUIT, {\n detail: { terminal }\n }));\n}\n\n/**\n * Helper for games to dispatch switch event\n * This triggers the switch transition before loading new game\n */\nexport function dispatchGameSwitch(terminal: Terminal): void {\n window.dispatchEvent(new CustomEvent(GAME_EVENTS.SWITCH, {\n detail: { terminal }\n }));\n}\n\n/**\n * Helper for games to dispatch games menu event\n * This triggers the games menu to let user select a game\n */\nexport function dispatchGamesMenu(terminal: Terminal): void {\n window.dispatchEvent(new CustomEvent(GAME_EVENTS.GAMES_MENU, {\n detail: { terminal }\n }));\n}\n\n/**\n * Helper to dispatch launch game event\n * This triggers TerminalPool to launch a specific game with proper tracking\n */\nexport function dispatchLaunchGame(terminal: Terminal, gameId: string): void {\n window.dispatchEvent(new CustomEvent(GAME_EVENTS.LAUNCH_GAME, {\n detail: { terminal, gameId }\n }));\n}\n","/**\n * Shared Menu System for Easter Egg Games\n *\n * Provides consistent menu navigation (arrow keys + Enter/Space)\n * while maintaining keyboard shortcuts for quick access.\n */\n\nimport { getCurrentThemeColor } from '../utils';\n\nexport interface MenuItem {\n label: string;\n shortcut?: string; // e.g., 'ESC', 'R', 'Q'\n action: () => void;\n}\n\nexport interface MenuState {\n selection: number;\n items: MenuItem[];\n}\n\n/**\n * Create a new menu state\n */\nexport function createMenuState(items: MenuItem[]): MenuState {\n return {\n selection: 0,\n items,\n };\n}\n\n/**\n * Navigate menu selection up\n */\nexport function menuUp(state: MenuState): void {\n state.selection = (state.selection - 1 + state.items.length) % state.items.length;\n}\n\n/**\n * Navigate menu selection down\n */\nexport function menuDown(state: MenuState): void {\n state.selection = (state.selection + 1) % state.items.length;\n}\n\n/**\n * Reset menu selection to top\n */\nexport function menuReset(state: MenuState): void {\n state.selection = 0;\n}\n\n/**\n * Execute the currently selected menu item\n */\nexport function menuConfirm(state: MenuState): void {\n const item = state.items[state.selection];\n if (item) {\n item.action();\n }\n}\n\n/**\n * Handle keyboard input for menu navigation\n * Returns true if the key was handled, false otherwise\n */\nexport function handleMenuInput(\n state: MenuState,\n key: string,\n domEvent: KeyboardEvent\n): boolean {\n // Arrow navigation\n if (domEvent.key === 'ArrowUp' || key === 'w') {\n menuUp(state);\n return true;\n }\n if (domEvent.key === 'ArrowDown' || key === 's') {\n menuDown(state);\n return true;\n }\n\n // Confirm selection\n if (domEvent.key === 'Enter' || domEvent.key === ' ') {\n menuConfirm(state);\n return true;\n }\n\n // Check keyboard shortcuts\n for (let i = 0; i < state.items.length; i++) {\n const item = state.items[i];\n if (item.shortcut && key === item.shortcut.toLowerCase()) {\n item.action();\n return true;\n }\n }\n\n return false;\n}\n\nexport interface RenderMenuOptions {\n title: string;\n x: number; // Center X position\n y: number; // Starting Y position\n width?: number; // Box width (auto-calculated if not provided)\n showShortcuts?: boolean; // Show shortcuts in menu (default: true)\n blinkTitle?: boolean; // Add blink effect to title (default: true)\n}\n\n/**\n * Render a menu box with highlighted selection\n * Returns ANSI escape sequence string\n */\nexport function renderMenu(\n state: MenuState,\n options: RenderMenuOptions\n): string {\n const themeColor = getCurrentThemeColor();\n const { title, x, y, showShortcuts = true, blinkTitle = true } = options;\n\n // Calculate width based on longest item\n let maxWidth = title.length;\n for (const item of state.items) {\n let itemText = item.label;\n if (showShortcuts && item.shortcut) {\n itemText += ` [${item.shortcut}]`;\n }\n // Account for selection indicators ► ◄\n maxWidth = Math.max(maxWidth, itemText.length + 6);\n }\n // width is calculated but not used currently - kept for potential future use\n void (options.width || maxWidth + 4);\n\n let output = '';\n\n // Title with optional blink\n const titleX = x - Math.floor(title.length / 2);\n const titleStyle = blinkTitle ? '\\x1b[5m' : '';\n output += `\\x1b[${y};${titleX}H${titleStyle}${themeColor}${title}\\x1b[0m`;\n\n // Menu items\n let itemY = y + 2;\n for (let i = 0; i < state.items.length; i++) {\n const item = state.items[i];\n const isSelected = i === state.selection;\n\n let displayText = item.label;\n if (showShortcuts && item.shortcut) {\n displayText += ` [${item.shortcut}]`;\n }\n\n // Selection highlighting\n const text = isSelected ? `► ${displayText} ◄` : ` ${displayText} `;\n const style = isSelected ? '\\x1b[1;93m' : `\\x1b[2m${themeColor}`;\n\n const itemX = x - Math.floor(text.length / 2);\n output += `\\x1b[${itemY};${itemX}H${style}${text}\\x1b[0m`;\n itemY++;\n }\n\n // Navigation hint\n const hint = '↑↓ Navigate Enter Select';\n const hintX = x - Math.floor(hint.length / 2);\n output += `\\x1b[${itemY + 1};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n return output;\n}\n\n/**\n * Standard pause menu items used across most games\n */\nexport function createPauseMenuItems(callbacks: {\n onResume: () => void;\n onRestart: () => void;\n onQuit: () => void;\n onListGames?: () => void;\n onNextGame?: () => void;\n onHelp?: () => void;\n}): MenuItem[] {\n const items: MenuItem[] = [\n { label: 'RESUME', shortcut: 'ESC', action: callbacks.onResume },\n { label: 'RESTART', shortcut: 'R', action: callbacks.onRestart },\n { label: 'QUIT', shortcut: 'Q', action: callbacks.onQuit },\n ];\n\n if (callbacks.onHelp) {\n items.push({ label: 'HELP', shortcut: 'H', action: callbacks.onHelp });\n }\n\n if (callbacks.onListGames) {\n items.push({ label: 'LIST GAMES', shortcut: 'L', action: callbacks.onListGames });\n }\n\n if (callbacks.onNextGame) {\n items.push({ label: 'NEXT GAME', shortcut: 'N', action: callbacks.onNextGame });\n }\n\n return items;\n}\n\n/**\n * Standard game over menu items\n */\nexport function createGameOverMenuItems(callbacks: {\n onRestart: () => void;\n onQuit: () => void;\n onNextGame?: () => void;\n}): MenuItem[] {\n const items: MenuItem[] = [\n { label: 'RESTART', shortcut: 'R', action: callbacks.onRestart },\n { label: 'QUIT', shortcut: 'Q', action: callbacks.onQuit },\n ];\n\n if (callbacks.onNextGame) {\n items.push({ label: 'NEXT GAME', shortcut: 'N', action: callbacks.onNextGame });\n }\n\n return items;\n}\n\n/**\n * Mode selection menu (Tutorial/Play) used by games with tutorials\n */\nexport function createModeSelectMenuItems(callbacks: {\n onTutorial: () => void;\n onPlay: () => void;\n}): MenuItem[] {\n return [\n { label: 'TUTORIAL', shortcut: 'T', action: callbacks.onTutorial },\n { label: 'PLAY', shortcut: 'P', action: callbacks.onPlay },\n ];\n}\n\n// ============================================================================\n// Simple Menu Helpers (for gradual adoption)\n// These work with just indices, no callbacks needed\n// ============================================================================\n\nexport interface SimpleMenuItem {\n label: string;\n shortcut?: string;\n}\n\n/**\n * Handle menu navigation without callbacks\n * Returns new selection index\n */\nexport function navigateMenu(\n currentSelection: number,\n itemCount: number,\n key: string,\n domEvent: KeyboardEvent\n): { newSelection: number; confirmed: boolean } {\n let newSelection = currentSelection;\n let confirmed = false;\n\n if (domEvent.key === 'ArrowUp' || key === 'w') {\n newSelection = (currentSelection - 1 + itemCount) % itemCount;\n } else if (domEvent.key === 'ArrowDown' || key === 's') {\n newSelection = (currentSelection + 1) % itemCount;\n } else if (domEvent.key === 'Enter' || domEvent.key === ' ') {\n confirmed = true;\n }\n\n return { newSelection, confirmed };\n}\n\n/**\n * Check if a shortcut key was pressed\n * Returns the index of the matching item, or -1 if no match\n */\nexport function checkShortcut(\n items: SimpleMenuItem[],\n key: string\n): number {\n for (let i = 0; i < items.length; i++) {\n const shortcut = items[i].shortcut;\n if (shortcut && key === shortcut.toLowerCase()) {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * Render a simple menu (index-based, no callbacks)\n * Returns ANSI escape sequence string\n */\nexport function renderSimpleMenu(\n items: SimpleMenuItem[],\n selection: number,\n options: {\n centerX: number;\n startY: number;\n showShortcuts?: boolean;\n }\n): string {\n const themeColor = getCurrentThemeColor();\n const { centerX, startY, showShortcuts = true } = options;\n\n let output = '';\n\n items.forEach((item, i) => {\n const isSelected = i === selection;\n\n let displayText = item.label;\n if (showShortcuts && item.shortcut) {\n displayText += ` [${item.shortcut}]`;\n }\n\n const text = isSelected ? `► ${displayText} ◄` : ` ${displayText} `;\n const style = isSelected ? '\\x1b[1;93m' : `\\x1b[2m${themeColor}`;\n\n const itemX = centerX - Math.floor(text.length / 2);\n output += `\\x1b[${startY + i};${itemX}H${style}${text}\\x1b[0m`;\n });\n\n return output;\n}\n\n/**\n * Common pause menu items definition\n */\nexport const PAUSE_MENU_ITEMS: SimpleMenuItem[] = [\n { label: 'RESUME', shortcut: 'ESC' },\n { label: 'RESTART', shortcut: 'R' },\n { label: 'QUIT', shortcut: 'Q' },\n { label: 'LIST GAMES', shortcut: 'L' },\n { label: 'NEXT GAME', shortcut: 'N' },\n];\n\n/**\n * Common mode select items definition\n */\nexport const MODE_SELECT_ITEMS: SimpleMenuItem[] = [\n { label: 'TUTORIAL', shortcut: 'T' },\n { label: 'PLAY', shortcut: 'P' },\n];\n","/**\n * Pure slide/merge logic for 2048 game\n * Extracted for testability\n */\n\nexport interface SlideResult {\n result: number[];\n merged: boolean[];\n moved: boolean;\n mergeScore: number;\n}\n\n/**\n * Slide and merge a row of tiles toward index 0\n * This is the core 2048 mechanic\n *\n * @param row - Array of tile values (0 = empty)\n * @param gridSize - Size of the grid (default 4)\n * @returns SlideResult with new row, merge info, and score\n */\nexport function slide(row: number[], gridSize: number = 4): SlideResult {\n // Filter out empty cells\n const filtered = row.filter(x => x !== 0);\n const merged: boolean[] = [];\n const result: number[] = [];\n\n // Check if tiles will move just by compacting\n let moved = row.some((v, i) => v !== 0 && i >= filtered.length);\n let mergeScore = 0;\n\n // Process tiles, merging adjacent equal values\n let i = 0;\n while (i < filtered.length) {\n if (i + 1 < filtered.length && filtered[i] === filtered[i + 1]) {\n // Merge two equal tiles\n const newVal = filtered[i] * 2;\n result.push(newVal);\n merged.push(true);\n mergeScore += newVal;\n moved = true;\n i += 2;\n } else {\n // Keep single tile\n result.push(filtered[i]);\n merged.push(false);\n i++;\n }\n }\n\n // Pad with zeros\n while (result.length < gridSize) {\n result.push(0);\n merged.push(false);\n }\n\n // Final check if anything actually moved\n if (!moved) {\n moved = row.some((v, idx) => v !== result[idx]);\n }\n\n return { result, merged, moved, mergeScore };\n}\n\n/**\n * Check if any moves are possible on the grid\n *\n * @param grid - 2D array of tile values\n * @returns true if at least one move is possible\n */\nexport function canMakeMove(grid: number[][]): boolean {\n const size = grid.length;\n\n // Check for empty cells\n for (let y = 0; y < size; y++) {\n for (let x = 0; x < size; x++) {\n if (grid[y][x] === 0) return true;\n }\n }\n\n // Check for adjacent equal values\n for (let y = 0; y < size; y++) {\n for (let x = 0; x < size; x++) {\n const val = grid[y][x];\n // Check right neighbor\n if (x < size - 1 && grid[y][x + 1] === val) return true;\n // Check bottom neighbor\n if (y < size - 1 && grid[y + 1][x] === val) return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if the grid contains a 2048 (or higher) tile\n *\n * @param grid - 2D array of tile values\n * @param target - Target value (default 2048)\n * @returns true if target value exists\n */\nexport function hasReachedTarget(grid: number[][], target: number = 2048): boolean {\n for (const row of grid) {\n for (const cell of row) {\n if (cell >= target) return true;\n }\n }\n return false;\n}\n","/**\n * Hyper 2048\n *\n * Slide and merge DATA PACKETS to reach TERABYTE (2048).\n * Cyberpunk-themed with glitchy effects and theme-aware colors.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\nimport { slide as slideLogic, canMakeMove, hasReachedTarget } from './slideLogic';\n\n/**\n * 2048 Game Controller\n */\nexport interface Game2048Controller {\n stop: () => void;\n isRunning: boolean;\n}\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\ninterface UndoState {\n grid: number[][];\n score: number;\n}\n\n// ============================================================================\n// TILE COLORS AND NAMES (Cyberpunk Data Theme)\n// ============================================================================\n\nconst TILE_COLORS: Record<number, string> = {\n 2: '\\x1b[38;5;252m', // Light gray - BIT\n 4: '\\x1b[38;5;159m', // Light cyan - BYTE\n 8: '\\x1b[38;5;51m', // Cyan - WORD\n 16: '\\x1b[38;5;45m', // Blue-cyan - BLOCK\n 32: '\\x1b[38;5;39m', // Blue - SECTOR\n 64: '\\x1b[38;5;33m', // Deep blue - CLUSTER\n 128: '\\x1b[38;5;171m', // Purple - SEGMENT\n 256: '\\x1b[38;5;207m', // Magenta - PACKET\n 512: '\\x1b[38;5;213m', // Pink - FRAME\n 1024: '\\x1b[38;5;220m', // Gold - GIGABYTE\n 2048: '\\x1b[38;5;226m', // Bright gold - TERABYTE\n 4096: '\\x1b[38;5;196m', // Red - PETABYTE\n 8192: '\\x1b[38;5;201m', // Hot pink - EXABYTE\n};\n\nconst TILE_NAMES: Record<number, string> = {\n 2: 'BIT',\n 4: 'BYTE',\n 8: 'WORD',\n 16: 'BLOCK',\n 32: 'SECTOR',\n 64: 'CLUSTER',\n 128: 'SEGMENT',\n 256: 'PACKET',\n 512: 'FRAME',\n 1024: 'GIGA',\n 2048: 'TERA',\n 4096: 'PETA',\n 8192: 'EXA',\n};\n\nconst TILE_BG_COLORS: Record<number, string> = {\n 2: '\\x1b[48;5;236m',\n 4: '\\x1b[48;5;23m',\n 8: '\\x1b[48;5;24m',\n 16: '\\x1b[48;5;25m',\n 32: '\\x1b[48;5;26m',\n 64: '\\x1b[48;5;27m',\n 128: '\\x1b[48;5;53m',\n 256: '\\x1b[48;5;90m',\n 512: '\\x1b[48;5;127m',\n 1024: '\\x1b[48;5;136m',\n 2048: '\\x1b[48;5;178m',\n 4096: '\\x1b[48;5;160m',\n 8192: '\\x1b[48;5;198m',\n};\n\n// ============================================================================\n// MAIN GAME FUNCTION\n// ============================================================================\n\nexport function run2048Game(terminal: Terminal): Game2048Controller {\n const themeColor = getCurrentThemeColor();\n\n // -------------------------------------------------------------------------\n // CONSTANTS\n // -------------------------------------------------------------------------\n const MIN_COLS = 36;\n const MIN_ROWS = 16;\n const GRID_SIZE = 4;\n const TILE_WIDTH = 8;\n const TILE_HEIGHT = 3;\n const GAME_WIDTH = GRID_SIZE * TILE_WIDTH + 2;\n const GAME_HEIGHT = GRID_SIZE * TILE_HEIGHT + 2;\n const MAX_UNDOS = 3;\n\n // -------------------------------------------------------------------------\n // STATE\n // -------------------------------------------------------------------------\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let won = false;\n let continuedAfterWin = false;\n let score = 0;\n let highScore = 0;\n\n let grid: number[][] = [];\n let undoStack: UndoState[] = [];\n let undosRemaining = MAX_UNDOS;\n\n let gameLeft = 2;\n let gameTop = 4;\n\n let glitchFrame = 0;\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let shakeFrames = 0;\n let shakeIntensity = 0;\n\n // -------------------------------------------------------------------------\n // CONTROLLER\n // -------------------------------------------------------------------------\n const controller: Game2048Controller = {\n stop: () => {\n if (!running) return;\n running = false;\n },\n get isRunning() { return running; }\n };\n\n // -------------------------------------------------------------------------\n // ASCII ART TITLE\n // -------------------------------------------------------------------------\n const title = [\n '\\u2588 \\u2588 \\u2588\\u2584\\u2588 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2580\\u2588 \\u2582\\u2580\\u2580\\u2588 \\u2580\\u2580\\u2588 \\u2584 \\u2588\\u2580\\u2580 \\u2580\\u2588\\u2580',\n '\\u2588\\u2580\\u2588 \\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2588\\u2584 \\u2588\\u2580\\u2584 \\u2584\\u2580\\u2580\\u2584 \\u2580\\u2580\\u2584 \\u2588\\u2580\\u2584 \\u2588\\u2588\\u2584 \\u2588 ',\n ];\n\n // -------------------------------------------------------------------------\n // EFFECTS\n // -------------------------------------------------------------------------\n\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['\\u2726', '\\u2605', '\\u25C6', '\\u25CF']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.3 + Math.random() * 0.5;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 12 + Math.floor(Math.random() * 8),\n });\n }\n }\n\n function spawnMergeParticles(gridX: number, gridY: number, value: number) {\n const screenX = gridX * TILE_WIDTH + TILE_WIDTH / 2;\n const screenY = gridY * TILE_HEIGHT + TILE_HEIGHT / 2;\n const color = TILE_COLORS[value] || '\\x1b[97m';\n const dataChars = ['\\u2588', '\\u2593', '\\u2592', '\\u2591', '\\u25A0', '\\u25A1'];\n spawnParticles(screenX, screenY, 8, color, dataChars);\n }\n\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 20, color });\n }\n\n function triggerShake(frames: number, intensity: number) {\n shakeFrames = frames;\n shakeIntensity = intensity;\n }\n\n // -------------------------------------------------------------------------\n // GRID HELPERS\n // -------------------------------------------------------------------------\n\n function createEmptyGrid(): number[][] {\n return Array(GRID_SIZE).fill(null).map(() => Array(GRID_SIZE).fill(0));\n }\n\n function copyGrid(g: number[][]): number[][] {\n return g.map(row => [...row]);\n }\n\n function getEmptyCells(): [number, number][] {\n const empty: [number, number][] = [];\n for (let y = 0; y < GRID_SIZE; y++) {\n for (let x = 0; x < GRID_SIZE; x++) {\n if (grid[y][x] === 0) {\n empty.push([x, y]);\n }\n }\n }\n return empty;\n }\n\n function spawnTile() {\n const empty = getEmptyCells();\n if (empty.length === 0) return;\n const [x, y] = empty[Math.floor(Math.random() * empty.length)];\n grid[y][x] = Math.random() < 0.9 ? 2 : 4;\n }\n\n // Use imported canMakeMove\n function canMove(): boolean {\n return canMakeMove(grid);\n }\n\n // Use imported hasReachedTarget\n function has2048(): boolean {\n return hasReachedTarget(grid, 2048);\n }\n\n // -------------------------------------------------------------------------\n // MOVE LOGIC\n // -------------------------------------------------------------------------\n\n function saveState() {\n if (undoStack.length >= MAX_UNDOS) {\n undoStack.shift();\n }\n undoStack.push({\n grid: copyGrid(grid),\n score: score,\n });\n }\n\n function undo() {\n if (undoStack.length === 0 || undosRemaining <= 0) return false;\n const state = undoStack.pop()!;\n grid = state.grid;\n score = state.score;\n undosRemaining--;\n gameOver = false;\n won = false;\n return true;\n }\n\n // Use imported slideLogic with GRID_SIZE\n function slide(row: number[]) {\n return slideLogic(row, GRID_SIZE);\n }\n\n function move(direction: 'up' | 'down' | 'left' | 'right'): boolean {\n let totalMergeScore = 0;\n let anyMoved = false;\n\n if (direction === 'left') {\n for (let y = 0; y < GRID_SIZE; y++) {\n const { result, merged, moved, mergeScore } = slide(grid[y]);\n if (moved) anyMoved = true;\n totalMergeScore += mergeScore;\n for (let x = 0; x < GRID_SIZE; x++) {\n if (merged[x] && result[x] > 0) {\n spawnMergeParticles(x, y, result[x]);\n addScorePopup(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${result[x]}`, TILE_COLORS[result[x]]);\n }\n }\n grid[y] = result;\n }\n } else if (direction === 'right') {\n for (let y = 0; y < GRID_SIZE; y++) {\n const reversed = [...grid[y]].reverse();\n const { result, merged, moved, mergeScore } = slide(reversed);\n if (moved) anyMoved = true;\n totalMergeScore += mergeScore;\n const finalRow = result.reverse();\n const finalMerged = merged.reverse();\n for (let x = 0; x < GRID_SIZE; x++) {\n if (finalMerged[x] && finalRow[x] > 0) {\n spawnMergeParticles(x, y, finalRow[x]);\n addScorePopup(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${finalRow[x]}`, TILE_COLORS[finalRow[x]]);\n }\n }\n grid[y] = finalRow;\n }\n } else if (direction === 'up') {\n for (let x = 0; x < GRID_SIZE; x++) {\n const col = [];\n for (let y = 0; y < GRID_SIZE; y++) col.push(grid[y][x]);\n const { result, merged, moved, mergeScore } = slide(col);\n if (moved) anyMoved = true;\n totalMergeScore += mergeScore;\n for (let y = 0; y < GRID_SIZE; y++) {\n if (merged[y] && result[y] > 0) {\n spawnMergeParticles(x, y, result[y]);\n addScorePopup(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${result[y]}`, TILE_COLORS[result[y]]);\n }\n grid[y][x] = result[y];\n }\n }\n } else if (direction === 'down') {\n for (let x = 0; x < GRID_SIZE; x++) {\n const col = [];\n for (let y = 0; y < GRID_SIZE; y++) col.push(grid[y][x]);\n const reversed = col.reverse();\n const { result, merged, moved, mergeScore } = slide(reversed);\n if (moved) anyMoved = true;\n totalMergeScore += mergeScore;\n const finalCol = result.reverse();\n const finalMerged = merged.reverse();\n for (let y = 0; y < GRID_SIZE; y++) {\n if (finalMerged[y] && finalCol[y] > 0) {\n spawnMergeParticles(x, y, finalCol[y]);\n addScorePopup(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${finalCol[y]}`, TILE_COLORS[finalCol[y]]);\n }\n grid[y][x] = finalCol[y];\n }\n }\n }\n\n if (anyMoved) {\n score += totalMergeScore;\n if (totalMergeScore > 0) {\n triggerShake(4, 1);\n }\n spawnTile();\n\n if (!won && !continuedAfterWin && has2048()) {\n won = true;\n if (score > highScore) highScore = score;\n triggerShake(8, 2);\n for (let y = 0; y < GRID_SIZE; y++) {\n for (let x = 0; x < GRID_SIZE; x++) {\n if (grid[y][x] === 2048) {\n spawnMergeParticles(x, y, 2048);\n spawnMergeParticles(x, y, 2048);\n }\n }\n }\n }\n\n if (!canMove()) {\n gameOver = true;\n if (score > highScore) highScore = score;\n }\n\n return true;\n }\n\n return false;\n }\n\n // -------------------------------------------------------------------------\n // GAME LOGIC\n // -------------------------------------------------------------------------\n\n function initGame() {\n grid = createEmptyGrid();\n score = 0;\n gameOver = false;\n won = false;\n continuedAfterWin = false;\n paused = false;\n undoStack = [];\n undosRemaining = MAX_UNDOS;\n\n particles = [];\n scorePopups = [];\n shakeFrames = 0;\n\n spawnTile();\n spawnTile();\n }\n\n function update() {\n if (!gameStarted || (gameOver && !won) || paused) return;\n\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.03;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.2;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n }\n\n // -------------------------------------------------------------------------\n // RENDERING\n // -------------------------------------------------------------------------\n\n function renderTile(value: number, screenX: number, screenY: number): string {\n if (value === 0) {\n let output = '';\n const emptyChar = '\\u2591';\n for (let row = 0; row < TILE_HEIGHT; row++) {\n output += `\\x1b[${screenY + row};${screenX}H\\x1b[38;5;238m`;\n for (let col = 0; col < TILE_WIDTH; col++) {\n output += emptyChar;\n }\n output += '\\x1b[0m';\n }\n return output;\n }\n\n const color = TILE_COLORS[value] || '\\x1b[97m';\n const bgColor = TILE_BG_COLORS[value] || '\\x1b[48;5;240m';\n const name = TILE_NAMES[value] || value.toString();\n\n let output = '';\n\n output += `\\x1b[${screenY};${screenX}H${bgColor}${color}`;\n output += '\\u2584'.repeat(TILE_WIDTH);\n output += '\\x1b[0m';\n\n output += `\\x1b[${screenY + 1};${screenX}H${bgColor}${color}\\x1b[1m`;\n const displayText = name.length <= TILE_WIDTH - 2 ? name : value.toString();\n const padding = Math.floor((TILE_WIDTH - displayText.length) / 2);\n output += ' '.repeat(padding) + displayText + ' '.repeat(TILE_WIDTH - padding - displayText.length);\n output += '\\x1b[0m';\n\n output += `\\x1b[${screenY + 2};${screenX}H${bgColor}${color}`;\n output += '\\u2580'.repeat(TILE_WIDTH);\n output += '\\x1b[0m';\n\n return output;\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n if (shakeFrames > 0) shakeFrames--;\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = needWidth && needHeight ? 'Make pane larger'\n : needWidth ? 'Make pane wider ->' : 'Make pane taller v';\n const msg2 = `Need: ${MIN_COLS}x${MIN_ROWS} Have: ${cols}x${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH) / 2));\n gameTop = Math.max(4, Math.floor((rows - GAME_HEIGHT - 6) / 2));\n\n let renderLeft = gameLeft;\n let renderTop = gameTop;\n if (shakeFrames > 0) {\n renderLeft += Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n renderTop += Math.floor((Math.random() - 0.5) * shakeIntensity);\n }\n\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[1;${titleX}H\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `\\x1b[1;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n const stats = `SCORE: ${score.toString().padStart(6, '0')} HIGH: ${highScore.toString().padStart(6, '0')} UNDO: ${undosRemaining}/${MAX_UNDOS}`;\n const statsX = Math.floor((cols - stats.length) / 2);\n output += `\\x1b[${gameTop - 1};${statsX}H${themeColor}${stats}\\x1b[0m`;\n\n const borderWidth = GAME_WIDTH;\n output += `\\x1b[${renderTop};${renderLeft}H${themeColor}\\u2554${'\\u2550'.repeat(borderWidth)}\\u2557\\x1b[0m`;\n for (let y = 0; y < GAME_HEIGHT - 2; y++) {\n output += `\\x1b[${renderTop + 1 + y};${renderLeft}H${themeColor}\\u2551\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + y};${renderLeft + borderWidth + 1}H${themeColor}\\u2551\\x1b[0m`;\n }\n output += `\\x1b[${renderTop + GAME_HEIGHT - 1};${renderLeft}H${themeColor}\\u255A${'\\u2550'.repeat(borderWidth)}\\u255D\\x1b[0m`;\n\n if (paused) {\n const pauseMsg = '\\u2550\\u2550 PAUSED \\u2550\\u2550';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseY = gameTop + Math.floor(GAME_HEIGHT / 2) - 3;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = 'Up/Down select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n }\n else if (!gameStarted) {\n for (let gy = 0; gy < GRID_SIZE; gy++) {\n for (let gx = 0; gx < GRID_SIZE; gx++) {\n const tileX = renderLeft + 1 + gx * TILE_WIDTH;\n const tileY = renderTop + 1 + gy * TILE_HEIGHT;\n output += renderTile(0, tileX, tileY);\n }\n }\n\n const startMsg = '[ PRESS ANY KEY TO PLAY ]';\n const startX = Math.floor((cols - startMsg.length) / 2);\n const startY = gameTop + Math.floor(GAME_HEIGHT / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = 'Arrow Keys: SLIDE U: UNDO ESC: MENU';\n const ctrlX = Math.floor((cols - controls.length) / 2);\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n\n const goal = 'MERGE DATA PACKETS TO REACH TERABYTE (2048)';\n const goalX = Math.floor((cols - goal.length) / 2);\n output += `\\x1b[${startY + 4};${goalX}H\\x1b[2m${themeColor}${goal}\\x1b[0m`;\n }\n else if (won && !continuedAfterWin) {\n for (let gy = 0; gy < GRID_SIZE; gy++) {\n for (let gx = 0; gx < GRID_SIZE; gx++) {\n const tileX = renderLeft + 1 + gx * TILE_WIDTH;\n const tileY = renderTop + 1 + gy * TILE_HEIGHT;\n output += renderTile(grid[gy][gx], tileX, tileY);\n }\n }\n\n const winBox = [\n '\\u2554\\u2550\\u2550 TERABYTE ACHIEVED! \\u2550\\u2550\\u2557',\n '\\u2551 \\u2551',\n '\\u2551 [C] CONTINUE PLAYING \\u2551',\n '\\u2551 [R] NEW GAME \\u2551',\n '\\u2551 [Q] QUIT \\u2551',\n '\\u2551 \\u2551',\n '\\u255A\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255D',\n ];\n const boxWidth = winBox[0].length;\n const boxX = Math.floor((cols - boxWidth) / 2);\n const boxY = gameTop + Math.floor(GAME_HEIGHT / 2) - 3;\n\n for (let i = 0; i < winBox.length; i++) {\n const lineColor = i === 0 ? '\\x1b[1;92m' : themeColor;\n output += `\\x1b[${boxY + i};${boxX}H${lineColor}${winBox[i]}\\x1b[0m`;\n }\n }\n else if (gameOver) {\n for (let gy = 0; gy < GRID_SIZE; gy++) {\n for (let gx = 0; gx < GRID_SIZE; gx++) {\n const tileX = renderLeft + 1 + gx * TILE_WIDTH;\n const tileY = renderTop + 1 + gy * TILE_HEIGHT;\n output += renderTile(grid[gy][gx], tileX, tileY);\n }\n }\n\n const overMsg = '\\u2554\\u2550\\u2550 SYSTEM CRASH \\u2550\\u2550\\u2557';\n const overX = Math.floor((cols - overMsg.length) / 2);\n const overY = gameTop + Math.floor(GAME_HEIGHT / 2) - 2;\n output += `\\x1b[${overY};${overX}H\\x1b[1;91m${overMsg}\\x1b[0m`;\n\n const scoreLine = `SCORE: ${score} HIGH: ${highScore}`;\n const scoreX = Math.floor((cols - scoreLine.length) / 2);\n output += `\\x1b[${overY + 2};${scoreX}H${themeColor}${scoreLine}\\x1b[0m`;\n\n const undoHint = undosRemaining > 0 ? ' [U] UNDO' : '';\n const restart = `\\u255A [R] RESTART [Q] QUIT${undoHint} \\u255D`;\n const restartX = Math.floor((cols - restart.length) / 2);\n output += `\\x1b[${overY + 4};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n }\n else {\n for (let gy = 0; gy < GRID_SIZE; gy++) {\n for (let gx = 0; gx < GRID_SIZE; gx++) {\n const tileX = renderLeft + 1 + gx * TILE_WIDTH;\n const tileY = renderTop + 1 + gy * TILE_HEIGHT;\n output += renderTile(grid[gy][gx], tileX, tileY);\n }\n }\n\n for (const p of particles) {\n const screenX = Math.round(renderLeft + 1 + p.x);\n const screenY = Math.round(renderTop + 1 + p.y);\n if (screenX > renderLeft && screenX < renderLeft + GAME_WIDTH &&\n screenY > renderTop && screenY < renderTop + GAME_HEIGHT) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n for (const popup of scorePopups) {\n const screenX = Math.round(renderLeft + 1 + popup.x);\n const screenY = Math.round(renderTop + 1 + popup.y);\n if (screenY > renderTop && screenY < renderTop + GAME_HEIGHT) {\n const alpha = popup.frames > 12 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n }\n\n const hint = gameStarted && !gameOver && !paused && !won\n ? `Arrows: SLIDE U: UNDO(${undosRemaining}) ESC: MENU`\n : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${gameTop + GAME_HEIGHT + 1};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n // -------------------------------------------------------------------------\n // GAME LOOP\n // -------------------------------------------------------------------------\n\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) { clearInterval(gameInterval); return; }\n update();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n if (key === 'escape') {\n if (won && !continuedAfterWin) return;\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n if (key === 'q' && (paused || gameOver || !gameStarted || (won && !continuedAfterWin))) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n\n if (!gameStarted && !paused) {\n saveState();\n gameStarted = true;\n return;\n }\n\n if (won && !continuedAfterWin) {\n if (key === 'c') {\n continuedAfterWin = true;\n won = false;\n return;\n }\n if (key === 'r') {\n if (score > highScore) highScore = score;\n initGame();\n gameStarted = true;\n return;\n }\n return;\n }\n\n if (gameOver) {\n if (key === 'r') {\n if (score > highScore) highScore = score;\n initGame();\n gameStarted = true;\n } else if (key === 'u') {\n undo();\n }\n return;\n }\n\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: paused = false; break;\n case 1: initGame(); gameStarted = true; paused = false; break;\n case 2:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n if (key === 'r') { initGame(); gameStarted = true; paused = false; }\n else if (key === 'l') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGamesMenu(terminal); }\n else if (key === 'n') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGameSwitch(terminal); }\n return;\n }\n\n switch (domEvent.key) {\n case 'ArrowLeft':\n case 'a':\n saveState();\n move('left');\n break;\n case 'ArrowRight':\n case 'd':\n saveState();\n move('right');\n break;\n case 'ArrowUp':\n case 'w':\n saveState();\n move('up');\n break;\n case 'ArrowDown':\n case 's':\n saveState();\n move('down');\n break;\n case 'u':\n case 'U':\n undo();\n break;\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 50);\n\n return controller;\n}\n","/**\n * Hyper Asteroids\n *\n * Classic asteroids with ship rotation, thrust physics, and shooting.\n * Simplified visuals for terminal - single-character asteroids and ship.\n * Features screen wrapping, asteroid splitting, particle effects.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\nexport interface AsteroidsController {\n stop: () => void;\n isRunning: boolean;\n}\n\ninterface Ship {\n x: number;\n y: number;\n vx: number;\n vy: number;\n angle: number;\n thrusting: boolean;\n}\n\ninterface Bullet {\n x: number;\n y: number;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface Asteroid {\n x: number;\n y: number;\n vx: number;\n vy: number;\n size: 'large' | 'medium' | 'small';\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\nexport function runAsteroidsGame(terminal: Terminal): AsteroidsController {\n const themeColor = getCurrentThemeColor();\n\n // Lower minimum requirements\n const MIN_COLS = 35;\n const MIN_ROWS = 16;\n\n // Adaptive game dimensions\n let GAME_WIDTH = 30;\n let GAME_HEIGHT = 12;\n\n // Ship physics\n const SHIP_TURN_SPEED = 0.2;\n const SHIP_THRUST = 0.06;\n const SHIP_FRICTION = 0.98;\n const SHIP_MAX_SPEED = 0.8;\n const BULLET_SPEED = 1.2;\n const BULLET_LIFE = 30;\n const SHOOT_COOLDOWN = 10;\n\n // Asteroid speeds\n const ASTEROID_SPEEDS = { large: 0.12, medium: 0.2, small: 0.35 };\n const ASTEROID_SCORES = { large: 20, medium: 50, small: 100 };\n const ASTEROID_RADIUS = { large: 2, medium: 1.5, small: 1 };\n\n // State\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let score = 0;\n let highScore = 0;\n let lives = 3;\n let wave = 1;\n let invincibilityFrames = 0;\n let shootCooldown = 0;\n let glitchFrame = 0;\n let shakeFrames = 0;\n let shakeIntensity = 0;\n\n let gameLeft = 2;\n let gameTop = 4;\n\n let ship: Ship = { x: 0, y: 0, vx: 0, vy: 0, angle: -Math.PI / 2, thrusting: false };\n let keysDown: Set<string> = new Set();\n let bullets: Bullet[] = [];\n let asteroids: Asteroid[] = [];\n let particles: Particle[] = [];\n\n const controller: AsteroidsController = {\n stop: () => { if (running) running = false; },\n get isRunning() { return running; }\n };\n\n // Ship directions (8 directions)\n const SHIP_CHARS = ['→', '↘', '↓', '↙', '←', '↖', '↑', '↗'];\n // Asteroid characters by size\n const ASTEROID_CHARS = { large: '◉', medium: '●', small: '•' };\n\n const title = ['▄▀█ █▀ ▀█▀ █▀▀ █▀█ █▀█ █ █▀▄ █▀',\n '█▀█ ▄█ █ ██▄ █▀▄ █▄█ █ █▄▀ ▄█'];\n\n function initGame() {\n const cols = terminal.cols;\n const rows = terminal.rows;\n GAME_WIDTH = Math.min(50, Math.max(28, cols - 6));\n GAME_HEIGHT = Math.min(18, Math.max(10, rows - 8));\n\n score = 0;\n lives = 3;\n wave = 1;\n gameOver = false;\n paused = false;\n\n ship = {\n x: GAME_WIDTH / 2,\n y: GAME_HEIGHT / 2,\n vx: 0,\n vy: 0,\n angle: -Math.PI / 2,\n thrusting: false,\n };\n\n keysDown.clear();\n bullets = [];\n asteroids = [];\n particles = [];\n invincibilityFrames = 60;\n shootCooldown = 0;\n\n spawnWave();\n }\n\n function spawnWave() {\n const count = 3 + wave;\n for (let i = 0; i < count; i++) {\n let x, y;\n // Spawn away from ship\n do {\n x = Math.random() * GAME_WIDTH;\n y = Math.random() * GAME_HEIGHT;\n } while (Math.abs(x - ship.x) < 8 && Math.abs(y - ship.y) < 4);\n\n const angle = Math.random() * Math.PI * 2;\n const speed = ASTEROID_SPEEDS.large * (0.8 + Math.random() * 0.4);\n asteroids.push({\n x, y,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n size: 'large',\n });\n }\n }\n\n function wrap(value: number, max: number): number {\n if (value < 0) return max + value;\n if (value >= max) return value - max;\n return value;\n }\n\n function triggerShake(frames: number, intensity: number) {\n shakeFrames = frames;\n shakeIntensity = intensity;\n }\n\n function spawnParticles(x: number, y: number, count: number, color: string) {\n const chars = ['*', '+', '.', '·'];\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.2 + Math.random() * 0.4;\n particles.push({\n x, y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 10 + Math.floor(Math.random() * 10),\n });\n }\n }\n\n function shoot() {\n if (shootCooldown > 0) return;\n shootCooldown = SHOOT_COOLDOWN;\n\n const bulletX = ship.x + Math.cos(ship.angle) * 1.5;\n const bulletY = ship.y + Math.sin(ship.angle) * 0.75;\n\n bullets.push({\n x: bulletX,\n y: bulletY,\n vx: Math.cos(ship.angle) * BULLET_SPEED + ship.vx * 0.5,\n vy: Math.sin(ship.angle) * BULLET_SPEED * 0.5 + ship.vy * 0.5,\n life: BULLET_LIFE,\n });\n }\n\n function hitShip() {\n if (invincibilityFrames > 0) return;\n\n lives--;\n spawnParticles(ship.x, ship.y, 15, '\\x1b[91m');\n triggerShake(10, 3);\n\n if (lives <= 0) {\n gameOver = true;\n if (score > highScore) highScore = score;\n } else {\n // Reset ship position\n ship.x = GAME_WIDTH / 2;\n ship.y = GAME_HEIGHT / 2;\n ship.vx = 0;\n ship.vy = 0;\n invincibilityFrames = 90;\n }\n }\n\n function splitAsteroid(asteroid: Asteroid) {\n spawnParticles(asteroid.x, asteroid.y, 8, '\\x1b[93m');\n score += ASTEROID_SCORES[asteroid.size];\n\n if (asteroid.size === 'large') {\n for (let i = 0; i < 2; i++) {\n const angle = Math.random() * Math.PI * 2;\n asteroids.push({\n x: asteroid.x,\n y: asteroid.y,\n vx: Math.cos(angle) * ASTEROID_SPEEDS.medium,\n vy: Math.sin(angle) * ASTEROID_SPEEDS.medium * 0.5,\n size: 'medium',\n });\n }\n } else if (asteroid.size === 'medium') {\n for (let i = 0; i < 2; i++) {\n const angle = Math.random() * Math.PI * 2;\n asteroids.push({\n x: asteroid.x,\n y: asteroid.y,\n vx: Math.cos(angle) * ASTEROID_SPEEDS.small,\n vy: Math.sin(angle) * ASTEROID_SPEEDS.small * 0.5,\n size: 'small',\n });\n }\n }\n }\n\n function update() {\n if (paused || !gameStarted || gameOver) return;\n\n glitchFrame = (glitchFrame + 1) % 60;\n if (invincibilityFrames > 0) invincibilityFrames--;\n if (shootCooldown > 0) shootCooldown--;\n\n // Ship input\n if (keysDown.has('ArrowLeft') || keysDown.has('a')) ship.angle -= SHIP_TURN_SPEED;\n if (keysDown.has('ArrowRight') || keysDown.has('d')) ship.angle += SHIP_TURN_SPEED;\n\n ship.thrusting = keysDown.has('ArrowUp') || keysDown.has('w');\n if (ship.thrusting) {\n ship.vx += Math.cos(ship.angle) * SHIP_THRUST;\n ship.vy += Math.sin(ship.angle) * SHIP_THRUST * 0.5;\n }\n\n if (keysDown.has(' ')) shoot();\n\n // Physics\n ship.vx *= SHIP_FRICTION;\n ship.vy *= SHIP_FRICTION;\n\n const speed = Math.sqrt(ship.vx ** 2 + ship.vy ** 2);\n if (speed > SHIP_MAX_SPEED) {\n ship.vx = (ship.vx / speed) * SHIP_MAX_SPEED;\n ship.vy = (ship.vy / speed) * SHIP_MAX_SPEED;\n }\n\n ship.x = wrap(ship.x + ship.vx, GAME_WIDTH);\n ship.y = wrap(ship.y + ship.vy, GAME_HEIGHT);\n\n // Bullets\n for (let i = bullets.length - 1; i >= 0; i--) {\n const bullet = bullets[i];\n bullet.x = wrap(bullet.x + bullet.vx, GAME_WIDTH);\n bullet.y = wrap(bullet.y + bullet.vy, GAME_HEIGHT);\n bullet.life--;\n if (bullet.life <= 0) bullets.splice(i, 1);\n }\n\n // Asteroids\n for (let i = asteroids.length - 1; i >= 0; i--) {\n const ast = asteroids[i];\n ast.x = wrap(ast.x + ast.vx, GAME_WIDTH);\n ast.y = wrap(ast.y + ast.vy, GAME_HEIGHT);\n\n // Bullet collision\n const radius = ASTEROID_RADIUS[ast.size];\n for (let j = bullets.length - 1; j >= 0; j--) {\n const bullet = bullets[j];\n const dx = bullet.x - ast.x;\n const dy = (bullet.y - ast.y) * 2; // Account for terminal aspect\n if (dx * dx + dy * dy < radius * radius) {\n bullets.splice(j, 1);\n splitAsteroid(ast);\n asteroids.splice(i, 1);\n triggerShake(4, 1);\n break;\n }\n }\n\n // Ship collision\n if (invincibilityFrames <= 0) {\n const dx = ship.x - ast.x;\n const dy = (ship.y - ast.y) * 2;\n if (dx * dx + dy * dy < (radius + 0.5) * (radius + 0.5)) {\n hitShip();\n }\n }\n }\n\n // Particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.02;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Next wave\n if (asteroids.length === 0) {\n wave++;\n spawnWave();\n }\n }\n\n function render() {\n let output = '\\x1b[2J\\x1b[H';\n if (shakeFrames > 0) shakeFrames--;\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg = 'Terminal too small!';\n const need = `Need: ${MIN_COLS}×${MIN_ROWS} Have: ${cols}×${rows}`;\n output += `\\x1b[${Math.floor(rows/2)};${Math.max(1, Math.floor((cols-msg.length)/2))}H${themeColor}${msg}\\x1b[0m`;\n output += `\\x1b[${Math.floor(rows/2)+2};${Math.max(1, Math.floor((cols-need.length)/2))}H\\x1b[2m${need}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH - 2) / 2));\n gameTop = Math.max(4, Math.floor((rows - GAME_HEIGHT - 6) / 2));\n\n let renderLeft = gameLeft;\n let renderTop = gameTop;\n if (shakeFrames > 0) {\n renderLeft += Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n renderTop += Math.floor((Math.random() - 0.5) * shakeIntensity);\n }\n\n // Title\n const titleX = Math.floor((cols - title[0].length) / 2);\n output += `\\x1b[1;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n\n // Stats\n const stats = `SCORE: ${score.toString().padStart(5, '0')} WAVE: ${wave} ${'♥'.repeat(lives)}`;\n output += `\\x1b[${gameTop - 1};${Math.floor((cols - stats.length) / 2)}H${themeColor}${stats}\\x1b[0m`;\n\n // Border\n output += `\\x1b[${renderTop};${renderLeft}H${themeColor}╔${'═'.repeat(GAME_WIDTH)}╗\\x1b[0m`;\n for (let y = 0; y < GAME_HEIGHT; y++) {\n output += `\\x1b[${renderTop + 1 + y};${renderLeft}H${themeColor}║\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + y};${renderLeft + GAME_WIDTH + 1}H${themeColor}║\\x1b[0m`;\n }\n output += `\\x1b[${renderTop + GAME_HEIGHT + 1};${renderLeft}H${themeColor}╚${'═'.repeat(GAME_WIDTH)}╝\\x1b[0m`;\n\n // Pause menu\n if (paused) {\n const pauseY = gameTop + Math.floor(GAME_HEIGHT / 2) - 2;\n output += `\\x1b[${pauseY};${Math.floor(cols/2) - 5}H\\x1b[5m${themeColor}══ PAUSED ══\\x1b[0m`;\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: Math.floor(cols / 2),\n startY: pauseY + 2,\n showShortcuts: false,\n });\n }\n // Start screen\n else if (!gameStarted) {\n const msg = '[ PRESS SPACE TO START ]';\n output += `\\x1b[${gameTop + Math.floor(GAME_HEIGHT/2)};${gameLeft + Math.floor((GAME_WIDTH - msg.length) / 2) + 1}H\\x1b[5m${themeColor}${msg}\\x1b[0m`;\n const ctrl = '← → rotate ↑ thrust SPACE shoot';\n output += `\\x1b[${gameTop + Math.floor(GAME_HEIGHT/2) + 2};${gameLeft + Math.floor((GAME_WIDTH - ctrl.length) / 2) + 1}H\\x1b[2m${themeColor}${ctrl}\\x1b[0m`;\n }\n // Game over\n else if (gameOver) {\n const overY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n output += `\\x1b[${overY};${gameLeft + Math.floor((GAME_WIDTH - 11) / 2) + 1}H\\x1b[1;91m╔ GAME OVER ╗\\x1b[0m`;\n output += `\\x1b[${overY + 1};${gameLeft + Math.floor((GAME_WIDTH - 18) / 2) + 1}H${themeColor}SCORE: ${score} HIGH: ${highScore}\\x1b[0m`;\n output += `\\x1b[${overY + 3};${gameLeft + Math.floor((GAME_WIDTH - 20) / 2) + 1}H\\x1b[2m${themeColor}[R] RESTART [Q] QUIT\\x1b[0m`;\n }\n // Gameplay\n else {\n // Draw asteroids\n for (const ast of asteroids) {\n const sx = renderLeft + 1 + Math.floor(ast.x);\n const sy = renderTop + 1 + Math.floor(ast.y);\n if (sx > renderLeft && sx < renderLeft + GAME_WIDTH + 1 && sy > renderTop && sy < renderTop + GAME_HEIGHT + 1) {\n const color = ast.size === 'large' ? '\\x1b[93m' : ast.size === 'medium' ? '\\x1b[33m' : '\\x1b[2;33m';\n output += `\\x1b[${sy};${sx}H${color}${ASTEROID_CHARS[ast.size]}\\x1b[0m`;\n }\n }\n\n // Draw bullets\n for (const b of bullets) {\n const sx = renderLeft + 1 + Math.floor(b.x);\n const sy = renderTop + 1 + Math.floor(b.y);\n if (sx > renderLeft && sx < renderLeft + GAME_WIDTH + 1 && sy > renderTop && sy < renderTop + GAME_HEIGHT + 1) {\n output += `\\x1b[${sy};${sx}H\\x1b[1;97m•\\x1b[0m`;\n }\n }\n\n // Draw particles\n for (const p of particles) {\n const sx = renderLeft + 1 + Math.floor(p.x);\n const sy = renderTop + 1 + Math.floor(p.y);\n if (sx > renderLeft && sx < renderLeft + GAME_WIDTH + 1 && sy > renderTop && sy < renderTop + GAME_HEIGHT + 1) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${sy};${sx}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw ship\n const showShip = invincibilityFrames <= 0 || Math.floor(glitchFrame / 3) % 2 === 0;\n if (showShip) {\n const sx = renderLeft + 1 + Math.floor(ship.x);\n const sy = renderTop + 1 + Math.floor(ship.y);\n if (sx > renderLeft && sx < renderLeft + GAME_WIDTH + 1 && sy > renderTop && sy < renderTop + GAME_HEIGHT + 1) {\n // 8 directions - ensure positive index with double modulo\n const dir = ((Math.round(ship.angle / (Math.PI / 4)) % 8) + 8) % 8;\n const shipChar = SHIP_CHARS[dir];\n const shipColor = ship.thrusting ? '\\x1b[1;93m' : themeColor;\n output += `\\x1b[${sy};${sx}H${shipColor}${shipChar}\\x1b[0m`;\n\n // Thrust trail\n if (ship.thrusting) {\n const trailX = sx - Math.round(Math.cos(ship.angle) * 1.5);\n const trailY = sy - Math.round(Math.sin(ship.angle) * 0.75);\n if (trailX > renderLeft && trailX < renderLeft + GAME_WIDTH + 1 && trailY > renderTop && trailY < renderTop + GAME_HEIGHT + 1) {\n output += `\\x1b[${trailY};${trailX}H\\x1b[91m${Math.random() > 0.5 ? '~' : '*'}\\x1b[0m`;\n }\n }\n }\n }\n }\n\n // Bottom hint\n const hint = `HIGH: ${highScore} [ ESC ] MENU`;\n output += `\\x1b[${gameTop + GAME_HEIGHT + 3};${Math.floor((cols - hint.length) / 2)}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n // Game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h\\x1b[?25l');\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) { clearInterval(gameInterval); return; }\n update();\n }, 25);\n\n // Use terminal.onKey for menu/game control, track keydown for continuous input\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key;\n const keyLower = key.toLowerCase();\n\n // Track continuous input\n keysDown.add(key);\n setTimeout(() => keysDown.delete(key), 100);\n\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(pauseMenuSelection, PAUSE_MENU_ITEMS.length, key, domEvent);\n if (newSelection !== pauseMenuSelection) { pauseMenuSelection = newSelection; return; }\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: paused = false; break;\n case 1: initGame(); gameStarted = true; paused = false; break;\n case 2: controller.stop(); dispatchGameQuit(terminal); break;\n case 3: controller.stop(); dispatchGamesMenu(terminal); break;\n case 4: controller.stop(); dispatchGameSwitch(terminal); break;\n }\n return;\n }\n return;\n }\n\n if (gameOver) {\n if (keyLower === 'r') { initGame(); gameStarted = true; return; }\n if (keyLower === 'q' || key === 'Escape') { controller.stop(); dispatchGameQuit(terminal); return; }\n return;\n }\n\n if (key === 'Escape') { paused = true; pauseMenuSelection = 0; return; }\n\n if (!gameStarted && key === ' ') { gameStarted = true; return; }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n keyListener.dispose();\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n terminal.write('\\x1b[?25h\\x1b[?1049l');\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Breakout\n *\n * Classic breakout/brick breaker with cyberpunk theme.\n * Paddle at bottom, ball bounces to break bricks at top.\n * Features power-ups, particle explosions, and screen shake.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Breakout Game Controller\n */\nexport interface BreakoutController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\ninterface Brick {\n x: number;\n y: number;\n width: number;\n alive: boolean;\n type: number;\n hits: number;\n}\n\ninterface Ball {\n x: number;\n y: number;\n vx: number;\n vy: number;\n active: boolean;\n}\n\ninterface PowerUp {\n x: number;\n y: number;\n type: 'multiball' | 'wide' | 'laser' | 'slow' | 'extra';\n vy: number;\n}\n\ninterface Laser {\n x: number;\n y: number;\n}\n\n// ============================================================================\n// MAIN GAME FUNCTION\n// ============================================================================\n\nexport function runBreakoutGame(terminal: Terminal): BreakoutController {\n const themeColor = getCurrentThemeColor();\n\n const MIN_COLS = 40;\n const MIN_ROWS = 18;\n const GAME_WIDTH = 46;\n const GAME_HEIGHT = 20;\n const PADDLE_WIDTH_NORMAL = 7;\n const PADDLE_WIDTH_WIDE = 11;\n const BRICK_WIDTH = 5;\n const BRICK_HEIGHT = 1;\n const BRICK_ROWS = 5;\n const BRICK_COLS = 8;\n const BALL_SPEED = 0.4;\n const MAX_BALL_SPEED = 0.7;\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let won = false;\n let score = 0;\n let highScore = 0;\n let lives = 3;\n let level = 1;\n\n let gameLeft = 2;\n let gameTop = 4;\n\n let paddleX = GAME_WIDTH / 2;\n let paddleWidth = PADDLE_WIDTH_NORMAL;\n let paddleWidthTimer = 0;\n\n let balls: Ball[] = [];\n let bricks: Brick[] = [];\n let powerUps: PowerUp[] = [];\n let lasers: Laser[] = [];\n let laserActive = false;\n let laserTimer = 0;\n let laserCooldown = 0;\n let slowActive = false;\n let slowTimer = 0;\n\n let glitchFrame = 0;\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let shakeFrames = 0;\n let shakeIntensity = 0;\n let comboCount = 0;\n let comboTimer = 0;\n let borderFlash = 0;\n let ballAttached = true;\n\n const controller: BreakoutController = {\n stop: () => { if (!running) return; running = false; },\n get isRunning() { return running; }\n };\n\n const title = [\n '\\u2588 \\u2588 \\u2588\\u2584\\u2588 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2580\\u2588 \\u2588 \\u2580 \\u2588\\u2580\\u2588 \\u2588 \\u2588 \\u2580\\u2588\\u2580',\n '\\u2588\\u2580\\u2588 \\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2588\\u2584 \\u2588\\u2580\\u2584 \\u2588\\u2580\\u2588 \\u2588\\u2584\\u2588 \\u2588\\u2584\\u2584 \\u2588\\u2584\\u2588 \\u2588\\u2580\\u2584 \\u2588\\u2584\\u2588 \\u2588\\u2584\\u2588 \\u2588 ',\n ];\n\n const brickColors = ['\\x1b[1;91m', '\\x1b[1;93m', '\\x1b[1;92m', '\\x1b[1;96m', '\\x1b[1;95m'];\n const brickPoints = [50, 40, 30, 20, 10];\n\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['\\u2726', '\\u2605', '\\u25c6', '\\u25cf']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.2 + Math.random() * 0.4;\n particles.push({ x, y, char: chars[Math.floor(Math.random() * chars.length)], color, vx: Math.cos(angle) * speed, vy: Math.sin(angle) * speed * 0.5, life: 10 + Math.floor(Math.random() * 8) });\n }\n }\n\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 18, color });\n }\n\n function triggerShake(frames: number, intensity: number) {\n shakeFrames = frames;\n shakeIntensity = intensity;\n }\n\n function initGame() {\n score = won ? score : 0;\n lives = won ? lives : 3;\n gameOver = false;\n won = false;\n paused = false;\n paddleX = GAME_WIDTH / 2;\n paddleWidth = PADDLE_WIDTH_NORMAL;\n paddleWidthTimer = 0;\n powerUps = [];\n lasers = [];\n laserActive = false;\n laserTimer = 0;\n laserCooldown = 0;\n slowActive = false;\n slowTimer = 0;\n particles = [];\n scorePopups = [];\n shakeFrames = 0;\n comboCount = 0;\n comboTimer = 0;\n borderFlash = 0;\n ballAttached = true;\n balls = [{ x: paddleX, y: GAME_HEIGHT - 3, vx: 0, vy: 0, active: true }];\n initBricks();\n }\n\n function initBricks() {\n bricks = [];\n const startX = Math.floor((GAME_WIDTH - BRICK_COLS * BRICK_WIDTH) / 2);\n const startY = 2;\n for (let row = 0; row < BRICK_ROWS; row++) {\n for (let col = 0; col < BRICK_COLS; col++) {\n const type = row;\n const hits = level >= 3 && row === 0 ? 2 : 1;\n bricks.push({ x: startX + col * BRICK_WIDTH, y: startY + row * (BRICK_HEIGHT + 1), width: BRICK_WIDTH - 1, alive: true, type, hits });\n }\n }\n }\n\n function launchBall() {\n if (!ballAttached || balls.length === 0) return;\n ballAttached = false;\n const ball = balls[0];\n const angle = -Math.PI / 2 + (Math.random() - 0.5) * Math.PI / 2;\n const speed = BALL_SPEED + (level - 1) * 0.03;\n ball.vx = Math.cos(angle) * speed;\n ball.vy = Math.sin(angle) * speed;\n }\n\n function spawnPowerUp(x: number, y: number) {\n if (Math.random() > 0.2) return;\n const types: PowerUp['type'][] = ['multiball', 'wide', 'laser', 'slow', 'extra'];\n powerUps.push({ x, y, type: types[Math.floor(Math.random() * types.length)], vy: 0.15 });\n }\n\n function applyPowerUp(type: PowerUp['type']) {\n triggerShake(8, 2);\n borderFlash = 15;\n switch (type) {\n case 'multiball': {\n const activeBalls = balls.filter(b => b.active);\n if (activeBalls.length > 0) {\n const src = activeBalls[0];\n for (let i = 0; i < 2; i++) {\n const angle = (Math.random() - 0.5) * Math.PI;\n const speed = Math.sqrt(src.vx ** 2 + src.vy ** 2);\n balls.push({ x: src.x, y: src.y, vx: Math.cos(angle) * speed, vy: -Math.abs(Math.sin(angle) * speed), active: true });\n }\n }\n addScorePopup(paddleX, GAME_HEIGHT - 5, 'MULTI-BALL!', '\\x1b[1;96m');\n break;\n }\n case 'wide': paddleWidth = PADDLE_WIDTH_WIDE; paddleWidthTimer = 600; addScorePopup(paddleX, GAME_HEIGHT - 5, 'WIDE PADDLE!', '\\x1b[1;92m'); break;\n case 'laser': laserActive = true; laserTimer = 400; addScorePopup(paddleX, GAME_HEIGHT - 5, 'LASER!', '\\x1b[1;91m'); break;\n case 'slow': slowActive = true; slowTimer = 300; for (const b of balls) { b.vx *= 0.6; b.vy *= 0.6; } addScorePopup(paddleX, GAME_HEIGHT - 5, 'SLOW-MO!', '\\x1b[1;93m'); break;\n case 'extra': lives++; addScorePopup(paddleX, GAME_HEIGHT - 5, '+1 LIFE!', '\\x1b[1;95m'); break;\n }\n }\n\n function getPowerUpChar(type: PowerUp['type']): string { return type === 'multiball' ? 'M' : type === 'wide' ? 'W' : type === 'laser' ? 'L' : type === 'slow' ? 'S' : '+'; }\n function getPowerUpColor(type: PowerUp['type']): string { return type === 'multiball' ? '\\x1b[1;96m' : type === 'wide' ? '\\x1b[1;92m' : type === 'laser' ? '\\x1b[1;91m' : type === 'slow' ? '\\x1b[1;93m' : '\\x1b[1;95m'; }\n\n function update() {\n if (!gameStarted || gameOver || paused) return;\n const speedMult = slowActive ? 0.5 : 1;\n\n if (paddleWidthTimer > 0) { paddleWidthTimer--; if (paddleWidthTimer === 0) paddleWidth = PADDLE_WIDTH_NORMAL; }\n if (laserTimer > 0) { laserTimer--; if (laserTimer === 0) laserActive = false; }\n if (slowTimer > 0) { slowTimer--; if (slowTimer === 0) { slowActive = false; for (const b of balls) { const s = Math.sqrt(b.vx ** 2 + b.vy ** 2); if (s > 0) { const f = Math.min(BALL_SPEED, s * 1.67) / s; b.vx *= f; b.vy *= f; } } } }\n if (laserCooldown > 0) laserCooldown--;\n if (comboTimer > 0) { comboTimer--; if (comboTimer === 0) comboCount = 0; }\n\n for (let i = particles.length - 1; i >= 0; i--) { const p = particles[i]; p.x += p.vx; p.y += p.vy; p.vy += 0.02; p.life--; if (p.life <= 0) particles.splice(i, 1); }\n for (let i = scorePopups.length - 1; i >= 0; i--) { const p = scorePopups[i]; p.y -= 0.25; p.frames--; if (p.frames <= 0) scorePopups.splice(i, 1); }\n\n for (let i = powerUps.length - 1; i >= 0; i--) {\n const pu = powerUps[i];\n pu.y += pu.vy * speedMult;\n const pL = paddleX - paddleWidth / 2, pR = paddleX + paddleWidth / 2;\n if (pu.y >= GAME_HEIGHT - 2 && pu.y <= GAME_HEIGHT - 1 && pu.x >= pL && pu.x <= pR) { applyPowerUp(pu.type); powerUps.splice(i, 1); continue; }\n if (pu.y >= GAME_HEIGHT) powerUps.splice(i, 1);\n }\n\n for (let i = lasers.length - 1; i >= 0; i--) {\n const laser = lasers[i];\n laser.y -= 1;\n for (const brick of bricks) {\n if (!brick.alive) continue;\n if (laser.y >= brick.y && laser.y <= brick.y + BRICK_HEIGHT && laser.x >= brick.x && laser.x <= brick.x + brick.width) {\n brick.hits--;\n if (brick.hits <= 0) { brick.alive = false; const pts = brickPoints[brick.type] || 10; score += pts; spawnParticles(brick.x + brick.width / 2, brick.y, 6, brickColors[brick.type]); addScorePopup(brick.x + 1, brick.y - 1, `+${pts}`, brickColors[brick.type]); spawnPowerUp(brick.x + brick.width / 2, brick.y); }\n lasers.splice(i, 1);\n break;\n }\n }\n if (laser.y < 0) lasers.splice(i, 1);\n }\n\n if (ballAttached && balls.length > 0) { balls[0].x = paddleX; balls[0].y = GAME_HEIGHT - 3; }\n\n for (let i = balls.length - 1; i >= 0; i--) {\n const ball = balls[i];\n if (!ball.active || ballAttached) continue;\n ball.x += ball.vx * speedMult;\n ball.y += ball.vy * speedMult;\n\n if (ball.x <= 0) { ball.x = 0; ball.vx = Math.abs(ball.vx); spawnParticles(0, ball.y, 3, themeColor, ['\\u00b7', '\\u2022']); }\n if (ball.x >= GAME_WIDTH - 1) { ball.x = GAME_WIDTH - 1; ball.vx = -Math.abs(ball.vx); spawnParticles(GAME_WIDTH - 1, ball.y, 3, themeColor, ['\\u00b7', '\\u2022']); }\n if (ball.y <= 0) { ball.y = 0; ball.vy = Math.abs(ball.vy); spawnParticles(ball.x, 0, 3, themeColor, ['\\u00b7', '\\u2022']); }\n\n const pL = paddleX - paddleWidth / 2, pR = paddleX + paddleWidth / 2, pY = GAME_HEIGHT - 2;\n if (ball.vy > 0 && ball.y >= pY - 0.5 && ball.y <= pY + 0.5 && ball.x >= pL - 0.5 && ball.x <= pR + 0.5) {\n const hitPos = (ball.x - paddleX) / (paddleWidth / 2);\n const angle = hitPos * Math.PI / 3;\n const curSpeed = Math.sqrt(ball.vx ** 2 + ball.vy ** 2);\n const newSpeed = Math.min(MAX_BALL_SPEED, curSpeed * 1.02);\n ball.vx = Math.sin(angle) * newSpeed;\n ball.vy = -Math.cos(angle) * newSpeed;\n ball.y = pY - 1;\n spawnParticles(ball.x, pY, 4, themeColor, ['\\u2726', '\\u25cf']);\n }\n\n for (const brick of bricks) {\n if (!brick.alive) continue;\n const bL = brick.x, bR = brick.x + brick.width, bT = brick.y, bB = brick.y + BRICK_HEIGHT;\n if (ball.x >= bL - 0.5 && ball.x <= bR + 0.5 && ball.y >= bT - 0.5 && ball.y <= bB + 0.5) {\n const fromL = ball.x < bL, fromR = ball.x > bR, fromT = ball.y < bT, fromB = ball.y > bB;\n if (fromL || fromR) ball.vx = -ball.vx;\n if (fromT || fromB) ball.vy = -ball.vy;\n if (!fromL && !fromR && !fromT && !fromB) ball.vy = -ball.vy;\n brick.hits--;\n if (brick.hits <= 0) {\n brick.alive = false;\n comboCount++; comboTimer = 40;\n const basePts = brickPoints[brick.type] || 10;\n const comboBonus = comboCount > 1 ? Math.floor(comboCount * 5) : 0;\n const totalPts = basePts + comboBonus;\n score += totalPts;\n const intensity = Math.min(comboCount, 8);\n triggerShake(3 + intensity, 1 + Math.floor(intensity / 3));\n spawnParticles(brick.x + brick.width / 2, brick.y, 6 + intensity, brickColors[brick.type]);\n addScorePopup(brick.x + 1, brick.y - 1, comboCount > 1 ? `+${totalPts}!` : `+${totalPts}`, brickColors[brick.type]);\n spawnPowerUp(brick.x + brick.width / 2, brick.y);\n } else {\n spawnParticles(ball.x, ball.y, 3, '\\x1b[2m' + brickColors[brick.type], ['\\u00b7', 'x']);\n }\n break;\n }\n }\n\n if (ball.y >= GAME_HEIGHT) ball.active = false;\n }\n\n balls = balls.filter(b => b.active);\n\n if (balls.length === 0 && !ballAttached) {\n lives--;\n if (lives <= 0) { gameOver = true; if (score > highScore) highScore = score; triggerShake(20, 4); spawnParticles(paddleX, GAME_HEIGHT - 2, 15, '\\x1b[1;91m', ['\\u2717', '\\u2620', '\\u00d7', '\\u2593']); }\n else { ballAttached = true; balls = [{ x: paddleX, y: GAME_HEIGHT - 3, vx: 0, vy: 0, active: true }]; triggerShake(10, 2); }\n }\n\n const aliveBricks = bricks.filter(b => b.alive);\n if (aliveBricks.length === 0) {\n won = true; gameOver = true; level++; if (score > highScore) highScore = score; triggerShake(12, 2);\n for (let i = 0; i < 5; i++) setTimeout(() => spawnParticles(Math.random() * GAME_WIDTH, Math.random() * GAME_HEIGHT / 2, 15, brickColors[Math.floor(Math.random() * brickColors.length)], ['\\u2605', '\\u2726', '\\u25c6', '\\u25cf', '\\u2727']), i * 100);\n }\n }\n\n function render() {\n let output = '\\x1b[2J\\x1b[H';\n if (shakeFrames > 0) shakeFrames--;\n if (borderFlash > 0) borderFlash--;\n\n const cols = terminal.cols, rows = terminal.rows;\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needW = cols < MIN_COLS, needH = rows < MIN_ROWS;\n const hint = needW && needH ? 'Make pane larger' : needW ? 'Make pane wider \\u2192' : 'Make pane taller \\u2193';\n const msg2 = `Need: ${MIN_COLS}\\u00d7${MIN_ROWS} Have: ${cols}\\u00d7${rows}`;\n const cX = Math.floor(cols / 2), cY = Math.floor(rows / 2);\n output += `\\x1b[${cY - 1};${Math.max(1, cX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${cY + 1};${Math.max(1, cX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${cY + 3};${Math.max(1, cX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH - 2) / 2));\n gameTop = Math.max(4, Math.floor((rows - GAME_HEIGHT - 6) / 2));\n\n let rL = gameLeft, rT = gameTop;\n if (shakeFrames > 0) { rL += Math.floor((Math.random() - 0.5) * shakeIntensity * 2); rT += Math.floor((Math.random() - 0.5) * shakeIntensity); }\n\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOff = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOff;\n if (glitchFrame >= 55 && glitchFrame < 58) { output += `\\x1b[1;${titleX}H\\x1b[91m${title[0]}\\x1b[0m\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`; }\n else { output += `\\x1b[1;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`; }\n\n const livesDisp = '\\u2665'.repeat(Math.max(0, lives));\n const stats = `SCORE: ${score.toString().padStart(5, '0')} LVL: ${level} ${livesDisp}`;\n const statsX = Math.floor((cols - stats.length) / 2);\n output += `\\x1b[${gameTop - 1};${statsX}H${themeColor}${stats}\\x1b[0m`;\n\n let ind = '';\n if (paddleWidthTimer > 0) ind += ' [W]';\n if (laserActive) ind += ' [L]';\n if (slowActive) ind += ' [S]';\n if (ind) output += `\\x1b[${gameTop - 1};${statsX + stats.length + 1}H\\x1b[2m${themeColor}${ind}\\x1b[0m`;\n\n const bC = borderFlash > 0 && borderFlash % 4 < 2 ? '\\x1b[1;93m' : themeColor;\n output += `\\x1b[${rT};${rL}H${bC}\\u2554${'═'.repeat(GAME_WIDTH)}\\u2557\\x1b[0m`;\n for (let y = 0; y < GAME_HEIGHT; y++) { output += `\\x1b[${rT + 1 + y};${rL}H${bC}\\u2551\\x1b[0m\\x1b[${rT + 1 + y};${rL + GAME_WIDTH + 1}H${bC}\\u2551\\x1b[0m`; }\n output += `\\x1b[${rT + GAME_HEIGHT + 1};${rL}H${bC}\\u255a${'═'.repeat(GAME_WIDTH)}\\u255d\\x1b[0m`;\n\n if (paused) {\n const pauseMsg = '\\u2550\\u2550 PAUSED \\u2550\\u2550';\n const pCX = Math.floor(cols / 2), pY = gameTop + Math.floor(GAME_HEIGHT / 2) - 3;\n output += `\\x1b[${pY};${pCX - Math.floor(pauseMsg.length / 2)}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, { centerX: pCX, startY: pY + 2, showShortcuts: false });\n output += `\\x1b[${pY + 8};${pCX - 13}H\\x1b[2m${themeColor}\\u2191\\u2193 select ENTER confirm\\x1b[0m`;\n } else if (!gameStarted) {\n const startMsg = '[ PRESS SPACE TO LAUNCH ]';\n const sX = gameLeft + Math.floor((GAME_WIDTH - startMsg.length) / 2) + 1;\n const sY = gameTop + Math.floor(GAME_HEIGHT / 2) + 2;\n output += `\\x1b[${sY};${sX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n const controls = '\\u2190\\u2192 MOVE SPC FIRE/LAUNCH ESC MENU';\n output += `\\x1b[${sY + 2};${gameLeft + Math.floor((GAME_WIDTH - controls.length) / 2) + 1}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n output = renderGameObjects(output, rL, rT);\n } else if (gameOver) {\n const overMsg = won ? '\\u2554\\u2550\\u2550 LEVEL COMPLETE! \\u2550\\u2550\\u2557' : '\\u2554\\u2550\\u2550 GAME OVER \\u2550\\u2550\\u2557';\n const oX = gameLeft + Math.floor((GAME_WIDTH - overMsg.length) / 2) + 1;\n const oY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n output += `\\x1b[${oY};${oX}H${won ? '\\x1b[1;92m' : '\\x1b[1;91m'}${overMsg}\\x1b[0m`;\n const scoreLine = `SCORE: ${score} HIGH: ${highScore}`;\n output += `\\x1b[${oY + 1};${gameLeft + Math.floor((GAME_WIDTH - scoreLine.length) / 2) + 1}H${themeColor}${scoreLine}\\x1b[0m`;\n const restart = won ? '\\u255a [R] NEXT LEVEL [Q] QUIT \\u255d' : '\\u255a [R] RESTART [Q] QUIT \\u255d';\n output += `\\x1b[${oY + 2};${gameLeft + Math.floor((GAME_WIDTH - restart.length) / 2) + 1}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n output = drawEffects(output, rL, rT);\n } else {\n output = renderGameObjects(output, rL, rT);\n }\n\n const hint = gameStarted && !gameOver && !paused ? `HIGH: ${highScore} [ ESC ] MENU` : '';\n output += `\\x1b[${gameTop + GAME_HEIGHT + 3};${Math.floor((cols - hint.length) / 2)}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n }\n\n function renderGameObjects(output: string, rL: number, rT: number): string {\n for (const brick of bricks) { if (!brick.alive) continue; const sX = rL + 1 + brick.x, sY = rT + 1 + brick.y; const c = brickColors[brick.type] || themeColor; const ch = brick.hits > 1 ? '\\u2593' : '\\u2588'; output += `\\x1b[${sY};${sX}H${c}${ch.repeat(brick.width)}\\x1b[0m`; }\n for (const pu of powerUps) { const sX = Math.round(rL + 1 + pu.x), sY = Math.round(rT + 1 + pu.y); if (sY > rT && sY < rT + GAME_HEIGHT + 1) output += `\\x1b[${sY};${sX}H${getPowerUpColor(pu.type)}[${getPowerUpChar(pu.type)}]\\x1b[0m`; }\n for (const laser of lasers) { const sX = rL + 1 + Math.floor(laser.x), sY = rT + 1 + Math.floor(laser.y); if (sY > rT && sY < rT + GAME_HEIGHT + 1) output += `\\x1b[${sY};${sX}H\\x1b[1;91m\\u2502\\x1b[0m`; }\n const pSX = rL + 1 + Math.floor(paddleX - paddleWidth / 2), pSY = rT + GAME_HEIGHT - 1;\n const pCh = laserActive ? '\\u2550' : '\\u2588';\n output += `\\x1b[${pSY};${pSX}H${themeColor}${pCh.repeat(Math.ceil(paddleWidth))}\\x1b[0m`;\n if (laserActive) { output += `\\x1b[${pSY};${pSX}H\\x1b[1;91m\\u2191\\x1b[0m\\x1b[${pSY};${pSX + Math.ceil(paddleWidth) - 1}H\\x1b[1;91m\\u2191\\x1b[0m`; }\n for (const ball of balls) { if (!ball.active) continue; const sX = Math.round(rL + 1 + ball.x), sY = Math.round(rT + 1 + ball.y); if (sX > rL && sX < rL + GAME_WIDTH + 1 && sY > rT && sY < rT + GAME_HEIGHT + 1) { const spd = Math.sqrt(ball.vx ** 2 + ball.vy ** 2); output += `\\x1b[${sY};${sX}H${spd > 0.5 ? '\\x1b[1;93m' : '\\x1b[1;97m'}\\u25cf\\x1b[0m`; } }\n if (comboCount >= 3) { const comboMsg = comboCount >= 5 ? `\\u2605 ${comboCount}x COMBO! \\u2605` : `${comboCount}x COMBO!`; const comboX = rL + Math.floor((GAME_WIDTH - comboMsg.length) / 2) + 1; output += `\\x1b[${rT + GAME_HEIGHT - 3};${comboX}H${glitchFrame % 6 < 3 ? '\\x1b[1;91m' : '\\x1b[1;93m'}${comboMsg}\\x1b[0m`; }\n return drawEffects(output, rL, rT);\n }\n\n function drawEffects(output: string, rL: number, rT: number): string {\n for (const p of particles) { const sX = Math.round(rL + 1 + p.x), sY = Math.round(rT + 1 + p.y); if (sX > rL && sX < rL + GAME_WIDTH + 1 && sY > rT && sY < rT + GAME_HEIGHT + 1) output += `\\x1b[${sY};${sX}H${p.life > 5 ? '' : '\\x1b[2m'}${p.color}${p.char}\\x1b[0m`; }\n for (const popup of scorePopups) { const sX = Math.round(rL + 1 + popup.x), sY = Math.round(rT + 1 + popup.y); if (sY > rT && sY < rT + GAME_HEIGHT + 1) output += `\\x1b[${sY};${sX}H${popup.frames > 10 ? '\\x1b[1m' : '\\x1b[2m'}${popup.color}${popup.text}\\x1b[0m`; }\n return output;\n }\n\n setTimeout(() => {\n if (!running) return;\n terminal.write('\\x1b[?1049h\\x1b[?25l');\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => { if (!running) { clearInterval(renderInterval); return; } render(); }, 25);\n const gameInterval = setInterval(() => { if (!running) { clearInterval(gameInterval); return; } update(); }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n domEvent.preventDefault();\n domEvent.stopPropagation();\n const key = domEvent.key.toLowerCase();\n\n if (key === 'escape') { paused = !paused; if (paused) pauseMenuSelection = 0; return; }\n if (key === 'q' && (paused || gameOver || !gameStarted)) { clearInterval(renderInterval); clearInterval(gameInterval); controller.stop(); dispatchGameQuit(terminal); return; }\n if (!gameStarted && !paused) { if (domEvent.key === ' ') { gameStarted = true; launchBall(); } return; }\n if (gameOver) { if (key === 'r') { if (score > highScore) highScore = score; if (won) initGame(); else { level = 1; initGame(); } gameStarted = true; launchBall(); } return; }\n\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(pauseMenuSelection, PAUSE_MENU_ITEMS.length, key, domEvent);\n if (newSelection !== pauseMenuSelection) { pauseMenuSelection = newSelection; return; }\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: paused = false; break;\n case 1: level = 1; initGame(); gameStarted = true; launchBall(); paused = false; break;\n case 2: clearInterval(renderInterval); clearInterval(gameInterval); controller.stop(); dispatchGameQuit(terminal); break;\n case 3: clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGamesMenu(terminal); break;\n case 4: clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGameSwitch(terminal); break;\n }\n return;\n }\n if (key === 'r') { level = 1; initGame(); gameStarted = true; launchBall(); paused = false; }\n else if (key === 'l') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGamesMenu(terminal); }\n else if (key === 'n') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGameSwitch(terminal); }\n return;\n }\n\n const moveSpeed = 2.5;\n switch (domEvent.key) {\n case 'ArrowLeft': case 'a': paddleX = Math.max(paddleWidth / 2, paddleX - moveSpeed); break;\n case 'ArrowRight': case 'd': paddleX = Math.min(GAME_WIDTH - paddleWidth / 2, paddleX + moveSpeed); break;\n case ' ': if (ballAttached) launchBall(); else if (laserActive && laserCooldown === 0) { lasers.push({ x: paddleX - paddleWidth / 2 + 0.5, y: GAME_HEIGHT - 3 }); lasers.push({ x: paddleX + paddleWidth / 2 - 0.5, y: GAME_HEIGHT - 3 }); laserCooldown = 8; } break;\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => { clearInterval(renderInterval); clearInterval(gameInterval); keyListener.dispose(); originalStop(); };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Chopper - Level Definitions\n *\n * Each level has:\n * - name: Display name\n * - platforms: Array of {x, y, width} - huts spawn centered on each\n * - waterLevel: Y position where water starts (death zone)\n * - timeLimit: Seconds to complete all deliveries\n * - parTime: Target time for 3 stars\n *\n * Map is ~70 chars wide, ~16 rows tall\n * Y=0 is top, Y increases downward\n * Platforms need headroom above for huts (3 rows tall)\n */\n\nexport interface Platform {\n x: number;\n y: number;\n width: number;\n}\n\nexport interface Level {\n name: string;\n platforms: Platform[];\n waterLevel: number;\n timeLimit: number;\n parTime: number;\n}\n\n// Tutorial levels - progressive learning, no time pressure\nexport const TUTORIAL_LEVELS: Level[] = [\n // Tutorial 1: Flight School - just learn to fly and steer\n {\n name: 'FLIGHT SCHOOL',\n waterLevel: 17, // Very low water for safety\n platforms: [\n { x: 5, y: 14, width: 20 }, // Left platform (start here)\n { x: 45, y: 14, width: 20 }, // Right platform (fly to here)\n ],\n timeLimit: 300,\n parTime: 60,\n },\n // Tutorial 2: First Delivery - learn pickup and dropoff\n {\n name: 'FIRST DELIVERY',\n waterLevel: 17,\n platforms: [\n { x: 5, y: 14, width: 20 }, // Left platform\n { x: 45, y: 14, width: 20 }, // Right platform (same height)\n ],\n timeLimit: 300,\n parTime: 60,\n },\n // Tutorial 3: Rope Master - platforms at different heights\n {\n name: 'ROPE MASTER',\n waterLevel: 17,\n platforms: [\n { x: 5, y: 14, width: 18 }, // Low left (near water)\n { x: 45, y: 6, width: 18 }, // High right (need to raise rope!)\n ],\n timeLimit: 300,\n parTime: 60,\n },\n];\n\nexport const LEVELS: Level[] = [\n // Level 1 - Easy intro\n {\n name: 'STONE AGE TAXI',\n waterLevel: 16,\n platforms: [\n { x: 0, y: 14, width: 18 }, // Left cliff\n { x: 52, y: 14, width: 18 }, // Right cliff\n { x: 26, y: 8, width: 16 }, // Center high\n ],\n timeLimit: 60,\n parTime: 30,\n },\n\n // Level 2 - Wider gaps\n {\n name: 'CANYON RUN',\n waterLevel: 16,\n platforms: [\n { x: 0, y: 14, width: 16 }, // Bottom left\n { x: 54, y: 14, width: 16 }, // Bottom right\n { x: 26, y: 9, width: 18 }, // Center mid\n ],\n timeLimit: 75,\n parTime: 40,\n },\n\n // Level 3 - High center peak\n {\n name: 'TRIPLE PEAK',\n waterLevel: 16,\n platforms: [\n { x: 0, y: 12, width: 14 }, // Left peak\n { x: 28, y: 6, width: 14 }, // Center peak (highest)\n { x: 56, y: 12, width: 14 }, // Right peak\n ],\n timeLimit: 80,\n parTime: 45,\n },\n\n // Level 4 - Ascending platforms\n {\n name: 'THE STAIRS',\n waterLevel: 16,\n platforms: [\n { x: 0, y: 14, width: 18 }, // Ground floor\n { x: 26, y: 10, width: 16 }, // Mid level\n { x: 52, y: 6, width: 18 }, // Top level\n ],\n timeLimit: 85,\n parTime: 50,\n },\n\n // Level 5 - All same height, small islands\n {\n name: 'ISLAND HOP',\n waterLevel: 15,\n platforms: [\n { x: 5, y: 13, width: 12 }, // Left island\n { x: 29, y: 13, width: 12 }, // Center island\n { x: 53, y: 13, width: 12 }, // Right island\n ],\n timeLimit: 70,\n parTime: 40,\n },\n\n // Level 6 - Very high center tower\n {\n name: 'THE TOWER',\n waterLevel: 16,\n platforms: [\n { x: 0, y: 14, width: 20 }, // Ground left\n { x: 28, y: 5, width: 14 }, // Tower top (very high!)\n { x: 50, y: 14, width: 20 }, // Ground right\n ],\n timeLimit: 90,\n parTime: 55,\n },\n\n // Level 7 - Alternating heights\n {\n name: 'ZIGZAG',\n waterLevel: 16,\n platforms: [\n { x: 0, y: 12, width: 16 }, // High left\n { x: 27, y: 14, width: 16 }, // Low center\n { x: 54, y: 8, width: 16 }, // Higher right\n ],\n timeLimit: 85,\n parTime: 50,\n },\n\n // Level 8 - Final challenge, platforms near water\n {\n name: 'FINAL FLIGHT',\n waterLevel: 15,\n platforms: [\n { x: 2, y: 13, width: 14 }, // Left (near water!)\n { x: 28, y: 7, width: 14 }, // High center\n { x: 54, y: 13, width: 14 }, // Right (near water!)\n ],\n timeLimit: 100,\n parTime: 60,\n },\n];\n","/**\n * Hyper Chopper - Visual Effects\n *\n * Particle systems, fireworks, and celebration effects.\n */\n\nexport interface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\nexport interface Popup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\n// Maximum particles to prevent performance issues\nexport const MAX_PARTICLES = 100;\n\n// Encouraging messages for deliveries\nexport const DELIVERY_MESSAGES = [\n 'NICE!', 'AWESOME!', 'PERFECT!', 'GREAT!', 'SWEET!',\n 'BOOM!', 'YES!', 'NAILED IT!', 'SMOOTH!', 'SLICK!'\n];\n\n/**\n * Spawn particles in a burst pattern\n */\nexport function spawnParticles(\n particles: Particle[],\n x: number,\n y: number,\n count: number,\n color: string,\n chars: string[] = ['✦', '·', '○']\n): void {\n if (particles.length >= MAX_PARTICLES) return;\n\n const actualCount = Math.min(count, MAX_PARTICLES - particles.length);\n for (let i = 0; i < actualCount; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.2 + Math.random() * 0.3;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed + 0.2,\n life: 12 + Math.floor(Math.random() * 8),\n });\n }\n}\n\n/**\n * Spawn a colorful firework explosion\n */\nexport function spawnFirework(\n particles: Particle[],\n x: number,\n y: number,\n intensity: number = 1\n): void {\n const colors = ['\\x1b[1;93m', '\\x1b[1;92m', '\\x1b[1;96m', '\\x1b[1;95m', '\\x1b[1;91m', '\\x1b[1;97m'];\n const chars = ['★', '✦', '◆', '●', '✶', '✴', '◇', '♦', '•', '○'];\n\n // Central burst\n for (let i = 0; i < 12 * intensity; i++) {\n const angle = (Math.PI * 2 * i) / (12 * intensity);\n const speed = 0.4 + Math.random() * 0.4;\n const color = colors[Math.floor(Math.random() * colors.length)];\n const char = chars[Math.floor(Math.random() * chars.length)];\n particles.push({\n x, y,\n char,\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed - 0.2,\n life: 20 + Math.floor(Math.random() * 15),\n });\n }\n\n // Sparkle ring\n for (let i = 0; i < 8 * intensity; i++) {\n const angle = (Math.PI * 2 * i) / (8 * intensity) + Math.random() * 0.3;\n const dist = 1.5 + Math.random();\n particles.push({\n x: x + Math.cos(angle) * dist,\n y: y + Math.sin(angle) * dist,\n char: '✧',\n color: '\\x1b[1;97m',\n vx: Math.cos(angle) * 0.15,\n vy: Math.sin(angle) * 0.15 - 0.1,\n life: 15 + Math.floor(Math.random() * 10),\n });\n }\n}\n\n/**\n * Add a floating text popup\n */\nexport function addPopup(\n popups: Popup[],\n x: number,\n y: number,\n text: string,\n color: string = '\\x1b[1;93m'\n): void {\n popups.push({ x, y, text, frames: 25, color });\n}\n\n/**\n * Update all particles (apply physics, remove dead ones)\n */\nexport function updateParticles(particles: Particle[], gravityMult: number = 1): void {\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.02 * gravityMult;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n}\n\n/**\n * Update all popups (float up, fade out)\n */\nexport function updatePopups(popups: Popup[]): void {\n for (let i = popups.length - 1; i >= 0; i--) {\n const popup = popups[i];\n popup.y -= 0.12;\n popup.frames--;\n if (popup.frames <= 0) popups.splice(i, 1);\n }\n}\n\n/**\n * Spawn rising sparkle trail effect\n */\nexport function spawnSparkleTrail(\n particles: Particle[],\n x: number,\n y: number,\n count: number = 6,\n color: string = '\\x1b[1;93m'\n): void {\n for (let i = 0; i < count; i++) {\n particles.push({\n x: x + (Math.random() - 0.5) * 4,\n y,\n char: ['✦', '✧', '★'][Math.floor(Math.random() * 3)],\n color,\n vx: (Math.random() - 0.5) * 0.2,\n vy: -0.3 - Math.random() * 0.3,\n life: 25 + Math.floor(Math.random() * 15),\n });\n }\n}\n\n/**\n * Spawn splash effect (for water crashes)\n */\nexport function spawnSplash(\n particles: Particle[],\n x: number,\n waterY: number,\n intensity: number = 1\n): void {\n const count = Math.floor(20 * intensity);\n for (let i = 0; i < count; i++) {\n const spread = (Math.random() - 0.5) * 15 * intensity;\n particles.push({\n x: x + spread,\n y: waterY - 1,\n char: ['~', '≈', '○', '●', '◦', '∘', '█', '▓'][Math.floor(Math.random() * 8)],\n color: Math.random() > 0.3 ? '\\x1b[96m' : '\\x1b[1;97m',\n vx: spread * 0.1,\n vy: -0.5 - Math.random() * 0.8,\n life: 25 + Math.floor(Math.random() * 15),\n });\n }\n}\n\n/**\n * Get random delivery message\n */\nexport function getRandomDeliveryMessage(): string {\n return DELIVERY_MESSAGES[Math.floor(Math.random() * DELIVERY_MESSAGES.length)];\n}\n","/**\n * Hyper Chopper\n *\n * UGH!-inspired 2D physics delivery game.\n * Fly a prehistoric helicopter, pick up passengers,\n * deliver them to platforms. Don't fall in the water!\n *\n * FIXED SCREEN - no scrolling, like Pac-Man\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor, getSubtleBackgroundColor, getVerticalAnchor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { LEVELS, TUTORIAL_LEVELS, type Platform } from './levels';\nimport {\n type Particle,\n type Popup,\n spawnParticles,\n spawnFirework,\n addPopup,\n updateParticles,\n updatePopups,\n spawnSparkleTrail,\n spawnSplash,\n getRandomDeliveryMessage,\n} from './effects';\nimport {\n PAUSE_MENU_ITEMS,\n MODE_SELECT_ITEMS,\n renderSimpleMenu,\n navigateMenu,\n} from '../shared/menu';\n\n/**\n * Courier Game Controller\n */\nexport interface CourierController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// Physics constants - FLAPPY STYLE but playable! (adjusted for 40fps)\nconst GRAVITY = 0.04; // Halved for 2x frame rate\nconst FLAP_POWER = 0.35; // Halved for 2x frame rate\nconst THRUST_POWER = 0.09; // Halved for 2x frame rate\nconst MAX_VELOCITY_X = 0.35; // Halved for 2x frame rate\nconst MAX_VELOCITY_Y = 0.45; // Halved for 2x frame rate\nconst AIR_DRAG_X = 0.97; // Adjusted for 2x frame rate (sqrt of 0.94)\nconst AIR_DRAG_Y = 0.98; // Adjusted for 2x frame rate (sqrt of 0.96)\n\n// Rope mechanics - retractable! (adjusted for 40fps)\nconst ROPE_MIN_LENGTH = 1.5; // Retracted (default)\nconst ROPE_MAX_LENGTH = 5; // Extended (when SPACE held)\nconst ROPE_EXTEND_SPEED = 0.2; // Halved for 2x frame rate\nconst ROPE_RETRACT_SPEED = 0.15; // Halved for 2x frame rate\nconst ROPE_FAST_RETRACT_SPEED = 0.3; // Halved for 2x frame rate\n\n\n/**\n * Hyper Chopper Game\n */\nexport function runCourierGame(terminal: Terminal): CourierController {\n const themeColor = getCurrentThemeColor();\n\n // Minimum terminal size\n const MIN_COLS = 40;\n const MIN_ROWS = 16;\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let crashAnimation = 0; // Frames of crash animation before showing game over\n let paused = false;\n let levelComplete = false;\n\n // Menu state\n let showingModeSelect = true; // Show tutorial/play selection\n let menuSelection = 0; // 0 = Tutorial, 1 = Play\n let pauseMenuSelection = 0; // 0 = Resume, 1 = Restart, 2 = Quit, 3 = List Games, 4 = Next Game\n\n // Tutorial state\n let tutorialMode = false;\n let tutorialLevelIndex = 0; // Which tutorial level (0=flying, 1=delivery, 2=rope)\n let tutorialStep = 0; // Step within current tutorial level\n let tutorialPromptTimer = 0; // For flashing prompts\n\n // FIXED SCREEN - game world is the viewport!\n let screenWidth = 48;\n let screenHeight = 16;\n\n // Rig state\n let rigX = 10;\n let rigY = 4;\n let rigVX = 0;\n let rigVY = 0;\n let rigAngle = 0;\n\n // Passenger/payload state\n let passengerX = 0;\n let passengerY = 0;\n let passengerVX = 0;\n let passengerVY = 0;\n let hasPassenger = false;\n\n // Level state\n let currentLevel = 0;\n let timeRemaining = 60;\n let score = 0;\n let deliveriesComplete = 0;\n let totalDeliveries = 3; // Deliveries per level\n\n // Dynamic pickup/dropoff - randomly assigned each delivery\n let pickupPlatformIndex = -1;\n let dropoffPlatformIndex = -1;\n let doorAnimation = 0; // For door open/close animation\n let newPackageDelay = 0; // Delay before new package spawns (all doors inactive)\n let levelCompleteAnimation = 0; // Fun animation when level complete\n let deliveringAnimation = 0; // Animation when dropping package (before delivery completes)\n\n // Passenger pickup grace period (prevents instant water death)\n let passengerGraceFrames = 0;\n\n // Visual effects\n let particles: Particle[] = [];\n let popups: Popup[] = [];\n let screenShake = 0;\n let glitchFrame = 0;\n\n // Tutorial/grace period\n let tutorialCountdown = 0;\n let invincibleFrames = 0;\n\n // Flap state - CRITICAL FOR GAMEPLAY\n let flapCooldown = 0; // Frames until next flap (KEEP SHORT!)\n let flapAnimation = 0;\n let rotorFrame = 0;\n\n // Input state\n let inputLeft = false;\n let inputRight = false;\n let inputExtendRope = false; // SPACE held = extend rope\n let inputContractRope = false; // SHIFT held = fast retract rope\n\n // Rope state\n let currentRopeLength = ROPE_MIN_LENGTH;\n\n // Timeout tracking for cleanup\n const pendingTimeouts: ReturnType<typeof setTimeout>[] = [];\n\n // Levels imported from ./levels.ts\n const levels = LEVELS;\n\n // Interval references (set later in game loop)\n let renderInterval: ReturnType<typeof setInterval> | null = null;\n let gameInterval: ReturnType<typeof setInterval> | null = null;\n let keyListener: { dispose: () => void } | null = null;\n\n // Track if cleanup has been performed\n let cleanedUp = false;\n // Track if window listeners were added (for reliable cleanup)\n let windowListenersAdded = false;\n\n /**\n * Schedule a timeout and track it for cleanup\n */\n function scheduleTimeout(callback: () => void, delay: number): void {\n const id = setTimeout(() => {\n // Remove from tracking\n const idx = pendingTimeouts.indexOf(id);\n if (idx !== -1) pendingTimeouts.splice(idx, 1);\n // Only execute if still running\n if (running) callback();\n }, delay);\n pendingTimeouts.push(id);\n }\n\n /**\n * Clean up all game resources\n */\n function cleanup(): void {\n if (cleanedUp) return;\n cleanedUp = true;\n\n // Clear all pending timeouts\n pendingTimeouts.forEach(id => clearTimeout(id));\n pendingTimeouts.length = 0;\n\n // Clear intervals\n if (renderInterval) clearInterval(renderInterval);\n if (gameInterval) clearInterval(gameInterval);\n\n // Dispose terminal key listener\n if (keyListener) keyListener.dispose();\n\n // Remove window event listeners (only if they were added)\n if (windowListenersAdded && keyDownHandler && keyUpHandler) {\n window.removeEventListener('keydown', keyDownHandler);\n window.removeEventListener('keyup', keyUpHandler);\n windowListenersAdded = false;\n }\n\n running = false;\n }\n\n // Event handlers (defined here so cleanup can reference them)\n let keyDownHandler: (e: KeyboardEvent) => void;\n let keyUpHandler: (e: KeyboardEvent) => void;\n\n const controller: CourierController = {\n stop: () => {\n cleanup();\n },\n get isRunning() { return running; }\n };\n\n // ASCII art title\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ █▀▀ █ █ █▀█ █▀█ █▀█ █▀▀ █▀█',\n '█▀█ █ █▀▀ ██▄ █▀▄ █▄▄ █▀█ █▄█ █▀▀ █▀▀ ██▄ █▀▄',\n ];\n\n const subtitle = '~ STONE AGE TAXI SERVICE ~';\n\n /**\n * Select new random pickup and dropoff platforms for the next delivery\n */\n function selectNewRoute(): boolean {\n // Validate level index\n if (currentLevel < 0 || currentLevel >= levels.length) {\n console.error(`[Chopper] Invalid level index: ${currentLevel}`);\n return false;\n }\n\n const level = levels[currentLevel];\n const numPlatforms = level.platforms.length;\n\n // Need at least 2 platforms for pickup and dropoff\n if (numPlatforms < 2) {\n console.error(`[Chopper] Level ${currentLevel} needs at least 2 platforms`);\n return false;\n }\n\n // Pick random pickup platform\n pickupPlatformIndex = Math.floor(Math.random() * numPlatforms);\n\n // Pick random dropoff platform (different from pickup)\n do {\n dropoffPlatformIndex = Math.floor(Math.random() * numPlatforms);\n } while (dropoffPlatformIndex === pickupPlatformIndex);\n\n // Door animation - passenger appears\n doorAnimation = 30;\n\n // Spawn effect at pickup location\n const pickup = level.platforms[pickupPlatformIndex];\n spawnParticles(\n particles,\n pickup.x + Math.floor(pickup.width / 2),\n pickup.y - 1,\n 5,\n '\\x1b[92m',\n ['◇', '✦', '○']\n );\n\n return true;\n }\n\n function initGame() {\n gameOver = false;\n paused = false;\n levelComplete = false;\n score = 0;\n deliveriesComplete = 0;\n currentLevel = 0;\n tutorialMode = false;\n tutorialStep = 0;\n initLevel();\n }\n\n function initTutorial() {\n gameOver = false;\n paused = false;\n levelComplete = false;\n score = 0;\n deliveriesComplete = 0;\n tutorialMode = true;\n tutorialLevelIndex = 0; // Start at first tutorial level\n tutorialStep = 0;\n tutorialPromptTimer = 0;\n initTutorialLevel();\n }\n\n function initTutorialLevel(): boolean {\n const level = TUTORIAL_LEVELS[tutorialLevelIndex];\n if (!level) {\n console.error(`[Chopper] Invalid tutorial level: ${tutorialLevelIndex}`);\n return false;\n }\n\n // Reset tutorial step for this level\n tutorialStep = 0;\n tutorialPromptTimer = 0;\n\n // Start on left platform\n const startPlatform = level.platforms[0];\n rigX = startPlatform.x + Math.floor(startPlatform.width / 2);\n rigY = startPlatform.y - 4;\n rigVX = 0;\n rigVY = 0;\n rigAngle = 0;\n\n // No tutorial countdown in tutorial mode - we have our own prompts\n tutorialCountdown = 0;\n invincibleFrames = 200; // Extra invincibility for tutorial\n\n // Configure based on tutorial level\n if (tutorialLevelIndex === 0) {\n // FLIGHT SCHOOL - no passengers, just learn to fly\n pickupPlatformIndex = -1; // No pickup\n dropoffPlatformIndex = -1; // No dropoff\n hasPassenger = false;\n totalDeliveries = 0; // No deliveries\n } else if (tutorialLevelIndex === 1) {\n // FIRST DELIVERY - basic pickup and delivery\n pickupPlatformIndex = 0; // Left platform\n dropoffPlatformIndex = 1; // Right platform\n hasPassenger = false;\n totalDeliveries = 1;\n } else if (tutorialLevelIndex === 2) {\n // ROPE MASTER - start with passenger attached, different heights\n pickupPlatformIndex = -1; // Already have passenger\n dropoffPlatformIndex = 1; // High platform on right\n hasPassenger = true; // Start with passenger!\n totalDeliveries = 1;\n }\n\n // Reset passenger position\n passengerX = rigX;\n passengerY = rigY + ROPE_MIN_LENGTH;\n passengerVX = 0;\n passengerVY = 0;\n passengerGraceFrames = 0;\n currentRopeLength = ROPE_MIN_LENGTH;\n doorAnimation = 30;\n\n // Reset effects\n particles = [];\n popups = [];\n screenShake = 0;\n deliveringAnimation = 0;\n\n // Reset time\n timeRemaining = level.timeLimit;\n deliveriesComplete = 0;\n\n levelComplete = false;\n\n return true;\n }\n\n function initLevel(): boolean {\n // Validate level index\n if (currentLevel < 0 || currentLevel >= levels.length) {\n console.error(`[Chopper] Invalid level index: ${currentLevel}`);\n gameOver = true;\n return false;\n }\n\n const level = levels[currentLevel];\n\n // Need at least 2 platforms for pickup and dropoff\n if (level.platforms.length < 2) {\n console.error(`[Chopper] Level ${currentLevel} needs at least 2 platforms`);\n gameOver = true;\n return false;\n }\n\n // Select first random route (pickup and dropoff)\n // Do this first so we can avoid starting on pickup platform\n pickupPlatformIndex = Math.floor(Math.random() * level.platforms.length);\n do {\n dropoffPlatformIndex = Math.floor(Math.random() * level.platforms.length);\n } while (dropoffPlatformIndex === pickupPlatformIndex);\n\n // Find a start platform (not the pickup or dropoff)\n let startIndex = 0;\n for (let i = 0; i < level.platforms.length; i++) {\n if (i !== pickupPlatformIndex && i !== dropoffPlatformIndex) {\n startIndex = i;\n break;\n }\n }\n const startPlatform = level.platforms[startIndex];\n\n // Reset rig position - start ON the neutral platform\n rigX = startPlatform.x + Math.floor(startPlatform.width / 2);\n rigY = startPlatform.y - 4; // Just above platform\n rigVX = 0;\n rigVY = 0;\n rigAngle = 0;\n\n // Tutorial and safety\n tutorialCountdown = 80; // ~4 seconds (longer to read controls)\n invincibleFrames = 100; // ~5 seconds\n\n // Reset passenger and rope\n hasPassenger = false;\n passengerX = rigX;\n passengerY = rigY + ROPE_MIN_LENGTH;\n passengerVX = 0;\n passengerVY = 0;\n passengerGraceFrames = 0;\n currentRopeLength = ROPE_MIN_LENGTH;\n doorAnimation = 30; // Initial door animation\n\n // Reset effects\n particles = [];\n popups = [];\n screenShake = 0;\n deliveringAnimation = 0;\n\n // Reset time\n timeRemaining = level.timeLimit;\n deliveriesComplete = 0;\n\n levelComplete = false;\n\n return true;\n }\n\n // FLAP! - The core mechanic. Must be RESPONSIVE!\n function doFlap() {\n if (flapCooldown > 0) return;\n\n rigVY = -FLAP_POWER; // Instant upward velocity\n flapCooldown = 3; // VERY short cooldown! (~0.15s at 50ms updates)\n flapAnimation = 4;\n\n // Flap effects - subtle particles, no screen shake\n spawnParticles(particles, rigX, rigY + 2, 2, '\\x1b[93m', ['·', '∘']);\n }\n\n // Helper wrappers for effect functions (pass arrays)\n const spawn = (x: number, y: number, count: number, color: string, chars?: string[]) =>\n spawnParticles(particles, x, y, count, color, chars);\n const firework = (x: number, y: number, intensity?: number) =>\n spawnFirework(particles, x, y, intensity);\n const popup = (x: number, y: number, text: string, color?: string) =>\n addPopup(popups, x, y, text, color);\n const sparkleTrail = (x: number, y: number, count?: number, color?: string) =>\n spawnSparkleTrail(particles, x, y, count, color);\n const splash = (x: number, waterY: number, intensity?: number) =>\n spawnSplash(particles, x, waterY, intensity);\n\n function checkPlatformCollision(x: number, y: number): { platform: Platform; index: number } | null {\n const level = levels[currentLevel];\n for (let i = 0; i < level.platforms.length; i++) {\n const plat = level.platforms[i];\n // Check if position is on top of platform\n if (x >= plat.x && x < plat.x + plat.width &&\n y >= plat.y - 1 && y <= plat.y) {\n return { platform: plat, index: i };\n }\n }\n return null;\n }\n\n function checkWaterCollision(y: number): boolean {\n const level = levels[currentLevel];\n return y >= level.waterLevel;\n }\n\n function handleDelivery() {\n deliveriesComplete++;\n const timeBonus = Math.floor(timeRemaining * 2);\n const basePoints = 100;\n const points = basePoints + timeBonus;\n score += points;\n\n hasPassenger = false;\n\n // === EPIC DELIVERY CELEBRATION ===\n\n // Screen shake for impact!\n screenShake = 8;\n\n // Main firework at delivery location\n firework(passengerX, passengerY, 1.5);\n\n // Secondary bursts nearby (using tracked timeouts)\n const px = passengerX;\n const py = passengerY;\n scheduleTimeout(() => firework(px - 4, py - 2, 0.8), 50);\n scheduleTimeout(() => firework(px + 4, py - 2, 0.8), 100);\n\n // Points popup with style\n popup(passengerX - 2, passengerY - 3, `+${points}`, '\\x1b[1;93m');\n\n // Random encouraging message\n const msg = getRandomDeliveryMessage();\n popup(passengerX - Math.floor(msg.length / 2), passengerY - 5, msg, '\\x1b[1;92m');\n\n // Advance tutorial step after delivery\n if (tutorialMode) {\n if (tutorialLevelIndex === 1 && tutorialStep === 2) {\n // FIRST DELIVERY complete -> advance to level complete\n tutorialStep = 3;\n tutorialPromptTimer = 0;\n } else if (tutorialLevelIndex === 2 && tutorialStep === 3) {\n // ROPE MASTER delivery -> full tutorial complete\n tutorialStep = 4;\n tutorialPromptTimer = 0;\n }\n }\n\n // Streak indicator\n if (deliveriesComplete > 1) {\n const streakMsg = `${deliveriesComplete}x COMBO!`;\n popup(passengerX - Math.floor(streakMsg.length / 2), passengerY - 7, streakMsg, '\\x1b[1;95m');\n }\n\n // Rising sparkle trail\n sparkleTrail(passengerX, passengerY);\n\n // Check if level complete\n if (deliveriesComplete >= totalDeliveries) {\n levelComplete = true;\n levelCompleteAnimation = 80; // ~4 seconds of celebration\n screenShake = 12; // Bigger shake for level complete\n\n // MASSIVE celebration - fireworks everywhere!\n for (let i = 0; i < 8; i++) {\n const delay = i * 80;\n scheduleTimeout(() => {\n if (levelComplete) {\n const fx = 8 + Math.random() * (screenWidth - 16);\n const fy = 3 + Math.random() * (screenHeight * 0.4);\n firework(fx, fy, 1.2);\n }\n }, delay);\n }\n\n popup(screenWidth / 2 - 8, screenHeight / 2 - 2, '★ LEVEL CLEAR! ★', '\\x1b[1;92m');\n } else {\n // All doors go inactive, then new package appears\n pickupPlatformIndex = -1;\n dropoffPlatformIndex = -1;\n newPackageDelay = 40; // Slightly longer to enjoy the effects\n\n // Big \"DELIVERED\" with flair\n popup(screenWidth / 2 - 5, screenHeight / 2, '◆ DELIVERED ◆', '\\x1b[1;92m');\n }\n }\n\n function update() {\n if (!gameStarted || gameOver || paused) return;\n\n // Handle level complete celebration animation\n if (levelComplete) {\n // Continue updating particles during celebration\n updateParticles(particles);\n updatePopups(popups);\n // Spawn periodic celebration particles\n if (levelCompleteAnimation > 0) {\n levelCompleteAnimation--;\n if (levelCompleteAnimation % 8 === 0) {\n // Firework bursts at random positions\n const burstX = 5 + Math.random() * (screenWidth - 10);\n const burstY = 2 + Math.random() * (screenHeight * 0.4);\n spawn(\n burstX,\n burstY,\n 5,\n ['\\x1b[93m', '\\x1b[92m', '\\x1b[96m', '\\x1b[95m', '\\x1b[91m'][Math.floor(Math.random() * 5)],\n ['★', '✦', '◆', '●', '✶', '✴']\n );\n }\n }\n return;\n }\n\n const level = tutorialMode ? TUTORIAL_LEVELS[tutorialLevelIndex] : levels[currentLevel];\n\n // Tutorial step progression - different steps for each tutorial level\n if (tutorialMode) {\n if (tutorialLevelIndex === 0) {\n // FLIGHT SCHOOL - just learn to fly and steer\n switch (tutorialStep) {\n case 0: // Wait for player to flap and go airborne\n if (rigY < level.platforms[0].y - 6 && rigVY < 0) {\n tutorialStep = 1;\n popup(rigX, rigY - 2, 'NICE!', '\\x1b[1;93m');\n }\n break;\n case 1: // Wait for player to steer\n if (Math.abs(rigVX) > 0.3) {\n tutorialStep = 2;\n popup(rigX, rigY - 2, 'GOOD!', '\\x1b[1;93m');\n }\n break;\n case 2: // Wait for player to reach the right platform area\n if (rigX > level.platforms[1].x && rigX < level.platforms[1].x + level.platforms[1].width) {\n tutorialStep = 3;\n popup(rigX, rigY - 2, 'PERFECT!', '\\x1b[1;92m');\n }\n break;\n case 3: // Level complete - auto-advance after celebration\n tutorialPromptTimer++;\n if (tutorialPromptTimer > 80) {\n levelComplete = true;\n levelCompleteAnimation = 50;\n screenShake = 6;\n firework(screenWidth / 2, screenHeight / 2, 1.2);\n }\n break;\n }\n } else if (tutorialLevelIndex === 1) {\n // FIRST DELIVERY - learn pickup and delivery\n switch (tutorialStep) {\n case 0: // Wait for player to fly up\n if (rigY < level.platforms[0].y - 4) {\n tutorialStep = 1;\n popup(rigX, rigY - 2, 'GO!', '\\x1b[1;93m');\n }\n break;\n case 1: // Wait for pickup\n if (hasPassenger) {\n tutorialStep = 2;\n popup(rigX, rigY - 2, 'GOT IT!', '\\x1b[1;93m');\n }\n break;\n case 2: // Wait for delivery (handled in handleDelivery)\n break;\n case 3: // Level complete\n if (!levelComplete) {\n levelComplete = true;\n levelCompleteAnimation = 50;\n screenShake = 6;\n firework(screenWidth / 2, screenHeight / 2, 1.2);\n }\n break;\n }\n } else if (tutorialLevelIndex === 2) {\n // ROPE MASTER - learn rope controls with height difference\n switch (tutorialStep) {\n case 0: // Show initial info about rope (auto-advance)\n tutorialPromptTimer++;\n if (tutorialPromptTimer > 80) {\n tutorialStep = 1;\n tutorialPromptTimer = 0;\n }\n break;\n case 1: // Wait for player to use SPACE (extend rope)\n if (inputExtendRope || currentRopeLength > ROPE_MIN_LENGTH + 1) {\n tutorialStep = 2;\n popup(rigX, rigY - 2, 'GOOD!', '\\x1b[1;93m');\n }\n break;\n case 2: // Wait for player to use SHIFT (contract rope)\n if (inputContractRope) {\n tutorialStep = 3;\n popup(rigX, rigY - 2, 'NICE!', '\\x1b[1;93m');\n }\n break;\n case 3: // Wait for delivery (handled in handleDelivery)\n break;\n case 4: // Full tutorial complete!\n if (!levelComplete) {\n levelComplete = true;\n levelCompleteAnimation = 80;\n screenShake = 10;\n // Big celebration!\n firework(screenWidth / 2, screenHeight / 2, 2);\n firework(screenWidth / 3, screenHeight / 3, 1.5);\n firework(screenWidth * 2 / 3, screenHeight / 3, 1.5);\n }\n break;\n }\n }\n }\n\n // Handle crash animation countdown\n if (crashAnimation > 0) {\n crashAnimation--;\n // Keep updating particles during crash (heavier gravity for dramatic fall)\n updateParticles(particles, 1.5);\n updatePopups(popups);\n if (screenShake > 0) screenShake--;\n // When crash animation ends, show game over\n if (crashAnimation === 0) {\n gameOver = true;\n }\n return;\n }\n\n // Update timers\n if (tutorialCountdown > 0) tutorialCountdown--;\n if (invincibleFrames > 0) invincibleFrames--;\n\n // Handle delivering animation - package is on dropoff, building anticipation!\n if (deliveringAnimation > 0) {\n deliveringAnimation--;\n\n // Keep the passenger still on the platform during animation\n if (hasPassenger) {\n passengerVX *= 0.5;\n passengerVY = 0;\n }\n\n // Building anticipation effects - get more intense as we approach completion\n const progress = 1 - (deliveringAnimation / 40); // 0 to 1\n\n // Sparkle particles - more frequent as we progress\n const spawnRate = deliveringAnimation > 30 ? 10 : deliveringAnimation > 15 ? 6 : 3;\n if (deliveringAnimation % spawnRate === 0 && hasPassenger) {\n // Spiral upward effect\n const angle = (40 - deliveringAnimation) * 0.5;\n const radius = 1 + progress * 2;\n particles.push({\n x: passengerX + Math.cos(angle) * radius,\n y: passengerY - 1,\n char: ['✦', '✧', '★', '◇'][Math.floor(Math.random() * 4)],\n color: progress > 0.7 ? '\\x1b[1;92m' : '\\x1b[1;93m',\n vx: Math.cos(angle) * 0.1,\n vy: -0.2 - progress * 0.2,\n life: 12 + Math.floor(Math.random() * 8),\n });\n }\n\n // Charging glow effect at key moments\n if (deliveringAnimation === 30 && hasPassenger) {\n popup(passengerX - 4, passengerY - 3, 'CHARGING...', '\\x1b[2;93m');\n }\n if (deliveringAnimation === 15 && hasPassenger) {\n popup(passengerX - 3, passengerY - 4, 'ALMOST...', '\\x1b[1;93m');\n // Pre-burst sparkles\n for (let i = 0; i < 4; i++) {\n const a = (Math.PI * 2 * i) / 4;\n particles.push({\n x: passengerX + Math.cos(a) * 2,\n y: passengerY + Math.sin(a) * 1.5,\n char: '✧',\n color: '\\x1b[1;97m',\n vx: -Math.cos(a) * 0.15,\n vy: -Math.sin(a) * 0.15,\n life: 15,\n });\n }\n }\n\n // When animation ends, actually complete the delivery with big celebration!\n if (deliveringAnimation === 0 && hasPassenger) {\n handleDelivery();\n }\n }\n\n // New package spawn animation\n if (newPackageDelay > 0) {\n newPackageDelay--;\n if (newPackageDelay === 0) {\n // Now spawn the new package with animation\n selectNewRoute();\n popup(screenWidth / 2 - 5, screenHeight / 2, 'NEW PACKAGE!', '\\x1b[1;93m');\n }\n }\n\n // Update time (don't count during tutorial)\n if (tutorialCountdown === 0) {\n timeRemaining -= 1 / 20;\n if (timeRemaining <= 0) {\n gameOver = true;\n popup(rigX, rigY - 2, 'TIME UP!', '\\x1b[91m');\n return;\n }\n }\n\n // Update flap cooldown and animation\n if (flapCooldown > 0) flapCooldown--;\n if (flapAnimation > 0) flapAnimation--;\n rotorFrame = (rotorFrame + 1) % 6;\n\n // Update rope length - SPACE extends, SHIFT fast retracts, auto-retracts otherwise\n if (inputExtendRope && !inputContractRope) {\n currentRopeLength = Math.min(ROPE_MAX_LENGTH, currentRopeLength + ROPE_EXTEND_SPEED);\n } else if (inputContractRope) {\n currentRopeLength = Math.max(ROPE_MIN_LENGTH, currentRopeLength - ROPE_FAST_RETRACT_SPEED);\n } else {\n currentRopeLength = Math.max(ROPE_MIN_LENGTH, currentRopeLength - ROPE_RETRACT_SPEED);\n }\n\n // Apply horizontal input\n if (inputLeft) {\n rigVX -= THRUST_POWER;\n rigAngle = Math.max(-15, rigAngle - 2);\n }\n if (inputRight) {\n rigVX += THRUST_POWER;\n rigAngle = Math.min(15, rigAngle + 2);\n }\n\n // Return angle to neutral\n if (!inputLeft && !inputRight) {\n rigAngle *= 0.9;\n }\n\n // Apply gravity - always pulling down!\n rigVY += GRAVITY;\n\n // Apply drag\n rigVX *= AIR_DRAG_X;\n rigVY *= AIR_DRAG_Y;\n\n // Clamp velocity\n rigVX = Math.max(-MAX_VELOCITY_X, Math.min(MAX_VELOCITY_X, rigVX));\n rigVY = Math.max(-MAX_VELOCITY_Y, Math.min(MAX_VELOCITY_Y, rigVY));\n\n // Move rig\n rigX += rigVX;\n rigY += rigVY;\n\n // Screen bounds - clamp to edges, no wrapping\n rigX = Math.max(2, Math.min(screenWidth - 4, rigX));\n rigY = Math.max(1, rigY); // Can't go above screen\n\n // Check platform collision for rig\n const rigPlatformResult = checkPlatformCollision(rigX, rigY + 2);\n if (rigPlatformResult && rigVY > 0) {\n const { platform: rigPlatform, index: rigPlatformIndex } = rigPlatformResult;\n const impactVelocity = rigVY;\n rigY = rigPlatform.y - 3;\n rigVY = -rigVY * 0.3; // Bounce\n\n // Only shake/particles on significant impacts\n if (impactVelocity > 0.3) {\n screenShake = Math.min(5, Math.floor(impactVelocity * 4));\n spawn(rigX, rigY + 2, Math.floor(impactVelocity * 5), '\\x1b[93m', ['·', '•']);\n }\n\n // AUTO-PICKUP: If we land on current pickup platform and don't have passenger\n // Don't pickup during tutorial - give player time to lift off first!\n if (rigPlatformIndex === pickupPlatformIndex && !hasPassenger && tutorialCountdown === 0) {\n hasPassenger = true;\n passengerX = rigX;\n passengerY = rigY + 2; // Start right at rig bottom\n passengerVX = rigVX * 0.5;\n passengerVY = rigVY * 0.5; // Inherit some rig momentum\n passengerGraceFrames = 20; // Grace period before water kills\n spawn(rigX, rigY + 2, 6, themeColor, ['◇', '✦']);\n popup(rigX - 3, rigY - 1, 'GOT IT!', '\\x1b[1;93m');\n\n // Show dropoff location with popup and animation\n doorAnimation = 30;\n const dropoffPlat = level.platforms[dropoffPlatformIndex];\n const dropX = dropoffPlat.x + Math.floor(dropoffPlat.width / 2);\n const dropY = dropoffPlat.y - 5; // Above the hut\n popup(dropX - 4, dropY, 'DROP HERE!', '\\x1b[1;93m');\n spawn(dropX, dropY + 2, 4, '\\x1b[93m', ['▽', '◇', '✦']);\n }\n }\n\n // Check water collision for rig\n if (checkWaterCollision(rigY + 2)) {\n if (invincibleFrames > 0) {\n // Bounce off water during invincibility\n rigY = level.waterLevel - 4;\n rigVY = -0.4;\n screenShake = 3;\n popup(rigX, rigY, 'SPLASH!', '\\x1b[96m');\n } else {\n // CRASH - fell in water! Epic crash effect\n crashAnimation = 35; // ~1.75 seconds of crash animation\n screenShake = 15;\n // Big splash\n splash(rigX, level.waterLevel, 1.25);\n // Explosion particles\n spawn(rigX, rigY, 12, '\\x1b[91m', ['✗', '×', '▓', '░', '!', '*']);\n popup(rigX - 4, rigY - 4, '💀 SPLASH! 💀', '\\x1b[1;91m');\n return;\n }\n }\n\n // Passenger physics\n if (hasPassenger) {\n // Decrement grace period\n if (passengerGraceFrames > 0) passengerGraceFrames--;\n\n // Apply gravity to passenger\n passengerVY += GRAVITY * 1.2;\n\n // Rope constraint - uses current (dynamic) rope length\n const dx = passengerX - rigX;\n const dy = passengerY - (rigY + 2);\n const dist = Math.sqrt(dx * dx + dy * dy);\n\n // Only apply rope constraint if distance is valid (avoid division by zero)\n if (dist > 0.01 && dist > currentRopeLength) {\n const nx = dx / dist;\n const ny = dy / dist;\n const stretch = dist - currentRopeLength;\n\n // Pull passenger toward rig\n passengerVX -= nx * stretch * 0.1;\n passengerVY -= ny * stretch * 0.1;\n\n // Also affect rig (lighter effect)\n rigVX += nx * stretch * 0.03;\n rigVY += ny * stretch * 0.03;\n }\n\n // Damping\n passengerVX *= 0.95;\n passengerVY *= 0.95;\n\n // Clamp velocities to prevent runaway values\n passengerVX = Math.max(-2, Math.min(2, passengerVX));\n passengerVY = Math.max(-2, Math.min(2, passengerVY));\n\n // Move passenger\n passengerX += passengerVX;\n passengerY += passengerVY;\n\n // Screen bounds for passenger - clamp to edges\n passengerX = Math.max(1, Math.min(screenWidth - 2, passengerX));\n\n // Platform collision for passenger\n const passPlatformResult = checkPlatformCollision(passengerX, passengerY);\n if (passPlatformResult && passengerVY > 0) {\n const { platform: passPlatform, index: passPlatformIndex } = passPlatformResult;\n passengerY = passPlatform.y - 1;\n passengerVY = -passengerVY * 0.2;\n passengerVX *= 0.8;\n\n // Check if this is the current dropoff platform - start delivery animation!\n if (passPlatformIndex === dropoffPlatformIndex && Math.abs(passengerVY) < 0.3 && deliveringAnimation === 0) {\n // Start delivering animation - player sees the package land\n deliveringAnimation = 40; // ~2 seconds to watch the delivery\n spawn(passengerX, passengerY - 1, 8, '\\x1b[1;93m', ['★', '✦', '◆']);\n popup(passengerX - 4, passengerY - 3, 'DROPPING!', '\\x1b[1;93m');\n }\n }\n\n // Water collision for passenger (skip during grace period)\n if (checkWaterCollision(passengerY) && passengerGraceFrames === 0) {\n hasPassenger = false;\n crashAnimation = 35; // ~1.75 seconds of crash animation\n screenShake = 12;\n // Dramatic splash for package\n splash(passengerX, level.waterLevel, 1);\n popup(passengerX - 5, passengerY - 3, '💀 PACKAGE LOST! 💀', '\\x1b[1;91m');\n return;\n }\n }\n\n // Update particles and popups\n updateParticles(particles);\n updatePopups(popups);\n\n // Update effects\n if (screenShake > 0) screenShake--;\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg = `Need ${MIN_COLS}×${MIN_ROWS}, have ${cols}×${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY};${Math.max(1, centerX - msg.length / 2)}H${themeColor}${msg}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Adapt viewport to terminal size - wider map!\n screenWidth = Math.min(cols - 4, 70);\n screenHeight = Math.min(rows - 8, 18);\n\n const gameLeft = Math.max(2, Math.floor((cols - screenWidth - 2) / 2));\n const gameTop = getVerticalAnchor(rows, screenHeight + 2, {\n headerRows: 4,\n footerRows: 2,\n minTop: 4,\n });\n\n // Apply screen shake\n const shakeX = screenShake > 0 ? Math.floor(Math.random() * 3) - 1 : 0;\n const shakeY = screenShake > 0 ? Math.floor(Math.random() * 2) : 0;\n const displayLeft = gameLeft + shakeX;\n const displayTop = gameTop + shakeY;\n\n // Title area - show tutorial during countdown, otherwise show title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n if (gameStarted && tutorialCountdown > 0 && !paused && !gameOver && !levelComplete) {\n // Show controls in title area during tutorial\n const controls1 = '↑/W = FLAP ←/→ = STEER SPACE/SHIFT = ROPE';\n const controls2 = 'Pickup the yellow package, deliver to the ▼ marker!';\n const ctrl1X = Math.floor((cols - controls1.length) / 2);\n const ctrl2X = Math.floor((cols - controls2.length) / 2);\n const fade = tutorialCountdown < 20 ? '\\x1b[2m' : '\\x1b[1m';\n output += `\\x1b[1;${ctrl1X}H${fade}${themeColor}${controls1}\\x1b[0m`;\n output += `\\x1b[2;${ctrl2X}H${fade}${themeColor}${controls2}\\x1b[0m`;\n const countdownBar = '▓'.repeat(Math.ceil(tutorialCountdown / 10)) + '░'.repeat(8 - Math.ceil(tutorialCountdown / 10));\n const barX = Math.floor((cols - countdownBar.length) / 2);\n output += `\\x1b[3;${barX}H\\x1b[2m${themeColor}${countdownBar}\\x1b[0m`;\n } else {\n // Normal title display\n output += `\\x1b[1;${titleX}H`;\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n const subtitleX = Math.floor((cols - subtitle.length) / 2);\n output += `\\x1b[3;${subtitleX}H\\x1b[2m${themeColor}${subtitle}\\x1b[0m`;\n }\n\n // Game border\n output += `\\x1b[${displayTop};${displayLeft}H${themeColor}╔${'═'.repeat(screenWidth)}╗\\x1b[0m`;\n for (let y = 0; y < screenHeight; y++) {\n output += `\\x1b[${displayTop + 1 + y};${displayLeft}H${themeColor}║\\x1b[0m`;\n output += `\\x1b[${displayTop + 1 + y};${displayLeft + screenWidth + 1}H${themeColor}║\\x1b[0m`;\n }\n output += `\\x1b[${displayTop + screenHeight + 1};${displayLeft}H${themeColor}╚${'═'.repeat(screenWidth)}╝\\x1b[0m`;\n\n if (paused) {\n const pauseMsg = '══ PAUSED ══';\n const pauseCenterX = gameLeft + Math.floor(screenWidth / 2) + 1;\n const pauseY = gameTop + Math.floor(screenHeight / 2) - 4;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[1m${themeColor}${pauseMsg}\\x1b[0m`;\n\n // Use shared menu rendering\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted && showingModeSelect) {\n // Mode selection screen with arrow key navigation\n const modeCenterX = gameLeft + Math.floor(screenWidth / 2) + 1;\n const modeStartY = gameTop + Math.floor(screenHeight / 2) - 2;\n\n const selectMsg = 'SELECT MODE';\n const selectX = modeCenterX - Math.floor(selectMsg.length / 2);\n output += `\\x1b[${modeStartY};${selectX}H\\x1b[1m${themeColor}${selectMsg}\\x1b[0m`;\n\n // Use shared menu rendering\n output += renderSimpleMenu(MODE_SELECT_ITEMS, menuSelection, {\n centerX: modeCenterX,\n startY: modeStartY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ to select ENTER to confirm';\n const navHintX = modeCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${modeStartY + 5};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n\n const hint = 'New players: Try the tutorial first!';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${modeStartY + 7};${hintX}H\\x1b[2;3m${themeColor}${hint}\\x1b[0m`;\n } else if (!gameStarted) {\n // Legacy start screen (shouldn't be reached now)\n const startMsg = '[ PRESS ANY KEY TO START ]';\n const startX = gameLeft + Math.floor((screenWidth - startMsg.length) / 2) + 1;\n const startY = gameTop + Math.floor(screenHeight / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = '↑/W = FLAP ←/→ = STEER SPACE/SHIFT = ROPE';\n const ctrlX = Math.floor((cols - controls.length) / 2);\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n\n const hook = 'Pickup yellow packages, deliver to markers. Avoid the water!';\n const hookX = Math.floor((cols - hook.length) / 2);\n output += `\\x1b[${startY + 4};${hookX}H\\x1b[2;3m${themeColor}${hook}\\x1b[0m`;\n } else if (levelComplete) {\n const msgY = gameTop + Math.floor(screenHeight / 2) - 3;\n\n if (tutorialMode) {\n const tutLevel = TUTORIAL_LEVELS[tutorialLevelIndex];\n const isLastLesson = tutorialLevelIndex >= TUTORIAL_LEVELS.length - 1;\n\n if (isLastLesson) {\n // Final tutorial complete screen\n const completeMsg = '★ TUTORIAL COMPLETE! ★';\n const msgX = gameLeft + Math.floor((screenWidth - completeMsg.length) / 2) + 1;\n output += `\\x1b[${msgY};${msgX}H\\x1b[1;92m${completeMsg}\\x1b[0m`;\n\n const congratsMsg = 'You mastered the controls!';\n const congratsX = gameLeft + Math.floor((screenWidth - congratsMsg.length) / 2) + 1;\n output += `\\x1b[${msgY + 2};${congratsX}H${themeColor}${congratsMsg}\\x1b[0m`;\n\n const controlsMsg = '↑/W=FLAP ←/→=STEER SPACE/SHIFT=ROPE';\n const controlsX = gameLeft + Math.floor((screenWidth - controlsMsg.length) / 2) + 1;\n output += `\\x1b[${msgY + 4};${controlsX}H\\x1b[2m${themeColor}${controlsMsg}\\x1b[0m`;\n\n const nextHint = '[ SPACE ] START GAME [ Q ] QUIT';\n const nextX = gameLeft + Math.floor((screenWidth - nextHint.length) / 2) + 1;\n output += `\\x1b[${msgY + 6};${nextX}H${themeColor}${nextHint}\\x1b[0m`;\n } else {\n // Lesson complete - more lessons to go\n const completeMsg = `★ ${tutLevel.name} COMPLETE! ★`;\n const msgX = gameLeft + Math.floor((screenWidth - completeMsg.length) / 2) + 1;\n output += `\\x1b[${msgY};${msgX}H\\x1b[1;92m${completeMsg}\\x1b[0m`;\n\n const nextLevelName = TUTORIAL_LEVELS[tutorialLevelIndex + 1]?.name || 'NEXT';\n const nextLessonMsg = `Next: ${nextLevelName}`;\n const nextLessonX = gameLeft + Math.floor((screenWidth - nextLessonMsg.length) / 2) + 1;\n output += `\\x1b[${msgY + 2};${nextLessonX}H${themeColor}${nextLessonMsg}\\x1b[0m`;\n\n const progressMsg = `Lesson ${tutorialLevelIndex + 1} of ${TUTORIAL_LEVELS.length}`;\n const progressX = gameLeft + Math.floor((screenWidth - progressMsg.length) / 2) + 1;\n output += `\\x1b[${msgY + 4};${progressX}H\\x1b[2m${themeColor}${progressMsg}\\x1b[0m`;\n\n const nextHint = '[ SPACE ] NEXT LESSON [ Q ] QUIT';\n const nextX = gameLeft + Math.floor((screenWidth - nextHint.length) / 2) + 1;\n output += `\\x1b[${msgY + 6};${nextX}H${themeColor}${nextHint}\\x1b[0m`;\n }\n } else {\n // Normal level complete screen\n const level = levels[currentLevel];\n const timeBonus = timeRemaining / level.timeLimit;\n const stars = timeRemaining >= level.parTime ? 3 : timeBonus > 0.3 ? 2 : 1;\n\n const completeMsg = '★ LEVEL COMPLETE! ★';\n const msgX = gameLeft + Math.floor((screenWidth - completeMsg.length) / 2) + 1;\n output += `\\x1b[${msgY};${msgX}H\\x1b[1;92m${completeMsg}\\x1b[0m`;\n\n const scoreMsg = `SCORE: ${score}`;\n const scoreX = gameLeft + Math.floor((screenWidth - scoreMsg.length) / 2) + 1;\n output += `\\x1b[${msgY + 2};${scoreX}H${themeColor}${scoreMsg}\\x1b[0m`;\n\n const starDisplay = '★'.repeat(stars) + '☆'.repeat(3 - stars);\n const starX = gameLeft + Math.floor((screenWidth - starDisplay.length) / 2) + 1;\n output += `\\x1b[${msgY + 3};${starX}H\\x1b[1;93m${starDisplay}\\x1b[0m`;\n\n const nextHint = currentLevel < levels.length - 1 ? '[ SPACE ] NEXT [ Q ] QUIT' : '[ R ] REPLAY [ Q ] QUIT';\n const nextX = gameLeft + Math.floor((screenWidth - nextHint.length) / 2) + 1;\n output += `\\x1b[${msgY + 5};${nextX}H\\x1b[2m${themeColor}${nextHint}\\x1b[0m`;\n }\n } else if (gameOver) {\n const overMsg = '══ GAME OVER ══';\n const overX = gameLeft + Math.floor((screenWidth - overMsg.length) / 2) + 1;\n const overY = gameTop + Math.floor(screenHeight / 2) - 1;\n output += `\\x1b[${overY};${overX}H\\x1b[1;91m${overMsg}\\x1b[0m`;\n\n const scoreMsg = `SCORE: ${score}`;\n const scoreX = gameLeft + Math.floor((screenWidth - scoreMsg.length) / 2) + 1;\n output += `\\x1b[${overY + 2};${scoreX}H${themeColor}${scoreMsg}\\x1b[0m`;\n\n const restart = '[ R ] RETRY [ Q ] QUIT';\n const restartX = gameLeft + Math.floor((screenWidth - restart.length) / 2) + 1;\n output += `\\x1b[${overY + 4};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n } else {\n const level = levels[currentLevel];\n\n // Draw water - fill from waterLevel to bottom of screen\n for (let x = 0; x < screenWidth; x++) {\n // First water line - wavy surface\n const waterChar1 = (x + glitchFrame) % 4 === 0 ? '≈' : '~';\n output += `\\x1b[${displayTop + 1 + level.waterLevel};${displayLeft + 1 + x}H\\x1b[96m${waterChar1}\\x1b[0m`;\n // Fill remaining rows with darker water\n for (let wy = level.waterLevel + 1; wy < screenHeight; wy++) {\n const waterChar = (x + wy + glitchFrame) % 3 === 0 ? '≈' : '~';\n const waterColor = wy === level.waterLevel + 1 ? '\\x1b[36m' : '\\x1b[34m'; // Gets darker\n output += `\\x1b[${displayTop + 1 + wy};${displayLeft + 1 + x}H${waterColor}${waterChar}\\x1b[0m`;\n }\n }\n\n // Draw platforms with doors\n for (let platIndex = 0; platIndex < level.platforms.length; platIndex++) {\n const plat = level.platforms[platIndex];\n const isCurrentPickup = platIndex === pickupPlatformIndex;\n const isCurrentDropoff = platIndex === dropoffPlatformIndex;\n\n // Platform is always neutral brown/earth color\n const platColor = '\\x1b[38;5;94m'; // Brown/earth tone\n\n // Draw platform surface\n for (let px = 0; px < plat.width; px++) {\n const screenX = plat.x + px;\n const screenY = plat.y;\n if (screenX >= 0 && screenX < screenWidth && screenY >= 0 && screenY < screenHeight) {\n output += `\\x1b[${displayTop + 1 + screenY};${displayLeft + 1 + screenX}H${platColor}▀\\x1b[0m`;\n // Thick platform - add bottom\n if (screenY + 1 < screenHeight && screenY + 1 < level.waterLevel) {\n output += `\\x1b[${displayTop + 2 + screenY};${displayLeft + 1 + screenX}H${platColor}█\\x1b[0m`;\n }\n }\n }\n\n // Draw door/hut on each platform (5 wide, 3 tall solid block)\n const doorWidth = 5;\n const doorX = plat.x + Math.floor(plat.width / 2) - Math.floor(doorWidth / 2);\n const doorY1 = plat.y - 3; // Top row\n const doorY2 = plat.y - 2; // Middle row\n const doorY3 = plat.y - 1; // Bottom row (connects to platform)\n\n // All doors are always dim monochrome - adapts to terminal theme\n const doorColor = getSubtleBackgroundColor();\n\n // Draw 5x3 hut block (solid, always same color)\n const hutChars = '█████';\n if (doorX >= 0 && doorX + doorWidth - 1 < screenWidth && doorY1 >= 0 && doorY1 < screenHeight) {\n output += `\\x1b[${displayTop + 1 + doorY1};${displayLeft + 1 + doorX}H${doorColor}${hutChars}\\x1b[0m`;\n }\n if (doorX >= 0 && doorX + doorWidth - 1 < screenWidth && doorY2 >= 0 && doorY2 < screenHeight) {\n output += `\\x1b[${displayTop + 1 + doorY2};${displayLeft + 1 + doorX}H${doorColor}${hutChars}\\x1b[0m`;\n }\n if (doorX >= 0 && doorX + doorWidth - 1 < screenWidth && doorY3 >= 0 && doorY3 < screenHeight) {\n output += `\\x1b[${displayTop + 1 + doorY3};${displayLeft + 1 + doorX}H${doorColor}${hutChars}\\x1b[0m`;\n }\n\n // Draw yellow package on floor at pickup (the indicator!)\n if (isCurrentPickup && !hasPassenger) {\n const packageX = doorX + Math.floor(doorWidth / 2);\n const packageY = plat.y - 1; // On the platform, in front of door\n if (packageX >= 0 && packageX < screenWidth && packageY >= 0 && packageY < screenHeight) {\n const pkgChar = doorAnimation > 0 && doorAnimation % 6 < 3 ? '▪' : '█';\n output += `\\x1b[${displayTop + 1 + packageY};${displayLeft + 1 + packageX}H\\x1b[1;93m${pkgChar}\\x1b[0m`;\n }\n }\n\n // Dropoff indicator - arrow above the door pointing down\n if (isCurrentDropoff && hasPassenger) {\n const markerX = doorX + Math.floor(doorWidth / 2);\n const markerY = doorY1 - 1; // Above the door\n if (markerX >= 0 && markerX < screenWidth && markerY >= 0 && markerY < screenHeight) {\n const marker = doorAnimation > 0 && doorAnimation % 8 < 4 ? '▼' : '▽';\n output += `\\x1b[${displayTop + 1 + markerY};${displayLeft + 1 + markerX}H\\x1b[1;93m${marker}\\x1b[0m`;\n }\n }\n }\n\n // Update door animation\n if (doorAnimation > 0) doorAnimation--;\n\n // Draw rope if carrying passenger\n if (hasPassenger) {\n const dx = passengerX - rigX;\n const dy = passengerY - (rigY + 2);\n const dist = Math.sqrt(dx * dx + dy * dy);\n const steps = Math.max(2, Math.floor(dist));\n\n for (let i = 1; i < steps; i++) {\n const t = i / steps;\n const rx = Math.floor(rigX + dx * t);\n const ry = Math.floor((rigY + 2) + dy * t);\n if (rx >= 0 && rx < screenWidth && ry >= 0 && ry < screenHeight) {\n output += `\\x1b[${displayTop + 1 + ry};${displayLeft + 1 + rx}H\\x1b[2m${themeColor}│\\x1b[0m`;\n }\n }\n\n // Draw package (yellow box)\n const pScreenX = Math.floor(passengerX);\n const pScreenY = Math.floor(passengerY);\n if (pScreenX >= 0 && pScreenX < screenWidth && pScreenY >= 0 && pScreenY < screenHeight) {\n output += `\\x1b[${displayTop + 1 + pScreenY};${displayLeft + 1 + pScreenX}H\\x1b[1;93m█\\x1b[0m`;\n }\n }\n\n // Draw rig - SIMPLE BOXY HELICOPTER like UGH!\n const rigScreenX = Math.floor(rigX);\n const rigScreenY = Math.floor(rigY);\n if (rigScreenX >= 1 && rigScreenX < screenWidth - 3 && rigScreenY >= 1 && rigScreenY < screenHeight - 3) {\n // Blink if invincible\n const isBlinking = invincibleFrames > 0 && Math.floor(invincibleFrames / 4) % 2 === 0;\n const bodyColor = isBlinking ? '\\x1b[2m' + themeColor : '\\x1b[1m' + themeColor;\n\n // ROTOR - simple spinning blade, 3 chars\n const rotorFrames = ['─O─', '\\\\O/', '│O│', '/O\\\\'];\n const rotor = rotorFrames[Math.floor(rotorFrame / 1.5) % rotorFrames.length];\n output += `\\x1b[${displayTop + 1 + rigScreenY};${displayLeft + rigScreenX}H${bodyColor}${rotor}\\x1b[0m`;\n\n // BODY - simple box, 3 chars wide\n let body: string;\n if (flapAnimation > 0) {\n body = '[^]'; // Boost!\n } else if (rigAngle < -5) {\n body = '/o]'; // Tilting left\n } else if (rigAngle > 5) {\n body = '[o\\\\'; // Tilting right\n } else {\n body = '[o]'; // Centered caveman\n }\n output += `\\x1b[${displayTop + 2 + rigScreenY};${displayLeft + rigScreenX}H${bodyColor}${body}\\x1b[0m`;\n\n // SKIDS - landing gear\n output += `\\x1b[${displayTop + 3 + rigScreenY};${displayLeft + rigScreenX}H${bodyColor}└─┘\\x1b[0m`;\n }\n\n // Draw particles\n for (const p of particles) {\n const px = Math.floor(p.x);\n const py = Math.floor(p.y);\n if (px >= 0 && px < screenWidth && py >= 0 && py < screenHeight) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${displayTop + 1 + py};${displayLeft + 1 + px}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw popups\n for (const popup of popups) {\n const px = Math.floor(popup.x);\n const py = Math.floor(popup.y);\n if (px >= 0 && px < screenWidth - popup.text.length && py >= 0 && py < screenHeight) {\n const alpha = popup.frames > 15 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${displayTop + 1 + py};${displayLeft + 1 + px}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n\n // In-game tutorial prompt overlay at TOP of game area\n if (tutorialMode && !levelComplete) {\n const promptBright = Math.floor(Date.now() / 300) % 2 === 0 ? '\\x1b[1m' : '';\n let inGamePrompt = '';\n\n if (tutorialLevelIndex === 0) {\n switch (tutorialStep) {\n case 0: inGamePrompt = '▲ PRESS UP TO FLY ▲'; break;\n case 1: inGamePrompt = '◄ ► STEER LEFT/RIGHT'; break;\n case 2: inGamePrompt = '► FLY TO RIGHT PLATFORM ►'; break;\n }\n } else if (tutorialLevelIndex === 1) {\n switch (tutorialStep) {\n case 0: inGamePrompt = '▲ TAKE OFF! ▲'; break;\n case 1: inGamePrompt = '▼ LAND ON HUT TO PICKUP ▼'; break;\n case 2: inGamePrompt = '► DELIVER TO RIGHT HUT ►'; break;\n }\n } else if (tutorialLevelIndex === 2) {\n switch (tutorialStep) {\n case 0: inGamePrompt = '~ ROPE CONTROLS ~'; break;\n case 1: inGamePrompt = '[ SPACE ] = LOWER ROPE'; break;\n case 2: inGamePrompt = '[ SHIFT ] = RAISE ROPE'; break;\n case 3: inGamePrompt = '▲ DELIVER TO HIGH PLATFORM ▲'; break;\n }\n }\n\n if (inGamePrompt) {\n const promptX = displayLeft + Math.floor((screenWidth - inGamePrompt.length) / 2) + 1;\n const promptY = displayTop + 2; // Near top of game area\n // Draw a subtle background bar\n const bgBar = '─'.repeat(inGamePrompt.length + 4);\n output += `\\x1b[${promptY - 1};${promptX - 2}H\\x1b[2m${themeColor}${bgBar}\\x1b[0m`;\n output += `\\x1b[${promptY};${promptX}H${promptBright}\\x1b[1;93m${inGamePrompt}\\x1b[0m`;\n output += `\\x1b[${promptY + 1};${promptX - 2}H\\x1b[2m${themeColor}${bgBar}\\x1b[0m`;\n }\n }\n }\n\n // HUD\n if (gameStarted && !levelComplete && !gameOver && !paused) {\n const level = tutorialMode ? TUTORIAL_LEVELS[tutorialLevelIndex] : levels[currentLevel];\n const hudY = displayTop + screenHeight + 2;\n\n if (tutorialMode) {\n // Tutorial HUD - show level name and step-based prompts\n const tutorialTitle = `═══ ${level.name} (${tutorialLevelIndex + 1}/3) ═══`;\n const titleX = gameLeft + Math.floor((screenWidth - tutorialTitle.length) / 2) + 1;\n output += `\\x1b[${hudY};${titleX}H\\x1b[1;93m${tutorialTitle}\\x1b[0m`;\n\n // Tutorial step prompts with flashing effect - different for each level\n const promptBright = Math.floor(Date.now() / 300) % 2 === 0 ? '\\x1b[1m' : '\\x1b[2m';\n\n let tutorialHint = '';\n if (tutorialLevelIndex === 0) {\n // FLIGHT SCHOOL prompts\n switch (tutorialStep) {\n case 0:\n tutorialHint = '↑ Press UP or W to FLAP and fly!';\n break;\n case 1:\n tutorialHint = '← → Use arrow keys to STEER left/right';\n break;\n case 2:\n tutorialHint = '▶ Fly to the RIGHT platform!';\n break;\n case 3:\n tutorialHint = '★ GREAT! You can fly! ★';\n break;\n }\n } else if (tutorialLevelIndex === 1) {\n // FIRST DELIVERY prompts\n switch (tutorialStep) {\n case 0:\n tutorialHint = '↑ Take off and fly!';\n break;\n case 1:\n tutorialHint = '▼ Land on the LEFT hut to PICKUP package';\n break;\n case 2:\n tutorialHint = '▶ Deliver to the RIGHT hut!';\n break;\n case 3:\n tutorialHint = '★ Delivery complete! ★';\n break;\n }\n } else if (tutorialLevelIndex === 2) {\n // ROPE MASTER prompts\n switch (tutorialStep) {\n case 0:\n tutorialHint = 'You have a passenger! Learn rope controls...';\n break;\n case 1:\n tutorialHint = 'SPACE = Lower rope (hold to extend)';\n break;\n case 2:\n tutorialHint = 'SHIFT = Raise rope (hold to retract)';\n break;\n case 3:\n tutorialHint = '▶ Deliver to the HIGH platform on right!';\n break;\n case 4:\n tutorialHint = '★ TUTORIAL COMPLETE! ★';\n break;\n }\n }\n const hintX = gameLeft + Math.floor((screenWidth - tutorialHint.length) / 2) + 1;\n output += `\\x1b[${hudY + 1};${hintX}H${promptBright}${themeColor}${tutorialHint}\\x1b[0m`;\n\n // Progress indicator within level\n const maxSteps = tutorialLevelIndex === 2 ? 5 : 4;\n const progress = `Step ${Math.min(tutorialStep + 1, maxSteps)}/${maxSteps}`;\n const progressX = gameLeft + Math.floor((screenWidth - progress.length) / 2) + 1;\n output += `\\x1b[${hudY + 2};${progressX}H\\x1b[2m${themeColor}${progress}\\x1b[0m`;\n } else {\n // Normal game HUD\n // Line 1: Level name on left, Time on right\n const levelName = `LVL ${currentLevel + 1}: ${level.name}`;\n output += `\\x1b[${hudY};${gameLeft + 1}H${themeColor}${levelName}\\x1b[0m`;\n\n const timeColor = timeRemaining < 15 ? '\\x1b[91m' : timeRemaining < 30 ? '\\x1b[93m' : themeColor;\n const timeDisplay = `TIME: ${Math.ceil(timeRemaining)}s`;\n output += `\\x1b[${hudY};${gameLeft + screenWidth - timeDisplay.length + 1}H${timeColor}${timeDisplay}\\x1b[0m`;\n\n // Line 2: Deliveries centered\n const deliveryStatus = `DELIVERIES: ${deliveriesComplete}/${totalDeliveries} | SCORE: ${score}`;\n const deliveryX = gameLeft + Math.floor((screenWidth - deliveryStatus.length) / 2) + 1;\n output += `\\x1b[${hudY + 1};${deliveryX}H${themeColor}${deliveryStatus}\\x1b[0m`;\n\n // Line 3: Hint\n let hint = '';\n if (!hasPassenger) {\n hint = '▶ Land where you see the yellow package';\n } else {\n hint = '▶ Deliver to the marker (▼)';\n }\n const hintX = gameLeft + Math.floor((screenWidth - hint.length) / 2) + 1;\n output += `\\x1b[${hudY + 2};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n }\n }\n\n // Bottom hint (only when not showing game HUD)\n if (!gameStarted || paused || gameOver || levelComplete) {\n const menuHint = '[ ESC ] MENU';\n const menuX = Math.floor((cols - menuHint.length) / 2);\n output += `\\x1b[${rows - 1};${menuX}H\\x1b[2m${themeColor}${menuHint}\\x1b[0m`;\n }\n\n terminal.write(output);\n }\n\n // Start game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n renderInterval = setInterval(() => {\n if (!running) {\n clearInterval(renderInterval!);\n return;\n }\n render();\n }, 25);\n\n gameInterval = setInterval(() => {\n if (!running) {\n clearInterval(gameInterval!);\n return;\n }\n update();\n }, 25);\n\n keyDownHandler = (e: KeyboardEvent) => {\n if (!running || !gameStarted || paused || gameOver || levelComplete) return;\n\n switch (e.key) {\n case 'ArrowLeft':\n case 'a':\n inputLeft = true;\n break;\n case 'ArrowRight':\n case 'd':\n inputRight = true;\n break;\n case 'ArrowUp':\n case 'w':\n doFlap();\n break;\n case ' ':\n inputExtendRope = true;\n break;\n case 'Shift':\n inputContractRope = true;\n break;\n }\n };\n\n keyUpHandler = (e: KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowLeft':\n case 'a':\n inputLeft = false;\n break;\n case 'ArrowRight':\n case 'd':\n inputRight = false;\n break;\n case ' ':\n inputExtendRope = false;\n break;\n case 'Shift':\n inputContractRope = false;\n break;\n }\n };\n\n window.addEventListener('keydown', keyDownHandler);\n window.addEventListener('keyup', keyUpHandler);\n windowListenersAdded = true;\n\n keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener?.dispose();\n return;\n }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // ESC - toggle pause\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0; // Reset selection when opening\n return;\n }\n\n // Q to quit\n if (key === 'q') {\n if (paused || gameOver || !gameStarted || levelComplete) {\n cleanup();\n dispatchGameQuit(terminal);\n return;\n }\n }\n\n // Mode selection screen - arrow key navigation\n if (!gameStarted && showingModeSelect && !paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n menuSelection,\n MODE_SELECT_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== menuSelection) {\n menuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n showingModeSelect = false;\n if (menuSelection === 0) {\n initTutorial();\n } else {\n initGame();\n }\n gameStarted = true;\n return;\n }\n\n // Legacy shortcut keys still work\n if (key === 't') {\n showingModeSelect = false;\n initTutorial();\n gameStarted = true;\n return;\n }\n if (key === 'p') {\n showingModeSelect = false;\n initGame();\n gameStarted = true;\n return;\n }\n return;\n }\n\n // Legacy start screen (shouldn't be reached)\n if (!gameStarted && !paused) {\n showingModeSelect = false;\n initGame();\n gameStarted = true;\n return;\n }\n\n // Level complete\n if (levelComplete) {\n if (domEvent.key === ' ') {\n if (tutorialMode) {\n // Check if there are more tutorial levels\n if (tutorialLevelIndex < TUTORIAL_LEVELS.length - 1) {\n // Advance to next tutorial level\n tutorialLevelIndex++;\n initTutorialLevel();\n levelComplete = false;\n } else {\n // All tutorial levels complete - start normal game\n tutorialMode = false;\n initGame();\n levelComplete = false;\n }\n } else if (currentLevel < levels.length - 1) {\n currentLevel++;\n initLevel();\n levelComplete = false;\n }\n } else if (key === 'r') {\n if (tutorialMode) {\n initTutorial();\n } else {\n initGame();\n }\n gameStarted = true;\n }\n return;\n }\n\n // Game over\n if (gameOver) {\n if (key === 'r') {\n initLevel();\n gameStarted = true;\n gameOver = false;\n }\n return;\n }\n\n // Pause menu - arrow navigation + shortcuts\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n initLevel();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n cleanup();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n cleanup();\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n cleanup();\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (key === 'r') {\n initLevel();\n gameStarted = true;\n paused = false;\n } else if (key === 'l') {\n cleanup();\n dispatchGamesMenu(terminal);\n } else if (key === 'n') {\n cleanup();\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n // Gameplay controls - MUST handle here since terminal captures keys!\n if (domEvent.key === 'ArrowUp' || key === 'w') {\n doFlap();\n }\n // Handle left/right - apply thrust directly since onKey fires repeatedly when held\n if (domEvent.key === 'ArrowLeft' || key === 'a') {\n rigVX -= THRUST_POWER;\n rigAngle = Math.max(-15, rigAngle - 3);\n }\n if (domEvent.key === 'ArrowRight' || key === 'd') {\n rigVX += THRUST_POWER;\n rigAngle = Math.min(15, rigAngle + 3);\n }\n // SPACE extends rope - set flag (keyup handler will unset)\n if (domEvent.key === ' ') {\n inputExtendRope = true;\n }\n });\n }, 50);\n\n return controller;\n}\n","/**\n * Hyper Crack - Terminal Hacking Game\n *\n * Crack passwords to breach security layers before\n * the trace detection catches you. Wordle-style mechanics\n * with cyberpunk hacker aesthetics.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { type SimpleMenuItem, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n// Custom pause menu items with HELP option\nconst CRACK_PAUSE_MENU_ITEMS: SimpleMenuItem[] = [\n { label: 'Resume', shortcut: 'ESC' },\n { label: 'Restart', shortcut: 'R' },\n { label: 'Quit', shortcut: 'Q' },\n { label: 'Help', shortcut: 'H' },\n { label: 'List Games', shortcut: 'L' },\n { label: 'Next Game', shortcut: 'N' },\n];\n\n/**\n * Crack Game Controller\n */\nexport interface CrackController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// Word lists by difficulty (5-letter words for classic feel)\nconst PASSWORDS = [\n // Easy - common tech words\n 'ADMIN', 'LOGIN', 'GUEST', 'PROXY', 'QUERY', 'DEBUG', 'CACHE', 'STACK',\n 'PARSE', 'TOKEN', 'ROUTE', 'PATCH', 'BUILD', 'MERGE', 'CLONE', 'FETCH',\n // Medium - more obscure\n 'CRYPT', 'VAULT', 'NEXUS', 'HELIX', 'CYBER', 'GHOST', 'ROGUE', 'VENOM',\n 'CHAOS', 'RAZOR', 'BLAZE', 'STORM', 'FROST', 'SPARK', 'SURGE', 'PULSE',\n // Hard - hacker/cyber themed\n 'BREACH', 'BYPASS', 'CIPHER', 'DAEMON', 'INJECT', 'KERNEL', 'MALLOC',\n 'PHISH', 'ROOTKIT', 'SHELL', 'SPOOF', 'TROJAN', 'VECTOR', 'ZOMBIE',\n].filter(w => w.length === 5); // Ensure all 5 letters\n\n// Fake system names for immersion\nconst SYSTEM_NAMES = [\n 'NEXUS-CORP MAINFRAME',\n 'DARKNET NODE #7749',\n 'PENTAGON SUBNET',\n 'SWISS BANK VAULT',\n 'CRYPTO EXCHANGE',\n 'SATELLITE UPLINK',\n 'NEURAL NETWORK HUB',\n 'QUANTUM CLUSTER',\n];\n\nconst FAKE_IPS = [\n '192.168.13.37', '10.0.66.6', '172.16.42.0', '203.0.113.99',\n '198.51.100.23', '185.199.108.1', '140.82.114.4', '151.101.1.69',\n];\n\n// Hacker log messages\nconst LOG_MESSAGES = {\n attempt: [\n 'Attempting password injection...',\n 'Running dictionary attack...',\n 'Brute forcing hash...',\n 'Decrypting auth token...',\n 'Bypassing security layer...',\n ],\n partial: [\n 'Partial match detected!',\n 'Hash collision found...',\n 'Encryption weakening...',\n 'Security gap identified!',\n 'Pattern recognized...',\n ],\n wrong: [\n 'Access denied.',\n 'Invalid credentials.',\n 'Authentication failed.',\n 'Security block triggered.',\n 'Firewall rejected attempt.',\n ],\n success: [\n 'ACCESS GRANTED!',\n 'SECURITY BYPASSED!',\n 'LAYER BREACHED!',\n 'ENCRYPTION CRACKED!',\n 'FIREWALL DOWN!',\n ],\n detection: [\n 'INTRUSION DETECTED',\n 'TRACE COMPLETE',\n 'LOCATION COMPROMISED',\n 'SECURITY ALERTED',\n ],\n};\n\n// Particle interface for visual effects\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\n// Score popup interface for floating text\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\n/**\n * Cyberpunk Terminal Hacking Game\n */\nexport function runCrackGame(terminal: Terminal): CrackController {\n const themeColor = getCurrentThemeColor();\n\n // Minimum terminal size\n const MIN_COLS = 40;\n const MIN_ROWS = 16;\n\n let cols = terminal.cols;\n let rows = terminal.rows;\n\n const updateDimensions = () => {\n cols = terminal.cols;\n rows = terminal.rows;\n };\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let won = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let showHelp = false;\n\n // Game state\n let currentLayer = 1;\n const totalLayers = 3;\n let targetPassword = '';\n let guesses: string[] = [];\n let currentGuess = '';\n let maxGuesses = 6;\n let timeLeft = 90; // seconds\n let lastTick = Date.now();\n\n // Visual state\n let glitchFrame = 0;\n let logMessages: string[] = [];\n let systemName = '';\n let systemIP = '';\n let scanlineY = 0;\n let gameOverFrame = 0;\n let fakeCoords = { lat: 0, lng: 0 };\n\n // Juicy effect state\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let screenShake = 0;\n let shakeIntensity = 0;\n let borderFlash = 0;\n let correctFlash = 0;\n let wrongFlash = 0;\n let layerBreachFlash = 0;\n\n // Generate fake coordinates\n function generateFakeCoords(): void {\n fakeCoords = {\n lat: (Math.random() * 180 - 90).toFixed(6) as unknown as number,\n lng: (Math.random() * 360 - 180).toFixed(6) as unknown as number,\n };\n }\n\n // Spawn particles for juicy effects\n function spawnParticles(\n x: number,\n y: number,\n count: number,\n color: string,\n chars: string[] = ['█', '▓', '▒', '░', '●', '◆', '✦']\n ): void {\n for (let i = 0; i < count; i++) {\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: (Math.random() - 0.5) * 2,\n vy: (Math.random() - 0.8) * 1.5,\n life: 15 + Math.floor(Math.random() * 15),\n });\n }\n }\n\n // Add score popup for floating text feedback\n function addScorePopup(x: number, y: number, text: string, color: string): void {\n scorePopups.push({ x, y, text, frames: 30, color });\n }\n\n const controller: CrackController = {\n stop: () => {\n if (!running) return;\n running = false;\n // Note: Buffer exit is handled by TerminalPool via dispatchGameQuit\n },\n get isRunning() { return running; }\n };\n\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ █▀▀ █▀█ ▄▀█ █▀▀ █▄▀',\n '█▀█ █ █▀▀ ██▄ █▀▄ █▄▄ █▀▄ █▀█ █▄▄ █ █',\n ];\n\n function pickPassword(): string {\n return PASSWORDS[Math.floor(Math.random() * PASSWORDS.length)];\n }\n\n function pickSystem(): void {\n systemName = SYSTEM_NAMES[Math.floor(Math.random() * SYSTEM_NAMES.length)];\n systemIP = FAKE_IPS[Math.floor(Math.random() * FAKE_IPS.length)];\n }\n\n function addLog(category: keyof typeof LOG_MESSAGES): void {\n const messages = LOG_MESSAGES[category];\n const msg = messages[Math.floor(Math.random() * messages.length)];\n const timestamp = new Date().toISOString().substr(11, 8);\n logMessages.unshift(`[${timestamp}] ${msg}`);\n if (logMessages.length > 5) logMessages.pop();\n }\n\n function initGame(): void {\n currentLayer = 1;\n targetPassword = pickPassword();\n guesses = [];\n currentGuess = '';\n timeLeft = 90;\n lastTick = Date.now();\n gameOver = false;\n won = false;\n paused = false;\n logMessages = [];\n pickSystem();\n addLog('attempt');\n }\n\n function initLayer(): void {\n targetPassword = pickPassword();\n guesses = [];\n currentGuess = '';\n addLog('attempt');\n }\n\n // Check guess against target - returns array of states: 'correct', 'present', 'absent'\n function checkGuess(guess: string): ('correct' | 'present' | 'absent')[] {\n const result: ('correct' | 'present' | 'absent')[] = [];\n const targetChars = targetPassword.split('');\n const guessChars = guess.split('');\n const used = new Array(5).fill(false);\n\n // First pass: find exact matches\n for (let i = 0; i < 5; i++) {\n if (guessChars[i] === targetChars[i]) {\n result[i] = 'correct';\n used[i] = true;\n }\n }\n\n // Second pass: find present but wrong position\n for (let i = 0; i < 5; i++) {\n if (result[i]) continue;\n const idx = targetChars.findIndex((c, j) => c === guessChars[i] && !used[j]);\n if (idx !== -1) {\n result[i] = 'present';\n used[idx] = true;\n } else {\n result[i] = 'absent';\n }\n }\n\n return result;\n }\n\n function submitGuess(): void {\n if (currentGuess.length !== 5) return;\n\n const result = checkGuess(currentGuess);\n guesses.push(currentGuess);\n\n const allCorrect = result.every(r => r === 'correct');\n const correctCount = result.filter(r => r === 'correct').length;\n const presentCount = result.filter(r => r === 'present').length;\n const hasPartial = correctCount > 0 || presentCount > 0;\n\n // Calculate effect center position\n const effectX = Math.floor(cols / 2);\n const effectY = 12 + guesses.length;\n\n if (allCorrect) {\n addLog('success');\n // Big celebration for cracking the password!\n correctFlash = 12;\n borderFlash = 15;\n layerBreachFlash = 20;\n screenShake = 8;\n shakeIntensity = 3;\n\n // Massive particle explosion\n spawnParticles(effectX, effectY, 25, '\\x1b[1;32m', ['█', '▓', '✦', '★', '◆', '●']);\n spawnParticles(effectX - 5, effectY, 15, '\\x1b[1;92m', ['░', '▒', '▓']);\n spawnParticles(effectX + 5, effectY, 15, '\\x1b[1;92m', ['░', '▒', '▓']);\n\n if (currentLayer >= totalLayers) {\n won = true;\n gameOver = true;\n addScorePopup(effectX, effectY - 2, '◆ SYSTEM COMPROMISED ◆', '\\x1b[1;32m');\n // Victory explosion\n for (let i = 0; i < 5; i++) {\n setTimeout(() => {\n if (running) {\n spawnParticles(\n Math.floor(cols / 4) + Math.random() * cols / 2,\n 5 + Math.random() * 10,\n 10,\n '\\x1b[1;32m',\n ['█', '★', '◆', '●']\n );\n }\n }, i * 100);\n }\n } else {\n addScorePopup(effectX, effectY - 2, `LAYER ${currentLayer} BREACHED!`, '\\x1b[1;32m');\n currentLayer++;\n setTimeout(() => {\n if (running && !gameOver) initLayer();\n }, 1000);\n }\n } else if (guesses.length >= maxGuesses) {\n addLog('detection');\n // Dramatic failure effects\n wrongFlash = 15;\n borderFlash = 20;\n screenShake = 12;\n shakeIntensity = 4;\n gameOver = true;\n gameOverFrame = 0;\n generateFakeCoords();\n\n // Red explosion for detection\n spawnParticles(effectX, effectY, 20, '\\x1b[1;31m', ['█', '▓', '▒', '!', '@', '#']);\n addScorePopup(effectX, effectY - 2, '◆ TRACED ◆', '\\x1b[1;31m');\n } else if (hasPartial) {\n addLog('partial');\n // Encouraging feedback for partial matches\n correctFlash = 4 + correctCount * 2;\n screenShake = Math.min(correctCount + 1, 4);\n shakeIntensity = 1;\n\n // Green particles for correct, yellow for present\n if (correctCount > 0) {\n spawnParticles(effectX, effectY, 3 + correctCount * 2, '\\x1b[1;32m', ['█', '●', '◆']);\n addScorePopup(effectX, effectY - 1, `${correctCount} EXACT!`, '\\x1b[1;32m');\n }\n if (presentCount > 0) {\n spawnParticles(effectX + 3, effectY, 2 + presentCount, '\\x1b[1;33m', ['░', '▒', '●']);\n if (correctCount === 0) {\n addScorePopup(effectX, effectY - 1, `${presentCount} CLOSE`, '\\x1b[1;33m');\n }\n }\n } else {\n addLog('wrong');\n // Miss feedback - shake and red flash\n wrongFlash = 6;\n screenShake = 3;\n shakeIntensity = 2;\n\n // Small red particles\n spawnParticles(effectX, effectY, 5, '\\x1b[31m', ['░', '▒', '×', '·']);\n addScorePopup(effectX, effectY - 1, 'DENIED', '\\x1b[2;31m');\n }\n\n currentGuess = '';\n }\n\n function render(): void {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const msg2 = `Need: ${MIN_COLS}x${MIN_ROWS} Have: ${cols}x${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 2};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Calculate screen shake offset\n let shakeOffsetX = 0;\n let shakeOffsetY = 0;\n if (screenShake > 0) {\n shakeOffsetX = Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n shakeOffsetY = Math.floor((Math.random() - 0.5) * shakeIntensity);\n screenShake--;\n }\n\n // Decrement effect timers\n if (borderFlash > 0) borderFlash--;\n if (correctFlash > 0) correctFlash--;\n if (wrongFlash > 0) wrongFlash--;\n if (layerBreachFlash > 0) layerBreachFlash--;\n\n // Update particles\n particles = particles.filter(p => {\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.03; // gravity\n p.life--;\n return p.life > 0;\n });\n\n // Update score popups\n scorePopups = scorePopups.filter(sp => {\n sp.y -= 0.15; // float upward\n sp.frames--;\n return sp.frames > 0;\n });\n\n glitchFrame = (glitchFrame + 1) % 60;\n scanlineY = (scanlineY + 1) % rows;\n\n // Title (with shake offset)\n const titleX = Math.floor((cols - title[0].length) / 2) + shakeOffsetX;\n const titleY = 1 + shakeOffsetY;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n\n // Title color based on effects\n let titleColor = themeColor;\n if (layerBreachFlash > 0 && layerBreachFlash % 4 < 2) {\n titleColor = '\\x1b[1;32m'; // Green flash on layer breach\n } else if (wrongFlash > 0 && wrongFlash % 4 < 2) {\n titleColor = '\\x1b[1;31m'; // Red flash on wrong\n } else if (correctFlash > 0 && correctFlash % 3 < 2) {\n titleColor = '\\x1b[1;92m'; // Bright green on correct\n }\n\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[${Math.max(1, titleY)};${Math.max(1, titleX + glitchOffset)}H\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[${Math.max(1, titleY + 1)};${Math.max(1, titleX + glitchOffset + 1)}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `\\x1b[${Math.max(1, titleY)};${Math.max(1, titleX)}H${titleColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[${Math.max(1, titleY + 1)};${Math.max(1, titleX)}H${titleColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n if (paused) {\n // Pause menu\n const pauseY = 8;\n const pauseMsg = '══ PAUSED ══';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(CRACK_PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 10};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted) {\n // Start screen\n const startY = 5;\n\n // Fake target system info\n output += `\\x1b[${startY};3H${themeColor}TARGET SYSTEM:\\x1b[0m`;\n output += `\\x1b[${startY + 1};3H\\x1b[2m${themeColor}├─ ${systemName || 'CLASSIFIED'}\\x1b[0m`;\n output += `\\x1b[${startY + 2};3H\\x1b[2m${themeColor}└─ IP: ${systemIP || '???.???.???.???'}\\x1b[0m`;\n\n // Mission briefing\n const missionY = startY + 5;\n output += `\\x1b[${missionY};3H${themeColor}MISSION:\\x1b[0m`;\n output += `\\x1b[${missionY + 1};3H\\x1b[2m${themeColor}Crack ${totalLayers} security layers before trace detection.\\x1b[0m`;\n output += `\\x1b[${missionY + 2};3H\\x1b[2m${themeColor}Each password is 5 characters.\\x1b[0m`;\n output += `\\x1b[${missionY + 3};3H\\x1b[2m${themeColor}You have ${maxGuesses} attempts per layer.\\x1b[0m`;\n\n // Color legend\n const legendY = missionY + 6;\n output += `\\x1b[${legendY};3H${themeColor}FEEDBACK:\\x1b[0m`;\n output += `\\x1b[${legendY + 1};3H\\x1b[1;32m█\\x1b[0m\\x1b[2m = Correct position\\x1b[0m`;\n output += `\\x1b[${legendY + 2};3H\\x1b[1;33m█\\x1b[0m\\x1b[2m = Wrong position\\x1b[0m`;\n output += `\\x1b[${legendY + 3};3H\\x1b[2m█ = Not in password\\x1b[0m`;\n\n // Start prompt\n const startMsg = '[ PRESS ENTER TO BEGIN BREACH ]';\n const startX = Math.floor((cols - startMsg.length) / 2);\n output += `\\x1b[${rows - 4};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = 'ESC: Menu';\n output += `\\x1b[${rows - 2};3H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n } else if (gameOver) {\n // Game over screen - more dramatic!\n const overY = 4;\n\n if (won) {\n // SUCCESS - Hacker victory screen\n const accessGranted = '╔═══════════════════════════════════╗';\n const accessMsg = '║ ██ ACCESS GRANTED ██ ║';\n const accessBottom = '╚═══════════════════════════════════╝';\n const boxX = Math.floor((cols - accessGranted.length) / 2);\n\n output += `\\x1b[${overY};${boxX}H\\x1b[1;32m${accessGranted}\\x1b[0m`;\n output += `\\x1b[${overY + 1};${boxX}H\\x1b[1;32m${accessMsg}\\x1b[0m`;\n output += `\\x1b[${overY + 2};${boxX}H\\x1b[1;32m${accessBottom}\\x1b[0m`;\n\n output += `\\x1b[${overY + 4};${boxX}H${themeColor}Target: ${systemName}\\x1b[0m`;\n output += `\\x1b[${overY + 5};${boxX}H${themeColor}Status: \\x1b[32mFULLY COMPROMISED\\x1b[0m`;\n output += `\\x1b[${overY + 6};${boxX}H${themeColor}Time remaining: \\x1b[33m${timeLeft}s\\x1b[0m`;\n output += `\\x1b[${overY + 7};${boxX}H${themeColor}Layers breached: \\x1b[32m${totalLayers}/${totalLayers}\\x1b[0m`;\n\n // Download animation\n const dlProgress = Math.min(gameOverFrame * 5, 100);\n const dlBar = '█'.repeat(Math.floor(dlProgress / 5)) + '░'.repeat(20 - Math.floor(dlProgress / 5));\n output += `\\x1b[${overY + 9};${boxX}H\\x1b[32mDownloading data... [${dlBar}] ${dlProgress}%\\x1b[0m`;\n\n if (dlProgress >= 100) {\n output += `\\x1b[${overY + 11};${boxX}H\\x1b[1;32m✓ 847 FILES EXTRACTED\\x1b[0m`;\n output += `\\x1b[${overY + 12};${boxX}H\\x1b[1;32m✓ LOGS WIPED\\x1b[0m`;\n output += `\\x1b[${overY + 13};${boxX}H\\x1b[1;32m✓ BACKDOOR INSTALLED\\x1b[0m`;\n }\n } else {\n // FAILURE - Dramatic busted screen\n const warningGlitch = gameOverFrame % 8 < 4;\n const glitchChar = warningGlitch ? '▓' : '░';\n\n // Flashing warning banner\n const warningColor = gameOverFrame % 6 < 3 ? '\\x1b[1;31m' : '\\x1b[41;97m';\n const warningBanner = `${glitchChar}${glitchChar} INTRUSION DETECTED ${glitchChar}${glitchChar}`;\n output += `\\x1b[${overY};${Math.floor((cols - warningBanner.length) / 2)}H${warningColor}${warningBanner}\\x1b[0m`;\n\n // Connection terminated box\n const termBox = [\n '┌─────────────────────────────────────┐',\n '│ ▄▀▀▀▄ CONNECTION TERMINATED ▄▀▀▀▄│',\n '├─────────────────────────────────────┤',\n ];\n const boxX = Math.floor((cols - termBox[0].length) / 2);\n\n for (let i = 0; i < termBox.length; i++) {\n output += `\\x1b[${overY + 2 + i};${boxX}H\\x1b[31m${termBox[i]}\\x1b[0m`;\n }\n\n // Trace info with fake coordinates\n output += `\\x1b[${overY + 5};${boxX}H\\x1b[31m│\\x1b[0m TRACE STATUS: \\x1b[1;31mCOMPLETE\\x1b[0m`;\n output += `\\x1b[${overY + 6};${boxX}H\\x1b[31m│\\x1b[0m YOUR COORDS: \\x1b[33m${fakeCoords.lat}, ${fakeCoords.lng}\\x1b[0m`;\n output += `\\x1b[${overY + 7};${boxX}H\\x1b[31m│\\x1b[0m ISP: \\x1b[33mIDENTIFIED\\x1b[0m`;\n output += `\\x1b[${overY + 8};${boxX}H\\x1b[31m│\\x1b[0m AUTHORITIES: \\x1b[5;31mDISPATCHED\\x1b[0m`;\n output += `\\x1b[${overY + 9};${boxX}H\\x1b[31m└─────────────────────────────────────┘\\x1b[0m`;\n\n // Stats\n output += `\\x1b[${overY + 11};${boxX}H\\x1b[2m${themeColor}Layers cracked: ${currentLayer - 1}/${totalLayers}\\x1b[0m`;\n output += `\\x1b[${overY + 12};${boxX}H\\x1b[2m${themeColor}Password was: \\x1b[33m${targetPassword}\\x1b[0m`;\n\n // Glitch effect - random characters at edges\n if (gameOverFrame % 4 === 0) {\n const glitchChars = '!@#$%^&*░▒▓█';\n for (let i = 0; i < 3; i++) {\n const gx = Math.floor(Math.random() * cols);\n const gy = Math.floor(Math.random() * rows);\n const gc = glitchChars[Math.floor(Math.random() * glitchChars.length)];\n output += `\\x1b[${gy};${gx}H\\x1b[31m${gc}\\x1b[0m`;\n }\n }\n }\n\n const restartMsg = '[ R ] RESTART [ Q ] QUIT [ N ] NEXT GAME';\n output += `\\x1b[${rows - 3};${Math.floor((cols - restartMsg.length) / 2)}H\\x1b[2m${themeColor}${restartMsg}\\x1b[0m`;\n } else if (showHelp) {\n // Help overlay\n const helpY = 5;\n const helpBox = [\n '╔══════════════════════════════════════╗',\n '║ HYPER CRACK HELP ║',\n '╠══════════════════════════════════════╣',\n '║ Crack passwords before trace timer ║',\n '║ runs out. Breach all 3 layers! ║',\n '╠══════════════════════════════════════╣',\n '║ ■ GREEN = Correct position ║',\n '║ ■ YELLOW = Wrong position ║',\n '║ ■ DIM = Not in password ║',\n '╠══════════════════════════════════════╣',\n '║ CONTROLS: ║',\n '║ A-Z = Type letters ║',\n '║ ENTER = Submit guess ║',\n '║ BKSP = Delete letter ║',\n '║ ESC = Pause menu ║',\n '╚══════════════════════════════════════╝',\n ];\n const helpX = Math.floor((cols - helpBox[0].length) / 2);\n for (let i = 0; i < helpBox.length; i++) {\n output += `\\x1b[${helpY + i};${helpX}H${themeColor}${helpBox[i]}\\x1b[0m`;\n }\n output += `\\x1b[${helpY + helpBox.length + 1};${helpX + 8}H\\x1b[2m[ Press ESC to close ]\\x1b[0m`;\n } else {\n // Main game screen\n const gameY = 4;\n\n // System info header\n output += `\\x1b[${gameY};2H${themeColor}┌─ TARGET: ${systemName} ─┐\\x1b[0m`;\n output += `\\x1b[${gameY + 1};2H${themeColor}│\\x1b[0m IP: ${systemIP}`;\n output += `\\x1b[${gameY + 2};2H${themeColor}│\\x1b[0m LAYER: \\x1b[1m${currentLayer}/${totalLayers}\\x1b[0m`;\n\n // Trace timer - more urgent as time decreases\n const timerColor = timeLeft <= 10 ? '\\x1b[1;31m' : timeLeft <= 30 ? '\\x1b[33m' : themeColor;\n const timerBlink = timeLeft <= 10 ? '\\x1b[5m' : '';\n output += `\\x1b[${gameY + 3};2H${themeColor}│\\x1b[0m TRACE: ${timerBlink}${timerColor}${timeLeft}s\\x1b[0m`;\n output += `\\x1b[${gameY + 4};2H${themeColor}└${'─'.repeat(30)}┘\\x1b[0m`;\n\n // Password display area\n const pwdY = gameY + 6;\n output += `\\x1b[${pwdY};2H${themeColor}PASSWORD CRACK:\\x1b[0m`;\n\n // Previous guesses\n for (let i = 0; i < guesses.length; i++) {\n const guess = guesses[i];\n const result = checkGuess(guess);\n let guessDisplay = '';\n for (let j = 0; j < 5; j++) {\n const char = guess[j];\n if (result[j] === 'correct') {\n guessDisplay += `\\x1b[1;32m${char}\\x1b[0m `;\n } else if (result[j] === 'present') {\n guessDisplay += `\\x1b[1;33m${char}\\x1b[0m `;\n } else {\n guessDisplay += `\\x1b[2m${char}\\x1b[0m `;\n }\n }\n output += `\\x1b[${pwdY + 1 + i};4H${guessDisplay}`;\n }\n\n // Current guess input\n const inputY = pwdY + 1 + guesses.length;\n let inputDisplay = '';\n for (let i = 0; i < 5; i++) {\n if (i < currentGuess.length) {\n inputDisplay += `${themeColor}\\x1b[1m${currentGuess[i]}\\x1b[0m `;\n } else if (i === currentGuess.length) {\n // Blinking cursor\n const cursorChar = glitchFrame % 20 < 10 ? '█' : '_';\n inputDisplay += `${themeColor}${cursorChar}\\x1b[0m `;\n } else {\n inputDisplay += `\\x1b[2m_\\x1b[0m `;\n }\n }\n output += `\\x1b[${inputY};4H${inputDisplay}`;\n\n // Remaining attempts\n const attemptsLeft = maxGuesses - guesses.length;\n output += `\\x1b[${inputY + 2};4H\\x1b[2mAttempts: ${attemptsLeft}/${maxGuesses}\\x1b[0m`;\n\n // System log area (right side)\n const logX = 40;\n const logY = gameY;\n output += `\\x1b[${logY};${logX}H${themeColor}┌─ SYSTEM LOG ─┐\\x1b[0m`;\n for (let i = 0; i < 5; i++) {\n const logMsg = logMessages[i] || '';\n const truncated = logMsg.substring(0, cols - logX - 4);\n output += `\\x1b[${logY + 1 + i};${logX}H${themeColor}│\\x1b[0m\\x1b[2m ${truncated}\\x1b[0m`;\n }\n output += `\\x1b[${logY + 6};${logX}H${themeColor}└${'─'.repeat(16)}┘\\x1b[0m`;\n\n // Help\n output += `\\x1b[${rows - 2};2H\\x1b[2m${themeColor}Type 5 letters, ENTER to submit | ESC: Menu\\x1b[0m`;\n }\n\n // Render particles\n for (const p of particles) {\n const px = Math.round(p.x) + shakeOffsetX;\n const py = Math.round(p.y) + shakeOffsetY;\n if (px >= 1 && px < cols && py >= 1 && py < rows) {\n const fade = p.life > 10 ? '' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${p.color}${fade}${p.char}\\x1b[0m`;\n }\n }\n\n // Render score popups\n for (const sp of scorePopups) {\n const px = Math.round(sp.x - sp.text.length / 2) + shakeOffsetX;\n const py = Math.round(sp.y) + shakeOffsetY;\n if (py >= 1 && py < rows && px >= 1) {\n const fade = sp.frames > 15 ? '' : sp.frames > 8 ? '\\x1b[2m' : '\\x1b[2m';\n output += `\\x1b[${py};${Math.max(1, px)}H${sp.color}${fade}${sp.text}\\x1b[0m`;\n }\n }\n\n // Border flash effect\n if (borderFlash > 0) {\n const flashColor = wrongFlash > 0 ? '\\x1b[31m' : '\\x1b[32m';\n const flashChar = borderFlash % 4 < 2 ? '█' : '▓';\n // Top and bottom borders\n for (let x = 1; x <= cols; x += 3) {\n if (Math.random() > 0.5) {\n output += `\\x1b[1;${x}H${flashColor}${flashChar}\\x1b[0m`;\n output += `\\x1b[${rows};${x}H${flashColor}${flashChar}\\x1b[0m`;\n }\n }\n // Left and right borders\n for (let y = 1; y <= rows; y += 2) {\n if (Math.random() > 0.5) {\n output += `\\x1b[${y};1H${flashColor}${flashChar}\\x1b[0m`;\n output += `\\x1b[${y};${cols}H${flashColor}${flashChar}\\x1b[0m`;\n }\n }\n }\n\n terminal.write(output);\n }\n\n function update(): void {\n if (!gameStarted || gameOver || paused) return;\n\n // Update timer\n const now = Date.now();\n if (now - lastTick >= 1000) {\n timeLeft--;\n lastTick = now;\n\n // Low time warning effects\n if (timeLeft <= 10 && timeLeft > 0) {\n screenShake = 2;\n shakeIntensity = 1;\n borderFlash = 3;\n wrongFlash = 3;\n // Spawn warning particles around edges\n if (timeLeft % 2 === 0) {\n spawnParticles(Math.random() * cols, 2, 3, '\\x1b[1;31m', ['!', '▓', '░']);\n }\n }\n\n if (timeLeft <= 0) {\n addLog('detection');\n gameOver = true;\n gameOverFrame = 0;\n generateFakeCoords();\n // Big explosion for trace complete\n screenShake = 15;\n shakeIntensity = 5;\n wrongFlash = 20;\n borderFlash = 25;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n spawnParticles(centerX, centerY, 30, '\\x1b[1;31m', ['█', '▓', '▒', '!', '@', '#', '×']);\n addScorePopup(centerX, centerY - 3, '◆◆ TRACE COMPLETE ◆◆', '\\x1b[1;31m');\n }\n }\n\n // Increment game over animation frame\n if (gameOver) {\n gameOverFrame++;\n }\n }\n\n // Start game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n pickSystem();\n initGame();\n gameStarted = false; // Show start screen first\n\n const renderInterval = setInterval(() => {\n if (!running) {\n clearInterval(renderInterval);\n return;\n }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) {\n clearInterval(gameInterval);\n return;\n }\n update();\n }, 100);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener.dispose();\n return;\n }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key;\n const keyLower = key.toLowerCase();\n\n // ESC - toggle pause or close help\n if (key === 'Escape') {\n if (showHelp) {\n showHelp = false;\n } else {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n }\n return;\n }\n\n // Start screen\n if (!gameStarted && !paused) {\n if (key === 'Enter') {\n gameStarted = true;\n initGame();\n }\n return;\n }\n\n // Game over\n if (gameOver) {\n if (keyLower === 'r') {\n initGame();\n gameStarted = true;\n } else if (keyLower === 'q') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n } else if (keyLower === 'n') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n // Pause menu\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n CRACK_PAUSE_MENU_ITEMS.length,\n keyLower,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n initGame();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // Help\n showHelp = true;\n paused = false;\n break;\n case 4: // List Games\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 5: // Next Game\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (keyLower === 'r') {\n initGame();\n gameStarted = true;\n paused = false;\n } else if (keyLower === 'l') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (keyLower === 'n') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n } else if (keyLower === 'h') {\n showHelp = true;\n paused = false;\n }\n return;\n }\n\n // Help screen - ESC closes it (handled above)\n if (showHelp) {\n return;\n }\n\n // Gameplay input\n if (key === 'Backspace') {\n currentGuess = currentGuess.slice(0, -1);\n } else if (key === 'Enter') {\n submitGuess();\n } else if (key.length === 1 && /[a-zA-Z]/.test(key) && currentGuess.length < 5) {\n currentGuess += key.toUpperCase();\n // Subtle typing feedback\n const inputX = 4 + currentGuess.length * 2;\n const inputY = 12 + guesses.length;\n spawnParticles(inputX, inputY, 1, themeColor, ['·', '●']);\n // Tiny shake on last letter\n if (currentGuess.length === 5) {\n screenShake = 2;\n shakeIntensity = 1;\n borderFlash = 2;\n }\n }\n });\n\n const resizeListener = terminal.onResize(() => {\n updateDimensions();\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n resizeListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Frogger\n *\n * Guide your frog across dangerous roads and rivers!\n * - Avoid cars and trucks on the road\n * - Hop on logs and turtles to cross the water\n * - Reach all 5 lily pads to advance\n *\n * Features:\n * - Progressive difficulty (starts easy)\n * - Visual frog character with animation\n * - Better themed obstacles\n * - Lower terminal requirements\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\nexport interface FroggerController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface Vehicle {\n x: number;\n width: number;\n sprite: string;\n color: string;\n}\n\ninterface Log {\n x: number;\n width: number;\n sprite: string;\n isTurtle: boolean;\n submergeTimer?: number;\n}\n\ninterface Lane {\n type: 'road' | 'water' | 'safe' | 'goal';\n speed: number;\n vehicles?: Vehicle[];\n logs?: Log[];\n}\n\n// ============================================================================\n// MAIN GAME FUNCTION\n// ============================================================================\n\nexport function runFroggerGame(terminal: Terminal): FroggerController {\n const themeColor = getCurrentThemeColor();\n\n // -------------------------------------------------------------------------\n // CONSTANTS\n // -------------------------------------------------------------------------\n const MIN_COLS = 40;\n const MIN_ROWS = 16;\n const LILY_PAD_COUNT = 5;\n const TIME_LIMIT = 45;\n const MOVE_COOLDOWN = 100;\n\n // -------------------------------------------------------------------------\n // STATE\n // -------------------------------------------------------------------------\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let score = 0;\n let highScore = 0;\n let level = 1;\n let lives = 3;\n\n // Computed dimensions\n let GAME_WIDTH = 40;\n let GAME_HEIGHT = 13;\n let gameLeft = 2;\n let gameTop = 4;\n\n // Lane layout (from bottom to top)\n const SAFE_START = 0; // Starting safe zone\n const ROAD_START = 1; // Road lanes start\n const ROAD_END = 4; // Road lanes end\n const MEDIAN = 5; // Middle safe zone\n const WATER_START = 6; // Water lanes start\n const WATER_END = 9; // Water lanes end\n const GOAL_ROW = 10; // Lily pad row\n\n let timeRemaining = TIME_LIMIT;\n let lastTimeUpdate = Date.now();\n\n let playerX = 0;\n let playerY = 0;\n let playerOnLog = false;\n let lastMoveTime = 0;\n let furthestY = 0;\n let hopFrame = 0;\n\n let lilyPads: boolean[] = [false, false, false, false, false];\n let lilyPadX: number[] = [];\n let lanes: Lane[] = [];\n\n let particles: Particle[] = [];\n let shakeFrames = 0;\n let deathFlash = 0;\n let winFlash = 0;\n\n // Frog sprites (facing up)\n const FROG_IDLE = '◎';\n const FROG_HOP = '^';\n const FROG_ON_LOG = '●';\n\n // Vehicle sprites\n const CAR_LEFT = '<≡>';\n const CAR_RIGHT = '<≡>';\n const TRUCK = '⊏══⊐';\n const MOTORCYCLE = '○>';\n\n // Water sprites\n const LOG_CHAR = '═';\n const TURTLE = '◗◖';\n\n // -------------------------------------------------------------------------\n // CONTROLLER\n // -------------------------------------------------------------------------\n const controller: FroggerController = {\n stop: () => {\n if (!running) return;\n running = false;\n },\n get isRunning() { return running; }\n };\n\n // -------------------------------------------------------------------------\n // ASCII ART\n // -------------------------------------------------------------------------\n const title = [\n '█▀▀ █▀█ █▀█ █▀▀ █▀▀ █▀▀ █▀█',\n '█▀ █▀▄ █▄█ █▄█ █▄█ ██▄ █▀▄',\n ];\n\n // -------------------------------------------------------------------------\n // EFFECTS\n // -------------------------------------------------------------------------\n\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[]) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.1 + Math.random() * 0.15; // Halved for 2x frame rate\n particles.push({\n x, y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 16 + Math.floor(Math.random() * 12), // Doubled for 2x frame rate\n });\n }\n }\n\n function spawnSplash(x: number, y: number) {\n spawnParticles(x, y, 8, '\\x1b[96m', ['~', '∼', '≈', '○']);\n }\n\n function spawnCrash(x: number, y: number) {\n spawnParticles(x, y, 10, '\\x1b[91m', ['*', 'x', '×', '#']);\n }\n\n function spawnSuccess(x: number, y: number) {\n spawnParticles(x, y, 12, '\\x1b[92m', ['*', '+', '♦', '◇']);\n }\n\n // -------------------------------------------------------------------------\n // GAME SETUP\n // -------------------------------------------------------------------------\n\n function calculateLilyPads() {\n lilyPadX = [];\n const padSpacing = Math.floor(GAME_WIDTH / (LILY_PAD_COUNT + 1));\n for (let i = 0; i < LILY_PAD_COUNT; i++) {\n lilyPadX.push(padSpacing * (i + 1) - 1);\n }\n }\n\n function generateLanes() {\n lanes = [];\n\n // Difficulty scaling\n const speedMult = 0.6 + level * 0.15;\n const vehicleCountBase = Math.min(level + 1, 4);\n\n for (let row = 0; row <= GOAL_ROW; row++) {\n if (row === SAFE_START || row === MEDIAN) {\n lanes.push({ type: 'safe', speed: 0 });\n } else if (row >= ROAD_START && row <= ROAD_END) {\n // Road lanes\n const direction = row % 2 === 0 ? 1 : -1;\n const speed = (0.075 + Math.random() * 0.075) * direction * speedMult; // Halved for 2x frame rate\n const lane: Lane = { type: 'road', speed, vehicles: [] };\n\n const vehicleCount = vehicleCountBase - Math.floor(Math.random() * 2);\n const spacing = GAME_WIDTH / vehicleCount;\n\n for (let v = 0; v < vehicleCount; v++) {\n const rand = Math.random();\n let sprite: string, width: number, color: string;\n\n if (rand < 0.2 && level >= 2) {\n // Motorcycle (fast, small)\n sprite = MOTORCYCLE;\n width = 2;\n color = '\\x1b[93m';\n } else if (rand < 0.5) {\n // Truck (slow, big)\n sprite = TRUCK;\n width = 5;\n color = '\\x1b[33m';\n } else {\n // Car\n sprite = direction > 0 ? CAR_RIGHT : CAR_LEFT;\n width = 3;\n color = '\\x1b[91m';\n }\n\n lane.vehicles!.push({\n x: v * spacing + Math.random() * (spacing / 3),\n width,\n sprite,\n color,\n });\n }\n lanes.push(lane);\n } else if (row >= WATER_START && row <= WATER_END) {\n // Water lanes\n const direction = row % 2 === 0 ? 1 : -1;\n const speed = (0.04 + Math.random() * 0.05) * direction * speedMult; // Halved for 2x frame rate\n const lane: Lane = { type: 'water', speed, logs: [] };\n\n const logCount = 2 + Math.floor(Math.random() * 2);\n const spacing = GAME_WIDTH / logCount;\n\n for (let l = 0; l < logCount; l++) {\n const isTurtle = Math.random() < 0.3 && level >= 2;\n const width = isTurtle ? 4 : 4 + Math.floor(Math.random() * 3);\n\n lane.logs!.push({\n x: l * spacing + Math.random() * (spacing / 3),\n width,\n sprite: isTurtle ? TURTLE.repeat(2) : LOG_CHAR.repeat(width),\n isTurtle,\n submergeTimer: isTurtle ? Math.random() * 200 : undefined,\n });\n }\n lanes.push(lane);\n } else if (row === GOAL_ROW) {\n lanes.push({ type: 'goal', speed: 0 });\n } else {\n lanes.push({ type: 'safe', speed: 0 });\n }\n }\n }\n\n function initGame() {\n score = 0;\n level = 1;\n lives = 3;\n gameOver = false;\n paused = false;\n lilyPads = [false, false, false, false, false];\n timeRemaining = TIME_LIMIT;\n lastTimeUpdate = Date.now();\n furthestY = GAME_HEIGHT - 1;\n\n particles = [];\n shakeFrames = 0;\n deathFlash = 0;\n winFlash = 0;\n\n calculateLilyPads();\n generateLanes();\n resetPlayer();\n }\n\n function resetPlayer() {\n playerX = Math.floor(GAME_WIDTH / 2);\n playerY = GAME_HEIGHT - 1;\n playerOnLog = false;\n furthestY = GAME_HEIGHT - 1;\n timeRemaining = TIME_LIMIT;\n lastTimeUpdate = Date.now();\n hopFrame = 0;\n }\n\n function advanceLevel() {\n level++;\n lilyPads = [false, false, false, false, false];\n timeRemaining = TIME_LIMIT;\n lastTimeUpdate = Date.now();\n\n const bonus = level * 500 + Math.floor(timeRemaining) * 5;\n score += bonus;\n if (score > highScore) highScore = score;\n\n winFlash = 25;\n for (let i = 0; i < 3; i++) {\n spawnSuccess(Math.random() * GAME_WIDTH, Math.random() * GAME_HEIGHT);\n }\n\n generateLanes();\n resetPlayer();\n }\n\n function die() {\n lives--;\n spawnCrash(playerX, playerY);\n shakeFrames = 12;\n deathFlash = 15;\n\n if (lives <= 0) {\n gameOver = true;\n if (score > highScore) highScore = score;\n } else {\n resetPlayer();\n }\n }\n\n // -------------------------------------------------------------------------\n // COLLISION\n // -------------------------------------------------------------------------\n\n function getLaneAt(y: number): Lane | null {\n const row = GAME_HEIGHT - 1 - y;\n if (row < 0 || row >= lanes.length) return null;\n return lanes[row];\n }\n\n function checkVehicleCollision(): boolean {\n const lane = getLaneAt(playerY);\n if (!lane || lane.type !== 'road' || !lane.vehicles) return false;\n\n for (const v of lane.vehicles) {\n const vLeft = v.x;\n const vRight = v.x + v.width;\n if (playerX >= vLeft && playerX < vRight) {\n return true;\n }\n // Handle wrap\n if (vLeft < 0 && playerX >= GAME_WIDTH + vLeft) return true;\n if (vRight > GAME_WIDTH && playerX < vRight - GAME_WIDTH) return true;\n }\n return false;\n }\n\n function checkWaterSafety(): { safe: boolean; speed: number } {\n const lane = getLaneAt(playerY);\n if (!lane || lane.type !== 'water' || !lane.logs) {\n return { safe: false, speed: 0 };\n }\n\n for (const log of lane.logs) {\n // Skip submerged turtles\n if (log.isTurtle && log.submergeTimer !== undefined && log.submergeTimer < 30) {\n continue;\n }\n\n const logLeft = log.x;\n const logRight = log.x + log.width;\n\n if (playerX >= logLeft && playerX < logRight) {\n return { safe: true, speed: lane.speed };\n }\n // Handle wrap\n if (logLeft < 0 && playerX >= GAME_WIDTH + logLeft) {\n return { safe: true, speed: lane.speed };\n }\n if (logRight > GAME_WIDTH && playerX < logRight - GAME_WIDTH) {\n return { safe: true, speed: lane.speed };\n }\n }\n\n return { safe: false, speed: 0 };\n }\n\n function checkGoal() {\n const row = GAME_HEIGHT - 1 - playerY;\n if (row !== GOAL_ROW) return;\n\n for (let i = 0; i < LILY_PAD_COUNT; i++) {\n const padX = lilyPadX[i];\n // Lily pad visual is \"(○)\" at padX, padX+1, padX+2\n // Center collision on the middle character (padX+1) with ±2 tolerance\n const padCenter = padX + 1;\n if (Math.abs(playerX - padCenter) <= 2) {\n if (!lilyPads[i]) {\n lilyPads[i] = true;\n const bonus = 100 + timeRemaining * 5;\n score += bonus;\n spawnSuccess(padCenter, playerY); // Spawn particles at pad center\n\n if (lilyPads.every(p => p)) {\n advanceLevel();\n return;\n }\n resetPlayer();\n return;\n } else {\n // Already filled - die\n die();\n return;\n }\n }\n }\n // Missed lily pad - die (fell into water)\n spawnSplash(playerX, playerY);\n die();\n }\n\n // -------------------------------------------------------------------------\n // UPDATE\n // -------------------------------------------------------------------------\n\n function update() {\n if (!gameStarted || gameOver || paused) return;\n\n // Timer\n const now = Date.now();\n if (now - lastTimeUpdate >= 1000) {\n timeRemaining--;\n lastTimeUpdate = now;\n if (timeRemaining <= 0) {\n die();\n return;\n }\n }\n\n // Particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.015;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update flash counters\n if (shakeFrames > 0) shakeFrames--;\n if (deathFlash > 0) deathFlash--;\n if (winFlash > 0) winFlash--;\n\n // Hop animation\n if (hopFrame > 0) hopFrame--;\n\n // Move vehicles and logs\n for (const lane of lanes) {\n if (lane.type === 'road' && lane.vehicles) {\n for (const v of lane.vehicles) {\n v.x += lane.speed;\n if (v.x > GAME_WIDTH) v.x = -v.width;\n if (v.x + v.width < 0) v.x = GAME_WIDTH;\n }\n } else if (lane.type === 'water' && lane.logs) {\n for (const log of lane.logs) {\n log.x += lane.speed;\n if (log.x > GAME_WIDTH) log.x = -log.width;\n if (log.x + log.width < 0) log.x = GAME_WIDTH;\n\n // Turtle submerge cycle\n if (log.isTurtle && log.submergeTimer !== undefined) {\n log.submergeTimer--;\n if (log.submergeTimer <= 0) {\n log.submergeTimer = 150 + Math.random() * 100;\n }\n }\n }\n }\n }\n\n // Check water safety and move with log\n const lane = getLaneAt(playerY);\n if (lane && lane.type === 'water') {\n const waterCheck = checkWaterSafety();\n if (waterCheck.safe) {\n playerOnLog = true;\n playerX += waterCheck.speed;\n // Boundary check\n if (playerX < 0 || playerX >= GAME_WIDTH) {\n spawnSplash(playerX, playerY);\n die();\n return;\n }\n } else {\n // In water without log\n spawnSplash(playerX, playerY);\n die();\n return;\n }\n } else {\n playerOnLog = false;\n }\n\n // Check vehicle collision\n if (checkVehicleCollision()) {\n die();\n return;\n }\n\n // Check goal\n checkGoal();\n }\n\n // -------------------------------------------------------------------------\n // PLAYER MOVEMENT\n // -------------------------------------------------------------------------\n\n function movePlayer(dx: number, dy: number) {\n const now = Date.now();\n if (now - lastMoveTime < MOVE_COOLDOWN) return;\n lastMoveTime = now;\n\n const newX = playerX + dx;\n const newY = playerY + dy;\n\n if (newX < 0 || newX >= GAME_WIDTH) return;\n if (newY < 0 || newY >= GAME_HEIGHT) return;\n\n playerX = newX;\n playerY = newY;\n hopFrame = 4;\n\n // Score for forward progress\n if (dy < 0 && playerY < furthestY) {\n score += 10;\n furthestY = playerY;\n }\n\n // Immediate collision check\n const lane = getLaneAt(playerY);\n\n if (lane && lane.type === 'road') {\n if (checkVehicleCollision()) {\n die();\n return;\n }\n }\n\n if (lane && lane.type === 'water') {\n const waterCheck = checkWaterSafety();\n if (!waterCheck.safe) {\n spawnSplash(playerX, playerY);\n die();\n return;\n }\n playerOnLog = true;\n }\n\n checkGoal();\n }\n\n // -------------------------------------------------------------------------\n // RENDERING\n // -------------------------------------------------------------------------\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const msg2 = `Need: ${MIN_COLS}×${MIN_ROWS} Have: ${cols}×${rows}`;\n const hint = cols < MIN_COLS && rows < MIN_ROWS ? 'Make pane larger'\n : cols < MIN_COLS ? 'Make pane wider →' : 'Make pane taller ↓';\n const cx = Math.floor(cols / 2);\n const cy = Math.floor(rows / 2);\n output += `\\x1b[${cy - 1};${Math.max(1, cx - msg1.length / 2)}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${cy + 1};${Math.max(1, cx - msg2.length / 2)}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${cy + 3};${Math.max(1, cx - hint.length / 2)}H${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Adaptive dimensions\n GAME_WIDTH = Math.min(cols - 4, 50);\n GAME_HEIGHT = Math.min(rows - 8, 15);\n gameLeft = Math.floor((cols - GAME_WIDTH - 2) / 2);\n gameTop = Math.floor((rows - GAME_HEIGHT - 6) / 2) + 2;\n\n // Recalculate lily pads if needed\n if (lilyPadX.length === 0) {\n calculateLilyPads();\n }\n\n // Apply shake\n let renderLeft = gameLeft;\n let renderTop = gameTop;\n if (shakeFrames > 0) {\n renderLeft += Math.floor((Math.random() - 0.5) * 4);\n renderTop += Math.floor((Math.random() - 0.5) * 2);\n }\n\n // Title\n const titleX = Math.floor((cols - title[0].length) / 2);\n output += `\\x1b[1;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n\n // Stats\n const hearts = '♥'.repeat(lives);\n const timerColor = timeRemaining <= 10 ? '\\x1b[91m' : '\\x1b[97m';\n const stats = `SCORE: ${score.toString().padStart(5, '0')} LVL: ${level} TIME: ${timerColor}${timeRemaining.toString().padStart(2, '0')}\\x1b[0m \\x1b[91m${hearts}\\x1b[0m`;\n const statsX = Math.floor((cols - 45) / 2);\n output += `\\x1b[${gameTop - 1};${statsX}H${stats}`;\n\n // Border\n let borderColor = themeColor;\n if (deathFlash > 0 && deathFlash % 4 < 2) borderColor = '\\x1b[91m';\n if (winFlash > 0 && winFlash % 4 < 2) borderColor = '\\x1b[92m';\n\n output += `\\x1b[${renderTop};${renderLeft}H${borderColor}╔${'═'.repeat(GAME_WIDTH)}╗\\x1b[0m`;\n for (let y = 0; y < GAME_HEIGHT; y++) {\n output += `\\x1b[${renderTop + 1 + y};${renderLeft}H${borderColor}║\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + y};${renderLeft + GAME_WIDTH + 1}H${borderColor}║\\x1b[0m`;\n }\n output += `\\x1b[${renderTop + GAME_HEIGHT + 1};${renderLeft}H${borderColor}╚${'═'.repeat(GAME_WIDTH)}╝\\x1b[0m`;\n\n // PAUSE MENU\n if (paused) {\n const pauseMsg = '══ PAUSED ══';\n const cx = Math.floor(cols / 2);\n const pauseY = gameTop + Math.floor(GAME_HEIGHT / 2) - 2;\n output += `\\x1b[${pauseY};${cx - pauseMsg.length / 2}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: cx,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n }\n // START SCREEN\n else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO PLAY ]';\n const startX = gameLeft + Math.floor((GAME_WIDTH - startMsg.length) / 2) + 1;\n const startY = gameTop + Math.floor(GAME_HEIGHT / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = '← → ↑ ↓ Move ESC Menu';\n const ctrlX = gameLeft + Math.floor((GAME_WIDTH - controls.length) / 2) + 1;\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${controls}\\x1b[0m`;\n\n const desc = 'Cross roads and rivers to reach the lily pads!';\n const descX = gameLeft + Math.floor((GAME_WIDTH - desc.length) / 2) + 1;\n output += `\\x1b[${startY + 4};${descX}H\\x1b[2m${desc}\\x1b[0m`;\n }\n // GAME OVER\n else if (gameOver) {\n const overMsg = '╔══ GAME OVER ══╗';\n const overX = gameLeft + Math.floor((GAME_WIDTH - overMsg.length) / 2) + 1;\n const overY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n output += `\\x1b[${overY};${overX}H\\x1b[1;91m${overMsg}\\x1b[0m`;\n\n const scoreLine = `SCORE: ${score} HIGH: ${highScore}`;\n const scoreX = gameLeft + Math.floor((GAME_WIDTH - scoreLine.length) / 2) + 1;\n output += `\\x1b[${overY + 1};${scoreX}H${themeColor}${scoreLine}\\x1b[0m`;\n\n const restart = '╚ [R] RETRY [Q] QUIT ╝';\n const restartX = gameLeft + Math.floor((GAME_WIDTH - restart.length) / 2) + 1;\n output += `\\x1b[${overY + 2};${restartX}H\\x1b[2m${restart}\\x1b[0m`;\n }\n // GAMEPLAY\n else {\n // Draw lanes\n for (let y = 0; y < GAME_HEIGHT; y++) {\n const row = GAME_HEIGHT - 1 - y;\n if (row < 0 || row >= lanes.length) continue;\n\n const lane = lanes[row];\n const screenY = renderTop + 1 + y;\n\n // Background\n let bgColor = '\\x1b[48;5;22m'; // Green grass\n let bgChar = ' ';\n\n if (lane.type === 'road') {\n bgColor = '\\x1b[48;5;236m'; // Dark gray road\n bgChar = ' ';\n } else if (lane.type === 'water') {\n bgColor = '\\x1b[48;5;17m'; // Dark blue water\n bgChar = '~';\n } else if (lane.type === 'goal') {\n bgColor = '\\x1b[48;5;22m'; // Green\n bgChar = ' ';\n }\n\n output += `\\x1b[${screenY};${renderLeft + 1}H${bgColor}\\x1b[34m${bgChar.repeat(GAME_WIDTH)}\\x1b[0m`;\n\n // Draw lily pads in goal row\n if (lane.type === 'goal') {\n for (let i = 0; i < LILY_PAD_COUNT; i++) {\n const padX = lilyPadX[i];\n if (padX >= 0 && padX < GAME_WIDTH - 2) {\n const screenX = renderLeft + 1 + padX;\n if (lilyPads[i]) {\n output += `\\x1b[${screenY};${screenX}H\\x1b[92m[◎]\\x1b[0m`;\n } else {\n output += `\\x1b[${screenY};${screenX}H\\x1b[32m(○)\\x1b[0m`;\n }\n }\n }\n }\n\n // Draw vehicles\n if (lane.type === 'road' && lane.vehicles) {\n for (const v of lane.vehicles) {\n const vx = Math.floor(v.x);\n if (vx >= 0 && vx + v.width <= GAME_WIDTH) {\n output += `\\x1b[${screenY};${renderLeft + 1 + vx}H${v.color}${v.sprite}\\x1b[0m`;\n } else if (vx < 0) {\n // Wrap from left\n const visible = v.sprite.slice(-vx);\n if (visible.length > 0) {\n output += `\\x1b[${screenY};${renderLeft + 1}H${v.color}${visible}\\x1b[0m`;\n }\n } else if (vx < GAME_WIDTH) {\n // Partial from right\n const visible = v.sprite.slice(0, GAME_WIDTH - vx);\n output += `\\x1b[${screenY};${renderLeft + 1 + vx}H${v.color}${visible}\\x1b[0m`;\n }\n }\n }\n\n // Draw logs/turtles\n if (lane.type === 'water' && lane.logs) {\n for (const log of lane.logs) {\n // Skip submerged turtles\n const isSubmerged = log.isTurtle && log.submergeTimer !== undefined && log.submergeTimer < 30;\n\n const lx = Math.floor(log.x);\n const logColor = isSubmerged ? '\\x1b[34m' : (log.isTurtle ? '\\x1b[92m' : '\\x1b[33m');\n const displaySprite = isSubmerged ? '∼'.repeat(log.width) : log.sprite;\n\n if (lx >= 0 && lx + log.width <= GAME_WIDTH) {\n output += `\\x1b[${screenY};${renderLeft + 1 + lx}H${logColor}${displaySprite.slice(0, log.width)}\\x1b[0m`;\n } else if (lx < 0) {\n const visible = displaySprite.slice(-lx, log.width);\n if (visible.length > 0) {\n output += `\\x1b[${screenY};${renderLeft + 1}H${logColor}${visible}\\x1b[0m`;\n }\n } else if (lx < GAME_WIDTH) {\n const visible = displaySprite.slice(0, GAME_WIDTH - lx);\n output += `\\x1b[${screenY};${renderLeft + 1 + lx}H${logColor}${visible}\\x1b[0m`;\n }\n }\n }\n }\n\n // Draw frog\n const frogScreenX = renderLeft + 1 + Math.floor(playerX);\n const frogScreenY = renderTop + 1 + playerY;\n let frogChar = FROG_IDLE;\n if (hopFrame > 0) frogChar = FROG_HOP;\n else if (playerOnLog) frogChar = FROG_ON_LOG;\n\n const frogColor = deathFlash > 0 ? '\\x1b[91m' : '\\x1b[1;92m';\n output += `\\x1b[${frogScreenY};${frogScreenX}H${frogColor}${frogChar}\\x1b[0m`;\n\n // Draw particles\n for (const p of particles) {\n const sx = Math.round(renderLeft + 1 + p.x);\n const sy = Math.round(renderTop + 1 + p.y);\n if (sx > renderLeft && sx < renderLeft + GAME_WIDTH + 1 &&\n sy > renderTop && sy < renderTop + GAME_HEIGHT + 1) {\n output += `\\x1b[${sy};${sx}H${p.color}${p.char}\\x1b[0m`;\n }\n }\n }\n\n // Bottom hint\n const hint = gameStarted && !gameOver && !paused ? `HIGH: ${highScore} [ ESC ] MENU` : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${gameTop + GAME_HEIGHT + 3};${hintX}H\\x1b[2m${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n // -------------------------------------------------------------------------\n // GAME LOOP\n // -------------------------------------------------------------------------\n\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) { clearInterval(gameInterval); return; }\n update();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n if (key === 'q' && (paused || gameOver || !gameStarted)) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n\n if (!gameStarted && !paused) {\n gameStarted = true;\n return;\n }\n\n if (gameOver) {\n if (key === 'r') {\n if (score > highScore) highScore = score;\n initGame();\n gameStarted = true;\n }\n return;\n }\n\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: paused = false; break;\n case 1: initGame(); gameStarted = true; paused = false; break;\n case 2:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n if (key === 'r') { initGame(); gameStarted = true; paused = false; }\n else if (key === 'l') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGamesMenu(terminal); }\n else if (key === 'n') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGameSwitch(terminal); }\n return;\n }\n\n // Movement\n switch (domEvent.key) {\n case 'ArrowLeft':\n case 'a':\n movePlayer(-1, 0);\n break;\n case 'ArrowRight':\n case 'd':\n movePlayer(1, 0);\n break;\n case 'ArrowUp':\n case 'w':\n movePlayer(0, -1);\n break;\n case 'ArrowDown':\n case 's':\n movePlayer(0, 1);\n break;\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Hangman\n *\n * Cyberpunk-themed word guessing game with glitchy effects,\n * neon visuals, and theme-aware colors.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor, getVerticalAnchor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Hangman Game Controller\n */\nexport interface HangmanController {\n stop: () => void;\n isRunning: boolean;\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\n// Word list - cyberpunk/tech themed\nconst WORDS = [\n 'TERMINAL', 'HACKER', 'MATRIX', 'CYBER', 'NEURAL', 'QUANTUM',\n 'BINARY', 'PROTOCOL', 'NETWORK', 'ENCRYPT', 'DECRYPT', 'SYSTEM',\n 'CIRCUIT', 'DAEMON', 'KERNEL', 'BUFFER', 'MEMORY', 'PROCESS',\n 'SCRIPT', 'MODULE', 'VECTOR', 'SYNTAX', 'COMPILE', 'RUNTIME',\n 'CURSOR', 'PROMPT', 'SHELL', 'STREAM', 'SIGNAL', 'THREAD',\n 'SOCKET', 'SERVER', 'CLIENT', 'PACKET', 'ROUTER', 'FIREWALL',\n 'PROXY', 'TOKEN', 'CIPHER', 'BREACH', 'SPLICE', 'INJECT',\n 'PATCH', 'DEBUG', 'TRACE', 'STACK', 'HEAP', 'CACHE',\n 'NEXUS', 'PULSE', 'GHOST', 'SHADOW', 'BLADE', 'CHROME',\n 'NEON', 'SYNTH', 'GRID', 'SURGE', 'FLUX', 'STORM',\n];\n\n// ASCII art hangman stages\nconst HANGMAN_STAGES = [\n // 0 mistakes\n [\n ' ┌───────┐ ',\n ' │ │ ',\n ' │ ',\n ' │ ',\n ' │ ',\n ' │ ',\n '══╧════════ ',\n ],\n // 1 mistake - head\n [\n ' ┌───────┐ ',\n ' │ │ ',\n ' │ ◯ ',\n ' │ ',\n ' │ ',\n ' │ ',\n '══╧════════ ',\n ],\n // 2 mistakes - body\n [\n ' ┌───────┐ ',\n ' │ │ ',\n ' │ ◯ ',\n ' │ │ ',\n ' │ ',\n ' │ ',\n '══╧════════ ',\n ],\n // 3 mistakes - left arm\n [\n ' ┌───────┐ ',\n ' │ │ ',\n ' │ ◯ ',\n ' │ ╱│ ',\n ' │ ',\n ' │ ',\n '══╧════════ ',\n ],\n // 4 mistakes - right arm\n [\n ' ┌───────┐ ',\n ' │ │ ',\n ' │ ◯ ',\n ' │ ╱│╲ ',\n ' │ ',\n ' │ ',\n '══╧════════ ',\n ],\n // 5 mistakes - left leg\n [\n ' ┌───────┐ ',\n ' │ │ ',\n ' │ ◯ ',\n ' │ ╱│╲ ',\n ' │ ╱ ',\n ' │ ',\n '══╧════════ ',\n ],\n // 6 mistakes - dead\n [\n ' ┌───────┐ ',\n ' │ │ ',\n ' │ ◯ ',\n ' │ ╱│╲ ',\n ' │ ╱ ╲ ',\n ' │ ',\n '══╧════════ ',\n ],\n];\n\n/**\n * Cyberpunk Hangman Game\n */\nexport function runHangmanGame(terminal: Terminal): HangmanController {\n const themeColor = getCurrentThemeColor();\n\n // Game dimensions\n const GAME_WIDTH = 40;\n\n // Minimum terminal size (compact - just needs to fit the content)\n const MIN_COLS = 32;\n const MIN_ROWS = 16;\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let won = false;\n let score = 0;\n let streak = 0;\n let highStreak = 0;\n\n // Game state\n let currentWord = '';\n let guessedLetters: Set<string> = new Set();\n let wrongGuesses = 0;\n const MAX_WRONG = 6;\n\n // Game area positioning\n let gameLeft = 2;\n let gameTop = 4;\n\n // Visual effects\n let glitchFrame = 0;\n let flashWrong = 0;\n let flashRight = 0;\n let winAnimation = 0;\n let loseAnimation = 0;\n let screenShake = 0;\n\n // Juicy effects\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let correctStreak = 0;\n let borderFlash = 0;\n\n const controller: HangmanController = {\n stop: () => {\n if (!running) return;\n running = false;\n // Note: Buffer exit is handled by TerminalPool via dispatchGameQuit\n },\n get isRunning() { return running; }\n };\n\n // ASCII art title\n const title = [\n '█ █ ▄▀█ █▄ █ █▀▀ █▄ ▄█ ▄▀█ █▄ █',\n '█▀█ █▀█ █ ▀█ █▄█ █ ▀ █ █▀█ █ ▀█',\n ];\n\n function updateLayout(rows: number) {\n // Core content: gallows, word, wrong letters, and status rows.\n gameTop = getVerticalAnchor(rows, 16, {\n headerRows: 3,\n footerRows: 2,\n minTop: 4,\n });\n }\n\n function initGame() {\n // Pick a random word\n currentWord = WORDS[Math.floor(Math.random() * WORDS.length)];\n guessedLetters = new Set();\n wrongGuesses = 0;\n gameOver = false;\n won = false;\n paused = false;\n flashWrong = 0;\n flashRight = 0;\n // Reset juicy effects\n particles = [];\n scorePopups = [];\n correctStreak = 0;\n borderFlash = 0;\n screenShake = 0;\n winAnimation = 0;\n loseAnimation = 0;\n }\n\n // Spawn particles at position\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['✦', '★', '◆', '●']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.3 + Math.random() * 0.5;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5 - 0.2,\n life: 15 + Math.floor(Math.random() * 10),\n });\n }\n }\n\n // Add score popup\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 22, color });\n }\n\n function getDisplayWord(): string {\n return currentWord\n .split('')\n .map(letter => guessedLetters.has(letter) ? letter : '_')\n .join(' ');\n }\n\n function getUsedLetters(): string {\n const wrong = [...guessedLetters].filter(l => !currentWord.includes(l)).sort().join(' ');\n return wrong || '-';\n }\n\n function checkWin(): boolean {\n return currentWord.split('').every(letter => guessedLetters.has(letter));\n }\n\n function guessLetter(letter: string) {\n if (gameOver || paused || guessedLetters.has(letter)) return;\n\n guessedLetters.add(letter);\n\n if (currentWord.includes(letter)) {\n // Correct guess\n flashRight = 8;\n borderFlash = 8;\n correctStreak++;\n const letterCount = currentWord.split(letter).length - 1;\n const points = 10 * letterCount;\n score += points;\n\n // Effects based on streak and letter count\n const effectIntensity = Math.min(correctStreak + letterCount, 8);\n screenShake = 2 + Math.floor(effectIntensity / 2);\n\n // Spawn particles at word display area (we'll use center screen)\n const centerX = Math.floor(terminal.cols / 2);\n const wordY = gameTop + 9;\n spawnParticles(centerX, wordY, 4 + effectIntensity, '\\x1b[1;92m', ['✦', '★', '◆', '●']);\n\n // Score popup\n const popupText = letterCount > 1 ? `+${points}!` : `+${points}`;\n const popupColor = correctStreak >= 3 ? '\\x1b[1;93m' : '\\x1b[1;92m';\n addScorePopup(centerX - 2, wordY - 2, popupText, popupColor);\n\n // Streak message\n if (correctStreak >= 3) {\n addScorePopup(centerX - 4, wordY - 4, `${correctStreak}x STREAK!`, '\\x1b[1;96m');\n }\n\n if (checkWin()) {\n won = true;\n gameOver = true;\n streak++;\n if (streak > highStreak) highStreak = streak;\n const bonus = Math.max(0, (MAX_WRONG - wrongGuesses)) * 20;\n score += bonus;\n winAnimation = 30;\n screenShake = 8;\n // Big win explosion\n spawnParticles(centerX, wordY, 15, '\\x1b[1;93m', ['★', '✦', '♦', '◆', '●']);\n if (bonus > 0) {\n addScorePopup(centerX - 3, wordY + 2, `+${bonus} BONUS!`, '\\x1b[1;93m');\n }\n }\n } else {\n // Wrong guess\n flashWrong = 8;\n wrongGuesses++;\n correctStreak = 0; // Reset correct streak on wrong\n\n // Shake and particles\n screenShake = 4 + wrongGuesses;\n\n // Spawn red particles at hangman\n const hangmanX = gameLeft + 6;\n const hangmanY = gameTop + 4;\n spawnParticles(hangmanX, hangmanY, 5, '\\x1b[1;91m', ['✗', '×', '·', '○']);\n\n if (wrongGuesses >= MAX_WRONG) {\n gameOver = true;\n streak = 0;\n loseAnimation = 40;\n screenShake = 20;\n // Death explosion\n spawnParticles(hangmanX, hangmanY, 12, '\\x1b[1;91m', ['✗', '☠', '×', '▒', '░']);\n addScorePopup(hangmanX - 3, hangmanY - 2, 'FAILED!', '\\x1b[1;91m');\n }\n }\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Update effect timers\n if (borderFlash > 0) borderFlash--;\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.03;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.15;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = '';\n if (needWidth && needHeight) {\n hint = 'Make pane larger';\n } else if (needWidth) {\n hint = 'Make pane wider →';\n } else {\n hint = 'Make pane taller ↓';\n }\n const msg2 = `Need: ${MIN_COLS}×${MIN_ROWS} Have: ${cols}×${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n updateLayout(rows);\n\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH) / 2));\n\n // Glitchy title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n const titleTop = Math.max(1, gameTop - 2);\n output += `\\x1b[${titleTop};${titleX}H`;\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n if (paused) {\n const pauseMsg = '══ PAUSED ══';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseY = Math.floor(rows / 2) - 3;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted) {\n // Show start screen\n const startMsg = '[ PRESS ANY KEY TO START ]';\n const startX = Math.floor((cols - startMsg.length) / 2);\n const startY = Math.floor(rows / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = 'A-Z GUESS ESC MENU';\n const ctrlX = Math.floor((cols - controls.length) / 2);\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n } else {\n // Apply screen shake offset\n const shakeOffsetX = screenShake > 0 ? Math.floor((Math.random() - 0.5) * Math.min(screenShake, 3)) : 0;\n const shakeOffsetY = screenShake > 0 ? Math.floor((Math.random() - 0.5) * Math.min(screenShake / 2, 1)) : 0;\n const renderLeft = gameLeft + shakeOffsetX;\n const renderTop = gameTop + shakeOffsetY;\n\n // Stats bar\n const statsColor = borderFlash > 0 && borderFlash % 4 < 2 ? '\\x1b[1;92m' : themeColor;\n const stats = `SCORE: ${score.toString().padStart(4, '0')} STREAK: ${streak} BEST: ${highStreak}`;\n const statsX = Math.floor((cols - stats.length) / 2) + shakeOffsetX;\n output += `\\x1b[${gameTop - 1};${statsX}H${statsColor}${stats}\\x1b[0m`;\n\n // Draw hangman with shake\n const hangmanStage = HANGMAN_STAGES[Math.min(wrongGuesses, MAX_WRONG)];\n const hangmanColor = flashWrong > 0 && flashWrong % 4 < 2 ? '\\x1b[1;91m' : themeColor;\n for (let i = 0; i < hangmanStage.length; i++) {\n output += `\\x1b[${renderTop + 1 + i};${renderLeft}H${hangmanColor}${hangmanStage[i]}\\x1b[0m`;\n }\n\n // Draw word display with shake\n const displayWord = getDisplayWord();\n const wordX = Math.floor((cols - displayWord.length) / 2) + shakeOffsetX;\n const wordY = renderTop + 9;\n const wordColor = flashRight > 0 && flashRight % 4 < 2 ? '\\x1b[1;92m' : themeColor;\n output += `\\x1b[${wordY};${wordX}H${wordColor}\\x1b[1m${displayWord}\\x1b[0m`;\n\n // Draw wrong letters\n const wrongLabel = 'WRONG: ';\n const wrongLetters = getUsedLetters();\n const wrongX = Math.floor((cols - (wrongLabel.length + wrongLetters.length)) / 2) + shakeOffsetX;\n const wrongY = wordY + 2;\n output += `\\x1b[${wrongY};${wrongX}H\\x1b[2m${themeColor}${wrongLabel}\\x1b[91m${wrongLetters}\\x1b[0m`;\n\n // Draw remaining guesses\n const remaining = `GUESSES LEFT: ${MAX_WRONG - wrongGuesses}`;\n const remainingX = Math.floor((cols - remaining.length) / 2) + shakeOffsetX;\n output += `\\x1b[${wrongY + 2};${remainingX}H\\x1b[2m${themeColor}${remaining}\\x1b[0m`;\n\n // Draw particles\n for (const p of particles) {\n const px = Math.round(p.x);\n const py = Math.round(p.y);\n if (px > 0 && px < cols && py > 0 && py < rows) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const px = Math.round(popup.x);\n const py = Math.round(popup.y);\n if (py > 0 && py < rows) {\n const alpha = popup.frames > 14 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n\n // Draw correct streak message\n if (correctStreak >= 3 && !gameOver) {\n const streakMsg = correctStreak >= 5 ? `★ ${correctStreak}x STREAK! ★` : `${correctStreak}x STREAK!`;\n const streakX = Math.floor((cols - streakMsg.length) / 2);\n const streakColor = glitchFrame % 6 < 3 ? '\\x1b[1;93m' : '\\x1b[1;96m';\n output += `\\x1b[${gameTop};${streakX}H${streakColor}${streakMsg}\\x1b[0m`;\n }\n\n if (gameOver) {\n const overY = gameTop + 15;\n\n if (won) {\n // Win animation - sparkles and color cycling\n const sparkles = ['✦', '✧', '★', '☆', '·'];\n const colors = ['\\x1b[92m', '\\x1b[96m', '\\x1b[93m', '\\x1b[95m'];\n const sparkleColor = colors[Math.floor(glitchFrame / 5) % colors.length];\n\n // Add sparkles around the message\n if (winAnimation > 0) {\n for (let i = 0; i < 6; i++) {\n const sx = Math.floor(cols / 2) + Math.floor(Math.cos(glitchFrame * 0.3 + i) * 15);\n const sy = overY - 2 + Math.floor(Math.sin(glitchFrame * 0.2 + i) * 2);\n const sparkle = sparkles[Math.floor(Math.random() * sparkles.length)];\n output += `\\x1b[${sy};${sx}H${sparkleColor}${sparkle}\\x1b[0m`;\n }\n }\n\n const overMsg = winAnimation > 20 ? '★ DECODED! ★' : '✦ DECODED! ✦';\n const msgColor = winAnimation > 0 && Math.floor(glitchFrame / 3) % 2 === 0 ? '\\x1b[1;93m' : '\\x1b[1;92m';\n const overX = Math.floor((cols - overMsg.length) / 2);\n output += `\\x1b[${overY};${overX}H${msgColor}${overMsg}\\x1b[0m`;\n } else {\n // Lose animation - glitch and shake\n const shakeX = screenShake > 0 ? Math.floor(Math.random() * 3) - 1 : 0;\n\n // Glitchy \"TERMINATED\" with random corruption\n let overMsg = '══ TERMINATED ══';\n if (loseAnimation > 20) {\n // Corrupt some characters\n const glitchChars = ['█', '▓', '░', '╳', '┼', '╬'];\n overMsg = overMsg.split('').map(c =>\n Math.random() < 0.2 ? glitchChars[Math.floor(Math.random() * glitchChars.length)] : c\n ).join('');\n }\n\n const loseColor = loseAnimation > 0 && Math.floor(glitchFrame / 2) % 2 === 0 ? '\\x1b[91m' : '\\x1b[1;31m';\n const overX = Math.floor((cols - overMsg.length) / 2) + shakeX;\n output += `\\x1b[${overY};${overX}H${loseColor}${overMsg}\\x1b[0m`;\n\n const wordReveal = `WORD: ${currentWord}`;\n const revealX = Math.floor((cols - wordReveal.length) / 2) + shakeX;\n output += `\\x1b[${overY + 1};${revealX}H${themeColor}${wordReveal}\\x1b[0m`;\n }\n\n const restart = '[ R ] NEW WORD [ ESC ] QUIT';\n const restartX = Math.floor((cols - restart.length) / 2);\n output += `\\x1b[${overY + 3};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n }\n }\n\n // Hint at bottom\n const hint = gameStarted && !gameOver && !paused ? '[ ESC ] MENU' : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${rows - 1};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n // Update flash effects\n if (flashWrong > 0) flashWrong--;\n if (flashRight > 0) flashRight--;\n if (winAnimation > 0) winAnimation--;\n if (loseAnimation > 0) loseAnimation--;\n if (screenShake > 0) screenShake--;\n\n terminal.write(output);\n }\n\n // Start game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) {\n clearInterval(renderInterval);\n return;\n }\n render();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener.dispose();\n return;\n }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // Handle ESC key - toggle pause (works on start screen too)\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Start screen - any key (except ESC handled above) starts the game\n // Skip if paused (ESC menu open on start screen)\n if (!gameStarted && !paused) {\n gameStarted = true;\n return;\n }\n\n // Game over - R to restart\n if (gameOver) {\n if (key === 'r') {\n initGame();\n gameStarted = true;\n }\n return;\n }\n\n // Pause menu actions\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n initGame();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n clearInterval(renderInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n clearInterval(renderInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n clearInterval(renderInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (key === 'r') {\n initGame();\n gameStarted = true;\n paused = false;\n } else if (key === 'l') {\n clearInterval(renderInterval);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (key === 'n') {\n clearInterval(renderInterval);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n // Handle letter guesses (only A-Z)\n if (/^[a-z]$/.test(key)) {\n guessLetter(key.toUpperCase());\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 50);\n\n return controller;\n}\n","/**\n * Hyper Minesweeper\n *\n * Cyberpunk minesweeper - \"defuse the malware grid\".\n * Navigate the grid, flag malware, reveal safe sectors.\n * Theme-aware with glitchy effects and particle systems.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Minesweeper Game Controller\n */\nexport interface MinesweeperController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface Cell {\n isMine: boolean;\n isRevealed: boolean;\n isFlagged: boolean;\n adjacentMines: number;\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\ninterface Difficulty {\n name: string;\n width: number;\n height: number;\n mines: number;\n minCols: number;\n minRows: number;\n}\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nconst DIFFICULTIES: Difficulty[] = [\n { name: 'EASY', width: 9, height: 9, mines: 10, minCols: 32, minRows: 16 },\n { name: 'MEDIUM', width: 16, height: 16, mines: 40, minCols: 44, minRows: 20 },\n { name: 'HARD', width: 20, height: 16, mines: 60, minCols: 54, minRows: 20 },\n];\n\n// Cell display characters\nconst CELL_HIDDEN = '[]';\nconst CELL_FLAG = '<>';\nconst CELL_MINE = '@@';\nconst CELL_EMPTY = ' ';\n\n// Number colors (1-8)\nconst NUMBER_COLORS = [\n '', // 0 - not used\n '\\x1b[96m', // 1 - cyan\n '\\x1b[92m', // 2 - green\n '\\x1b[91m', // 3 - red\n '\\x1b[94m', // 4 - blue\n '\\x1b[95m', // 5 - magenta\n '\\x1b[36m', // 6 - dark cyan\n '\\x1b[97m', // 7 - white\n '\\x1b[90m', // 8 - gray\n];\n\n// ============================================================================\n// MAIN GAME FUNCTION\n// ============================================================================\n\nexport function runMinesweeperGame(terminal: Terminal): MinesweeperController {\n const themeColor = getCurrentThemeColor();\n\n // -------------------------------------------------------------------------\n // STATE\n // -------------------------------------------------------------------------\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let won = false;\n let firstClick = true;\n\n // Difficulty\n let difficultyIndex = 0;\n let difficulty = DIFFICULTIES[difficultyIndex];\n let selectingDifficulty = true;\n let difficultySelection = 0;\n\n // Grid\n let grid: Cell[][] = [];\n let cursorX = 0;\n let cursorY = 0;\n\n // Stats\n let flagsPlaced = 0;\n let cellsRevealed = 0;\n let startTime = 0;\n let elapsedTime = 0;\n\n // Visual effects\n let glitchFrame = 0;\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let shakeFrames = 0;\n let shakeIntensity = 0;\n let scanLineY = -1;\n let scanLineFrames = 0;\n\n // Positioning\n let gameLeft = 2;\n let gameTop = 4;\n\n // -------------------------------------------------------------------------\n // CONTROLLER\n // -------------------------------------------------------------------------\n const controller: MinesweeperController = {\n stop: () => {\n if (!running) return;\n running = false;\n },\n get isRunning() { return running; }\n };\n\n // -------------------------------------------------------------------------\n // ASCII ART TITLE\n // -------------------------------------------------------------------------\n const title = [\n '█▄ ▄█ █ █▄ █ █▀▀ █▀▀ █ █ █ █▀▀ █▀▀ █▀█ █▀▀ █▀█',\n '█ ▀ █ █ █ ▀█ ██▄ ▄▄█ ▀▄▀▄▀ ██▄ ██▄ █▀▀ ██▄ █▀▄',\n ];\n\n // -------------------------------------------------------------------------\n // EFFECTS\n // -------------------------------------------------------------------------\n\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['*', '+', '.', 'o']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.2 + Math.random() * 0.4;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 10 + Math.floor(Math.random() * 8),\n });\n }\n }\n\n function spawnExplosion(x: number, y: number) {\n // Big explosion for mine hit\n const colors = ['\\x1b[1;91m', '\\x1b[1;93m', '\\x1b[1;97m'];\n const chars = ['*', '#', '@', '%', '!', 'X'];\n for (let i = 0; i < 20; i++) {\n const angle = (Math.PI * 2 * i) / 20 + Math.random() * 0.3;\n const speed = 0.3 + Math.random() * 0.5;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color: colors[Math.floor(Math.random() * colors.length)],\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5 - 0.2,\n life: 15 + Math.floor(Math.random() * 10),\n });\n }\n }\n\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 20, color });\n }\n\n function triggerShake(frames: number, intensity: number) {\n shakeFrames = frames;\n shakeIntensity = intensity;\n }\n\n // -------------------------------------------------------------------------\n // GRID GENERATION\n // -------------------------------------------------------------------------\n\n function createEmptyGrid(): Cell[][] {\n const newGrid: Cell[][] = [];\n for (let y = 0; y < difficulty.height; y++) {\n const row: Cell[] = [];\n for (let x = 0; x < difficulty.width; x++) {\n row.push({\n isMine: false,\n isRevealed: false,\n isFlagged: false,\n adjacentMines: 0,\n });\n }\n newGrid.push(row);\n }\n return newGrid;\n }\n\n function placeMines(safeX: number, safeY: number) {\n // Place mines avoiding the first clicked cell and its neighbors\n let minesPlaced = 0;\n while (minesPlaced < difficulty.mines) {\n const x = Math.floor(Math.random() * difficulty.width);\n const y = Math.floor(Math.random() * difficulty.height);\n\n // Skip if already a mine\n if (grid[y][x].isMine) continue;\n\n // Skip if within safe zone (3x3 around first click)\n if (Math.abs(x - safeX) <= 1 && Math.abs(y - safeY) <= 1) continue;\n\n grid[y][x].isMine = true;\n minesPlaced++;\n }\n\n // Calculate adjacent mine counts\n for (let y = 0; y < difficulty.height; y++) {\n for (let x = 0; x < difficulty.width; x++) {\n if (!grid[y][x].isMine) {\n grid[y][x].adjacentMines = countAdjacentMines(x, y);\n }\n }\n }\n }\n\n function countAdjacentMines(x: number, y: number): number {\n let count = 0;\n for (let dy = -1; dy <= 1; dy++) {\n for (let dx = -1; dx <= 1; dx++) {\n if (dx === 0 && dy === 0) continue;\n const nx = x + dx;\n const ny = y + dy;\n if (nx >= 0 && nx < difficulty.width && ny >= 0 && ny < difficulty.height) {\n if (grid[ny][nx].isMine) count++;\n }\n }\n }\n return count;\n }\n\n // -------------------------------------------------------------------------\n // GAME LOGIC\n // -------------------------------------------------------------------------\n\n function initGame() {\n difficulty = DIFFICULTIES[difficultyIndex];\n grid = createEmptyGrid();\n cursorX = Math.floor(difficulty.width / 2);\n cursorY = Math.floor(difficulty.height / 2);\n flagsPlaced = 0;\n cellsRevealed = 0;\n startTime = 0;\n elapsedTime = 0;\n gameOver = false;\n won = false;\n paused = false;\n firstClick = true;\n\n // Reset effects\n particles = [];\n scorePopups = [];\n shakeFrames = 0;\n scanLineY = -1;\n scanLineFrames = 0;\n }\n\n function revealCell(x: number, y: number, isChain = false) {\n if (x < 0 || x >= difficulty.width || y < 0 || y >= difficulty.height) return;\n const cell = grid[y][x];\n if (cell.isRevealed || cell.isFlagged) return;\n\n // First click - place mines avoiding this cell\n if (firstClick) {\n placeMines(x, y);\n firstClick = false;\n startTime = Date.now();\n\n // Start scan line effect\n scanLineY = 0;\n scanLineFrames = 40;\n }\n\n cell.isRevealed = true;\n cellsRevealed++;\n\n // Hit a mine!\n if (cell.isMine) {\n gameOver = true;\n won = false;\n triggerShake(25, 4);\n spawnExplosion(x * 2 + 1, y);\n addScorePopup(x * 2, y - 1, 'MALWARE!', '\\x1b[1;91m');\n revealAllMines();\n return;\n }\n\n // Spawn reveal particles\n if (!isChain) {\n spawnParticles(x * 2 + 1, y, 4, themeColor, ['.', '*', '+']);\n }\n\n // If empty cell, flood fill reveal\n if (cell.adjacentMines === 0) {\n for (let dy = -1; dy <= 1; dy++) {\n for (let dx = -1; dx <= 1; dx++) {\n if (dx !== 0 || dy !== 0) {\n // Add small delay for cascade effect\n setTimeout(() => {\n if (running && !gameOver) {\n revealCell(x + dx, y + dy, true);\n }\n }, 20);\n }\n }\n }\n }\n\n checkWin();\n }\n\n function toggleFlag(x: number, y: number) {\n const cell = grid[y][x];\n if (cell.isRevealed) return;\n\n cell.isFlagged = !cell.isFlagged;\n if (cell.isFlagged) {\n flagsPlaced++;\n spawnParticles(x * 2 + 1, y, 3, '\\x1b[1;93m', ['!', '^', '*']);\n } else {\n flagsPlaced--;\n }\n }\n\n function revealAllMines() {\n for (let y = 0; y < difficulty.height; y++) {\n for (let x = 0; x < difficulty.width; x++) {\n if (grid[y][x].isMine) {\n grid[y][x].isRevealed = true;\n }\n }\n }\n }\n\n function checkWin() {\n // Win if all non-mine cells are revealed\n const totalNonMines = difficulty.width * difficulty.height - difficulty.mines;\n if (cellsRevealed >= totalNonMines) {\n gameOver = true;\n won = true;\n triggerShake(10, 2);\n\n // Victory particles\n for (let i = 0; i < 5; i++) {\n const x = Math.floor(Math.random() * difficulty.width);\n const y = Math.floor(Math.random() * difficulty.height);\n spawnParticles(x * 2 + 1, y, 6, '\\x1b[1;92m', ['*', '+', '#']);\n }\n addScorePopup(difficulty.width, difficulty.height / 2, 'GRID SECURE!', '\\x1b[1;92m');\n }\n }\n\n function update() {\n if (!gameStarted || gameOver || paused || selectingDifficulty) return;\n\n // Update timer\n if (startTime > 0 && !gameOver) {\n elapsedTime = Math.floor((Date.now() - startTime) / 1000);\n }\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.03;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.2;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n // Update scan line\n if (scanLineFrames > 0) {\n scanLineFrames--;\n scanLineY = Math.floor((40 - scanLineFrames) / 40 * difficulty.height);\n if (scanLineFrames <= 0) {\n scanLineY = -1;\n }\n }\n }\n\n // -------------------------------------------------------------------------\n // RENDERING\n // -------------------------------------------------------------------------\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Effect timers\n if (shakeFrames > 0) shakeFrames--;\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n const currentDifficulty = DIFFICULTIES[selectingDifficulty ? difficultySelection : difficultyIndex];\n const minCols = currentDifficulty.minCols;\n const minRows = currentDifficulty.minRows;\n\n // Check minimum terminal size\n if (cols < minCols || rows < minRows) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < minCols;\n const needHeight = rows < minRows;\n let hint = needWidth && needHeight ? 'Make pane larger'\n : needWidth ? 'Make pane wider' : 'Make pane taller';\n const msg2 = `Need: ${minCols}x${minRows} Have: ${cols}x${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Calculate game area dimensions\n const gridWidth = difficulty.width * 2 + 2;\n const gridHeight = difficulty.height + 2;\n\n // Center game area\n gameLeft = Math.max(2, Math.floor((cols - gridWidth) / 2));\n gameTop = Math.max(4, Math.floor((rows - gridHeight - 6) / 2) + 3);\n\n // Apply screen shake\n let renderLeft = gameLeft;\n let renderTop = gameTop;\n if (shakeFrames > 0) {\n renderLeft += Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n renderTop += Math.floor((Math.random() - 0.5) * shakeIntensity);\n }\n\n // Glitch title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[1;${titleX}H\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `\\x1b[1;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n // DIFFICULTY SELECTION SCREEN\n if (selectingDifficulty) {\n const selectY = Math.floor(rows / 2) - 3;\n const selectMsg = '[ SELECT DIFFICULTY ]';\n const selectX = Math.floor((cols - selectMsg.length) / 2);\n output += `\\x1b[${selectY};${selectX}H${themeColor}\\x1b[1m${selectMsg}\\x1b[0m`;\n\n for (let i = 0; i < DIFFICULTIES.length; i++) {\n const d = DIFFICULTIES[i];\n const isSelected = i === difficultySelection;\n const label = `${d.name} (${d.width}x${d.height}, ${d.mines} malware)`;\n const labelX = Math.floor((cols - label.length - 4) / 2);\n const style = isSelected ? '\\x1b[1;93m' : `\\x1b[2m${themeColor}`;\n const prefix = isSelected ? ' >' : ' ';\n const suffix = isSelected ? '< ' : ' ';\n output += `\\x1b[${selectY + 2 + i};${labelX}H${style}${prefix}${label}${suffix}\\x1b[0m`;\n }\n\n const hint = 'Arrow keys to select, ENTER to confirm';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${selectY + 6};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n return;\n }\n\n // Stats bar\n const minesLeft = difficulty.mines - flagsPlaced;\n const timeStr = formatTime(elapsedTime);\n const stats = `MALWARE: ${minesLeft.toString().padStart(3, ' ')} TIME: ${timeStr} [${difficulty.name}]`;\n const statsX = Math.floor((cols - stats.length) / 2);\n output += `\\x1b[${renderTop - 1};${statsX}H${themeColor}${stats}\\x1b[0m`;\n\n // Grid border\n const borderColor = gameOver && !won ? '\\x1b[1;91m' : themeColor;\n output += `\\x1b[${renderTop};${renderLeft}H${borderColor}+${'-'.repeat(difficulty.width * 2)}+\\x1b[0m`;\n for (let y = 0; y < difficulty.height; y++) {\n output += `\\x1b[${renderTop + 1 + y};${renderLeft}H${borderColor}|\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + y};${renderLeft + difficulty.width * 2 + 1}H${borderColor}|\\x1b[0m`;\n }\n output += `\\x1b[${renderTop + difficulty.height + 1};${renderLeft}H${borderColor}+${'-'.repeat(difficulty.width * 2)}+\\x1b[0m`;\n\n // PAUSE MENU\n if (paused) {\n const pauseMsg = '== PAUSED ==';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseY = Math.floor(rows / 2) - 3;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = 'Arrow keys select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n }\n // START SCREEN\n else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO SCAN ]';\n const startX = Math.floor((cols - startMsg.length) / 2);\n const startY = Math.floor(rows / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = 'ARROWS move SPACE reveal F flag ESC menu';\n const ctrlX = Math.floor((cols - controls.length) / 2);\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n\n // Draw empty grid preview\n for (let y = 0; y < difficulty.height; y++) {\n for (let x = 0; x < difficulty.width; x++) {\n const cellX = renderLeft + 1 + x * 2;\n const cellY = renderTop + 1 + y;\n output += `\\x1b[${cellY};${cellX}H\\x1b[2m${themeColor}${CELL_HIDDEN}\\x1b[0m`;\n }\n }\n }\n // GAME OVER\n else if (gameOver) {\n // Draw the final grid state\n output += renderGrid(renderLeft, renderTop, false);\n\n const overMsg = won ? '== GRID SECURED ==' : '== MALWARE BREACH ==';\n const overX = Math.floor((cols - overMsg.length) / 2);\n const overY = Math.floor(rows / 2) - 1;\n output += `\\x1b[${overY};${overX}H${won ? '\\x1b[1;92m' : '\\x1b[1;91m'}${overMsg}\\x1b[0m`;\n\n const timeMsg = `Time: ${formatTime(elapsedTime)}`;\n const timeX = Math.floor((cols - timeMsg.length) / 2);\n output += `\\x1b[${overY + 1};${timeX}H${themeColor}${timeMsg}\\x1b[0m`;\n\n const restart = '[ R ] RESTART [ D ] DIFFICULTY [ Q ] QUIT';\n const restartX = Math.floor((cols - restart.length) / 2);\n output += `\\x1b[${overY + 3};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n }\n // GAMEPLAY\n else {\n output += renderGrid(renderLeft, renderTop, true);\n\n // Draw scan line effect\n if (scanLineY >= 0 && scanLineY < difficulty.height) {\n const scanX = renderLeft + 1;\n const scanY = renderTop + 1 + scanLineY;\n output += `\\x1b[${scanY};${scanX}H\\x1b[7m${themeColor}${' '.repeat(difficulty.width * 2)}\\x1b[0m`;\n }\n\n // Draw particles\n for (const p of particles) {\n const screenX = Math.round(renderLeft + 1 + p.x);\n const screenY = Math.round(renderTop + 1 + p.y);\n if (screenX > renderLeft && screenX < renderLeft + difficulty.width * 2 + 1 &&\n screenY > renderTop && screenY < renderTop + difficulty.height + 1) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const screenX = Math.round(renderLeft + 1 + popup.x);\n const screenY = Math.round(renderTop + 1 + popup.y);\n if (screenY > renderTop && screenY < renderTop + difficulty.height + 1) {\n const alpha = popup.frames > 10 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n }\n\n // Bottom hint\n const hint = gameStarted && !gameOver && !paused\n ? `Revealed: ${cellsRevealed}/${difficulty.width * difficulty.height - difficulty.mines} [ ESC ] MENU`\n : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${renderTop + difficulty.height + 3};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n function renderGrid(renderLeft: number, renderTop: number, showCursor: boolean): string {\n let output = '';\n\n for (let y = 0; y < difficulty.height; y++) {\n for (let x = 0; x < difficulty.width; x++) {\n const cell = grid[y][x];\n const cellX = renderLeft + 1 + x * 2;\n const cellY = renderTop + 1 + y;\n const isCursor = showCursor && x === cursorX && y === cursorY;\n\n let cellChar = '';\n let cellColor = '';\n\n if (cell.isRevealed) {\n if (cell.isMine) {\n cellChar = CELL_MINE;\n cellColor = '\\x1b[1;91m';\n } else if (cell.adjacentMines > 0) {\n cellChar = ` ${cell.adjacentMines}`;\n cellColor = NUMBER_COLORS[cell.adjacentMines] || themeColor;\n } else {\n cellChar = CELL_EMPTY;\n cellColor = '\\x1b[2m';\n }\n } else if (cell.isFlagged) {\n cellChar = CELL_FLAG;\n cellColor = '\\x1b[1;93m';\n } else {\n cellChar = CELL_HIDDEN;\n cellColor = `\\x1b[2m${themeColor}`;\n }\n\n if (isCursor) {\n // Cursor highlight - invert colors\n output += `\\x1b[${cellY};${cellX}H\\x1b[7m${cellColor}${cellChar}\\x1b[0m`;\n } else {\n output += `\\x1b[${cellY};${cellX}H${cellColor}${cellChar}\\x1b[0m`;\n }\n }\n }\n\n return output;\n }\n\n function formatTime(seconds: number): string {\n const mins = Math.floor(seconds / 60);\n const secs = seconds % 60;\n return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;\n }\n\n // -------------------------------------------------------------------------\n // GAME LOOP\n // -------------------------------------------------------------------------\n\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n selectingDifficulty = true;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) { clearInterval(gameInterval); return; }\n update();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // ESC toggles pause (not in difficulty select)\n if (key === 'escape' && !selectingDifficulty) {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Q to quit from pause/game over/start screen\n if (key === 'q' && (paused || gameOver || !gameStarted)) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n\n // Difficulty selection\n if (selectingDifficulty) {\n if (domEvent.key === 'ArrowUp') {\n difficultySelection = (difficultySelection - 1 + DIFFICULTIES.length) % DIFFICULTIES.length;\n } else if (domEvent.key === 'ArrowDown') {\n difficultySelection = (difficultySelection + 1) % DIFFICULTIES.length;\n } else if (domEvent.key === 'Enter' || domEvent.key === ' ') {\n difficultyIndex = difficultySelection;\n selectingDifficulty = false;\n initGame();\n } else if (key === 'q') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n }\n return;\n }\n\n // Start screen - any key starts\n if (!gameStarted && !paused) {\n gameStarted = true;\n return;\n }\n\n // Game over\n if (gameOver) {\n if (key === 'r') {\n initGame();\n gameStarted = true;\n } else if (key === 'd') {\n selectingDifficulty = true;\n difficultySelection = difficultyIndex;\n }\n return;\n }\n\n // Pause menu navigation\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: paused = false; break;\n case 1: initGame(); gameStarted = true; paused = false; break;\n case 2:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcuts\n if (key === 'r') { initGame(); gameStarted = true; paused = false; }\n else if (key === 'l') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGamesMenu(terminal); }\n else if (key === 'n') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGameSwitch(terminal); }\n return;\n }\n\n // GAMEPLAY INPUT\n switch (domEvent.key) {\n case 'ArrowLeft':\n case 'a':\n cursorX = Math.max(0, cursorX - 1);\n break;\n case 'ArrowRight':\n case 'd':\n cursorX = Math.min(difficulty.width - 1, cursorX + 1);\n break;\n case 'ArrowUp':\n case 'w':\n cursorY = Math.max(0, cursorY - 1);\n break;\n case 'ArrowDown':\n case 's':\n cursorY = Math.min(difficulty.height - 1, cursorY + 1);\n break;\n case ' ':\n case 'Enter':\n // Reveal cell\n if (!grid[cursorY][cursorX].isFlagged) {\n revealCell(cursorX, cursorY);\n }\n break;\n case 'f':\n case 'F':\n // Toggle flag\n toggleFlag(cursorX, cursorY);\n break;\n }\n });\n\n // Clean up on stop\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Pong\n *\n * Cyberpunk-themed Pong game with glitchy effects,\n * neon visuals, and theme-aware colors.\n * Single player vs AI.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Pong Game Controller\n */\nexport interface PongController {\n stop: () => void;\n isRunning: boolean;\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\n/**\n * Cyberpunk Pong Game\n */\nexport function runPongGame(terminal: Terminal): PongController {\n const themeColor = getCurrentThemeColor();\n\n // Minimum terminal size (reduced for better compatibility)\n const MIN_COLS = 40;\n const MIN_ROWS = 16;\n\n // Game dimensions - adaptive based on terminal size\n // Width: 40-60, Height: 14-20\n const getGameDimensions = () => {\n const cols = terminal.cols;\n const rows = terminal.rows;\n const width = Math.min(60, Math.max(40, cols - 6));\n const height = Math.min(20, Math.max(14, rows - 6));\n return { width, height };\n };\n\n let { width: GAME_WIDTH, height: GAME_HEIGHT } = getGameDimensions();\n const PADDLE_HEIGHT = Math.max(3, Math.min(4, Math.floor(GAME_HEIGHT / 5)));\n const PADDLE_OFFSET = 2;\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n\n // Game area positioning\n let gameLeft = 2;\n let gameTop = 4;\n\n // Scores\n let playerScore = 0;\n let aiScore = 0;\n const WIN_SCORE = 7;\n\n // Paddle positions (y coordinate of top of paddle)\n let playerY = Math.floor((GAME_HEIGHT - PADDLE_HEIGHT) / 2);\n let aiY = Math.floor((GAME_HEIGHT - PADDLE_HEIGHT) / 2);\n\n // Ball state\n let ballX = GAME_WIDTH / 2;\n let ballY = GAME_HEIGHT / 2;\n let ballVX = 0.4;\n let ballVY = 0.3;\n const BALL_SPEED = 0.5;\n const MAX_BALL_SPEED = 0.9;\n\n // AI difficulty (reaction delay)\n let aiReactionTimer = 0;\n const AI_REACTION_DELAY = 3;\n const AI_SPEED = 0.4;\n\n // Visual effects\n let glitchFrame = 0;\n let scoreFlash = 0;\n let ballTrail: { x: number; y: number; speed: number }[] = [];\n\n // Score celebration effects\n let scoreFreeze = 0; // Pause frames after scoring\n let lastScorer: 'player' | 'ai' | null = null;\n let screenShake = 0;\n let goalExplosion: { x: number; y: number; char: string; color: string }[] = [];\n let goalFlashSide: 'left' | 'right' | null = null;\n\n // Juicy effects\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let paddleHitFlash = 0;\n let rallyCount = 0;\n let wallHitFlash = 0;\n\n const controller: PongController = {\n stop: () => {\n if (!running) return;\n running = false;\n // Note: Buffer exit is handled by TerminalPool via dispatchGameQuit\n },\n get isRunning() { return running; }\n };\n\n // ASCII art title\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ █▀█ █▀█ █▄ █ █▀▀',\n '█▀█ █ █▀▀ ██▄ █▀▄ █▀▀ █▄█ █ ▀█ █▄█',\n ];\n\n function initGame() {\n playerY = Math.floor((GAME_HEIGHT - PADDLE_HEIGHT) / 2);\n aiY = Math.floor((GAME_HEIGHT - PADDLE_HEIGHT) / 2);\n resetBall(true);\n gameOver = false;\n paused = false;\n scoreFlash = 0;\n ballTrail = [];\n scoreFreeze = 0;\n lastScorer = null;\n screenShake = 0;\n goalExplosion = [];\n goalFlashSide = null;\n // Reset juicy effects\n particles = [];\n scorePopups = [];\n paddleHitFlash = 0;\n rallyCount = 0;\n wallHitFlash = 0;\n }\n\n // Spawn particles at position\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['✦', '★', '◆', '●']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.2 + Math.random() * 0.4;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 12 + Math.floor(Math.random() * 8),\n });\n }\n }\n\n // Add score popup\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 20, color });\n }\n\n function createGoalExplosion(side: 'left' | 'right') {\n const x = side === 'left' ? 1 : GAME_WIDTH - 2;\n const chars = ['*', '+', '\\u00d7', '\\u25cf', '\\u2022', '\\u2605'];\n const colors = ['\\x1b[93m', '\\x1b[91m', '\\x1b[95m', '\\x1b[96m', '\\x1b[97m'];\n\n goalExplosion = [];\n for (let i = 0; i < 12; i++) {\n goalExplosion.push({\n x: x + (Math.random() - 0.5) * 6,\n y: Math.floor(GAME_HEIGHT / 2) + (Math.random() - 0.5) * GAME_HEIGHT * 0.8,\n char: chars[Math.floor(Math.random() * chars.length)],\n color: colors[Math.floor(Math.random() * colors.length)],\n });\n }\n }\n\n function resetBall(towardsPlayer: boolean) {\n ballX = GAME_WIDTH / 2;\n ballY = GAME_HEIGHT / 2;\n\n // Random angle between -45 and 45 degrees\n const angle = (Math.random() - 0.5) * Math.PI / 2;\n const direction = towardsPlayer ? -1 : 1;\n\n ballVX = Math.cos(angle) * BALL_SPEED * direction;\n ballVY = Math.sin(angle) * BALL_SPEED;\n ballTrail = [];\n rallyCount = 0;\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Update effect timers\n if (paddleHitFlash > 0) paddleHitFlash--;\n if (wallHitFlash > 0) wallHitFlash--;\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.02;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.2;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = '';\n if (needWidth && needHeight) {\n hint = 'Make pane larger';\n } else if (needWidth) {\n hint = 'Make pane wider \\u2192';\n } else {\n hint = 'Make pane taller \\u2193';\n }\n const msg2 = `Need: ${MIN_COLS}\\u00d7${MIN_ROWS} Have: ${cols}\\u00d7${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Update game dimensions on resize\n const newDims = getGameDimensions();\n if (newDims.width !== GAME_WIDTH || newDims.height !== GAME_HEIGHT) {\n // Scale positions to new dimensions\n ballX = (ballX / GAME_WIDTH) * newDims.width;\n ballY = (ballY / GAME_HEIGHT) * newDims.height;\n playerY = Math.min(playerY, newDims.height - PADDLE_HEIGHT);\n aiY = Math.min(aiY, newDims.height - PADDLE_HEIGHT);\n GAME_WIDTH = newDims.width;\n GAME_HEIGHT = newDims.height;\n }\n\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH - 2) / 2));\n gameTop = Math.max(3, Math.floor((rows - GAME_HEIGHT - 4) / 2));\n\n // Apply screen shake\n const shakeOffsetX = screenShake > 0 ? Math.floor(Math.random() * 3) - 1 : 0;\n const shakeOffsetY = screenShake > 0 ? Math.floor(Math.random() * 2) : 0;\n const displayLeft = gameLeft + shakeOffsetX;\n const displayTop = gameTop + shakeOffsetY;\n\n // Glitchy title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n output += `\\x1b[1;${titleX}H`;\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n // Score display with flash effect\n const scoreColor = scoreFlash > 0 ? '\\x1b[1;93m' : themeColor;\n if (scoreFlash > 0) scoreFlash--;\n const scoreDisplay = `YOU [ ${playerScore} ] - [ ${aiScore} ] CPU`;\n const scoreX = Math.floor((cols - scoreDisplay.length) / 2);\n output += `\\x1b[4;${scoreX}H${scoreColor}${scoreDisplay}\\x1b[0m`;\n\n // Goal flash colors\n const leftBorderColor = goalFlashSide === 'left' ? '\\x1b[1;91m' : themeColor;\n const rightBorderColor = goalFlashSide === 'right' ? '\\x1b[1;92m' : themeColor;\n\n // Wall hit flash for top/bottom borders\n const topBottomBorderColor = wallHitFlash > 0 && wallHitFlash % 4 < 2 ? '\\x1b[1;93m' : themeColor;\n\n // Paddle hit flash for all borders\n const borderFlash = paddleHitFlash > 0 && paddleHitFlash % 4 < 2;\n const mainBorderColor = borderFlash ? '\\x1b[1;96m' : topBottomBorderColor;\n\n // Game border\n output += `\\x1b[${displayTop};${displayLeft}H${mainBorderColor}\\u2554${'═'.repeat(GAME_WIDTH)}\\u2557\\x1b[0m`;\n for (let y = 0; y < GAME_HEIGHT; y++) {\n output += `\\x1b[${displayTop + 1 + y};${displayLeft}H${borderFlash ? '\\x1b[1;96m' : leftBorderColor}\\u2551\\x1b[0m`;\n output += `\\x1b[${displayTop + 1 + y};${displayLeft + GAME_WIDTH + 1}H${borderFlash ? '\\x1b[1;96m' : rightBorderColor}\\u2551\\x1b[0m`;\n }\n output += `\\x1b[${displayTop + GAME_HEIGHT + 1};${displayLeft}H${mainBorderColor}\\u255a${'═'.repeat(GAME_WIDTH)}\\u255d\\x1b[0m`;\n\n // Center line (dashed)\n const centerX = displayLeft + 1 + Math.floor(GAME_WIDTH / 2);\n for (let y = 0; y < GAME_HEIGHT; y++) {\n if (y % 2 === 0) {\n output += `\\x1b[${displayTop + 1 + y};${centerX}H\\x1b[2m${themeColor}\\u2502\\x1b[0m`;\n }\n }\n\n if (paused) {\n const pauseMsg = '\\u2550\\u2550 PAUSED \\u2550\\u2550';\n const pauseCenterX = gameLeft + Math.floor(GAME_WIDTH / 2) + 1;\n const pauseY = gameTop + Math.floor(GAME_HEIGHT / 2) - 3;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO START ]';\n const startX = gameLeft + Math.floor((GAME_WIDTH - startMsg.length) / 2) + 1;\n const startY = gameTop + Math.floor(GAME_HEIGHT / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = '\\u2191\\u2193 MOVE ESC MENU FIRST TO 7 WINS';\n const ctrlX = gameLeft + Math.floor((GAME_WIDTH - controls.length) / 2) + 1;\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n } else if (gameOver) {\n const won = playerScore >= WIN_SCORE;\n const overMsg = won ? '\\u2550\\u2550 YOU WIN! \\u2550\\u2550' : '\\u2550\\u2550 CPU WINS \\u2550\\u2550';\n const overX = gameLeft + Math.floor((GAME_WIDTH - overMsg.length) / 2) + 1;\n const overY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n output += `\\x1b[${overY};${overX}H${won ? '\\x1b[1;92m' : '\\x1b[1;91m'}${overMsg}\\x1b[0m`;\n\n const finalScore = `FINAL: ${playerScore} - ${aiScore}`;\n const scoreX2 = gameLeft + Math.floor((GAME_WIDTH - finalScore.length) / 2) + 1;\n output += `\\x1b[${overY + 2};${scoreX2}H${themeColor}${finalScore}\\x1b[0m`;\n\n const restart = '[ R ] REMATCH [ Q ] QUIT';\n const restartX = gameLeft + Math.floor((GAME_WIDTH - restart.length) / 2) + 1;\n output += `\\x1b[${overY + 4};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n } else {\n // Draw goal explosion particles\n for (const particle of goalExplosion) {\n const px = displayLeft + 1 + Math.floor(particle.x);\n const py = displayTop + 1 + Math.floor(particle.y);\n if (particle.y >= 0 && particle.y < GAME_HEIGHT) {\n output += `\\x1b[${py};${px}H${particle.color}${particle.char}\\x1b[0m`;\n }\n }\n\n // Draw ball trail (only if not in score freeze)\n if (scoreFreeze === 0) {\n for (let i = 0; i < ballTrail.length; i++) {\n const trail = ballTrail[i];\n const trailX = displayLeft + 1 + Math.floor(trail.x);\n const trailY = displayTop + 1 + Math.floor(trail.y);\n const brightness = i < ballTrail.length / 2 ? '\\x1b[2m' : '';\n // Color based on speed\n const trailColor = trail.speed > 0.7 ? '\\x1b[91m' : trail.speed > 0.5 ? '\\x1b[93m' : themeColor;\n output += `\\x1b[${trailY};${trailX}H${brightness}${trailColor}\\u00b7\\x1b[0m`;\n }\n\n // Draw ball with color based on speed\n const ballScreenX = displayLeft + 1 + Math.floor(ballX);\n const ballScreenY = displayTop + 1 + Math.floor(ballY);\n const currentSpeed = Math.sqrt(ballVX * ballVX + ballVY * ballVY);\n const ballColor = currentSpeed > 0.7 ? '\\x1b[1;91m' : currentSpeed > 0.5 ? '\\x1b[1;93m' : '\\x1b[1;97m';\n output += `\\x1b[${ballScreenY};${ballScreenX}H${ballColor}\\u25cf\\x1b[0m`;\n }\n\n // Draw particles\n for (const p of particles) {\n const px = Math.round(displayLeft + 1 + p.x);\n const py = Math.round(displayTop + 1 + p.y);\n if (p.x >= 0 && p.x < GAME_WIDTH && p.y >= 0 && p.y < GAME_HEIGHT) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const px = Math.round(displayLeft + 1 + popup.x);\n const py = Math.round(displayTop + 1 + popup.y);\n if (popup.y >= 0 && popup.y < GAME_HEIGHT) {\n const alpha = popup.frames > 12 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n\n // Draw rally counter\n if (rallyCount >= 3) {\n const rallyMsg = rallyCount >= 10 ? `★ ${rallyCount} RALLY! ★` : `${rallyCount} RALLY!`;\n const rallyX = displayLeft + Math.floor((GAME_WIDTH - rallyMsg.length) / 2) + 1;\n const rallyColor = glitchFrame % 6 < 3 ? '\\x1b[1;93m' : '\\x1b[1;96m';\n output += `\\x1b[${displayTop + 2};${rallyX}H${rallyColor}${rallyMsg}\\x1b[0m`;\n }\n\n // Draw player paddle (left side) with hit flash\n const playerPaddleX = displayLeft + 1 + PADDLE_OFFSET;\n const playerPaddleColor = paddleHitFlash > 0 && paddleHitFlash % 4 < 2 ? '\\x1b[1;97m' : themeColor;\n for (let i = 0; i < PADDLE_HEIGHT; i++) {\n const py = Math.floor(playerY) + i;\n if (py >= 0 && py < GAME_HEIGHT) {\n output += `\\x1b[${displayTop + 1 + py};${playerPaddleX}H${playerPaddleColor}\\u2588\\x1b[0m`;\n }\n }\n\n // Draw AI paddle (right side) with hit flash\n const aiPaddleX = displayLeft + GAME_WIDTH - PADDLE_OFFSET;\n const aiPaddleColor = paddleHitFlash > 0 && paddleHitFlash % 4 < 2 ? '\\x1b[1;97m' : '\\x1b[91m';\n for (let i = 0; i < PADDLE_HEIGHT; i++) {\n const ay = Math.floor(aiY) + i;\n if (ay >= 0 && ay < GAME_HEIGHT) {\n output += `\\x1b[${displayTop + 1 + ay};${aiPaddleX}H${aiPaddleColor}\\u2588\\x1b[0m`;\n }\n }\n\n // Draw score message during freeze\n if (scoreFreeze > 0 && lastScorer) {\n const scoreMsg = lastScorer === 'player' ? '\\u2605 GOAL! \\u2605' : '\\u2716 MISS! \\u2716';\n const msgColor = lastScorer === 'player' ? '\\x1b[1;92m' : '\\x1b[1;91m';\n const msgX = displayLeft + Math.floor((GAME_WIDTH - scoreMsg.length) / 2) + 1;\n const msgY = displayTop + Math.floor(GAME_HEIGHT / 2);\n output += `\\x1b[${msgY};${msgX}H${msgColor}${scoreMsg}\\x1b[0m`;\n }\n }\n\n // Hint\n const hint = gameStarted && !gameOver && !paused ? '[ ESC ] MENU' : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${gameTop + GAME_HEIGHT + 3};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n function update() {\n if (!gameStarted || gameOver || paused) return;\n\n // Handle score freeze (pause after scoring)\n if (scoreFreeze > 0) {\n scoreFreeze--;\n if (screenShake > 0) screenShake--;\n\n // Animate explosion particles outward\n for (const particle of goalExplosion) {\n const dx = particle.x < GAME_WIDTH / 2 ? -0.5 : 0.5;\n particle.x += dx + (Math.random() - 0.5) * 0.3;\n particle.y += (Math.random() - 0.5) * 0.5;\n }\n\n // Clear effects when freeze ends\n if (scoreFreeze === 0) {\n goalExplosion = [];\n goalFlashSide = null;\n lastScorer = null;\n }\n return;\n }\n\n // Update ball trail with speed\n const currentSpeed = Math.sqrt(ballVX * ballVX + ballVY * ballVY);\n ballTrail.push({ x: ballX, y: ballY, speed: currentSpeed });\n if (ballTrail.length > 6) {\n ballTrail.shift();\n }\n\n // Move ball\n ballX += ballVX;\n ballY += ballVY;\n\n // Ball collision with top/bottom walls\n if (ballY <= 0 || ballY >= GAME_HEIGHT - 1) {\n ballVY = -ballVY;\n ballY = Math.max(0, Math.min(GAME_HEIGHT - 1, ballY));\n // Wall hit effects (subtle - no screen shake)\n wallHitFlash = 6;\n spawnParticles(ballX, ballY <= 0 ? 1 : GAME_HEIGHT - 2, 4, '\\x1b[1;93m', ['·', '•', '○']);\n }\n\n // Ball collision with player paddle\n if (ballX <= PADDLE_OFFSET + 1 && ballX >= PADDLE_OFFSET) {\n if (ballY >= playerY && ballY <= playerY + PADDLE_HEIGHT) {\n // Bounce off paddle\n ballVX = Math.abs(ballVX);\n\n // Adjust angle based on where ball hit paddle\n const hitPos = (ballY - playerY) / PADDLE_HEIGHT; // 0 to 1\n const angle = (hitPos - 0.5) * Math.PI / 3; // -30 to +30 degrees\n const speed = Math.min(MAX_BALL_SPEED, Math.sqrt(ballVX * ballVX + ballVY * ballVY) * 1.05);\n\n ballVX = Math.cos(angle) * speed;\n ballVY = Math.sin(angle) * speed;\n\n ballX = PADDLE_OFFSET + 2;\n\n // Rally and effects\n rallyCount++;\n const effectIntensity = Math.min(rallyCount, 10);\n paddleHitFlash = 8;\n // Only shake on high rallies (5+)\n if (rallyCount >= 5) screenShake = Math.floor(effectIntensity / 4);\n spawnParticles(PADDLE_OFFSET + 2, ballY, 4 + Math.floor(effectIntensity / 2), themeColor, ['✦', '★', '◆', '●']);\n\n // Rally popup\n if (rallyCount >= 3 && rallyCount % 3 === 0) {\n addScorePopup(PADDLE_OFFSET + 4, ballY - 1, `${rallyCount}!`, '\\x1b[1;96m');\n }\n }\n }\n\n // Ball collision with AI paddle\n if (ballX >= GAME_WIDTH - PADDLE_OFFSET - 2 && ballX <= GAME_WIDTH - PADDLE_OFFSET - 1) {\n if (ballY >= aiY && ballY <= aiY + PADDLE_HEIGHT) {\n ballVX = -Math.abs(ballVX);\n\n const hitPos = (ballY - aiY) / PADDLE_HEIGHT;\n const angle = (hitPos - 0.5) * Math.PI / 3;\n const speed = Math.min(MAX_BALL_SPEED, Math.sqrt(ballVX * ballVX + ballVY * ballVY) * 1.05);\n\n ballVX = -Math.abs(Math.cos(angle) * speed);\n ballVY = Math.sin(angle) * speed;\n\n ballX = GAME_WIDTH - PADDLE_OFFSET - 3;\n\n // Rally and effects (AI hit)\n rallyCount++;\n const effectIntensity = Math.min(rallyCount, 10);\n paddleHitFlash = 8;\n // Only shake on high rallies (5+)\n if (rallyCount >= 5) screenShake = Math.floor(effectIntensity / 4);\n spawnParticles(GAME_WIDTH - PADDLE_OFFSET - 2, ballY, 4 + Math.floor(effectIntensity / 2), '\\x1b[1;91m', ['✦', '★', '◆', '●']);\n\n // Rally popup\n if (rallyCount >= 3 && rallyCount % 3 === 0) {\n addScorePopup(GAME_WIDTH - PADDLE_OFFSET - 6, ballY - 1, `${rallyCount}!`, '\\x1b[1;91m');\n }\n }\n }\n\n // Scoring\n if (ballX < 0) {\n // AI scores\n aiScore++;\n scoreFlash = 15;\n scoreFreeze = 30; // Pause for celebration\n lastScorer = 'ai';\n screenShake = 8;\n goalFlashSide = 'left';\n createGoalExplosion('left');\n // Score popup\n addScorePopup(GAME_WIDTH / 2 - 3, GAME_HEIGHT / 2 - 2, 'CPU +1', '\\x1b[1;91m');\n // More particles on goal\n spawnParticles(2, ballY, 10, '\\x1b[1;91m', ['✗', '×', '▒', '░']);\n if (aiScore >= WIN_SCORE) {\n gameOver = true;\n scoreFreeze = 0; // Skip freeze on game end\n screenShake = 15;\n spawnParticles(GAME_WIDTH / 2, GAME_HEIGHT / 2, 20, '\\x1b[1;91m', ['✗', '☠', '×', '▓']);\n } else {\n resetBall(true);\n }\n } else if (ballX > GAME_WIDTH - 1) {\n // Player scores\n playerScore++;\n scoreFlash = 15;\n scoreFreeze = 30; // Pause for celebration\n lastScorer = 'player';\n screenShake = 8;\n goalFlashSide = 'right';\n createGoalExplosion('right');\n // Score popup with rally bonus display\n const rallyBonus = rallyCount >= 5 ? ` (${rallyCount} rally!)` : '';\n addScorePopup(GAME_WIDTH / 2 - 2, GAME_HEIGHT / 2 - 2, `+1${rallyBonus}`, '\\x1b[1;92m');\n // More particles on goal\n spawnParticles(GAME_WIDTH - 3, ballY, 10, '\\x1b[1;92m', ['✦', '★', '◆', '●']);\n if (playerScore >= WIN_SCORE) {\n gameOver = true;\n scoreFreeze = 0; // Skip freeze on game end\n screenShake = 15;\n spawnParticles(GAME_WIDTH / 2, GAME_HEIGHT / 2, 20, '\\x1b[1;93m', ['★', '✦', '♦', '◆']);\n } else {\n resetBall(false);\n }\n }\n\n // AI movement\n aiReactionTimer++;\n if (aiReactionTimer >= AI_REACTION_DELAY) {\n aiReactionTimer = 0;\n\n // AI tracks the ball with some prediction\n const targetY = ballY + ballVY * 5; // Predict where ball will be\n const aiCenter = aiY + PADDLE_HEIGHT / 2;\n\n if (targetY < aiCenter - 1) {\n aiY = Math.max(0, aiY - AI_SPEED);\n } else if (targetY > aiCenter + 1) {\n aiY = Math.min(GAME_HEIGHT - PADDLE_HEIGHT, aiY + AI_SPEED);\n }\n }\n }\n\n // Start game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n playerScore = 0;\n aiScore = 0;\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) {\n clearInterval(renderInterval);\n return;\n }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) {\n clearInterval(gameInterval);\n return;\n }\n update();\n }, 30); // Faster update for smoother ball movement\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener.dispose();\n return;\n }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // Handle ESC key - toggle pause (works on start screen too)\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Q to quit (from start screen, pause, or game over)\n if (key === 'q') {\n if (paused || gameOver || !gameStarted) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n }\n\n // Start screen - any key (except ESC/Q handled above) starts the game\n // Skip if paused (ESC menu open on start screen)\n if (!gameStarted && !paused) {\n gameStarted = true;\n return;\n }\n\n if (gameOver) {\n if (key === 'r') {\n playerScore = 0;\n aiScore = 0;\n initGame();\n gameStarted = true;\n }\n return;\n }\n\n // Pause menu actions\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n playerScore = 0;\n aiScore = 0;\n initGame();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (key === 'r') {\n playerScore = 0;\n aiScore = 0;\n initGame();\n gameStarted = true;\n paused = false;\n } else if (key === 'l') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (key === 'n') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n switch (domEvent.key) {\n case 'ArrowUp':\n case 'w':\n if (playerY > 0) playerY -= 1.5;\n break;\n case 'ArrowDown':\n case 's':\n if (playerY < GAME_HEIGHT - PADDLE_HEIGHT) playerY += 1.5;\n break;\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Runner\n *\n * Cyberpunk endless runner game - dodge obstacles,\n * collect power-ups, and survive as long as you can.\n * Subway Surfers-style vertical perspective with cyberpunk aesthetics.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor, getVerticalAnchor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Runner Game Controller\n */\nexport interface RunnerController {\n stop: () => void;\n isRunning: boolean;\n}\n\ninterface Obstacle {\n y: number; // Distance from player (higher = further away)\n lane: number; // 0, 1, 2\n type: 'car' | 'barrier' | 'drone';\n height: 'low' | 'high';\n}\n\ninterface Coin {\n y: number;\n lane: number;\n}\n\ninterface Building {\n y: number;\n side: 'left' | 'right';\n height: number; // 1-3\n style: number; // 0-2\n}\n\ninterface SpeedStreak {\n y: number;\n x: number;\n life: number;\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\n/**\n * Cyberpunk Endless Runner - Vertical perspective\n */\nexport function runRunnerGame(terminal: Terminal): RunnerController {\n const themeColor = getCurrentThemeColor();\n\n // Game dimensions\n const LANES = 3;\n const TRACK_HEIGHT = 14;\n const ROAD_WIDTH_BOTTOM = 24; // Road width at bottom (near player)\n const ROAD_WIDTH_TOP = 6; // Road width at top (horizon)\n const SCENERY_WIDTH = 8; // Space for buildings on each side\n const GAME_WIDTH = ROAD_WIDTH_BOTTOM + SCENERY_WIDTH * 2;\n let gameTop = 5;\n let gameLeft = 4;\n\n // Minimum terminal size\n const MIN_COLS = GAME_WIDTH + 2;\n const MIN_ROWS = TRACK_HEIGHT + 8;\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let score = 0;\n let highScore = 0;\n let distance = 0;\n let speed = 1;\n let coins = 0;\n let combo = 0;\n let comboTimer = 0;\n let nearMissFlash = 0;\n\n // Player state\n let playerLane = 1;\n let isJumping = false;\n let jumpFrame = 0;\n const JUMP_DURATION = 12;\n let isSliding = false;\n let slideFrame = 0;\n const SLIDE_DURATION = 10;\n\n // Game objects\n let obstacles: Obstacle[] = [];\n let coinItems: Coin[] = [];\n let buildings: Building[] = [];\n let speedStreaks: SpeedStreak[] = [];\n let spawnTimer = 0;\n let buildingTimer = 0;\n\n // Visual effects\n let glitchFrame = 0;\n let screenShake = 0;\n let trackOffset = 0;\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let crashFlashFrames = 0;\n let coinFlashFrames = 0;\n let jumpFlashFrames = 0;\n let landingShakeFrames = 0;\n\n const controller: RunnerController = {\n stop: () => {\n if (!running) return;\n running = false;\n // Note: Buffer exit is handled by TerminalPool via dispatchGameQuit\n },\n get isRunning() { return running; }\n };\n\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ █▀█ █ █ █▄ █ █▄ █ █▀▀ █▀█',\n '█▀█ █ █▀▀ ██▄ █▀▄ █▀▄ █▄█ █ ▀█ █ ▀█ ██▄ █▀▄',\n ];\n\n function updateLayout(rows: number, cols: number) {\n gameTop = getVerticalAnchor(rows, TRACK_HEIGHT, {\n headerRows: 4,\n footerRows: 2,\n minTop: 5,\n });\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH) / 2));\n }\n\n // Calculate road width at a given row (0 = top/far, TRACK_HEIGHT-1 = bottom/near)\n function getRoadWidth(row: number): number {\n const t = row / (TRACK_HEIGHT - 1); // 0 to 1\n // Exponential interpolation for perspective\n const factor = Math.pow(t, 0.6);\n return Math.floor(ROAD_WIDTH_TOP + (ROAD_WIDTH_BOTTOM - ROAD_WIDTH_TOP) * factor);\n }\n\n // Spawn particles at position\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['✦', '★', '◆', '●']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.3 + Math.random() * 0.5;\n particles.push({\n x: x,\n y: y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color: color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 12 + Math.floor(Math.random() * 8),\n });\n }\n }\n\n // Add score popup\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 20, color });\n }\n\n function initGame() {\n playerLane = 1;\n isJumping = false;\n isSliding = false;\n jumpFrame = 0;\n slideFrame = 0;\n score = 0;\n distance = 0;\n speed = 1;\n coins = 0;\n combo = 0;\n comboTimer = 0;\n nearMissFlash = 0;\n obstacles = [];\n coinItems = [];\n buildings = [];\n speedStreaks = [];\n spawnTimer = 0;\n buildingTimer = 0;\n gameOver = false;\n paused = false;\n trackOffset = 0;\n // Reset effects\n particles = [];\n scorePopups = [];\n crashFlashFrames = 0;\n coinFlashFrames = 0;\n jumpFlashFrames = 0;\n landingShakeFrames = 0;\n screenShake = 0;\n\n // Spawn initial buildings\n for (let i = 0; i < 8; i++) {\n buildings.push({\n y: i * 2,\n side: i % 2 === 0 ? 'left' : 'right',\n height: Math.floor(Math.random() * 3) + 1,\n style: Math.floor(Math.random() * 3),\n });\n }\n }\n\n function spawnObstacle() {\n if (obstacles.some(o => o.y > TRACK_HEIGHT - 2)) return;\n\n const lane = Math.floor(Math.random() * LANES);\n const types: Obstacle['type'][] = ['car', 'barrier', 'drone'];\n const type = types[Math.floor(Math.random() * types.length)];\n const height: Obstacle['height'] = type === 'drone' ? 'high' : (Math.random() > 0.6 ? 'high' : 'low');\n\n obstacles.push({\n y: TRACK_HEIGHT + 2,\n lane,\n type,\n height,\n });\n\n // Spawn coin in different lane\n if (Math.random() > 0.4) {\n let coinLane = Math.floor(Math.random() * LANES);\n if (coinLane === lane) coinLane = (coinLane + 1) % LANES;\n coinItems.push({\n y: TRACK_HEIGHT + 3 + Math.random() * 2,\n lane: coinLane,\n });\n }\n }\n\n function spawnBuilding() {\n const side = Math.random() > 0.5 ? 'left' : 'right';\n buildings.push({\n y: TRACK_HEIGHT + 2,\n side,\n height: Math.floor(Math.random() * 3) + 1,\n style: Math.floor(Math.random() * 3),\n });\n }\n\n function getJumpHeight(): number {\n if (isJumping) {\n const progress = jumpFrame / JUMP_DURATION;\n return Math.sin(progress * Math.PI) * 2.5;\n }\n return 0;\n }\n\n function checkCollision(): boolean {\n const playerY = 2;\n\n for (const obs of obstacles) {\n if (obs.lane !== playerLane) continue;\n const dist = Math.abs(obs.y - playerY);\n if (dist > 1.5) continue;\n\n // Near miss detection (close but not collision)\n if (dist > 0.8 && dist <= 1.5) {\n // Check if we're actually dodging\n if (obs.height === 'high' && isSliding) continue;\n if (obs.height === 'low' && getJumpHeight() > 0.5) continue;\n }\n\n if (obs.height === 'high' && isSliding) continue;\n if (obs.height === 'low' && getJumpHeight() > 0.5) continue;\n\n return true;\n }\n return false;\n }\n\n function checkNearMiss(): boolean {\n const playerY = 2;\n for (const obs of obstacles) {\n // Check adjacent lanes for near miss\n if (Math.abs(obs.lane - playerLane) === 1 && Math.abs(obs.y - playerY) < 1) {\n return true;\n }\n // Check same lane with jump/slide dodge\n if (obs.lane === playerLane && Math.abs(obs.y - playerY) < 1) {\n if ((obs.height === 'high' && isSliding) || (obs.height === 'low' && getJumpHeight() > 0.5)) {\n return true;\n }\n }\n }\n return false;\n }\n\n function collectCoins() {\n const playerY = 2;\n const newCoins: Coin[] = [];\n const cols = terminal.cols;\n const centerX = Math.max(2, Math.floor((cols - GAME_WIDTH) / 2)) + Math.floor(GAME_WIDTH / 2);\n\n for (const coin of coinItems) {\n if (coin.lane === playerLane && Math.abs(coin.y - playerY) < 1.5) {\n coins++;\n const points = Math.floor(50 * (1 + combo * 0.5));\n score += points;\n\n // Coin collection effects\n coinFlashFrames = 6;\n const roadWidth = getRoadWidth(TRACK_HEIGHT - 1);\n const roadLeft = centerX - Math.floor(roadWidth / 2);\n const coinX = roadLeft + Math.floor(((coin.lane + 0.5) / LANES) * roadWidth);\n const coinY = gameTop + TRACK_HEIGHT - Math.floor(coin.y);\n\n spawnParticles(coinX - gameLeft, coinY - gameTop, 6, '\\x1b[1;93m', ['◆', '★', '●', '♦']);\n addScorePopup(coinX, coinY, `+${points}`, '\\x1b[1;93m');\n } else {\n newCoins.push(coin);\n }\n }\n coinItems = newCoins;\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Update effect timers\n if (crashFlashFrames > 0) crashFlashFrames--;\n if (coinFlashFrames > 0) coinFlashFrames--;\n if (jumpFlashFrames > 0) jumpFlashFrames--;\n if (landingShakeFrames > 0) landingShakeFrames--;\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.03;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.3;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = needWidth && needHeight ? 'Make pane larger' : needWidth ? 'Make pane wider →' : 'Make pane taller ↓';\n const msg2 = `Need: ${MIN_COLS}×${MIN_ROWS} Have: ${cols}×${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n updateLayout(rows, cols);\n const shakeX = screenShake > 0 ? Math.floor(Math.random() * 3) - 1 : 0;\n const actualLeft = gameLeft + shakeX;\n const centerX = actualLeft + Math.floor(GAME_WIDTH / 2);\n\n // Title with glitch effect\n glitchFrame = (glitchFrame + 1) % 80;\n const glitchOffset = glitchFrame >= 75 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n const titleTop = Math.max(1, gameTop - 3);\n if (glitchFrame >= 75 && glitchFrame < 78) {\n output += `\\x1b[${titleTop};${titleX}H\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `\\x1b[${titleTop};${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n // Stats bar with combo indicator\n let stats = `SCORE: ${score.toString().padStart(5, '0')} COINS: ${coins} SPEED: ${speed.toFixed(1)}x`;\n if (combo > 0) {\n stats += ` \\x1b[93mCOMBO x${combo}\\x1b[0m${themeColor}`;\n }\n const statsX = Math.floor((cols - stats.length + (combo > 0 ? 15 : 0)) / 2);\n output += `\\x1b[4;${statsX}H${themeColor}${stats}\\x1b[0m`;\n\n // Near miss flash\n if (nearMissFlash > 0) {\n const flashMsg = '★ NEAR MISS! ★';\n const flashX = Math.floor((cols - flashMsg.length) / 2);\n output += `\\x1b[3;${flashX}H\\x1b[1;93m${flashMsg}\\x1b[0m`;\n }\n\n const trackBottom = gameTop + TRACK_HEIGHT;\n\n // Draw buildings on the sides (background layer)\n for (const bld of buildings) {\n if (bld.y < 0 || bld.y > TRACK_HEIGHT) continue;\n const row = TRACK_HEIGHT - Math.floor(bld.y);\n if (row < 0 || row >= TRACK_HEIGHT) continue;\n\n const screenY = gameTop + row;\n const roadWidth = getRoadWidth(row);\n const roadLeft = centerX - Math.floor(roadWidth / 2);\n const roadRight = centerX + Math.floor(roadWidth / 2);\n\n // Building appearance based on distance and style\n const normalizedDepth = row / TRACK_HEIGHT;\n const dim = normalizedDepth < 0.5 ? '\\x1b[2m' : '';\n\n // Different building styles\n const buildingChars = [\n ['█', '▓', '░'], // Solid building\n ['▐', '│', '░'], // Slim building\n ['◰', '◱', '·'], // Tech building\n ];\n const chars = buildingChars[bld.style];\n\n if (bld.side === 'left') {\n const bldX = roadLeft - 3 - Math.floor(normalizedDepth * 2);\n for (let h = 0; h < bld.height && screenY - h >= gameTop; h++) {\n const char = chars[Math.min(h, chars.length - 1)];\n output += `\\x1b[${screenY - h};${bldX}H${dim}\\x1b[35m${char}${char}\\x1b[0m`;\n }\n } else {\n const bldX = roadRight + 2 + Math.floor(normalizedDepth * 2);\n for (let h = 0; h < bld.height && screenY - h >= gameTop; h++) {\n const char = chars[Math.min(h, chars.length - 1)];\n output += `\\x1b[${screenY - h};${bldX}H${dim}\\x1b[35m${char}${char}\\x1b[0m`;\n }\n }\n }\n\n // Draw speed streaks when going fast\n if (speed > 1.5) {\n for (const streak of speedStreaks) {\n if (streak.life <= 0) continue;\n const intensity = streak.life > 2 ? '│' : streak.life > 1 ? '¦' : '·';\n output += `\\x1b[${streak.y};${streak.x}H\\x1b[2m${themeColor}${intensity}\\x1b[0m`;\n }\n }\n\n // Draw road with proper perspective\n for (let row = 0; row < TRACK_HEIGHT; row++) {\n const screenY = gameTop + row;\n const roadWidth = getRoadWidth(row);\n const roadLeft = centerX - Math.floor(roadWidth / 2);\n const roadRight = centerX + Math.floor(roadWidth / 2);\n const normalizedDepth = row / TRACK_HEIGHT;\n\n // Road edge style based on distance\n const edgeChar = normalizedDepth < 0.2 ? '·' : normalizedDepth < 0.4 ? '│' : normalizedDepth < 0.7 ? '┃' : '█';\n const edgeDim = normalizedDepth < 0.4 ? '\\x1b[2m' : '';\n\n // Draw road edges (solid white lines)\n output += `\\x1b[${screenY};${roadLeft}H${edgeDim}\\x1b[97m${edgeChar}\\x1b[0m`;\n output += `\\x1b[${screenY};${roadRight}H${edgeDim}\\x1b[97m${edgeChar}\\x1b[0m`;\n\n // Road surface (dark fill between edges)\n const surfaceChar = normalizedDepth < 0.3 ? ' ' : normalizedDepth < 0.6 ? '░' : '▒';\n if (normalizedDepth >= 0.3) {\n for (let x = roadLeft + 1; x < roadRight; x++) {\n // Skip lane divider positions\n const laneWidth = (roadRight - roadLeft) / LANES;\n const inLaneDivider = Math.abs((x - roadLeft) % laneWidth) < 0.5;\n if (!inLaneDivider) {\n output += `\\x1b[${screenY};${x}H\\x1b[2m\\x1b[90m${surfaceChar}\\x1b[0m`;\n }\n }\n }\n\n // Lane dividers (dashed white lines)\n const dashPhase = (Math.floor(trackOffset * 3) + row) % 4;\n for (let lane = 1; lane < LANES; lane++) {\n const laneX = roadLeft + Math.floor((lane / LANES) * roadWidth);\n const laneDim = normalizedDepth < 0.4 ? '\\x1b[2m' : '';\n\n if (dashPhase < 2) {\n // Dashed line - visible\n const laneChar = normalizedDepth < 0.25 ? '·' : normalizedDepth < 0.5 ? '¦' : '│';\n output += `\\x1b[${screenY};${laneX}H${laneDim}\\x1b[97m${laneChar}\\x1b[0m`;\n } else {\n // Gap in dashed line\n if (normalizedDepth >= 0.3) {\n output += `\\x1b[${screenY};${laneX}H\\x1b[2m\\x1b[90m${surfaceChar}\\x1b[0m`;\n }\n }\n }\n }\n\n if (paused) {\n const pauseMsg = '══ PAUSED ══';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseY = gameTop + Math.floor(TRACK_HEIGHT / 2) - 2;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO RUN ]';\n const startX = Math.floor((cols - startMsg.length) / 2);\n const startY = gameTop + Math.floor(TRACK_HEIGHT / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = '←→ LANE ↑/SPC JUMP ↓ SLIDE ESC MENU';\n const ctrlX = Math.floor((cols - controls.length) / 2);\n output += `\\x1b[${trackBottom + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n } else if (gameOver) {\n // Flashing crash banner\n const crashColor = crashFlashFrames > 0 && crashFlashFrames % 4 < 2 ? '\\x1b[41;97m' : '\\x1b[1;91m';\n const overMsg = '╔══ CRASHED! ══╗';\n const overX = Math.floor((cols - overMsg.length) / 2);\n const overY = gameTop + Math.floor(TRACK_HEIGHT / 2) - 1;\n output += `\\x1b[${overY};${overX}H${crashColor}${overMsg}\\x1b[0m`;\n\n const scoreLine = ` DISTANCE: ${Math.floor(distance)}m `;\n const coinsLine = ` COINS: ${coins} SCORE: ${score} `;\n output += `\\x1b[${overY + 1};${Math.floor((cols - scoreLine.length) / 2)}H${themeColor}${scoreLine}\\x1b[0m`;\n output += `\\x1b[${overY + 2};${Math.floor((cols - coinsLine.length) / 2)}H${themeColor}${coinsLine}\\x1b[0m`;\n\n const restart = '╚ [R] RESTART [Q] QUIT ╝';\n output += `\\x1b[${overY + 3};${Math.floor((cols - restart.length) / 2)}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n\n // Draw crash particles even on game over screen\n for (const p of particles) {\n const px = Math.round(actualLeft + p.x);\n const py = Math.round(gameTop + p.y);\n if (px > actualLeft && px < actualLeft + GAME_WIDTH && py >= gameTop && py < trackBottom) {\n const alpha = p.life > 6 ? '' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n } else {\n // Draw coins\n for (const coin of coinItems) {\n if (coin.y < 0 || coin.y > TRACK_HEIGHT) continue;\n const row = TRACK_HEIGHT - Math.floor(coin.y);\n if (row < 0 || row >= TRACK_HEIGHT) continue;\n\n const screenY = gameTop + row;\n const roadWidth = getRoadWidth(row);\n const roadLeft = centerX - Math.floor(roadWidth / 2);\n const coinX = roadLeft + Math.floor(((coin.lane + 0.5) / LANES) * roadWidth);\n const normalizedDepth = row / TRACK_HEIGHT;\n\n const coinChar = normalizedDepth < 0.3 ? '·' : normalizedDepth < 0.6 ? '●' : '◉';\n const coinDim = normalizedDepth < 0.4 ? '\\x1b[2m' : '\\x1b[1m';\n output += `\\x1b[${screenY};${coinX}H${coinDim}\\x1b[93m${coinChar}\\x1b[0m`;\n }\n\n // Draw obstacles\n for (const obs of obstacles) {\n if (obs.y < 0 || obs.y > TRACK_HEIGHT + 1) continue;\n const row = TRACK_HEIGHT - Math.floor(obs.y);\n if (row < 0 || row >= TRACK_HEIGHT) continue;\n\n const screenY = gameTop + row;\n const roadWidth = getRoadWidth(row);\n const roadLeft = centerX - Math.floor(roadWidth / 2);\n const obsCenter = roadLeft + Math.floor(((obs.lane + 0.5) / LANES) * roadWidth);\n const normalizedDepth = row / TRACK_HEIGHT;\n\n let obsChar: string;\n let obsColor: string;\n\n // Scale obstacle size with perspective\n if (normalizedDepth < 0.25) {\n // Far - tiny\n if (obs.type === 'car') { obsChar = '▪'; obsColor = '\\x1b[91m'; }\n else if (obs.type === 'drone') { obsChar = '·'; obsColor = '\\x1b[95m'; }\n else { obsChar = '▬'; obsColor = '\\x1b[93m'; }\n } else if (normalizedDepth < 0.5) {\n // Medium distance\n if (obs.type === 'car') { obsChar = '▐▌'; obsColor = '\\x1b[91m'; }\n else if (obs.type === 'drone') { obsChar = '◇'; obsColor = '\\x1b[95m'; }\n else { obsChar = '▄▄'; obsColor = '\\x1b[93m'; }\n } else if (normalizedDepth < 0.75) {\n // Closer\n if (obs.type === 'car') { obsChar = '▐█▌'; obsColor = '\\x1b[91m'; }\n else if (obs.type === 'drone') { obsChar = '◆◇◆'; obsColor = '\\x1b[95m'; }\n else { obsChar = '███'; obsColor = '\\x1b[93m'; }\n } else {\n // Near - largest\n if (obs.type === 'car') { obsChar = '▐███▌'; obsColor = '\\x1b[1;91m'; }\n else if (obs.type === 'drone') { obsChar = '◆◆◆◆'; obsColor = '\\x1b[1;95m'; }\n else { obsChar = '█████'; obsColor = '\\x1b[1;93m'; }\n }\n\n const obsX = obsCenter - Math.floor(obsChar.length / 2);\n const obsDim = normalizedDepth < 0.35 ? '\\x1b[2m' : '';\n output += `\\x1b[${screenY};${obsX}H${obsDim}${obsColor}${obsChar}\\x1b[0m`;\n\n // Draw top row for tall obstacles when close\n if (obs.height === 'high' && normalizedDepth > 0.6 && row > 0) {\n const topChar = obs.type === 'drone' ? '◆◆◆◆' : obs.type === 'car' ? '▐▀▀▀▌' : '█████';\n output += `\\x1b[${screenY - 1};${obsX}H${obsColor}${topChar}\\x1b[0m`;\n }\n }\n\n // Draw player\n const playerRow = TRACK_HEIGHT - 1;\n const playerScreenY = gameTop + playerRow;\n const roadWidth = getRoadWidth(playerRow);\n const roadLeft = centerX - Math.floor(roadWidth / 2);\n const playerCenter = roadLeft + Math.floor(((playerLane + 0.5) / LANES) * roadWidth);\n\n let playerChars: string[];\n let playerColor = themeColor;\n const jumpHeight = getJumpHeight();\n\n if (isJumping) {\n playerChars = ['╱▲╲', ' ▼ '];\n playerColor = '\\x1b[1m' + themeColor;\n } else if (isSliding) {\n playerChars = ['▬▬▬'];\n playerColor = themeColor;\n } else {\n const runFrame = Math.floor(distance * 3) % 4;\n if (runFrame === 0) playerChars = ['◢█◣', '╱ ╲'];\n else if (runFrame === 1) playerChars = ['◢█◣', '│ │'];\n else if (runFrame === 2) playerChars = ['◢█◣', '╲ ╱'];\n else playerChars = ['◢█◣', '│ │'];\n }\n\n const playerX = playerCenter - Math.floor(playerChars[0].length / 2);\n const playerYOffset = Math.floor(jumpHeight);\n const finalPlayerY = playerScreenY - playerYOffset;\n\n // Draw player character (multi-row)\n for (let i = 0; i < playerChars.length; i++) {\n if (finalPlayerY - (playerChars.length - 1 - i) >= gameTop) {\n output += `\\x1b[${finalPlayerY - (playerChars.length - 1 - i)};${playerX}H${playerColor}${playerChars[i]}\\x1b[0m`;\n }\n }\n\n // Shadow when jumping\n if (jumpHeight > 0.5) {\n const shadowSize = Math.max(1, 3 - Math.floor(jumpHeight));\n const shadow = '░'.repeat(shadowSize);\n output += `\\x1b[${playerScreenY};${playerCenter - Math.floor(shadowSize / 2)}H\\x1b[2m${themeColor}${shadow}\\x1b[0m`;\n }\n\n // Draw particles\n for (const p of particles) {\n const px = Math.round(actualLeft + p.x);\n const py = Math.round(gameTop + p.y);\n if (px > actualLeft && px < actualLeft + GAME_WIDTH && py >= gameTop && py < trackBottom) {\n const alpha = p.life > 6 ? '' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const px = Math.round(popup.x);\n const py = Math.round(popup.y);\n if (py >= gameTop && py < trackBottom) {\n const alpha = popup.frames > 10 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n }\n\n // Bottom hint\n const hint = gameStarted && !gameOver && !paused ? `HIGH: ${highScore} [ ESC ] MENU` : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${trackBottom + 1};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n function update() {\n if (!gameStarted || gameOver || paused) return;\n\n if (screenShake > 0) screenShake--;\n if (nearMissFlash > 0) nearMissFlash--;\n if (comboTimer > 0) {\n comboTimer--;\n if (comboTimer === 0) combo = 0;\n }\n\n trackOffset += speed * 0.4;\n\n // Update jump\n if (isJumping) {\n jumpFrame++;\n if (jumpFrame >= JUMP_DURATION) {\n isJumping = false;\n jumpFrame = 0;\n }\n }\n\n // Update slide\n if (isSliding) {\n slideFrame++;\n if (slideFrame >= SLIDE_DURATION) {\n isSliding = false;\n slideFrame = 0;\n }\n }\n\n // Move objects\n const moveSpeed = 0.35 * speed;\n obstacles = obstacles.filter(obs => {\n obs.y -= moveSpeed;\n return obs.y > -2;\n });\n coinItems = coinItems.filter(coin => {\n coin.y -= moveSpeed;\n return coin.y > -2;\n });\n buildings = buildings.filter(bld => {\n bld.y -= moveSpeed * 0.7; // Buildings move slower (parallax)\n return bld.y > -3;\n });\n\n // Update speed streaks\n if (speed > 1.5 && Math.random() > 0.7) {\n speedStreaks.push({\n y: gameTop + Math.floor(Math.random() * TRACK_HEIGHT),\n x: gameLeft + Math.floor(Math.random() * GAME_WIDTH),\n life: 3,\n });\n }\n speedStreaks = speedStreaks.filter(s => {\n s.life--;\n return s.life > 0;\n });\n\n // Spawn obstacles\n spawnTimer++;\n const spawnRate = Math.max(15, 35 - speed * 6);\n if (spawnTimer >= spawnRate) {\n spawnTimer = 0;\n spawnObstacle();\n }\n\n // Spawn buildings\n buildingTimer++;\n if (buildingTimer >= 20) {\n buildingTimer = 0;\n spawnBuilding();\n }\n\n // Near miss detection\n if (checkNearMiss()) {\n combo++;\n comboTimer = 40; // Combo lasts ~2 seconds\n nearMissFlash = 10;\n const nearMissPoints = 25 * combo;\n score += nearMissPoints;\n\n // Near miss effects - just particles, no popup (combo counter shows progress)\n const cols = terminal.cols;\n const centerX = Math.max(2, Math.floor((cols - GAME_WIDTH) / 2)) + Math.floor(GAME_WIDTH / 2);\n const roadWidth = getRoadWidth(TRACK_HEIGHT - 1);\n const roadLeft = centerX - Math.floor(roadWidth / 2);\n const playerCenter = roadLeft + Math.floor(((playerLane + 0.5) / LANES) * roadWidth);\n spawnParticles(playerCenter - gameLeft, TRACK_HEIGHT - 2, 4, '\\x1b[96m', ['✦', '★', '◇']);\n }\n\n collectCoins();\n\n if (checkCollision()) {\n gameOver = true;\n screenShake = 15;\n crashFlashFrames = 20;\n if (score > highScore) highScore = score;\n\n // Crash particles\n const cols = terminal.cols;\n const centerX = Math.max(2, Math.floor((cols - GAME_WIDTH) / 2)) + Math.floor(GAME_WIDTH / 2);\n const roadWidth = getRoadWidth(TRACK_HEIGHT - 1);\n const roadLeft = centerX - Math.floor(roadWidth / 2);\n const playerCenter = roadLeft + Math.floor(((playerLane + 0.5) / LANES) * roadWidth);\n spawnParticles(playerCenter - gameLeft, TRACK_HEIGHT - 1, 15, '\\x1b[1;91m', ['✗', '☠', '×', '▓', '░']);\n return;\n }\n\n distance += 0.18 * speed;\n score += Math.floor(speed * (1 + combo * 0.1));\n speed = Math.min(4, 1 + Math.floor(distance / 60) * 0.3);\n }\n\n // Start game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) { clearInterval(gameInterval); return; }\n update();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // Handle ESC key - toggle pause (works on start screen too)\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Q to quit (from start screen, pause, or game over)\n if (key === 'q') {\n if (paused || gameOver || !gameStarted) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n }\n\n // Start screen - any key (except ESC/Q handled above) starts the game\n // Skip if paused (ESC menu open on start screen)\n if (!gameStarted && !paused) {\n gameStarted = true;\n return;\n }\n\n if (gameOver) {\n if (key === 'r') {\n initGame();\n gameStarted = true;\n }\n return;\n }\n\n // Pause menu actions\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n initGame();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (key === 'r') {\n initGame();\n gameStarted = true;\n paused = false;\n } else if (key === 'l') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (key === 'n') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n switch (domEvent.key) {\n case 'ArrowLeft':\n case 'a':\n if (playerLane > 0) playerLane--;\n break;\n case 'ArrowRight':\n case 'd':\n if (playerLane < LANES - 1) playerLane++;\n break;\n case 'ArrowUp':\n case 'w':\n case ' ':\n if (!isJumping && !isSliding) {\n isJumping = true;\n jumpFrame = 0;\n }\n break;\n case 'ArrowDown':\n case 's':\n if (!isJumping && !isSliding) {\n isSliding = true;\n slideFrame = 0;\n }\n break;\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Simon\n *\n * Cyberpunk memory sequence game - \"hack the mainframe\" by repeating patterns.\n * Features 4 quadrants (1/2/3/4 or arrow keys), visual flash effects,\n * speed increases, and particle bursts on success.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Simon Game Controller\n */\nexport interface SimonController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\ntype Quadrant = 0 | 1 | 2 | 3; // 0=top, 1=right, 2=bottom, 3=left\n\n// ============================================================================\n// MAIN GAME FUNCTION\n// ============================================================================\n\nexport function runSimonGame(terminal: Terminal): SimonController {\n const themeColor = getCurrentThemeColor();\n\n // -------------------------------------------------------------------------\n // CONSTANTS\n // -------------------------------------------------------------------------\n const MIN_COLS = 40;\n const MIN_ROWS = 18;\n const GAME_WIDTH = 40;\n const GAME_HEIGHT = 18;\n\n // Quadrant colors\n const QUADRANT_COLORS = [\n '\\x1b[1;91m', // 0 - Top (Red)\n '\\x1b[1;92m', // 1 - Right (Green)\n '\\x1b[1;94m', // 2 - Bottom (Blue)\n '\\x1b[1;93m', // 3 - Left (Yellow)\n ];\n\n const QUADRANT_DIM_COLORS = [\n '\\x1b[2;31m', // 0 - Top (Dim Red)\n '\\x1b[2;32m', // 1 - Right (Dim Green)\n '\\x1b[2;34m', // 2 - Bottom (Dim Blue)\n '\\x1b[2;33m', // 3 - Left (Dim Yellow)\n ];\n\n const QUADRANT_CHARS = ['1', '2', '3', '4'];\n const QUADRANT_NAMES = ['UP', 'RIGHT', 'DOWN', 'LEFT'];\n\n // Timing\n const BASE_FLASH_DURATION = 12; // frames\n const BASE_PAUSE_DURATION = 6; // frames between flashes\n const SPEED_MULTIPLIER = 0.92; // Speed up each round\n\n // -------------------------------------------------------------------------\n // STATE\n // -------------------------------------------------------------------------\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let won = false;\n let score = 0;\n let highScore = 0;\n\n // Positioning\n let gameLeft = 2;\n let gameTop = 5;\n\n // Visual effects\n let glitchFrame = 0;\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let shakeFrames = 0;\n let shakeIntensity = 0;\n\n // Simon-specific state\n let sequence: Quadrant[] = [];\n let playerIndex = 0;\n let currentRound = 1;\n let flashSpeed = 1.0;\n\n // Animation states\n type GamePhase = 'waiting' | 'showing' | 'player_turn' | 'success' | 'failure';\n let phase: GamePhase = 'waiting';\n let showingIndex = 0;\n let flashTimer = 0;\n let pauseTimer = 0;\n let successTimer = 0;\n let failureTimer = 0;\n\n // Which quadrant is currently lit\n let litQuadrant: Quadrant | null = null;\n let playerLitQuadrant: Quadrant | null = null;\n let playerLitTimer = 0;\n\n // Message display\n let statusMessage = '';\n let statusColor = themeColor;\n let statusBlink = false;\n\n // Suppress unused variable warnings\n void won;\n void failureTimer;\n\n // -------------------------------------------------------------------------\n // CONTROLLER\n // -------------------------------------------------------------------------\n const controller: SimonController = {\n stop: () => {\n if (!running) return;\n running = false;\n },\n get isRunning() { return running; }\n };\n\n // -------------------------------------------------------------------------\n // ASCII ART TITLE\n // -------------------------------------------------------------------------\n const title = [\n '\\u2588 \\u2588 \\u2588\\u2584\\u2588 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2580 \\u2588 \\u2588\\u2580\\u2580\\u2588 \\u2580\\u2588\\u2580\\u2588 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2588',\n '\\u2588\\u2580\\u2588 \\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2588\\u2584 \\u2588\\u2580\\u2584 \\u2584\\u2584\\u2588 \\u2588 \\u2588\\u2588\\u2584 \\u2588 \\u2588 \\u2588 \\u2588\\u2580\\u2584 \\u2588 \\u2588',\n ];\n\n // -------------------------------------------------------------------------\n // EFFECTS\n // -------------------------------------------------------------------------\n\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['\\u2726', '\\u2605', '\\u25C6', '\\u25CF']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.3 + Math.random() * 0.5;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 12 + Math.floor(Math.random() * 8),\n });\n }\n }\n\n function spawnBurstParticles(quadrant: Quadrant) {\n const centerX = GAME_WIDTH / 2;\n const centerY = GAME_HEIGHT / 2;\n const offset = 5;\n\n let x = centerX;\n let y = centerY;\n\n switch (quadrant) {\n case 0: y = centerY - offset; break;\n case 1: x = centerX + offset * 2; break;\n case 2: y = centerY + offset; break;\n case 3: x = centerX - offset * 2; break;\n }\n\n spawnParticles(x, y, 8, QUADRANT_COLORS[quadrant], ['\\u2726', '\\u2605', '\\u25C6', '\\u25CF']);\n }\n\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 20, color });\n }\n\n function triggerShake(frames: number, intensity: number) {\n shakeFrames = frames;\n shakeIntensity = intensity;\n }\n\n // -------------------------------------------------------------------------\n // GAME LOGIC\n // -------------------------------------------------------------------------\n\n function initGame() {\n score = 0;\n gameOver = false;\n won = false;\n paused = false;\n\n // Reset effects\n particles = [];\n scorePopups = [];\n shakeFrames = 0;\n\n // Reset Simon state\n sequence = [];\n playerIndex = 0;\n currentRound = 1;\n flashSpeed = 1.0;\n phase = 'waiting';\n showingIndex = 0;\n flashTimer = 0;\n pauseTimer = 0;\n successTimer = 0;\n failureTimer = 0;\n litQuadrant = null;\n playerLitQuadrant = null;\n playerLitTimer = 0;\n\n statusMessage = 'INITIATING SEQUENCE...';\n statusColor = themeColor;\n statusBlink = true;\n\n // Start first round after brief delay\n setTimeout(() => {\n if (running && gameStarted && !paused && !gameOver) {\n startNewRound();\n }\n }, 1000);\n }\n\n function startNewRound() {\n // Add a new random quadrant to the sequence\n sequence.push(Math.floor(Math.random() * 4) as Quadrant);\n\n // Start showing the sequence\n phase = 'showing';\n showingIndex = 0;\n flashTimer = 0;\n pauseTimer = Math.floor(BASE_PAUSE_DURATION * 2); // Initial pause before showing\n\n statusMessage = `LEVEL ${currentRound}: DECRYPTING...`;\n statusColor = '\\x1b[1;96m';\n statusBlink = false;\n }\n\n function handlePlayerInput(quadrant: Quadrant) {\n if (phase !== 'player_turn' || paused || gameOver) return;\n\n // Light up the quadrant player pressed\n playerLitQuadrant = quadrant;\n playerLitTimer = 8;\n\n // Check if correct\n if (quadrant === sequence[playerIndex]) {\n // Correct!\n playerIndex++;\n spawnBurstParticles(quadrant);\n\n if (playerIndex >= sequence.length) {\n // Completed the sequence!\n phase = 'success';\n successTimer = 30;\n score += currentRound * 10;\n\n const centerX = GAME_WIDTH / 2;\n const centerY = GAME_HEIGHT / 2;\n addScorePopup(centerX - 2, centerY - 2, `+${currentRound * 10}`, '\\x1b[1;92m');\n\n // Big particle burst\n spawnParticles(centerX, centerY, 20, '\\x1b[1;92m', ['\\u2726', '\\u2605', '\\u2606', '\\u25C8']);\n\n statusMessage = 'PATTERN ACCEPTED';\n statusColor = '\\x1b[1;92m';\n statusBlink = true;\n\n triggerShake(6, 1);\n }\n } else {\n // Wrong!\n phase = 'failure';\n failureTimer = 40;\n gameOver = true;\n\n if (score > highScore) {\n highScore = score;\n }\n\n statusMessage = 'ACCESS DENIED';\n statusColor = '\\x1b[1;91m';\n statusBlink = true;\n\n triggerShake(15, 3);\n\n // Error particles\n const centerX = GAME_WIDTH / 2;\n const centerY = GAME_HEIGHT / 2;\n spawnParticles(centerX, centerY, 15, '\\x1b[1;91m', ['\\u2717', '\\u2716', '\\u00D7', '\\u2573']);\n }\n }\n\n function update() {\n if (!gameStarted || gameOver || paused) return;\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.03;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.2;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n // Update player lit timer\n if (playerLitTimer > 0) {\n playerLitTimer--;\n if (playerLitTimer <= 0) {\n playerLitQuadrant = null;\n }\n }\n\n // Phase-specific updates\n switch (phase) {\n case 'showing':\n updateShowingPhase();\n break;\n case 'success':\n updateSuccessPhase();\n break;\n }\n }\n\n function updateShowingPhase() {\n const flashDuration = Math.floor(BASE_FLASH_DURATION * flashSpeed);\n const pauseDuration = Math.floor(BASE_PAUSE_DURATION * flashSpeed);\n\n if (pauseTimer > 0) {\n // Waiting between flashes\n pauseTimer--;\n litQuadrant = null;\n return;\n }\n\n if (flashTimer > 0) {\n // Currently showing a quadrant\n flashTimer--;\n if (flashTimer <= 0) {\n litQuadrant = null;\n showingIndex++;\n\n if (showingIndex >= sequence.length) {\n // Done showing, player's turn\n phase = 'player_turn';\n playerIndex = 0;\n statusMessage = 'YOUR TURN: REPEAT PATTERN';\n statusColor = '\\x1b[1;93m';\n statusBlink = true;\n } else {\n pauseTimer = pauseDuration;\n }\n }\n return;\n }\n\n // Start showing next quadrant\n if (showingIndex < sequence.length) {\n litQuadrant = sequence[showingIndex];\n flashTimer = flashDuration;\n }\n }\n\n function updateSuccessPhase() {\n successTimer--;\n if (successTimer <= 0) {\n // Start next round\n currentRound++;\n playerIndex = 0;\n flashSpeed *= SPEED_MULTIPLIER;\n startNewRound();\n }\n }\n\n // -------------------------------------------------------------------------\n // RENDERING\n // -------------------------------------------------------------------------\n\n function renderQuadrant(output: string[], quadrant: Quadrant, isLit: boolean, renderLeft: number, renderTop: number): void {\n const centerX = Math.floor(GAME_WIDTH / 2);\n const centerY = Math.floor(GAME_HEIGHT / 2);\n const color = isLit ? QUADRANT_COLORS[quadrant] : QUADRANT_DIM_COLORS[quadrant];\n\n // Quadrant dimensions\n const qWidth = 12;\n const qHeight = 4;\n\n let startX = renderLeft + 1;\n let startY = renderTop + 1;\n\n // Position based on quadrant\n switch (quadrant) {\n case 0: // Top\n startX = renderLeft + centerX - Math.floor(qWidth / 2);\n startY = renderTop + 2;\n break;\n case 1: // Right\n startX = renderLeft + centerX + 3;\n startY = renderTop + centerY - Math.floor(qHeight / 2);\n break;\n case 2: // Bottom\n startX = renderLeft + centerX - Math.floor(qWidth / 2);\n startY = renderTop + GAME_HEIGHT - qHeight - 1;\n break;\n case 3: // Left\n startX = renderLeft + centerX - qWidth - 2;\n startY = renderTop + centerY - Math.floor(qHeight / 2);\n break;\n }\n\n // Draw quadrant box\n const fillChar = isLit ? '\\u2588' : '\\u2591';\n const topBorder = '\\u250C' + '\\u2500'.repeat(qWidth) + '\\u2510';\n const bottomBorder = '\\u2514' + '\\u2500'.repeat(qWidth) + '\\u2518';\n\n output.push(`\\x1b[${startY};${startX}H${color}${topBorder}\\x1b[0m`);\n\n for (let row = 0; row < qHeight; row++) {\n const y = startY + 1 + row;\n // Draw filled or empty content\n if (row === Math.floor(qHeight / 2)) {\n // Center row with label\n const label = `${QUADRANT_NAMES[quadrant]} [${QUADRANT_CHARS[quadrant]}]`;\n const padding = Math.floor((qWidth - label.length) / 2);\n const leftPad = fillChar.repeat(Math.max(0, padding));\n const rightPad = fillChar.repeat(Math.max(0, qWidth - padding - label.length));\n output.push(`\\x1b[${y};${startX}H${color}\\u2502${leftPad}${isLit ? '\\x1b[1;97m' : '\\x1b[2m'}${label}${color}${rightPad}\\u2502\\x1b[0m`);\n } else {\n output.push(`\\x1b[${y};${startX}H${color}\\u2502${fillChar.repeat(qWidth)}\\u2502\\x1b[0m`);\n }\n }\n\n output.push(`\\x1b[${startY + qHeight + 1};${startX}H${color}${bottomBorder}\\x1b[0m`);\n }\n\n function render() {\n const outputParts: string[] = [];\n outputParts.push('\\x1b[2J\\x1b[H');\n\n // Effect timers\n if (shakeFrames > 0) shakeFrames--;\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n const hint = needWidth && needHeight ? 'Make pane larger'\n : needWidth ? 'Make pane wider \\u2192' : 'Make pane taller \\u2193';\n const msg2 = `Need: ${MIN_COLS}\\u00D7${MIN_ROWS} Have: ${cols}\\u00D7${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n outputParts.push(`\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`);\n outputParts.push(`\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`);\n outputParts.push(`\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`);\n terminal.write(outputParts.join(''));\n return;\n }\n\n // Center game area\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH - 2) / 2));\n gameTop = Math.max(4, Math.floor((rows - GAME_HEIGHT - 8) / 2));\n\n // Apply screen shake\n let renderLeft = gameLeft;\n let renderTop = gameTop;\n if (shakeFrames > 0) {\n renderLeft += Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n renderTop += Math.floor((Math.random() - 0.5) * shakeIntensity);\n }\n\n // Glitch title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n if (glitchFrame >= 55 && glitchFrame < 58) {\n outputParts.push(`\\x1b[1;${titleX}H\\x1b[91m${title[0]}\\x1b[0m`);\n outputParts.push(`\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`);\n } else {\n outputParts.push(`\\x1b[1;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`);\n outputParts.push(`\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`);\n }\n\n // Stats bar\n const stats = `LEVEL: ${currentRound} SCORE: ${score.toString().padStart(5, '0')} HIGH: ${highScore.toString().padStart(5, '0')}`;\n const statsX = Math.floor((cols - stats.length) / 2);\n outputParts.push(`\\x1b[${gameTop - 1};${statsX}H${themeColor}${stats}\\x1b[0m`);\n\n // Game border\n outputParts.push(`\\x1b[${renderTop};${renderLeft}H${themeColor}\\u2554${'\\u2550'.repeat(GAME_WIDTH)}\\u2557\\x1b[0m`);\n for (let y = 0; y < GAME_HEIGHT; y++) {\n outputParts.push(`\\x1b[${renderTop + 1 + y};${renderLeft}H${themeColor}\\u2551\\x1b[0m`);\n outputParts.push(`\\x1b[${renderTop + 1 + y};${renderLeft + GAME_WIDTH + 1}H${themeColor}\\u2551\\x1b[0m`);\n }\n outputParts.push(`\\x1b[${renderTop + GAME_HEIGHT + 1};${renderLeft}H${themeColor}\\u255A${'\\u2550'.repeat(GAME_WIDTH)}\\u255D\\x1b[0m`);\n\n // PAUSE MENU\n if (paused) {\n const pauseMsg = '\\u2550\\u2550 PAUSED \\u2550\\u2550';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseY = gameTop + Math.floor(GAME_HEIGHT / 2) - 2;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n outputParts.push(`\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`);\n\n outputParts.push(renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n }));\n\n const navHint = '\\u2191\\u2193 select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n outputParts.push(`\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`);\n }\n // START SCREEN\n else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO HACK ]';\n const startX = gameLeft + Math.floor((GAME_WIDTH - startMsg.length) / 2) + 1;\n const startY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n outputParts.push(`\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`);\n\n const controls = '\\u2191\\u2193\\u2190\\u2192 or 1234 to match pattern';\n const ctrlX = gameLeft + Math.floor((GAME_WIDTH - controls.length) / 2) + 1;\n outputParts.push(`\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`);\n\n const desc = 'Watch. Remember. Repeat.';\n const descX = gameLeft + Math.floor((GAME_WIDTH - desc.length) / 2) + 1;\n outputParts.push(`\\x1b[${startY + 4};${descX}H\\x1b[2m${themeColor}${desc}\\x1b[0m`);\n }\n // GAME OVER\n else if (gameOver) {\n // Draw quadrants dimmed\n for (let q = 0; q < 4; q++) {\n renderQuadrant(outputParts, q as Quadrant, false, renderLeft, renderTop);\n }\n\n const overMsg = '\\u2554\\u2550\\u2550 SECURITY LOCKOUT \\u2550\\u2550\\u2557';\n const overX = gameLeft + Math.floor((GAME_WIDTH - overMsg.length) / 2) + 1;\n const overY = gameTop + Math.floor(GAME_HEIGHT / 2) - 2;\n outputParts.push(`\\x1b[${overY};${overX}H\\x1b[1;91m${overMsg}\\x1b[0m`);\n\n const scoreLine = `LEVELS CLEARED: ${currentRound - 1} SCORE: ${score}`;\n const scoreX = gameLeft + Math.floor((GAME_WIDTH - scoreLine.length) / 2) + 1;\n outputParts.push(`\\x1b[${overY + 1};${scoreX}H${themeColor}${scoreLine}\\x1b[0m`);\n\n const highLine = score >= highScore ? '\\u2606 NEW HIGH SCORE! \\u2606' : `HIGH SCORE: ${highScore}`;\n const highX = gameLeft + Math.floor((GAME_WIDTH - highLine.length) / 2) + 1;\n const highColor = score >= highScore ? '\\x1b[1;93m' : themeColor;\n outputParts.push(`\\x1b[${overY + 2};${highX}H${highColor}${highLine}\\x1b[0m`);\n\n const restart = '\\u255A [R] RESTART [Q] QUIT \\u255D';\n const restartX = gameLeft + Math.floor((GAME_WIDTH - restart.length) / 2) + 1;\n outputParts.push(`\\x1b[${overY + 4};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`);\n }\n // GAMEPLAY\n else {\n // Determine which quadrant is lit\n const activeLit = playerLitQuadrant !== null ? playerLitQuadrant : litQuadrant;\n\n // Draw all quadrants\n for (let q = 0; q < 4; q++) {\n renderQuadrant(outputParts, q as Quadrant, activeLit === q, renderLeft, renderTop);\n }\n\n // Status message in center\n const blinkStyle = statusBlink && glitchFrame % 20 < 10 ? '\\x1b[5m' : '';\n const msgX = gameLeft + Math.floor((GAME_WIDTH - statusMessage.length) / 2) + 1;\n const msgY = gameTop + Math.floor(GAME_HEIGHT / 2);\n outputParts.push(`\\x1b[${msgY};${msgX}H${blinkStyle}${statusColor}${statusMessage}\\x1b[0m`);\n\n // Progress indicator during player turn\n if (phase === 'player_turn') {\n const progress = `[${playerIndex + 1}/${sequence.length}]`;\n const progX = gameLeft + Math.floor((GAME_WIDTH - progress.length) / 2) + 1;\n outputParts.push(`\\x1b[${msgY + 1};${progX}H\\x1b[2m${themeColor}${progress}\\x1b[0m`);\n }\n\n // Draw particles\n for (const p of particles) {\n const screenX = Math.round(renderLeft + 1 + p.x);\n const screenY = Math.round(renderTop + 1 + p.y);\n if (screenX > renderLeft && screenX < renderLeft + GAME_WIDTH + 1 &&\n screenY > renderTop && screenY < renderTop + GAME_HEIGHT + 1) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n outputParts.push(`\\x1b[${screenY};${screenX}H${alpha}${p.color}${p.char}\\x1b[0m`);\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const screenX = Math.round(renderLeft + 1 + popup.x);\n const screenY = Math.round(renderTop + 1 + popup.y);\n if (screenY > renderTop && screenY < renderTop + GAME_HEIGHT + 1) {\n const alpha = popup.frames > 10 ? '\\x1b[1m' : '\\x1b[2m';\n outputParts.push(`\\x1b[${screenY};${screenX}H${alpha}${popup.color}${popup.text}\\x1b[0m`);\n }\n }\n }\n\n // Bottom hint\n const hint = gameStarted && !gameOver && !paused ? `SEQUENCE LENGTH: ${sequence.length} [ ESC ] MENU` : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n outputParts.push(`\\x1b[${gameTop + GAME_HEIGHT + 3};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`);\n\n terminal.write(outputParts.join(''));\n }\n\n // -------------------------------------------------------------------------\n // GAME LOOP\n // -------------------------------------------------------------------------\n\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h'); // Alternate buffer\n terminal.write('\\x1b[?25l'); // Hide cursor\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) { clearInterval(gameInterval); return; }\n update();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // ESC toggles pause\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Q to quit from pause/game over/start screen\n if (key === 'q' && (paused || gameOver || !gameStarted)) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n\n // Start screen - any key starts\n if (!gameStarted && !paused) {\n gameStarted = true;\n initGame();\n gameStarted = true;\n return;\n }\n\n // Game over - R to restart\n if (gameOver) {\n if (key === 'r') {\n initGame();\n gameStarted = true;\n }\n return;\n }\n\n // Pause menu navigation\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: paused = false; break;\n case 1: initGame(); gameStarted = true; paused = false; break;\n case 2:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcuts\n if (key === 'r') { initGame(); gameStarted = true; paused = false; }\n else if (key === 'l') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGamesMenu(terminal); }\n else if (key === 'n') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGameSwitch(terminal); }\n return;\n }\n\n // GAMEPLAY INPUT - Simon quadrant selection\n if (phase === 'player_turn') {\n switch (domEvent.key) {\n case 'ArrowUp':\n case '1':\n handlePlayerInput(0);\n break;\n case 'ArrowRight':\n case '2':\n handlePlayerInput(1);\n break;\n case 'ArrowDown':\n case '3':\n handlePlayerInput(2);\n break;\n case 'ArrowLeft':\n case '4':\n handlePlayerInput(3);\n break;\n }\n }\n });\n\n // Clean up on stop\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 50);\n\n return controller;\n}\n","/**\n * Hyper Snake Game\n *\n * Cyberpunk-themed snake game with glitchy title,\n * neon borders, and theme-aware colors.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor, getVerticalAnchor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Snake Game Controller\n */\nexport interface SnakeController {\n stop: () => void;\n isRunning: boolean;\n}\n\ntype Direction = 'up' | 'down' | 'left' | 'right';\n\n/**\n * Cyberpunk Snake Game\n */\nexport function runSnakeGame(terminal: Terminal): SnakeController {\n const themeColor = getCurrentThemeColor();\n\n // Minimum terminal size for playable game\n const MIN_COLS = 36;\n const MIN_ROWS = 16;\n\n // Game area (dynamically updated on resize)\n let cols = terminal.cols;\n let rows = terminal.rows;\n let gameTop = 6;\n let gameWidth = Math.min(cols - 4, 60);\n let gameHeight = Math.min(rows - 10, 20);\n let gameLeft = Math.max(2, Math.floor((cols - gameWidth - 2) / 2));\n\n // Update game dimensions when terminal resizes\n const updateDimensions = () => {\n cols = terminal.cols;\n rows = terminal.rows;\n gameWidth = Math.min(cols - 4, 60);\n gameHeight = Math.min(rows - 10, 20);\n gameTop = getVerticalAnchor(rows, gameHeight + 2, {\n headerRows: 4,\n footerRows: 3,\n minTop: 5,\n });\n gameLeft = Math.max(2, Math.floor((cols - gameWidth - 2) / 2));\n };\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let score = 0;\n let highScore = 0;\n\n // Snake state\n let snake: { x: number; y: number }[] = [];\n let direction: Direction = 'right';\n let nextDirection: Direction = 'right';\n let food: { x: number; y: number } = { x: 0, y: 0 };\n\n // Glitch effect state\n let glitchFrame = 0;\n\n // Juicy effects\n let shakeFrames = 0;\n let shakeIntensity = 0;\n let flashFrames = 0;\n let eatFlashFrames = 0;\n let deathFlashFrames = 0;\n let scorePopup: { x: number; y: number; text: string; frames: number } | null = null;\n let particles: { x: number; y: number; char: string; color: string; vx: number; vy: number; life: number }[] = [];\n let comboCount = 0; // Track rapid eating\n let lastEatTime = 0;\n\n const controller: SnakeController = {\n stop: () => {\n if (!running) return;\n running = false;\n // Note: Buffer exit is handled by TerminalPool via dispatchGameQuit\n },\n get isRunning() { return running; }\n };\n\n // ASCII art title\n const titleFrames = [\n [\n '█ █ █▄█ █▀█ █▀▀ █▀█ █▀▀ █▄ █ ▄▀█ █▄▀ █▀▀',\n '█▀█ █ █▀▀ ██▄ █▀▄ ▄▄█ █ ▀█ █▀█ █ █ ██▄',\n ],\n ];\n\n // Initialize game\n function initGame() {\n snake = [\n { x: Math.floor(gameWidth / 2), y: Math.floor(gameHeight / 2) },\n { x: Math.floor(gameWidth / 2) - 1, y: Math.floor(gameHeight / 2) },\n { x: Math.floor(gameWidth / 2) - 2, y: Math.floor(gameHeight / 2) },\n ];\n direction = 'right';\n nextDirection = 'right';\n score = 0;\n gameOver = false;\n paused = false;\n // Reset effects\n shakeFrames = 0;\n shakeIntensity = 0;\n flashFrames = 0;\n eatFlashFrames = 0;\n deathFlashFrames = 0;\n scorePopup = null;\n particles = [];\n comboCount = 0;\n lastEatTime = 0;\n spawnFood();\n }\n\n // Spawn food at random position\n function spawnFood() {\n let attempts = 0;\n do {\n food = {\n x: Math.floor(Math.random() * (gameWidth - 2)) + 1,\n y: Math.floor(Math.random() * (gameHeight - 2)) + 1,\n };\n attempts++;\n } while (snake.some(s => s.x === food.x && s.y === food.y) && attempts < 100);\n }\n\n // Spawn particles at a position\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['✦', '★', '◆', '●']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.3 + Math.random() * 0.4;\n particles.push({\n x: x,\n y: y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color: color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5, // Less vertical movement due to terminal aspect ratio\n life: 15 + Math.floor(Math.random() * 10),\n });\n }\n }\n\n // Update particles\n function updateParticles() {\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.05; // Gravity\n p.life--;\n if (p.life <= 0) {\n particles.splice(i, 1);\n }\n }\n }\n\n // Draw the game\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n updateDimensions();\n\n // Update effect timers\n if (shakeFrames > 0) shakeFrames--;\n if (flashFrames > 0) flashFrames--;\n if (eatFlashFrames > 0) eatFlashFrames--;\n if (deathFlashFrames > 0) deathFlashFrames--;\n if (scorePopup && scorePopup.frames > 0) {\n scorePopup.frames--;\n scorePopup.y -= 0.3; // Float upward\n if (scorePopup.frames <= 0) scorePopup = null;\n }\n updateParticles();\n\n // Apply screen shake\n let renderGameLeft = gameLeft;\n let renderGameTop = gameTop;\n if (shakeFrames > 0) {\n const shakeX = Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n const shakeY = Math.floor((Math.random() - 0.5) * shakeIntensity);\n renderGameLeft = Math.max(1, gameLeft + shakeX);\n renderGameTop = Math.max(3, gameTop + shakeY);\n }\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = '';\n if (needWidth && needHeight) {\n hint = 'Make pane larger';\n } else if (needWidth) {\n hint = 'Make pane wider →';\n } else {\n hint = 'Make pane taller ↓';\n }\n const msg2 = `Need: ${MIN_COLS}×${MIN_ROWS} Have: ${cols}×${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Glitchy title\n glitchFrame = (glitchFrame + 1) % 60;\n const titleIndex = glitchFrame < 55 ? 0 : Math.floor(Math.random() * titleFrames.length);\n const title = titleFrames[titleIndex];\n\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n const titleTop = Math.max(1, gameTop - 4);\n\n output += `\\x1b[${titleTop};${titleX}H`;\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n // Score display with eat flash effect\n const scoreText = `SCORE: ${score.toString().padStart(4, '0')}`;\n const highText = `HIGH: ${highScore.toString().padStart(4, '0')}`;\n const scoreColor = eatFlashFrames > 0 ? '\\x1b[1;33m' : themeColor;\n const scoreY = Math.max(3, gameTop - 2);\n output += `\\x1b[${scoreY};${renderGameLeft}H${scoreColor}${scoreText} ${highText}\\x1b[0m`;\n\n // Game border with death flash effect\n const borderColor = deathFlashFrames > 0 && deathFlashFrames % 4 < 2 ? '\\x1b[1;31m' : themeColor;\n output += `\\x1b[${renderGameTop};${renderGameLeft}H${borderColor}╔${'═'.repeat(gameWidth)}╗\\x1b[0m`;\n for (let y = 1; y <= gameHeight; y++) {\n output += `\\x1b[${renderGameTop + y};${renderGameLeft}H${borderColor}║\\x1b[0m`;\n output += `\\x1b[${renderGameTop + y};${renderGameLeft + gameWidth + 1}H${borderColor}║\\x1b[0m`;\n }\n output += `\\x1b[${renderGameTop + gameHeight + 1};${renderGameLeft}H${borderColor}╚${'═'.repeat(gameWidth)}╝\\x1b[0m`;\n\n if (paused) {\n const pauseMsg = '══ PAUSED ══';\n const pauseCenterX = renderGameLeft + Math.floor(gameWidth / 2) + 1;\n const pauseY = renderGameTop + Math.floor(gameHeight / 2) - 2;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n // Use shared menu rendering\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO START ]';\n const startX = renderGameLeft + Math.floor((gameWidth - startMsg.length) / 2) + 1;\n const startY = renderGameTop + Math.floor(gameHeight / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = '↑↓←→ MOVE ESC MENU';\n const ctrlX = renderGameLeft + Math.floor((gameWidth - controls.length) / 2) + 1;\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n } else if (gameOver) {\n const overMsg = '══ GAME OVER ══';\n const overX = renderGameLeft + Math.floor((gameWidth - overMsg.length) / 2) + 1;\n const overY = renderGameTop + Math.floor(gameHeight / 2) - 1;\n output += `\\x1b[${overY};${overX}H\\x1b[1;31m${overMsg}\\x1b[0m`;\n\n const finalScore = `FINAL SCORE: ${score}`;\n const scoreX = renderGameLeft + Math.floor((gameWidth - finalScore.length) / 2) + 1;\n output += `\\x1b[${overY + 2};${scoreX}H${themeColor}${finalScore}\\x1b[0m`;\n\n const restart = '[ R ] RESTART [ Q ] QUIT';\n const restartX = renderGameLeft + Math.floor((gameWidth - restart.length) / 2) + 1;\n output += `\\x1b[${overY + 4};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n } else {\n // Draw food (pulsing effect with enhanced glow)\n const foodChar = glitchFrame % 10 < 5 ? '◆' : '◇';\n const foodGlow = eatFlashFrames > 0 ? '\\x1b[1;97m' : '\\x1b[1;33m';\n output += `\\x1b[${renderGameTop + food.y};${renderGameLeft + food.x + 1}H${foodGlow}${foodChar}\\x1b[0m`;\n\n // Draw snake with eat flash effect\n const snakeColor = eatFlashFrames > 0 ? '\\x1b[1;33m' : themeColor;\n for (let i = 0; i < snake.length; i++) {\n const seg = snake[i];\n const char = i === 0 ? '█' : '▓';\n const brightness = i === 0 ? '\\x1b[1m' : (i < 3 ? '' : '\\x1b[2m');\n output += `\\x1b[${renderGameTop + seg.y};${renderGameLeft + seg.x + 1}H${brightness}${snakeColor}${char}\\x1b[0m`;\n }\n\n // Draw particles\n for (const p of particles) {\n const px = Math.round(renderGameLeft + p.x + 1);\n const py = Math.round(renderGameTop + p.y);\n if (px > renderGameLeft && px < renderGameLeft + gameWidth + 1 &&\n py > renderGameTop && py < renderGameTop + gameHeight + 1) {\n const alpha = p.life > 10 ? '' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popup\n if (scorePopup) {\n const popX = Math.round(renderGameLeft + scorePopup.x + 1);\n const popY = Math.round(renderGameTop + scorePopup.y);\n if (popY > renderGameTop && popY < renderGameTop + gameHeight + 1) {\n const popAlpha = scorePopup.frames > 10 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${popY};${popX}H${popAlpha}\\x1b[33m${scorePopup.text}\\x1b[0m`;\n }\n }\n\n // Draw combo message\n if (comboCount >= 3) {\n const comboMsg = comboCount >= 5 ? `★ ${comboCount}x COMBO! ★` : `${comboCount}x COMBO!`;\n const comboX = renderGameLeft + Math.floor((gameWidth - comboMsg.length) / 2) + 1;\n const comboColor = glitchFrame % 6 < 3 ? '\\x1b[1;33m' : '\\x1b[1;35m';\n output += `\\x1b[${renderGameTop + 2};${comboX}H${comboColor}${comboMsg}\\x1b[0m`;\n }\n }\n\n const hint = gameStarted && !gameOver && !paused ? '[ ESC ] MENU' : '';\n output += `\\x1b[${renderGameTop + gameHeight + 3};${renderGameLeft}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n // Update game state\n function update() {\n if (!gameStarted || gameOver || paused) return;\n\n direction = nextDirection;\n\n const head = { ...snake[0] };\n switch (direction) {\n case 'up': head.y--; break;\n case 'down': head.y++; break;\n case 'left': head.x--; break;\n case 'right': head.x++; break;\n }\n\n // Check wall collision\n if (head.x <= 0 || head.x >= gameWidth || head.y <= 0 || head.y >= gameHeight) {\n gameOver = true;\n if (score > highScore) highScore = score;\n // Death effects\n shakeFrames = 20;\n shakeIntensity = 3;\n deathFlashFrames = 30;\n // Death particles\n spawnParticles(snake[0].x, snake[0].y, 12, '\\x1b[1;31m', ['✗', '☠', '×', '▒']);\n comboCount = 0;\n return;\n }\n\n // Check self collision\n if (snake.some(s => s.x === head.x && s.y === head.y)) {\n gameOver = true;\n if (score > highScore) highScore = score;\n // Death effects\n shakeFrames = 20;\n shakeIntensity = 3;\n deathFlashFrames = 30;\n // Death particles\n spawnParticles(snake[0].x, snake[0].y, 12, '\\x1b[1;31m', ['✗', '☠', '×', '▒']);\n comboCount = 0;\n return;\n }\n\n snake.unshift(head);\n\n if (head.x === food.x && head.y === food.y) {\n const now = Date.now();\n\n // Track combo (eating within 2 seconds)\n if (now - lastEatTime < 2000) {\n comboCount++;\n } else {\n comboCount = 1;\n }\n lastEatTime = now;\n\n // Calculate points with combo bonus\n const basePoints = 10;\n const comboBonus = comboCount >= 3 ? Math.floor(comboCount * 2) : 0;\n const totalPoints = basePoints + comboBonus;\n score += totalPoints;\n\n // Eat effects - intensity scales with combo\n shakeFrames = 4 + Math.min(comboCount, 5);\n shakeIntensity = 1 + Math.floor(comboCount / 3);\n eatFlashFrames = 8;\n\n // Score popup\n const popupText = comboCount >= 3 ? `+${totalPoints}!` : `+${totalPoints}`;\n scorePopup = {\n x: food.x,\n y: food.y,\n text: popupText,\n frames: 20,\n };\n\n // Particles - more for higher combos\n const particleCount = 4 + Math.min(comboCount * 2, 10);\n spawnParticles(food.x, food.y, particleCount, '\\x1b[1;33m', ['✦', '★', '◆', '♦']);\n\n spawnFood();\n } else {\n snake.pop();\n }\n }\n\n // Start the game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n\n const renderInterval = setInterval(() => {\n if (!running) {\n clearInterval(renderInterval);\n return;\n }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) {\n clearInterval(gameInterval);\n return;\n }\n update();\n }, 120);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener.dispose();\n return;\n }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // Handle ESC key - toggle pause (works on start screen too)\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Q to quit (from start screen, pause, or game over)\n if (key === 'q') {\n if (paused || gameOver || !gameStarted) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n }\n\n // Start screen - any key (except ESC/Q handled above) starts the game\n // Skip if paused (ESC menu open on start screen)\n if (!gameStarted && !paused) {\n gameStarted = true;\n return;\n }\n\n if (gameOver) {\n if (key === 'r') {\n initGame();\n gameStarted = true;\n }\n return;\n }\n\n // Pause menu actions\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n initGame();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (key === 'r') {\n initGame();\n gameStarted = true;\n paused = false;\n } else if (key === 'l') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (key === 'n') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n switch (domEvent.key) {\n case 'ArrowUp':\n case 'w':\n if (direction !== 'down') nextDirection = 'up';\n break;\n case 'ArrowDown':\n case 's':\n if (direction !== 'up') nextDirection = 'down';\n break;\n case 'ArrowLeft':\n case 'a':\n if (direction !== 'right') nextDirection = 'left';\n break;\n case 'ArrowRight':\n case 'd':\n if (direction !== 'left') nextDirection = 'right';\n break;\n }\n });\n\n // Listen for terminal resize to update game dimensions\n const resizeListener = terminal.onResize(() => {\n updateDimensions();\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n resizeListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Space Invaders\n *\n * Cyberpunk-themed Space Invaders with glitchy effects,\n * neon visuals, and theme-aware colors.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Space Invaders Game Controller\n */\nexport interface SpaceInvadersController {\n stop: () => void;\n isRunning: boolean;\n}\n\ninterface Invader {\n x: number;\n y: number;\n alive: boolean;\n type: 0 | 1 | 2; // Different invader types\n}\n\ninterface Bullet {\n x: number;\n y: number;\n isPlayer: boolean;\n}\n\ninterface Explosion {\n x: number;\n y: number;\n frame: number;\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\n/**\n * Cyberpunk Space Invaders\n */\nexport function runSpaceInvadersGame(terminal: Terminal): SpaceInvadersController {\n const themeColor = getCurrentThemeColor();\n\n // Minimum terminal size (reduced for better compatibility)\n const MIN_COLS = 40;\n const MIN_ROWS = 16;\n\n // Game dimensions - adaptive based on terminal size\n const getGameDimensions = () => {\n const cols = terminal.cols;\n const rows = terminal.rows;\n const width = Math.min(50, Math.max(40, cols - 6));\n const height = Math.min(20, Math.max(14, rows - 6));\n return { width, height };\n };\n\n let { width: GAME_WIDTH, height: GAME_HEIGHT } = getGameDimensions();\n const INVADER_ROWS = 4;\n const INVADER_COLS = 8;\n const INVADER_SPACING_X = 5;\n const INVADER_SPACING_Y = 2;\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let won = false;\n let score = 0;\n let highScore = 0;\n let lives = 3;\n let level = 1;\n\n // Game area positioning\n let gameLeft = 2;\n let gameTop = 4;\n\n // Player state\n let playerX = GAME_WIDTH / 2;\n let playerY = GAME_HEIGHT - 1;\n\n // Invaders\n let invaders: Invader[] = [];\n let invaderDirection = 1; // 1 = right, -1 = left\n let invaderMoveTimer = 0;\n let invaderMoveDelay = 30; // Frames between moves\n let invaderDropAmount = 0;\n\n // Bullets\n let bullets: Bullet[] = [];\n let playerShootCooldown = 0;\n let invaderShootTimer = 0;\n\n // Explosions\n let explosions: Explosion[] = [];\n\n // Shields/barriers\n let shields: boolean[][][] = [];\n const SHIELD_COUNT = 4;\n const SHIELD_WIDTH = 6;\n const SHIELD_HEIGHT = 3;\n\n // Visual effects\n let glitchFrame = 0;\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let shakeFrames = 0;\n let shakeIntensity = 0;\n let hitFlashFrames = 0;\n let killStreakCount = 0;\n let killStreakTimer = 0;\n let gameOverFlashFrames = 0;\n\n const controller: SpaceInvadersController = {\n stop: () => {\n if (!running) return;\n running = false;\n // Note: Buffer exit is handled by TerminalPool via dispatchGameQuit\n },\n get isRunning() { return running; }\n };\n\n // ASCII art title\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ █ █▄ █ █ █ ▄▀█ █▀▄ █▀▀ █▀█ █▀',\n '█▀█ █ █▀▀ ██▄ █▀▄ █ █ ▀█ ▀▄▀ █▀█ █▄▀ ██▄ █▀▄ ▄█',\n ];\n\n // Invader sprites (different types)\n const invaderSprites = [\n ['<O>', '</\\\\>'], // Type 0 - bottom rows\n ['/V\\\\', '\\\\^/'], // Type 1 - middle rows\n ['|=|', '|#|'], // Type 2 - top rows\n ];\n\n // Spawn particles at position\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['✦', '★', '◆', '●']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.2 + Math.random() * 0.4;\n particles.push({\n x: x,\n y: y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color: color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 10 + Math.floor(Math.random() * 8),\n });\n }\n }\n\n // Add score popup\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 18, color });\n }\n\n function initGame() {\n playerX = GAME_WIDTH / 2;\n score = won ? score : 0; // Keep score if advancing levels\n lives = won ? lives : 3;\n gameOver = false;\n won = false;\n paused = false;\n bullets = [];\n explosions = [];\n playerShootCooldown = 0;\n invaderShootTimer = 0;\n invaderDirection = 1;\n invaderMoveTimer = 0;\n invaderDropAmount = 0;\n // Reset effects\n particles = [];\n scorePopups = [];\n shakeFrames = 0;\n shakeIntensity = 0;\n hitFlashFrames = 0;\n killStreakCount = 0;\n killStreakTimer = 0;\n gameOverFlashFrames = 0;\n\n // Speed increases with level\n invaderMoveDelay = Math.max(10, 30 - (level - 1) * 4);\n\n // Initialize invaders\n invaders = [];\n const startX = Math.floor((GAME_WIDTH - INVADER_COLS * INVADER_SPACING_X) / 2);\n const startY = 2;\n\n for (let row = 0; row < INVADER_ROWS; row++) {\n for (let col = 0; col < INVADER_COLS; col++) {\n invaders.push({\n x: startX + col * INVADER_SPACING_X,\n y: startY + row * INVADER_SPACING_Y,\n alive: true,\n type: row === 0 ? 2 : row === 1 ? 1 : 0,\n });\n }\n }\n\n // Initialize shields\n shields = [];\n for (let i = 0; i < SHIELD_COUNT; i++) {\n const shield: boolean[][] = [];\n for (let y = 0; y < SHIELD_HEIGHT; y++) {\n shield[y] = [];\n for (let x = 0; x < SHIELD_WIDTH; x++) {\n // Create arch shape\n if (y === 0 && (x === 0 || x === SHIELD_WIDTH - 1)) {\n shield[y][x] = false;\n } else if (y === SHIELD_HEIGHT - 1 && x >= 2 && x <= 3) {\n shield[y][x] = false; // Gap at bottom\n } else {\n shield[y][x] = true;\n }\n }\n }\n shields.push(shield);\n }\n }\n\n function getShieldX(shieldIndex: number): number {\n const shieldSpacing = Math.floor(GAME_WIDTH / (SHIELD_COUNT + 1));\n return shieldSpacing * (shieldIndex + 1) - Math.floor(SHIELD_WIDTH / 2);\n }\n\n function getShieldY(): number {\n return GAME_HEIGHT - 5;\n }\n\n function shootBullet(x: number, y: number, isPlayer: boolean) {\n bullets.push({ x, y, isPlayer });\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Update effect timers\n if (shakeFrames > 0) shakeFrames--;\n if (hitFlashFrames > 0) hitFlashFrames--;\n if (gameOverFlashFrames > 0) gameOverFlashFrames--;\n if (killStreakTimer > 0) {\n killStreakTimer--;\n if (killStreakTimer === 0) killStreakCount = 0;\n }\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.02;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.25;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = '';\n if (needWidth && needHeight) {\n hint = 'Make pane larger';\n } else if (needWidth) {\n hint = 'Make pane wider \\u2192';\n } else {\n hint = 'Make pane taller \\u2193';\n }\n const msg2 = `Need: ${MIN_COLS}\\u00d7${MIN_ROWS} Have: ${cols}\\u00d7${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Update game dimensions on resize\n const newDims = getGameDimensions();\n if (newDims.width !== GAME_WIDTH || newDims.height !== GAME_HEIGHT) {\n // Scale positions to new dimensions\n playerX = (playerX / GAME_WIDTH) * newDims.width;\n playerY = newDims.height - 1;\n GAME_WIDTH = newDims.width;\n GAME_HEIGHT = newDims.height;\n }\n\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH - 2) / 2));\n gameTop = Math.max(3, Math.floor((rows - GAME_HEIGHT - 4) / 2));\n\n // Apply screen shake\n let renderGameLeft = gameLeft;\n let renderGameTop = gameTop;\n if (shakeFrames > 0) {\n const shakeX = Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n const shakeY = Math.floor((Math.random() - 0.5) * shakeIntensity);\n renderGameLeft = Math.max(1, gameLeft + shakeX);\n renderGameTop = Math.max(3, gameTop + shakeY);\n }\n\n // Glitchy title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n output += `\\x1b[1;${titleX}H`;\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n // Stats bar\n const livesDisplay = '\\u2665'.repeat(lives);\n const stats = `SCORE: ${score.toString().padStart(5, '0')} LVL: ${level} ${livesDisplay}`;\n const statsX = Math.floor((cols - stats.length) / 2);\n output += `\\x1b[4;${statsX}H${themeColor}${stats}\\x1b[0m`;\n\n // Game border with flash effect\n const borderColor = hitFlashFrames > 0 && hitFlashFrames % 4 < 2 ? '\\x1b[1;91m' : themeColor;\n output += `\\x1b[${renderGameTop};${renderGameLeft}H${borderColor}\\u2554${'═'.repeat(GAME_WIDTH)}\\u2557\\x1b[0m`;\n for (let y = 0; y < GAME_HEIGHT; y++) {\n output += `\\x1b[${renderGameTop + 1 + y};${renderGameLeft}H${borderColor}\\u2551\\x1b[0m`;\n output += `\\x1b[${renderGameTop + 1 + y};${renderGameLeft + GAME_WIDTH + 1}H${borderColor}\\u2551\\x1b[0m`;\n }\n output += `\\x1b[${renderGameTop + GAME_HEIGHT + 1};${renderGameLeft}H${borderColor}\\u255a${'═'.repeat(GAME_WIDTH)}\\u255d\\x1b[0m`;\n\n if (paused) {\n const pauseMsg = '\\u2550\\u2550 PAUSED \\u2550\\u2550';\n const pauseCenterX = gameLeft + Math.floor(GAME_WIDTH / 2) + 1;\n const pauseY = gameTop + Math.floor(GAME_HEIGHT / 2) - 3;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO PLAY ]';\n const startX = gameLeft + Math.floor((GAME_WIDTH - startMsg.length) / 2) + 1;\n const startY = gameTop + Math.floor(GAME_HEIGHT / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = '←→ MOVE SPC FIRE ESC MENU';\n const ctrlX = gameLeft + Math.floor((GAME_WIDTH - controls.length) / 2) + 1;\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n } else if (gameOver) {\n const overMsg = won ? '╔══ LEVEL COMPLETE! ══╗' : '╔══ GAME OVER ══╗';\n const overX = gameLeft + Math.floor((GAME_WIDTH - overMsg.length) / 2) + 1;\n const overY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n output += `\\x1b[${overY};${overX}H${won ? '\\x1b[1;92m' : '\\x1b[1;91m'}${overMsg}\\x1b[0m`;\n\n const scoreLine = `SCORE: ${score} HIGH: ${highScore}`;\n output += `\\x1b[${overY + 1};${gameLeft + Math.floor((GAME_WIDTH - scoreLine.length) / 2) + 1}H${themeColor}${scoreLine}\\x1b[0m`;\n\n const restart = won ? '╚ [R] NEXT LEVEL [Q] QUIT ╝' : '╚ [R] RESTART [Q] QUIT ╝';\n output += `\\x1b[${overY + 2};${gameLeft + Math.floor((GAME_WIDTH - restart.length) / 2) + 1}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n } else {\n // Draw shields\n const shieldY = getShieldY();\n for (let i = 0; i < SHIELD_COUNT; i++) {\n const shieldX = getShieldX(i);\n for (let y = 0; y < SHIELD_HEIGHT; y++) {\n for (let x = 0; x < SHIELD_WIDTH; x++) {\n if (shields[i][y][x]) {\n const screenX = renderGameLeft + 1 + shieldX + x;\n const screenY = renderGameTop + 1 + shieldY + y;\n output += `\\x1b[${screenY};${screenX}H\\x1b[92m\\u2588\\x1b[0m`;\n }\n }\n }\n }\n\n // Draw invaders\n const animFrame = Math.floor(glitchFrame / 15) % 2;\n for (const invader of invaders) {\n if (!invader.alive) continue;\n const sprite = invaderSprites[invader.type][animFrame];\n const screenX = renderGameLeft + 1 + invader.x;\n const screenY = renderGameTop + 1 + invader.y;\n\n // Color based on type\n const colors = ['\\x1b[92m', '\\x1b[93m', '\\x1b[95m']; // Green, Yellow, Magenta\n output += `\\x1b[${screenY};${screenX}H${colors[invader.type]}${sprite}\\x1b[0m`;\n }\n\n // Draw bullets\n for (const bullet of bullets) {\n const screenX = renderGameLeft + 1 + Math.floor(bullet.x);\n const screenY = renderGameTop + 1 + Math.floor(bullet.y);\n if (bullet.isPlayer) {\n output += `\\x1b[${screenY};${screenX}H\\x1b[97m\\u2502\\x1b[0m`;\n } else {\n output += `\\x1b[${screenY};${screenX}H\\x1b[91m\\u25cf\\x1b[0m`;\n }\n }\n\n // Draw explosions\n for (const exp of explosions) {\n const screenX = renderGameLeft + 1 + exp.x;\n const screenY = renderGameTop + 1 + exp.y;\n const expChars = ['*', '+', '\\u00d7', '\\u00b7'];\n const char = expChars[Math.min(exp.frame, expChars.length - 1)];\n output += `\\x1b[${screenY};${screenX}H\\x1b[93m${char}\\x1b[0m`;\n }\n\n // Draw particles\n for (const p of particles) {\n const screenX = Math.round(renderGameLeft + 1 + p.x);\n const screenY = Math.round(renderGameTop + 1 + p.y);\n if (screenX > renderGameLeft && screenX < renderGameLeft + GAME_WIDTH + 1 &&\n screenY > renderGameTop && screenY < renderGameTop + GAME_HEIGHT + 1) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const screenX = Math.round(renderGameLeft + 1 + popup.x);\n const screenY = Math.round(renderGameTop + 1 + popup.y);\n if (screenY > renderGameTop && screenY < renderGameTop + GAME_HEIGHT + 1) {\n const alpha = popup.frames > 10 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n\n // Draw kill streak message\n if (killStreakCount >= 3) {\n const streakMsg = killStreakCount >= 5 ? `★ ${killStreakCount}x KILL STREAK! ★` : `${killStreakCount}x STREAK!`;\n const streakX = renderGameLeft + Math.floor((GAME_WIDTH - streakMsg.length) / 2) + 1;\n const streakColor = glitchFrame % 6 < 3 ? '\\x1b[1;91m' : '\\x1b[1;93m';\n output += `\\x1b[${renderGameTop + 2};${streakX}H${streakColor}${streakMsg}\\x1b[0m`;\n }\n\n // Draw player with hit flash\n const playerScreenX = renderGameLeft + 1 + Math.floor(playerX) - 1;\n const playerScreenY = renderGameTop + 1 + playerY;\n const playerColor = hitFlashFrames > 0 && hitFlashFrames % 4 < 2 ? '\\x1b[1;91m' : themeColor;\n output += `\\x1b[${playerScreenY};${playerScreenX}H${playerColor}/\\u2588\\\\\\x1b[0m`;\n }\n\n // Hint\n const hint = gameStarted && !gameOver && !paused ? `HIGH: ${highScore} [ ESC ] MENU` : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${gameTop + GAME_HEIGHT + 3};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n function update() {\n if (!gameStarted || gameOver || paused) return;\n\n // Update cooldowns\n if (playerShootCooldown > 0) playerShootCooldown--;\n invaderShootTimer++;\n\n // Update explosions\n explosions = explosions.filter(exp => {\n exp.frame++;\n return exp.frame < 4;\n });\n\n // Move invaders\n invaderMoveTimer++;\n if (invaderMoveTimer >= invaderMoveDelay) {\n invaderMoveTimer = 0;\n\n // Check if any invader hit the edge\n let hitEdge = false;\n for (const invader of invaders) {\n if (!invader.alive) continue;\n const nextX = invader.x + invaderDirection * 2;\n if (nextX <= 0 || nextX >= GAME_WIDTH - 3) {\n hitEdge = true;\n break;\n }\n }\n\n if (hitEdge) {\n invaderDirection *= -1;\n invaderDropAmount = 1;\n }\n\n // Move invaders\n for (const invader of invaders) {\n if (!invader.alive) continue;\n if (invaderDropAmount > 0) {\n invader.y += invaderDropAmount;\n } else {\n invader.x += invaderDirection * 2;\n }\n\n // Check if invaders reached the player\n if (invader.y >= playerY - 1) {\n gameOver = true;\n if (score > highScore) highScore = score;\n return;\n }\n }\n invaderDropAmount = 0;\n }\n\n // Invader shooting\n const aliveInvaders = invaders.filter(i => i.alive);\n if (aliveInvaders.length > 0 && invaderShootTimer >= 60) {\n invaderShootTimer = 0;\n // Random invader shoots\n const shooter = aliveInvaders[Math.floor(Math.random() * aliveInvaders.length)];\n shootBullet(shooter.x + 1, shooter.y + 1, false);\n }\n\n // Move bullets\n bullets = bullets.filter(bullet => {\n if (bullet.isPlayer) {\n bullet.y -= 0.8;\n } else {\n bullet.y += 0.5;\n }\n return bullet.y >= 0 && bullet.y < GAME_HEIGHT;\n });\n\n // Bullet collision with invaders\n for (const bullet of bullets) {\n if (!bullet.isPlayer) continue;\n\n for (const invader of invaders) {\n if (!invader.alive) continue;\n if (bullet.y >= invader.y && bullet.y <= invader.y + 1 &&\n bullet.x >= invader.x && bullet.x <= invader.x + 2) {\n invader.alive = false;\n bullet.y = -100; // Mark for removal\n explosions.push({ x: invader.x + 1, y: invader.y, frame: 0 });\n\n // Kill streak tracking\n killStreakCount++;\n killStreakTimer = 30; // Reset streak timer\n\n // Calculate score with streak bonus\n const baseScore = (invader.type + 1) * 10;\n const streakBonus = killStreakCount >= 3 ? Math.floor(killStreakCount * 5) : 0;\n const totalScore = baseScore + streakBonus;\n score += totalScore;\n\n // Effects\n shakeFrames = 3 + Math.min(killStreakCount, 5);\n shakeIntensity = 1 + Math.floor(killStreakCount / 3);\n\n // Particles - color based on invader type\n const invaderColors = ['\\x1b[1;92m', '\\x1b[1;93m', '\\x1b[1;95m'];\n spawnParticles(invader.x + 1, invader.y, 6 + Math.min(killStreakCount, 6), invaderColors[invader.type], ['✦', '★', '◆', '×']);\n\n // Score popup\n const popupText = killStreakCount >= 3 ? `+${totalScore}!` : `+${totalScore}`;\n const popupColor = killStreakCount >= 3 ? '\\x1b[1;91m' : '\\x1b[1;93m';\n addScorePopup(invader.x + 1, invader.y - 1, popupText, popupColor);\n }\n }\n }\n\n // Bullet collision with shields\n const shieldY = getShieldY();\n for (const bullet of bullets) {\n for (let i = 0; i < SHIELD_COUNT; i++) {\n const shieldX = getShieldX(i);\n const relX = Math.floor(bullet.x - shieldX);\n const relY = Math.floor(bullet.y - shieldY);\n\n if (relX >= 0 && relX < SHIELD_WIDTH && relY >= 0 && relY < SHIELD_HEIGHT) {\n if (shields[i][relY][relX]) {\n shields[i][relY][relX] = false;\n bullet.y = -100; // Mark for removal\n }\n }\n }\n }\n\n // Bullet collision with player\n for (const bullet of bullets) {\n if (bullet.isPlayer) continue;\n if (bullet.y >= playerY && bullet.y <= playerY + 1 &&\n bullet.x >= playerX - 1 && bullet.x <= playerX + 1) {\n bullet.y = -100;\n explosions.push({ x: Math.floor(playerX), y: playerY, frame: 0 });\n lives--;\n\n // Player hit effects\n shakeFrames = 12;\n shakeIntensity = 3;\n hitFlashFrames = 15;\n killStreakCount = 0; // Reset kill streak on hit\n spawnParticles(Math.floor(playerX), playerY, 10, '\\x1b[1;91m', ['✗', '☠', '×', '▒']);\n\n if (lives <= 0) {\n gameOver = true;\n gameOverFlashFrames = 30;\n shakeFrames = 20;\n shakeIntensity = 4;\n spawnParticles(Math.floor(playerX), playerY, 15, '\\x1b[1;91m', ['✗', '☠', '×', '▓', '░']);\n if (score > highScore) highScore = score;\n }\n }\n }\n\n // Remove destroyed bullets\n bullets = bullets.filter(b => b.y >= 0);\n\n // Check win condition\n if (aliveInvaders.length === 0) {\n won = true;\n gameOver = true;\n level++;\n if (score > highScore) highScore = score;\n }\n }\n\n // Start game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) {\n clearInterval(renderInterval);\n return;\n }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) {\n clearInterval(gameInterval);\n return;\n }\n update();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener.dispose();\n return;\n }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // Handle ESC key - toggle pause (works on start screen too)\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Q to quit (from start screen, pause, or game over)\n if (key === 'q') {\n if (paused || gameOver || !gameStarted) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n }\n\n // Start screen - any key (except ESC/Q handled above) starts the game\n // Skip if paused (ESC menu open on start screen)\n if (!gameStarted && !paused) {\n gameStarted = true;\n return;\n }\n\n if (gameOver) {\n if (key === 'r') {\n if (won) {\n // Continue to next level\n initGame();\n } else {\n // Full restart\n level = 1;\n initGame();\n }\n gameStarted = true;\n }\n return;\n }\n\n // Pause menu actions\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n level = 1;\n initGame();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (key === 'r') {\n level = 1;\n initGame();\n gameStarted = true;\n paused = false;\n } else if (key === 'l') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (key === 'n') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n switch (domEvent.key) {\n case 'ArrowLeft':\n case 'a':\n if (playerX > 2) playerX -= 2;\n break;\n case 'ArrowRight':\n case 'd':\n if (playerX < GAME_WIDTH - 2) playerX += 2;\n break;\n case ' ':\n if (playerShootCooldown === 0) {\n shootBullet(playerX, playerY - 1, true);\n playerShootCooldown = 10;\n }\n break;\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Tetris\n *\n * Cyberpunk-themed Tetris with glitchy effects,\n * neon borders, and theme-aware colors.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor, getVerticalAnchor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Tetris Game Controller\n */\nexport interface TetrisController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// Tetromino shapes (rotations included)\nconst TETROMINOES = {\n I: [\n [[1, 1, 1, 1]],\n [[1], [1], [1], [1]],\n ],\n O: [\n [[1, 1], [1, 1]],\n ],\n T: [\n [[0, 1, 0], [1, 1, 1]],\n [[1, 0], [1, 1], [1, 0]],\n [[1, 1, 1], [0, 1, 0]],\n [[0, 1], [1, 1], [0, 1]],\n ],\n S: [\n [[0, 1, 1], [1, 1, 0]],\n [[1, 0], [1, 1], [0, 1]],\n ],\n Z: [\n [[1, 1, 0], [0, 1, 1]],\n [[0, 1], [1, 1], [1, 0]],\n ],\n J: [\n [[1, 0, 0], [1, 1, 1]],\n [[1, 1], [1, 0], [1, 0]],\n [[1, 1, 1], [0, 0, 1]],\n [[0, 1], [0, 1], [1, 1]],\n ],\n L: [\n [[0, 0, 1], [1, 1, 1]],\n [[1, 0], [1, 0], [1, 1]],\n [[1, 1, 1], [1, 0, 0]],\n [[1, 1], [0, 1], [0, 1]],\n ],\n};\n\nconst PIECE_COLORS: Record<string, string> = {\n I: '\\x1b[96m', // Cyan\n O: '\\x1b[93m', // Yellow\n T: '\\x1b[95m', // Magenta\n S: '\\x1b[92m', // Green\n Z: '\\x1b[91m', // Red\n J: '\\x1b[94m', // Blue\n L: '\\x1b[33m', // Orange (dark yellow)\n};\n\ntype PieceType = keyof typeof TETROMINOES;\ntype GameMode = 'marathon' | 'sprint';\n\n/**\n * Cyberpunk Tetris Game\n */\nexport function runTetrisGame(terminal: Terminal): TetrisController {\n const themeColor = getCurrentThemeColor();\n\n // Game dimensions\n const BOARD_WIDTH = 12; // Wider board for better text fit\n const BOARD_HEIGHT = 20;\n const SIDE_PANEL_WIDTH = 14;\n const BOARD_ONLY_WIDTH = BOARD_WIDTH * 2 + 2; // Just board + borders\n const TOTAL_WIDTH = BOARD_WIDTH * 2 + SIDE_PANEL_WIDTH + 4; // Board + panel + gaps\n const TICK_MS = 25;\n const SPRINT_TARGET_LINES = 40;\n\n // Minimum terminal size (compact mode - just the board)\n const MIN_COLS = BOARD_ONLY_WIDTH + 2;\n const MIN_ROWS = BOARD_HEIGHT + 3; // Board + controls (title hides automatically on short panes)\n const MIN_ROWS_WITH_TITLE = BOARD_HEIGHT + 4;\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let won = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let score = 0;\n let level = 1;\n let lines = 0;\n let highScore = 0;\n let selectedMode: GameMode = 'marathon';\n let mode: GameMode = 'marathon';\n\n // Game board (0 = empty, string = color code)\n let board: (string | 0)[][] = [];\n\n // Current piece state\n let currentPiece: PieceType = 'T';\n let currentRotation = 0;\n let pieceX = 0;\n let pieceY = 0;\n let nextPiece: PieceType = 'T';\n\n // Glitch effect\n let glitchFrame = 0;\n\n // Drop timing\n let dropCounter = 0;\n let dropInterval = 1000;\n\n // Hard drop animation\n let hardDropping = false;\n let hardDropConsumed = false; // Prevents holding space from dropping multiple pieces\n\n // Line clear effects\n let shakeFrames = 0;\n let shakeIntensity = 0;\n let flashRows: number[] = [];\n let flashFrames = 0;\n let comboMessage = '';\n let comboFrames = 0;\n let comboChain = 0;\n let backToBackTetris = false;\n let particles: { x: number; y: number; char: string; color: string; vx: number; vy: number; life: number }[] = [];\n\n const controller: TetrisController = {\n stop: () => {\n if (!running) return;\n running = false;\n // Note: Buffer exit is handled by TerminalPool via dispatchGameQuit\n },\n get isRunning() { return running; }\n };\n\n // ASCII art title\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ ▀█▀ █▀▀ ▀█▀ █▀█ █ █▀',\n '█▀█ █ █▀▀ ██▄ █▀▄ █ ██▄ █ █▀▄ █ ▄█',\n ];\n\n function initGame(newMode: GameMode) {\n mode = newMode;\n board = Array(BOARD_HEIGHT).fill(null).map(() => Array(BOARD_WIDTH).fill(0));\n score = 0;\n level = 1;\n lines = 0;\n dropInterval = 1000;\n dropCounter = 0;\n gameOver = false;\n won = false;\n paused = false;\n comboChain = 0;\n backToBackTetris = false;\n hardDropping = false;\n hardDropConsumed = false;\n shakeFrames = 0;\n shakeIntensity = 0;\n flashRows = [];\n flashFrames = 0;\n comboMessage = '';\n comboFrames = 0;\n particles = [];\n spawnPiece();\n nextPiece = randomPiece();\n }\n\n function randomPiece(): PieceType {\n const pieces: PieceType[] = ['I', 'O', 'T', 'S', 'Z', 'J', 'L'];\n return pieces[Math.floor(Math.random() * pieces.length)];\n }\n\n function spawnPiece() {\n currentPiece = nextPiece || randomPiece();\n nextPiece = randomPiece();\n currentRotation = 0;\n const shape = TETROMINOES[currentPiece][0];\n pieceX = Math.floor((BOARD_WIDTH - shape[0].length) / 2);\n pieceY = 0;\n\n if (!isValidPosition(pieceX, pieceY, currentRotation)) {\n gameOver = true;\n if (score > highScore) highScore = score;\n }\n }\n\n function getShape(rotation: number = currentRotation): number[][] {\n const rotations = TETROMINOES[currentPiece];\n return rotations[rotation % rotations.length];\n }\n\n function isValidPosition(x: number, y: number, rotation: number): boolean {\n const shape = TETROMINOES[currentPiece][rotation % TETROMINOES[currentPiece].length];\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n const newX = x + col;\n const newY = y + row;\n if (newX < 0 || newX >= BOARD_WIDTH || newY >= BOARD_HEIGHT) {\n return false;\n }\n if (newY >= 0 && board[newY][newX]) {\n return false;\n }\n }\n }\n }\n return true;\n }\n\n function lockPiece() {\n const shape = getShape();\n const color = PIECE_COLORS[currentPiece];\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n const boardY = pieceY + row;\n const boardX = pieceX + col;\n if (boardY >= 0 && boardY < BOARD_HEIGHT && boardX >= 0 && boardX < BOARD_WIDTH) {\n board[boardY][boardX] = color;\n }\n }\n }\n }\n clearLines();\n if (!gameOver) {\n spawnPiece();\n }\n }\n\n function clearLines() {\n // First, find rows to clear and trigger flash effect\n const rowsToClear: number[] = [];\n for (let row = BOARD_HEIGHT - 1; row >= 0; row--) {\n if (board[row].every(cell => cell !== 0)) {\n rowsToClear.push(row);\n }\n }\n\n const clearedLines = rowsToClear.length;\n if (clearedLines > 0) {\n // Trigger flash effect on these rows\n flashRows = [...rowsToClear];\n flashFrames = 8; // Flash for 8 frames\n\n // Spawn particles from cleared rows\n const particleChars = ['█', '▓', '▒', '░', '✦', '✧', '◆', '◇'];\n const particleColors = ['\\x1b[91m', '\\x1b[93m', '\\x1b[92m', '\\x1b[96m', '\\x1b[95m', '\\x1b[97m'];\n for (const row of rowsToClear) {\n for (let x = 0; x < BOARD_WIDTH; x++) {\n if (Math.random() < 0.4) { // 40% chance for each cell\n particles.push({\n x: x * 2,\n y: row,\n char: particleChars[Math.floor(Math.random() * particleChars.length)],\n color: particleColors[Math.floor(Math.random() * particleColors.length)],\n vx: (Math.random() - 0.5) * 4,\n vy: (Math.random() - 0.8) * 3,\n life: 15 + Math.floor(Math.random() * 10),\n });\n }\n }\n }\n\n // Combo & back-to-back scoring\n comboChain++;\n const isTetris = clearedLines === 4;\n const b2bBonus = isTetris && backToBackTetris ? 400 * level : 0;\n const comboBonus = comboChain > 1 ? (comboChain - 1) * 50 * level : 0;\n backToBackTetris = isTetris;\n\n // Screen shake based on clear strength and combo\n shakeIntensity = clearedLines + Math.min(2, comboChain - 1);\n shakeFrames = clearedLines * 5 + (comboChain > 1 ? 6 : 4);\n\n // Combo message\n if (isTetris && b2bBonus > 0) {\n comboMessage = '⚡ B2B TETRIS! ⚡';\n comboFrames = 45;\n } else if (isTetris) {\n comboMessage = '★ TETRIS! ★';\n comboFrames = 40;\n } else if (clearedLines === 3) {\n comboMessage = 'TRIPLE!';\n comboFrames = 25;\n } else if (clearedLines === 2) {\n comboMessage = 'DOUBLE!';\n comboFrames = 20;\n } else {\n comboMessage = 'SINGLE!';\n comboFrames = 16;\n }\n\n if (comboChain > 1) {\n comboMessage += ` COMBO x${comboChain}`;\n comboFrames = Math.max(comboFrames, 24);\n }\n\n // Rebuild board to avoid index-shift bugs when clearing multiple rows.\n const remainingRows = board.filter(row => !row.every(cell => cell !== 0));\n board = [\n ...Array(clearedLines).fill(null).map(() => Array(BOARD_WIDTH).fill(0)),\n ...remainingRows,\n ];\n\n // Update flash indices to match the newly-inserted empty rows at the top.\n flashRows = Array.from({ length: clearedLines }, (_, i) => i);\n\n const pointsTable = [0, 100, 300, 500, 800];\n const points = (pointsTable[Math.min(clearedLines, pointsTable.length - 1)] ?? 0) * level + comboBonus + b2bBonus;\n score += points;\n lines += clearedLines;\n\n // Level up every 10 lines\n const newLevel = Math.floor(lines / 10) + 1;\n if (newLevel > level) {\n level = newLevel;\n dropInterval = Math.max(100, 1000 - (level - 1) * 100);\n }\n\n if (mode === 'sprint' && lines >= SPRINT_TARGET_LINES) {\n won = true;\n gameOver = true;\n if (score > highScore) highScore = score;\n }\n } else {\n comboChain = 0;\n }\n }\n\n function moveLeft() {\n if (isValidPosition(pieceX - 1, pieceY, currentRotation)) {\n pieceX--;\n }\n }\n\n function moveRight() {\n if (isValidPosition(pieceX + 1, pieceY, currentRotation)) {\n pieceX++;\n }\n }\n\n function moveDown(): boolean {\n if (isValidPosition(pieceX, pieceY + 1, currentRotation)) {\n pieceY++;\n return true;\n }\n return false;\n }\n\n function hardDrop() {\n if (hardDropping) return; // Already dropping\n if (hardDropConsumed) return; // Must release space before dropping again\n hardDropping = true;\n hardDropConsumed = true; // Mark as consumed until space is released\n }\n\n function rotate() {\n const newRotation = (currentRotation + 1) % TETROMINOES[currentPiece].length;\n // Try normal rotation\n if (isValidPosition(pieceX, pieceY, newRotation)) {\n currentRotation = newRotation;\n return;\n }\n // Wall kicks\n const kicks = [-1, 1, -2, 2];\n for (const kick of kicks) {\n if (isValidPosition(pieceX + kick, pieceY, newRotation)) {\n pieceX += kick;\n currentRotation = newRotation;\n return;\n }\n }\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = '';\n if (needWidth && needHeight) {\n hint = 'Make pane larger';\n } else if (needWidth) {\n hint = 'Make pane wider →';\n } else {\n hint = 'Make pane taller ↓';\n }\n const msg2 = `Need: ${MIN_COLS}×${MIN_ROWS} Have: ${cols}×${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Determine layout mode based on available space\n const showSidePanel = cols >= TOTAL_WIDTH + 4;\n const showTitle = rows >= MIN_ROWS_WITH_TITLE;\n const compactTitle = showTitle && rows < 30; // Use compact title if limited height\n const displayWidth = showSidePanel ? TOTAL_WIDTH : BOARD_ONLY_WIDTH;\n let gameLeft = Math.max(2, Math.floor((cols - displayWidth) / 2));\n const titleRows = showTitle ? (compactTitle ? 1 : 2) : 0;\n const gapAfterTitle = showTitle ? 1 : 0;\n const boardRows = BOARD_HEIGHT + 2;\n const footerRows = 2;\n const layoutRows = titleRows + gapAfterTitle + boardRows + footerRows;\n const titleTop = getVerticalAnchor(rows, layoutRows, {\n minTop: 1,\n footerRows: 1,\n });\n let gameTop = titleTop + titleRows + gapAfterTitle;\n\n // Apply screen shake\n if (shakeFrames > 0) {\n const shakeX = Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n const shakeY = Math.floor((Math.random() - 0.5) * shakeIntensity);\n gameLeft = Math.max(1, gameLeft + shakeX);\n gameTop = Math.max(2, gameTop + shakeY);\n }\n\n // Glitchy title (hidden first when height is constrained)\n if (showTitle) {\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n\n if (compactTitle) {\n const shortTitle = 'HYPER TETRIS';\n const titleX = Math.floor((cols - shortTitle.length) / 2) + glitchOffset;\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[${titleTop};${titleX}H\\x1b[91m${shortTitle}\\x1b[0m`;\n } else {\n output += `\\x1b[${titleTop};${titleX}H${themeColor}\\x1b[1m${shortTitle}\\x1b[0m`;\n }\n } else {\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n output += `\\x1b[${titleTop};${titleX}H`;\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n }\n }\n\n // Game border (double-width cells)\n output += `\\x1b[${gameTop};${gameLeft}H${themeColor}╔${'══'.repeat(BOARD_WIDTH)}╗\\x1b[0m`;\n for (let y = 0; y < BOARD_HEIGHT; y++) {\n output += `\\x1b[${gameTop + 1 + y};${gameLeft}H${themeColor}║\\x1b[0m`;\n output += `\\x1b[${gameTop + 1 + y};${gameLeft + 1 + BOARD_WIDTH * 2}H${themeColor}║\\x1b[0m`;\n }\n output += `\\x1b[${gameTop + BOARD_HEIGHT + 1};${gameLeft}H${themeColor}╚${'══'.repeat(BOARD_WIDTH)}╝\\x1b[0m`;\n\n if (paused) {\n const pauseMsg = '══ PAUSED ══';\n const pauseCenterX = gameLeft + Math.floor(BOARD_WIDTH * 2 / 2) + 1;\n const pauseY = gameTop + Math.floor(BOARD_HEIGHT / 2) - 3;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY ]';\n const startX = gameLeft + Math.floor((BOARD_WIDTH * 2 - startMsg.length) / 2) + 1;\n const startY = gameTop + Math.floor(BOARD_HEIGHT / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const modeY = startY + 2;\n const marathonLabel = selectedMode === 'marathon' ? '[1] MARATHON' : ' 1 MARATHON';\n const sprintLabel = selectedMode === 'sprint' ? '[2] SPRINT 40L' : ' 2 SPRINT 40L';\n const modePrompt = `MODE: ${marathonLabel} ${sprintLabel}`;\n const modeX = Math.floor((cols - modePrompt.length) / 2);\n output += `\\x1b[${modeY};${modeX}H\\x1b[1m${themeColor}${modePrompt}\\x1b[0m`;\n\n const controls = '←→ MODE ↓ MOVE ↑ ROT SPC DROP ESC MENU';\n const ctrlX = Math.floor((cols - controls.length) / 2);\n output += `\\x1b[${gameTop + BOARD_HEIGHT + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n } else if (gameOver) {\n const overMsg = won ? '══ YOU WIN ══' : '══ GAME OVER ══';\n const overX = gameLeft + Math.floor((BOARD_WIDTH * 2 - overMsg.length) / 2) + 1;\n const overY = gameTop + Math.floor(BOARD_HEIGHT / 2) - 1;\n const overColor = won ? '\\x1b[1;92m' : '\\x1b[1;31m';\n output += `\\x1b[${overY};${overX}H${overColor}${overMsg}\\x1b[0m`;\n\n const finalScore = `SCORE: ${score}`;\n const scoreX = gameLeft + Math.floor((BOARD_WIDTH * 2 - finalScore.length) / 2) + 1;\n output += `\\x1b[${overY + 2};${scoreX}H${themeColor}${finalScore}\\x1b[0m`;\n\n const finalLines = `LINES: ${lines} MODE: ${mode === 'sprint' ? 'SPRINT' : 'MARATHON'}`;\n const linesX = gameLeft + Math.floor((BOARD_WIDTH * 2 - finalLines.length) / 2) + 1;\n output += `\\x1b[${overY + 3};${linesX}H${themeColor}${finalLines}\\x1b[0m`;\n\n const restart = '[ R ] RESTART [ Q ] QUIT';\n const restartX = gameLeft + Math.floor((BOARD_WIDTH * 2 - restart.length) / 2) + 1;\n output += `\\x1b[${overY + 5};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n } else {\n // Draw board with flash effect\n for (let y = 0; y < BOARD_HEIGHT; y++) {\n const isFlashing = flashFrames > 0 && flashRows.includes(y);\n for (let x = 0; x < BOARD_WIDTH; x++) {\n const cell = board[y][x];\n if (cell) {\n if (isFlashing) {\n // Flash effect - alternate between white and original color\n const flashColor = flashFrames % 2 === 0 ? '\\x1b[97m\\x1b[47m' : cell;\n output += `\\x1b[${gameTop + 1 + y};${gameLeft + 1 + x * 2}H${flashColor}██\\x1b[0m`;\n } else {\n output += `\\x1b[${gameTop + 1 + y};${gameLeft + 1 + x * 2}H${cell}██\\x1b[0m`;\n }\n } else if (isFlashing) {\n // Flash empty cells too for full row flash\n const flashColor = flashFrames % 2 === 0 ? '\\x1b[97m\\x1b[47m' : '\\x1b[100m';\n output += `\\x1b[${gameTop + 1 + y};${gameLeft + 1 + x * 2}H${flashColor}██\\x1b[0m`;\n }\n }\n }\n\n // Draw current piece\n const shape = getShape();\n const pieceColor = PIECE_COLORS[currentPiece];\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n const screenY = gameTop + 1 + pieceY + row;\n const screenX = gameLeft + 1 + (pieceX + col) * 2;\n if (pieceY + row >= 0) {\n output += `\\x1b[${screenY};${screenX}H${pieceColor}██\\x1b[0m`;\n }\n }\n }\n }\n\n // Ghost piece (preview where piece will land)\n let ghostY = pieceY;\n while (isValidPosition(pieceX, ghostY + 1, currentRotation)) {\n ghostY++;\n }\n if (ghostY !== pieceY) {\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n const screenY = gameTop + 1 + ghostY + row;\n const screenX = gameLeft + 1 + (pieceX + col) * 2;\n if (ghostY + row >= 0) {\n output += `\\x1b[${screenY};${screenX}H\\x1b[2m${pieceColor}░░\\x1b[0m`;\n }\n }\n }\n }\n }\n\n // Draw particles\n for (const p of particles) {\n if (p.life > 0) {\n const px = Math.round(gameLeft + 1 + p.x);\n const py = Math.round(gameTop + 1 + p.y);\n if (px > 0 && px < cols && py > 0 && py < rows) {\n output += `\\x1b[${py};${px}H${p.color}${p.char}\\x1b[0m`;\n }\n }\n }\n\n // Draw combo message\n if (comboFrames > 0 && comboMessage) {\n const msgX = gameLeft + Math.floor((BOARD_WIDTH * 2 - comboMessage.length) / 2) + 1;\n const msgY = gameTop + Math.floor(BOARD_HEIGHT / 2);\n // Pulsing effect\n const pulse = comboFrames % 4 < 2;\n const msgColor = comboMessage.includes('TETRIS') ? (pulse ? '\\x1b[1;93m' : '\\x1b[1;91m') : (pulse ? '\\x1b[1;97m' : '\\x1b[1;96m');\n output += `\\x1b[${msgY};${msgX}H${msgColor}${comboMessage}\\x1b[0m`;\n }\n }\n\n // Stats display - either side panel or compact bar\n if (showSidePanel) {\n // Side panel\n const panelX = gameLeft + BOARD_WIDTH * 2 + 4;\n\n // Score\n output += `\\x1b[${gameTop};${panelX}H${themeColor}┌──────────┐\\x1b[0m`;\n output += `\\x1b[${gameTop + 1};${panelX}H${themeColor}│ SCORE │\\x1b[0m`;\n output += `\\x1b[${gameTop + 2};${panelX}H${themeColor}│ ${score.toString().padStart(8, ' ')} │\\x1b[0m`;\n output += `\\x1b[${gameTop + 3};${panelX}H${themeColor}├──────────┤\\x1b[0m`;\n output += `\\x1b[${gameTop + 4};${panelX}H${themeColor}│ LEVEL │\\x1b[0m`;\n output += `\\x1b[${gameTop + 5};${panelX}H${themeColor}│ ${level.toString().padStart(8, ' ')} │\\x1b[0m`;\n output += `\\x1b[${gameTop + 6};${panelX}H${themeColor}├──────────┤\\x1b[0m`;\n output += `\\x1b[${gameTop + 7};${panelX}H${themeColor}│ LINES │\\x1b[0m`;\n output += `\\x1b[${gameTop + 8};${panelX}H${themeColor}│ ${lines.toString().padStart(8, ' ')} │\\x1b[0m`;\n output += `\\x1b[${gameTop + 9};${panelX}H${themeColor}├──────────┤\\x1b[0m`;\n output += `\\x1b[${gameTop + 10};${panelX}H${themeColor}│ HIGH │\\x1b[0m`;\n output += `\\x1b[${gameTop + 11};${panelX}H${themeColor}│ ${highScore.toString().padStart(8, ' ')} │\\x1b[0m`;\n output += `\\x1b[${gameTop + 12};${panelX}H${themeColor}└──────────┘\\x1b[0m`;\n\n // Next piece preview\n output += `\\x1b[${gameTop + 14};${panelX}H${themeColor}┌──────────┐\\x1b[0m`;\n output += `\\x1b[${gameTop + 15};${panelX}H${themeColor}│ NEXT │\\x1b[0m`;\n output += `\\x1b[${gameTop + 16};${panelX}H${themeColor}│ │\\x1b[0m`;\n output += `\\x1b[${gameTop + 17};${panelX}H${themeColor}│ │\\x1b[0m`;\n output += `\\x1b[${gameTop + 18};${panelX}H${themeColor}│ │\\x1b[0m`;\n output += `\\x1b[${gameTop + 19};${panelX}H${themeColor}└──────────┘\\x1b[0m`;\n\n if (gameStarted && !gameOver) {\n const nextShape = TETROMINOES[nextPiece][0];\n const nextColor = PIECE_COLORS[nextPiece];\n const offsetX = Math.floor((4 - nextShape[0].length) / 2);\n const offsetY = Math.floor((2 - nextShape.length) / 2);\n for (let row = 0; row < nextShape.length; row++) {\n for (let col = 0; col < nextShape[row].length; col++) {\n if (nextShape[row][col]) {\n output += `\\x1b[${gameTop + 16 + offsetY + row};${panelX + 2 + (offsetX + col) * 2}H${nextColor}██\\x1b[0m`;\n }\n }\n }\n }\n\n const modeLabel = mode === 'sprint'\n ? `M:S ${Math.max(0, SPRINT_TARGET_LINES - lines).toString().padStart(3, ' ')}`\n : 'M:MARATHON';\n const modeLabelX = panelX + Math.max(0, Math.floor((12 - modeLabel.length) / 2));\n output += `\\x1b[${gameTop + 20};${modeLabelX}H\\x1b[2m${themeColor}${modeLabel}\\x1b[0m`;\n } else {\n // Compact mode - stats bar above board\n const sprintTail = mode === 'sprint' ? ` TGT:${Math.max(0, SPRINT_TARGET_LINES - lines).toString().padStart(2, '0')}` : '';\n const statsBar = `SCR:${score.toString().padStart(5)} LVL:${level} LNS:${lines.toString().padStart(3)}${sprintTail}`;\n const statsX = gameLeft + Math.floor((BOARD_WIDTH * 2 - statsBar.length) / 2) + 1;\n const statsY = gameTop - 1;\n if (statsY >= 1) {\n output += `\\x1b[${statsY};${statsX}H${themeColor}${statsBar}\\x1b[0m`;\n }\n }\n\n terminal.write(output);\n }\n\n function update() {\n if (!gameStarted || gameOver || paused) return;\n\n // Handle animated hard drop\n if (hardDropping) {\n // Move down 2 rows per frame for fast animation\n let moved = false;\n for (let i = 0; i < 2; i++) {\n if (moveDown()) {\n score += 2;\n moved = true;\n } else {\n break;\n }\n }\n if (!moved) {\n // Can't move down anymore, lock the piece\n hardDropping = false;\n lockPiece();\n }\n return; // Skip normal drop during hard drop animation\n }\n\n dropCounter++;\n if (dropCounter * TICK_MS >= dropInterval) {\n dropCounter = 0;\n if (!moveDown()) {\n lockPiece();\n }\n }\n\n // Update effect timers\n if (shakeFrames > 0) shakeFrames--;\n if (flashFrames > 0) flashFrames--;\n if (comboFrames > 0) comboFrames--;\n\n // Update particles\n for (const p of particles) {\n if (p.life > 0) {\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.2; // Gravity\n p.life--;\n }\n }\n // Remove dead particles\n particles = particles.filter(p => p.life > 0);\n }\n\n // Start game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h'); // Enter alternate buffer\n terminal.write('\\x1b[?25l'); // Hide cursor\n\n initGame(mode);\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) {\n clearInterval(renderInterval);\n return;\n }\n render();\n }, TICK_MS);\n\n const gameInterval = setInterval(() => {\n if (!running) {\n clearInterval(gameInterval);\n return;\n }\n update();\n }, TICK_MS);\n\n // Track space key release to allow next hard drop\n const handleKeyUp = (e: KeyboardEvent) => {\n if (e.key === ' ') {\n hardDropConsumed = false;\n }\n };\n window.addEventListener('keyup', handleKeyUp);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener.dispose();\n window.removeEventListener('keyup', handleKeyUp);\n return;\n }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // Handle ESC key - toggle pause (works on start screen too)\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Q to quit (from start screen, pause, or game over)\n if (key === 'q') {\n if (paused || gameOver || !gameStarted) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n window.removeEventListener('keyup', handleKeyUp);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n }\n\n // Start screen - any key (except ESC/Q handled above) starts the game\n // Skip if paused (ESC menu open on start screen)\n if (!gameStarted && !paused) {\n if (key === 'arrowleft' || key === 'a' || key === '1') {\n selectedMode = 'marathon';\n return;\n }\n if (key === 'arrowright' || key === 'd' || key === '2') {\n selectedMode = 'sprint';\n return;\n }\n if (key === 'tab' || key === 'm') {\n selectedMode = selectedMode === 'marathon' ? 'sprint' : 'marathon';\n return;\n }\n initGame(selectedMode);\n gameStarted = true;\n return;\n }\n\n // Game over - only R to restart\n if (gameOver) {\n if (key === 'r') {\n initGame(mode);\n gameStarted = true;\n }\n return;\n }\n\n // Pause menu actions\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n initGame(mode);\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n window.removeEventListener('keyup', handleKeyUp);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n window.removeEventListener('keyup', handleKeyUp);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n window.removeEventListener('keyup', handleKeyUp);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (key === 'r') {\n initGame(mode);\n gameStarted = true;\n paused = false;\n } else if (key === 'l') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n window.removeEventListener('keyup', handleKeyUp);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (key === 'n') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n window.removeEventListener('keyup', handleKeyUp);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n // Gameplay controls\n switch (domEvent.key) {\n case 'ArrowLeft':\n case 'a':\n moveLeft();\n break;\n case 'ArrowRight':\n case 'd':\n moveRight();\n break;\n case 'ArrowDown':\n case 's':\n if (moveDown()) score += 1;\n break;\n case 'ArrowUp':\n case 'w':\n rotate();\n break;\n case ' ':\n hardDrop();\n break;\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n window.removeEventListener('keyup', handleKeyUp);\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Tower\n *\n * Stack falling blocks perfectly to build the tallest tower.\n * Blocks swing left/right - press space to drop.\n * Overhanging parts fall off, making subsequent blocks narrower.\n * Perfect alignments give bonus points and combo multipliers.\n * Cyberpunk-themed with glitchy effects and theme-aware colors.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Tower Game Controller\n */\nexport interface TowerController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface Block {\n x: number; // Left edge position\n width: number; // Block width\n color: string; // ANSI color code\n}\n\ninterface FallingPiece {\n x: number;\n y: number;\n width: number;\n color: string;\n vy: number;\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\n// Block colors - cyberpunk neon palette\nconst BLOCK_COLORS = [\n '\\x1b[96m', // Cyan\n '\\x1b[95m', // Magenta\n '\\x1b[93m', // Yellow\n '\\x1b[92m', // Green\n '\\x1b[91m', // Red\n '\\x1b[94m', // Blue\n '\\x1b[97m', // White\n];\n\n// ============================================================================\n// MAIN GAME FUNCTION\n// ============================================================================\n\nexport function runTowerGame(terminal: Terminal): TowerController {\n const themeColor = getCurrentThemeColor();\n\n // -------------------------------------------------------------------------\n // CONSTANTS - Lowered minimums for better compatibility\n // -------------------------------------------------------------------------\n const MIN_COLS = 30;\n const MIN_ROWS = 16;\n const INITIAL_BLOCK_WIDTH = 8;\n const MIN_BLOCK_WIDTH = 2;\n const PERFECT_THRESHOLD = 0.5;\n\n // Game dimensions - adaptive\n let GAME_WIDTH = 24;\n let GAME_HEIGHT = 12;\n\n // -------------------------------------------------------------------------\n // STATE\n // -------------------------------------------------------------------------\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let score = 0;\n let highScore = 0;\n let height = 0;\n\n // Positioning\n let gameLeft = 2;\n let gameTop = 4;\n\n // Swinging block state\n let swingX = 0;\n let swingDirection = 1;\n let swingSpeed = 0.2; // Halved for 2x frame rate\n let currentBlockWidth = INITIAL_BLOCK_WIDTH;\n let currentBlockColor = BLOCK_COLORS[0];\n\n // Tower state - blocks stack upward, index 0 = bottom\n let tower: Block[] = [];\n\n // Combo system\n let perfectCombo = 0;\n let maxCombo = 0;\n\n // Visual effects\n let glitchFrame = 0;\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let fallingPieces: FallingPiece[] = [];\n let shakeFrames = 0;\n let shakeIntensity = 0;\n let flashFrames = 0;\n\n // Dropping animation\n let isDropping = false;\n let dropY = 0;\n let dropX = 0;\n let dropWidth = 0;\n let dropColor = '';\n\n // -------------------------------------------------------------------------\n // CONTROLLER\n // -------------------------------------------------------------------------\n const controller: TowerController = {\n stop: () => {\n if (!running) return;\n running = false;\n },\n get isRunning() { return running; }\n };\n\n // -------------------------------------------------------------------------\n // ASCII ART TITLE\n // -------------------------------------------------------------------------\n const title = [\n '▀█▀ █▀█ █ █ █ █▀▀ █▀█',\n ' █ █▄█ ▀▄▀▄▀ ██▄ █▀▄',\n ];\n\n // -------------------------------------------------------------------------\n // EFFECTS\n // -------------------------------------------------------------------------\n\n function spawnParticles(x: number, y: number, count: number, color: string) {\n const chars = ['✦', '★', '◆', '●'];\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.15 + Math.random() * 0.25; // Halved for 2x frame rate\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5 - 0.1, // Halved for 2x frame rate\n life: 24 + Math.floor(Math.random() * 16), // Doubled for 2x frame rate\n });\n }\n }\n\n function spawnFallingPiece(x: number, y: number, width: number, color: string) {\n fallingPieces.push({\n x,\n y,\n width,\n color,\n vy: 0.1,\n });\n }\n\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 24, color });\n }\n\n function triggerShake(frames: number, intensity: number) {\n shakeFrames = frames;\n shakeIntensity = intensity;\n }\n\n // -------------------------------------------------------------------------\n // GAME LOGIC\n // -------------------------------------------------------------------------\n\n function initGame() {\n // Adaptive sizing\n const cols = terminal.cols;\n const rows = terminal.rows;\n GAME_WIDTH = Math.min(32, Math.max(20, cols - 8));\n GAME_HEIGHT = Math.min(16, Math.max(8, rows - 10));\n\n score = 0;\n height = 0;\n gameOver = false;\n paused = false;\n perfectCombo = 0;\n maxCombo = 0;\n\n // Reset swinging block\n currentBlockWidth = Math.min(INITIAL_BLOCK_WIDTH, Math.floor(GAME_WIDTH / 3));\n swingX = Math.floor((GAME_WIDTH - currentBlockWidth) / 2);\n swingDirection = 1;\n swingSpeed = 0.2; // Halved for 2x frame rate\n currentBlockColor = BLOCK_COLORS[0];\n\n // Reset tower with initial platform\n tower = [];\n const platformWidth = currentBlockWidth;\n const platformX = Math.floor((GAME_WIDTH - platformWidth) / 2);\n tower.push({\n x: platformX,\n width: platformWidth,\n color: '\\x1b[2m\\x1b[90m',\n });\n\n // Reset effects\n particles = [];\n scorePopups = [];\n fallingPieces = [];\n shakeFrames = 0;\n flashFrames = 0;\n isDropping = false;\n }\n\n function getTopBlock(): Block {\n return tower[tower.length - 1];\n }\n\n function dropBlock() {\n if (isDropping || gameOver) return;\n\n isDropping = true;\n dropX = swingX;\n dropY = 0; // Start at top\n dropWidth = currentBlockWidth;\n dropColor = currentBlockColor;\n }\n\n function landBlock() {\n const topBlock = getTopBlock();\n\n // Calculate overlap\n const dropLeft = dropX;\n const dropRight = dropX + dropWidth;\n const topLeft = topBlock.x;\n const topRight = topBlock.x + topBlock.width;\n\n const overlapLeft = Math.max(dropLeft, topLeft);\n const overlapRight = Math.min(dropRight, topRight);\n const overlapWidth = overlapRight - overlapLeft;\n\n // Landing Y position (in game coordinates, 0 = top of visible area)\n const landY = GAME_HEIGHT - tower.length - 1;\n\n if (overlapWidth < MIN_BLOCK_WIDTH) {\n // Block missed - game over\n gameOver = true;\n if (score > highScore) highScore = score;\n if (perfectCombo > maxCombo) maxCombo = perfectCombo;\n\n spawnParticles(dropX + dropWidth / 2, landY, 15, '\\x1b[91m');\n triggerShake(10, 3);\n return;\n }\n\n // Check for perfect alignment\n const isPerfect = Math.abs(dropLeft - topLeft) < PERFECT_THRESHOLD &&\n Math.abs(dropRight - topRight) < PERFECT_THRESHOLD;\n\n let points = 10;\n\n if (isPerfect) {\n perfectCombo++;\n const comboBonus = Math.min(perfectCombo * 5, 50);\n points += 10 + comboBonus;\n\n flashFrames = 6;\n spawnParticles(dropX + dropWidth / 2, landY, 12, '\\x1b[93m');\n\n const popupText = perfectCombo > 1 ? `PERFECT! x${perfectCombo}` : 'PERFECT!';\n addScorePopup(\n Math.floor(GAME_WIDTH / 2) - Math.floor(popupText.length / 2),\n Math.floor(GAME_HEIGHT / 2),\n popupText,\n perfectCombo > 3 ? '\\x1b[1;91m' : '\\x1b[1;93m'\n );\n\n triggerShake(4, 1);\n } else {\n if (perfectCombo > maxCombo) maxCombo = perfectCombo;\n perfectCombo = 0;\n\n // Spawn falling pieces for overhanging parts\n if (dropLeft < topLeft) {\n const overhangWidth = topLeft - dropLeft;\n spawnFallingPiece(dropLeft, landY, overhangWidth, dropColor);\n spawnParticles(dropLeft + overhangWidth / 2, landY, 5, dropColor);\n }\n if (dropRight > topRight) {\n const overhangWidth = dropRight - topRight;\n spawnFallingPiece(topRight, landY, overhangWidth, dropColor);\n spawnParticles(topRight + overhangWidth / 2, landY, 5, dropColor);\n }\n\n triggerShake(3, 1);\n }\n\n score += points;\n height++;\n\n if (points > 10) {\n addScorePopup(overlapLeft + overlapWidth / 2, landY - 1, `+${points}`, '\\x1b[92m');\n }\n\n // Add the landed block to tower\n tower.push({\n x: overlapLeft,\n width: overlapWidth,\n color: dropColor,\n });\n\n // Update next block\n currentBlockWidth = overlapWidth;\n currentBlockColor = BLOCK_COLORS[tower.length % BLOCK_COLORS.length];\n\n // Reset swing position\n swingX = Math.floor((GAME_WIDTH - currentBlockWidth) / 2);\n swingDirection = Math.random() > 0.5 ? 1 : -1;\n\n // Increase speed slightly (halved for 2x frame rate)\n swingSpeed = Math.min(0.5, swingSpeed + 0.01);\n\n // Reset drop state\n isDropping = false;\n }\n\n function update() {\n if (paused || !gameStarted || gameOver) return;\n\n // Update swinging block\n if (!isDropping) {\n swingX += swingDirection * swingSpeed;\n if (swingX <= 0) {\n swingX = 0;\n swingDirection = 1;\n } else if (swingX + currentBlockWidth >= GAME_WIDTH) {\n swingX = GAME_WIDTH - currentBlockWidth;\n swingDirection = -1;\n }\n }\n\n // Update dropping animation (dropY is 0-1 progress)\n if (isDropping) {\n dropY += 0.08; // Progress speed (0.08 = ~12 frames to land)\n\n if (dropY >= 1) {\n dropY = 1;\n landBlock();\n }\n }\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.015; // Halved for 2x frame rate\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update falling pieces\n for (let i = fallingPieces.length - 1; i >= 0; i--) {\n const piece = fallingPieces[i];\n piece.y += piece.vy;\n piece.vy += 0.1;\n if (piece.y > GAME_HEIGHT + 5) {\n fallingPieces.splice(i, 1);\n }\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.15;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n if (flashFrames > 0) flashFrames--;\n }\n\n // -------------------------------------------------------------------------\n // RENDERING\n // -------------------------------------------------------------------------\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n if (shakeFrames > 0) shakeFrames--;\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n const hint = needWidth && needHeight ? 'Make pane larger'\n : needWidth ? 'Make pane wider →' : 'Make pane taller ↓';\n const msg2 = `Need: ${MIN_COLS}×${MIN_ROWS} Have: ${cols}×${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Center game area\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH - 2) / 2));\n gameTop = Math.max(4, Math.floor((rows - GAME_HEIGHT - 6) / 2));\n\n // Apply screen shake\n let renderLeft = gameLeft;\n let renderTop = gameTop;\n if (shakeFrames > 0) {\n renderLeft += Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n renderTop += Math.floor((Math.random() - 0.5) * shakeIntensity);\n }\n\n // Glitch title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[1;${titleX}H\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `\\x1b[1;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n // Stats bar\n const stats = `HEIGHT: ${height} SCORE: ${score.toString().padStart(5, '0')} COMBO: ${perfectCombo}`;\n const statsX = Math.floor((cols - stats.length) / 2);\n output += `\\x1b[${gameTop - 1};${statsX}H${themeColor}${stats}\\x1b[0m`;\n\n // Game border with flash effect\n const borderColor = flashFrames > 0 ? '\\x1b[1;93m' : themeColor;\n output += `\\x1b[${renderTop};${renderLeft}H${borderColor}╔${'═'.repeat(GAME_WIDTH)}╗\\x1b[0m`;\n for (let y = 0; y < GAME_HEIGHT; y++) {\n output += `\\x1b[${renderTop + 1 + y};${renderLeft}H${borderColor}║\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + y};${renderLeft + GAME_WIDTH + 1}H${borderColor}║\\x1b[0m`;\n }\n output += `\\x1b[${renderTop + GAME_HEIGHT + 1};${renderLeft}H${borderColor}╚${'═'.repeat(GAME_WIDTH)}╝\\x1b[0m`;\n\n // PAUSE MENU\n if (paused) {\n const pauseMsg = '══ PAUSED ══';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseY = gameTop + Math.floor(GAME_HEIGHT / 2) - 2;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n }\n // START SCREEN\n else if (!gameStarted) {\n const startMsg = '[ PRESS SPACE TO START ]';\n const startX = gameLeft + Math.floor((GAME_WIDTH - startMsg.length) / 2) + 1;\n const startY = gameTop + Math.floor(GAME_HEIGHT / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = 'SPACE to drop block';\n const ctrlX = gameLeft + Math.floor((GAME_WIDTH - controls.length) / 2) + 1;\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n\n const hint1 = 'Stack blocks perfectly!';\n const hint1X = gameLeft + Math.floor((GAME_WIDTH - hint1.length) / 2) + 1;\n output += `\\x1b[${startY + 4};${hint1X}H\\x1b[2m${themeColor}${hint1}\\x1b[0m`;\n }\n // GAME OVER\n else if (gameOver) {\n const overMsg = '╔══ GAME OVER ══╗';\n const overX = gameLeft + Math.floor((GAME_WIDTH - overMsg.length) / 2) + 1;\n const overY = gameTop + Math.floor(GAME_HEIGHT / 2) - 2;\n output += `\\x1b[${overY};${overX}H\\x1b[1;91m${overMsg}\\x1b[0m`;\n\n const scoreLine = `HEIGHT: ${height} SCORE: ${score}`;\n const scoreX = gameLeft + Math.floor((GAME_WIDTH - scoreLine.length) / 2) + 1;\n output += `\\x1b[${overY + 1};${scoreX}H${themeColor}${scoreLine}\\x1b[0m`;\n\n const highLine = `HIGH: ${highScore} BEST COMBO: ${maxCombo}`;\n const highX = gameLeft + Math.floor((GAME_WIDTH - highLine.length) / 2) + 1;\n output += `\\x1b[${overY + 2};${highX}H\\x1b[2m${themeColor}${highLine}\\x1b[0m`;\n\n const restart = '╚ [R] RESTART [Q] QUIT ╝';\n const restartX = gameLeft + Math.floor((GAME_WIDTH - restart.length) / 2) + 1;\n output += `\\x1b[${overY + 4};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n }\n // GAMEPLAY\n else {\n // Fixed swing position at upper portion of screen\n const SWING_ROW = 3; // Fixed row for swinging block (near top)\n\n // SIMPLIFIED: No camera scrolling for now - just render all blocks\n // Block 0 at bottom (row GAME_HEIGHT), each subsequent block one row up\n for (let i = 0; i < tower.length; i++) {\n const block = tower[i];\n // i=0 at bottom (highest screenY), i=N-1 at top (lowest screenY)\n const screenY = renderTop + GAME_HEIGHT - i;\n\n if (screenY > renderTop && screenY <= renderTop + GAME_HEIGHT) {\n const blockStr = '█'.repeat(Math.max(1, Math.round(block.width)));\n const blockX = renderLeft + 1 + Math.round(block.x);\n output += `\\x1b[${screenY};${blockX}H${block.color}${blockStr}\\x1b[0m`;\n }\n }\n\n // Swinging block at fixed position\n const swingScreenY = renderTop + SWING_ROW;\n\n // Landing position: one row above the current top of tower\n // Top block is at i = tower.length - 1, which is at screenY = renderTop + GAME_HEIGHT - (tower.length - 1)\n // New block lands one row above = screenY - 1 = renderTop + GAME_HEIGHT - tower.length\n const landingScreenY = renderTop + GAME_HEIGHT - tower.length;\n const dropDistance = landingScreenY - swingScreenY; // How far to drop\n\n // Draw dropping block (animates from swing down to landing)\n if (isDropping) {\n const dropProgress = dropY; // 0 to 1\n const dropScreenY = Math.round(swingScreenY + dropProgress * dropDistance);\n if (dropScreenY > renderTop && dropScreenY <= renderTop + GAME_HEIGHT) {\n const blockStr = '█'.repeat(Math.round(dropWidth));\n output += `\\x1b[${dropScreenY};${renderLeft + 1 + Math.round(dropX)}H${dropColor}${blockStr}\\x1b[0m`;\n }\n }\n\n // Draw swinging block at fixed position\n if (!isDropping) {\n const blockStr = '█'.repeat(Math.round(currentBlockWidth));\n output += `\\x1b[${swingScreenY};${renderLeft + 1 + Math.round(swingX)}H${currentBlockColor}${blockStr}\\x1b[0m`;\n\n // Draw guide line at landing position\n if (landingScreenY > swingScreenY && landingScreenY <= renderTop + GAME_HEIGHT) {\n const guideStr = '░'.repeat(Math.round(currentBlockWidth));\n output += `\\x1b[${landingScreenY};${renderLeft + 1 + Math.round(swingX)}H\\x1b[2m${currentBlockColor}${guideStr}\\x1b[0m`;\n }\n }\n\n // Draw falling pieces\n for (const piece of fallingPieces) {\n const screenY = Math.round(renderTop + 1 + piece.y);\n if (screenY > renderTop && screenY <= renderTop + GAME_HEIGHT + 2) {\n const pieceStr = '▓'.repeat(Math.round(piece.width));\n output += `\\x1b[${screenY};${renderLeft + 1 + Math.round(piece.x)}H\\x1b[2m${piece.color}${pieceStr}\\x1b[0m`;\n }\n }\n\n // Draw particles\n for (const p of particles) {\n const screenX = Math.round(renderLeft + 1 + p.x);\n const screenY = Math.round(renderTop + 1 + p.y);\n if (screenX > renderLeft && screenX < renderLeft + GAME_WIDTH + 1 &&\n screenY > renderTop && screenY < renderTop + GAME_HEIGHT + 1) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const screenX = Math.round(renderLeft + 1 + popup.x);\n const screenY = Math.round(renderTop + 1 + popup.y);\n if (screenY > renderTop && screenY < renderTop + GAME_HEIGHT + 1) {\n const alpha = popup.frames > 10 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n }\n\n // Bottom hint\n const hint = gameStarted && !gameOver && !paused ? `HIGH: ${highScore} [ ESC ] MENU` : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${gameTop + GAME_HEIGHT + 3};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n // -------------------------------------------------------------------------\n // GAME LOOP\n // -------------------------------------------------------------------------\n\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) { clearInterval(gameInterval); return; }\n update();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key;\n const keyLower = key.toLowerCase();\n\n // Pause menu handling\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(pauseMenuSelection, PAUSE_MENU_ITEMS.length, key, domEvent);\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: paused = false; break; // Resume\n case 1: initGame(); gameStarted = true; paused = false; break; // Restart\n case 2: controller.stop(); dispatchGameQuit(terminal); break; // Quit\n case 3: controller.stop(); dispatchGamesMenu(terminal); break; // List Games\n case 4: controller.stop(); dispatchGameSwitch(terminal); break; // Next Game\n }\n return;\n }\n return;\n }\n\n // Game over controls\n if (gameOver) {\n if (keyLower === 'r') {\n initGame();\n gameStarted = true;\n return;\n }\n if (keyLower === 'q' || key === 'Escape') {\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n return;\n }\n\n // In-game controls\n if (key === 'Escape') {\n paused = true;\n pauseMenuSelection = 0;\n return;\n }\n\n if (!gameStarted) {\n if (key === ' ') {\n gameStarted = true;\n }\n return;\n }\n\n // Drop block\n if (key === ' ') {\n dropBlock();\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n keyListener.dispose();\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n terminal.write('\\x1b[?25h');\n terminal.write('\\x1b[?1049l');\n originalStop();\n };\n }, 50);\n\n return controller;\n}\n","/**\n * Hyper Tron\n *\n * Light cycles - you vs AI. Don't hit walls or trails.\n * Cyberpunk-themed with glitchy effects and theme-aware colors.\n * Best of 5 rounds, speed increases each round, optional shrinking arena.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Tron Game Controller\n */\nexport interface TronController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ntype Direction = 'up' | 'down' | 'left' | 'right';\n\ninterface Position {\n x: number;\n y: number;\n}\n\ninterface LightCycle {\n x: number;\n y: number;\n direction: Direction;\n trail: Position[];\n alive: boolean;\n color: string;\n char: string;\n trailChar: string;\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\n// ============================================================================\n// MAIN GAME FUNCTION\n// ============================================================================\n\nexport function runTronGame(terminal: Terminal): TronController {\n const themeColor = getCurrentThemeColor();\n\n // -------------------------------------------------------------------------\n // CONSTANTS\n // -------------------------------------------------------------------------\n const MIN_COLS = 40;\n const MIN_ROWS = 18;\n const GAME_WIDTH = 46;\n const GAME_HEIGHT = 18;\n const ROUNDS_TO_WIN = 3;\n const BASE_SPEED = 100; // ms per move\n const SPEED_DECREASE_PER_ROUND = 12; // Faster each round\n const COUNTDOWN_SECONDS = 3;\n const SHRINK_INTERVAL = 150; // ticks before arena shrinks\n const SHRINK_AMOUNT = 1; // How much to shrink per side\n\n // -------------------------------------------------------------------------\n // STATE\n // -------------------------------------------------------------------------\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let matchOver = false;\n\n // Positioning\n let gameLeft = 2;\n let gameTop = 5;\n\n // Round state\n let currentRound = 1;\n let playerWins = 0;\n let aiWins = 0;\n let countdown = 0; // Countdown before round starts\n let countdownTimer: ReturnType<typeof setInterval> | null = null;\n let roundInProgress = false;\n\n // Arena shrinking\n const shrinkEnabled = true;\n let shrinkTicks = 0;\n let arenaMinX = 0;\n let arenaMaxX = GAME_WIDTH - 1;\n let arenaMinY = 0;\n let arenaMaxY = GAME_HEIGHT - 1;\n\n // Light cycles\n let player: LightCycle;\n let ai: LightCycle;\n let nextPlayerDirection: Direction = 'right';\n\n // Visual effects\n let glitchFrame = 0;\n let particles: Particle[] = [];\n let shakeFrames = 0;\n let shakeIntensity = 0;\n let winnerMessage = '';\n let gameSpeed = BASE_SPEED;\n let gameInterval: ReturnType<typeof setInterval> | null = null;\n\n // -------------------------------------------------------------------------\n // CONTROLLER\n // -------------------------------------------------------------------------\n const controller: TronController = {\n stop: () => {\n if (!running) return;\n running = false;\n },\n get isRunning() { return running; }\n };\n\n // -------------------------------------------------------------------------\n // ASCII ART TITLE\n // -------------------------------------------------------------------------\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ ▀█▀ █▀█ █▀█ █▄ █',\n '█▀█ █ █▀▀ ██▄ █▀▄ █ █▀▄ █▄█ █ ▀█',\n ];\n\n // -------------------------------------------------------------------------\n // EFFECTS\n // -------------------------------------------------------------------------\n\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['░', '▒', '▓', '█', '◆']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.3 + Math.random() * 0.5;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 12 + Math.floor(Math.random() * 10),\n });\n }\n }\n\n function spawnExplosion(x: number, y: number, color: string) {\n // Big explosion on crash\n spawnParticles(x, y, 20, color, ['✗', '×', '░', '▒', '▓', '█']);\n triggerShake(12, 3);\n }\n\n function triggerShake(frames: number, intensity: number) {\n shakeFrames = frames;\n shakeIntensity = intensity;\n }\n\n // -------------------------------------------------------------------------\n // GAME LOGIC\n // -------------------------------------------------------------------------\n\n function initGame() {\n currentRound = 1;\n playerWins = 0;\n aiWins = 0;\n matchOver = false;\n gameOver = false;\n paused = false;\n\n // Reset effects\n particles = [];\n shakeFrames = 0;\n winnerMessage = '';\n\n initRound();\n }\n\n function initRound() {\n // Reset arena\n arenaMinX = 0;\n arenaMaxX = GAME_WIDTH - 1;\n arenaMinY = 0;\n arenaMaxY = GAME_HEIGHT - 1;\n shrinkTicks = 0;\n\n // Calculate speed for this round\n gameSpeed = Math.max(40, BASE_SPEED - (currentRound - 1) * SPEED_DECREASE_PER_ROUND);\n\n // Initialize player (left side, moving right)\n player = {\n x: 5,\n y: Math.floor(GAME_HEIGHT / 2),\n direction: 'right',\n trail: [],\n alive: true,\n color: themeColor,\n char: '█',\n trailChar: '│',\n };\n\n // Initialize AI (right side, moving left)\n ai = {\n x: GAME_WIDTH - 6,\n y: Math.floor(GAME_HEIGHT / 2),\n direction: 'left',\n trail: [],\n alive: true,\n color: '\\x1b[91m', // Red for AI\n char: '█',\n trailChar: '│',\n };\n\n nextPlayerDirection = 'right';\n roundInProgress = false;\n particles = [];\n winnerMessage = '';\n\n // Start countdown\n countdown = COUNTDOWN_SECONDS;\n if (countdownTimer) clearInterval(countdownTimer);\n countdownTimer = setInterval(() => {\n countdown--;\n if (countdown <= 0) {\n if (countdownTimer) clearInterval(countdownTimer);\n countdownTimer = null;\n roundInProgress = true;\n startGameLoop();\n }\n }, 1000);\n }\n\n function startGameLoop() {\n if (gameInterval) clearInterval(gameInterval);\n gameInterval = setInterval(() => {\n if (!running) {\n if (gameInterval) clearInterval(gameInterval);\n return;\n }\n update();\n }, gameSpeed);\n }\n\n function stopGameLoop() {\n if (gameInterval) {\n clearInterval(gameInterval);\n gameInterval = null;\n }\n }\n\n function getTrailChar(dir: Direction): string {\n switch (dir) {\n case 'up':\n case 'down':\n return '│';\n case 'left':\n case 'right':\n return '─';\n }\n }\n\n function moveCycle(cycle: LightCycle) {\n if (!cycle.alive) return;\n\n // Add current position to trail\n cycle.trail.push({ x: cycle.x, y: cycle.y });\n cycle.trailChar = getTrailChar(cycle.direction);\n\n // Move\n switch (cycle.direction) {\n case 'up': cycle.y--; break;\n case 'down': cycle.y++; break;\n case 'left': cycle.x--; break;\n case 'right': cycle.x++; break;\n }\n }\n\n function checkCollision(cycle: LightCycle): boolean {\n // Wall collision (including shrinking arena)\n if (cycle.x <= arenaMinX || cycle.x >= arenaMaxX ||\n cycle.y <= arenaMinY || cycle.y >= arenaMaxY) {\n return true;\n }\n\n // Self trail collision\n for (const pos of cycle.trail) {\n if (pos.x === cycle.x && pos.y === cycle.y) {\n return true;\n }\n }\n\n // Other cycle trail collision\n const other = cycle === player ? ai : player;\n for (const pos of other.trail) {\n if (pos.x === cycle.x && pos.y === cycle.y) {\n return true;\n }\n }\n\n // Head-on collision with other cycle\n if (cycle.x === other.x && cycle.y === other.y) {\n return true;\n }\n\n return false;\n }\n\n function updateAI() {\n if (!ai.alive || !player.alive) return;\n\n // AI pathfinding - avoid walls and trails\n const possibleMoves: Direction[] = [];\n const opposite: Record<Direction, Direction> = {\n 'up': 'down',\n 'down': 'up',\n 'left': 'right',\n 'right': 'left',\n };\n\n const directions: Direction[] = ['up', 'down', 'left', 'right'];\n const currentOpposite = opposite[ai.direction];\n\n for (const dir of directions) {\n // Can't reverse\n if (dir === currentOpposite) continue;\n\n const testX = ai.x + (dir === 'left' ? -1 : dir === 'right' ? 1 : 0);\n const testY = ai.y + (dir === 'up' ? -1 : dir === 'down' ? 1 : 0);\n\n // Check if move is safe\n if (isSafePosition(testX, testY)) {\n possibleMoves.push(dir);\n }\n }\n\n if (possibleMoves.length === 0) {\n // No safe moves, keep going (will crash)\n return;\n }\n\n // Score each move - prefer moves that lead to more open space\n let bestMove = possibleMoves[0];\n let bestScore = -Infinity;\n\n for (const move of possibleMoves) {\n const testX = ai.x + (move === 'left' ? -1 : move === 'right' ? 1 : 0);\n const testY = ai.y + (move === 'up' ? -1 : move === 'down' ? 1 : 0);\n const score = evaluatePosition(testX, testY, move);\n if (score > bestScore) {\n bestScore = score;\n bestMove = move;\n }\n }\n\n // Add some randomness to make AI less predictable\n if (possibleMoves.length > 1 && Math.random() < 0.15) {\n bestMove = possibleMoves[Math.floor(Math.random() * possibleMoves.length)];\n }\n\n ai.direction = bestMove;\n }\n\n function isSafePosition(x: number, y: number): boolean {\n // Wall check\n if (x <= arenaMinX || x >= arenaMaxX || y <= arenaMinY || y >= arenaMaxY) {\n return false;\n }\n\n // Trail check\n for (const pos of player.trail) {\n if (pos.x === x && pos.y === y) return false;\n }\n for (const pos of ai.trail) {\n if (pos.x === x && pos.y === y) return false;\n }\n\n // Player position check\n if (player.x === x && player.y === y) return false;\n\n return true;\n }\n\n function evaluatePosition(x: number, y: number, direction: Direction): number {\n let score = 0;\n\n // Count open spaces in a cone in front\n const dx = direction === 'left' ? -1 : direction === 'right' ? 1 : 0;\n const dy = direction === 'up' ? -1 : direction === 'down' ? 1 : 0;\n\n // Look ahead 5 cells\n for (let i = 1; i <= 5; i++) {\n const checkX = x + dx * i;\n const checkY = y + dy * i;\n if (isSafePosition(checkX, checkY)) {\n score += 5 - i; // Closer cells worth more\n } else {\n break;\n }\n }\n\n // Prefer staying in center of arena\n const centerX = (arenaMinX + arenaMaxX) / 2;\n const centerY = (arenaMinY + arenaMaxY) / 2;\n const distFromCenter = Math.abs(x - centerX) + Math.abs(y - centerY);\n score -= distFromCenter * 0.1;\n\n // Try to cut off player - head toward their direction\n const distToPlayer = Math.abs(x - player.x) + Math.abs(y - player.y);\n if (distToPlayer < 10) {\n score += (10 - distToPlayer) * 0.5;\n }\n\n return score;\n }\n\n function updateArena() {\n if (!shrinkEnabled) return;\n\n shrinkTicks++;\n if (shrinkTicks >= SHRINK_INTERVAL) {\n shrinkTicks = 0;\n\n // Shrink arena\n const canShrinkX = arenaMaxX - arenaMinX > 20;\n const canShrinkY = arenaMaxY - arenaMinY > 10;\n\n if (canShrinkX || canShrinkY) {\n if (canShrinkX) {\n arenaMinX += SHRINK_AMOUNT;\n arenaMaxX -= SHRINK_AMOUNT;\n }\n if (canShrinkY) {\n arenaMinY += SHRINK_AMOUNT;\n arenaMaxY -= SHRINK_AMOUNT;\n }\n\n // Light shake to indicate shrink\n triggerShake(4, 1);\n }\n }\n }\n\n function update() {\n if (!gameStarted || gameOver || paused || !roundInProgress) return;\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.03;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update AI\n updateAI();\n\n // Apply player direction change\n player.direction = nextPlayerDirection;\n\n // Move cycles\n moveCycle(player);\n moveCycle(ai);\n\n // Check collisions\n const playerCollided = checkCollision(player);\n const aiCollided = checkCollision(ai);\n\n if (playerCollided && aiCollided) {\n // Both crashed - tie, no points\n player.alive = false;\n ai.alive = false;\n spawnExplosion(player.x, player.y, player.color);\n spawnExplosion(ai.x, ai.y, ai.color);\n winnerMessage = 'DRAW!';\n endRound();\n } else if (playerCollided) {\n player.alive = false;\n spawnExplosion(player.x, player.y, player.color);\n aiWins++;\n winnerMessage = 'AI WINS ROUND!';\n endRound();\n } else if (aiCollided) {\n ai.alive = false;\n spawnExplosion(ai.x, ai.y, ai.color);\n playerWins++;\n winnerMessage = 'YOU WIN ROUND!';\n endRound();\n }\n\n // Update arena shrinking\n updateArena();\n }\n\n function endRound() {\n stopGameLoop();\n roundInProgress = false;\n\n // Check for match end\n if (playerWins >= ROUNDS_TO_WIN) {\n matchOver = true;\n gameOver = true;\n winnerMessage = 'VICTORY! YOU WIN THE MATCH!';\n } else if (aiWins >= ROUNDS_TO_WIN) {\n matchOver = true;\n gameOver = true;\n winnerMessage = 'DEFEAT! AI WINS THE MATCH!';\n }\n }\n\n function nextRound() {\n if (!matchOver && !gameOver) {\n currentRound++;\n initRound();\n }\n }\n\n // -------------------------------------------------------------------------\n // RENDERING\n // -------------------------------------------------------------------------\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Effect timers\n if (shakeFrames > 0) shakeFrames--;\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n const hint = needWidth && needHeight ? 'Make pane larger'\n : needWidth ? 'Make pane wider \\u2192' : 'Make pane taller \\u2193';\n const msg2 = `Need: ${MIN_COLS}\\u00d7${MIN_ROWS} Have: ${cols}\\u00d7${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Center game area\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH - 2) / 2));\n gameTop = Math.max(4, Math.floor((rows - GAME_HEIGHT - 8) / 2));\n\n // Apply screen shake\n let renderLeft = gameLeft;\n let renderTop = gameTop;\n if (shakeFrames > 0) {\n renderLeft += Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n renderTop += Math.floor((Math.random() - 0.5) * shakeIntensity);\n }\n\n // Glitch title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[1;${titleX}H\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `\\x1b[1;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n // Stats bar\n const roundInfo = `ROUND ${currentRound}`;\n const scoreInfo = `YOU: ${playerWins} AI: ${aiWins} (First to ${ROUNDS_TO_WIN})`;\n const statsX = Math.floor((cols - scoreInfo.length) / 2);\n output += `\\x1b[${gameTop - 1};${statsX}H${themeColor}${roundInfo} ${scoreInfo}\\x1b[0m`;\n\n // Game border - draw full arena, then overlay shrink borders\n output += `\\x1b[${renderTop};${renderLeft}H${themeColor}\\x1b[2m\\u2554${'═'.repeat(GAME_WIDTH)}\\u2557\\x1b[0m`;\n for (let y = 0; y < GAME_HEIGHT; y++) {\n output += `\\x1b[${renderTop + 1 + y};${renderLeft}H${themeColor}\\x1b[2m\\u2551\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + y};${renderLeft + GAME_WIDTH + 1}H${themeColor}\\x1b[2m\\u2551\\x1b[0m`;\n }\n output += `\\x1b[${renderTop + GAME_HEIGHT + 1};${renderLeft}H${themeColor}\\x1b[2m\\u255a${'═'.repeat(GAME_WIDTH)}\\u255d\\x1b[0m`;\n\n // Draw shrinking arena borders (bright)\n if (shrinkEnabled && (arenaMinX > 0 || arenaMinY > 0)) {\n // Draw active arena boundary\n const shrinkColor = '\\x1b[1;93m'; // Bright yellow warning\n for (let x = arenaMinX; x <= arenaMaxX; x++) {\n output += `\\x1b[${renderTop + 1 + arenaMinY};${renderLeft + 1 + x}H${shrinkColor}\\u2500\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + arenaMaxY};${renderLeft + 1 + x}H${shrinkColor}\\u2500\\x1b[0m`;\n }\n for (let y = arenaMinY; y <= arenaMaxY; y++) {\n output += `\\x1b[${renderTop + 1 + y};${renderLeft + 1 + arenaMinX}H${shrinkColor}\\u2502\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + y};${renderLeft + 1 + arenaMaxX}H${shrinkColor}\\u2502\\x1b[0m`;\n }\n }\n\n // PAUSE MENU\n if (paused) {\n const pauseMsg = '\\u2550\\u2550 PAUSED \\u2550\\u2550';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseY = gameTop + Math.floor(GAME_HEIGHT / 2) - 3;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '\\u2191\\u2193 select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n }\n // START SCREEN\n else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO PLAY ]';\n const startX = gameLeft + Math.floor((GAME_WIDTH - startMsg.length) / 2) + 1;\n const startY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = '\\u2190\\u2191\\u2192\\u2193 TURN (no reverse)';\n const ctrlX = gameLeft + Math.floor((GAME_WIDTH - controls.length) / 2) + 1;\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n\n const info = 'Last cycle alive wins!';\n const infoX = gameLeft + Math.floor((GAME_WIDTH - info.length) / 2) + 1;\n output += `\\x1b[${startY + 3};${infoX}H\\x1b[2m${themeColor}${info}\\x1b[0m`;\n }\n // COUNTDOWN\n else if (countdown > 0) {\n // Draw cycles at starting positions\n output += `\\x1b[${renderTop + 1 + player.y};${renderLeft + 1 + player.x}H${player.color}${player.char}\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + ai.y};${renderLeft + 1 + ai.x}H${ai.color}${ai.char}\\x1b[0m`;\n\n const countdownStr = countdown.toString();\n const countdownX = gameLeft + Math.floor(GAME_WIDTH / 2);\n const countdownY = gameTop + Math.floor(GAME_HEIGHT / 2);\n output += `\\x1b[${countdownY};${countdownX}H\\x1b[1;97m${countdownStr}\\x1b[0m`;\n }\n // ROUND END (not match over)\n else if (!roundInProgress && !matchOver && gameStarted) {\n // Draw final state\n output = renderTrailsAndCycles(output, renderLeft, renderTop);\n\n // Winner message\n const msgX = gameLeft + Math.floor((GAME_WIDTH - winnerMessage.length) / 2) + 1;\n const msgY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n const msgColor = winnerMessage.includes('YOU') ? '\\x1b[1;92m' : '\\x1b[1;91m';\n output += `\\x1b[${msgY};${msgX}H${msgColor}${winnerMessage}\\x1b[0m`;\n\n const nextMsg = 'Press SPACE for next round';\n const nextX = gameLeft + Math.floor((GAME_WIDTH - nextMsg.length) / 2) + 1;\n output += `\\x1b[${msgY + 2};${nextX}H\\x1b[2m${themeColor}${nextMsg}\\x1b[0m`;\n\n // Draw particles\n output = renderParticles(output, renderLeft, renderTop);\n }\n // MATCH OVER\n else if (gameOver) {\n // Draw final state\n output = renderTrailsAndCycles(output, renderLeft, renderTop);\n\n const overColor = playerWins >= ROUNDS_TO_WIN ? '\\x1b[1;92m' : '\\x1b[1;91m';\n const overMsg = playerWins >= ROUNDS_TO_WIN\n ? '\\u2554\\u2550\\u2550 VICTORY! \\u2550\\u2550\\u2557'\n : '\\u2554\\u2550\\u2550 DEFEAT \\u2550\\u2550\\u2557';\n const overX = gameLeft + Math.floor((GAME_WIDTH - overMsg.length) / 2) + 1;\n const overY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n output += `\\x1b[${overY};${overX}H${overColor}${overMsg}\\x1b[0m`;\n\n const scoreLine = `FINAL: YOU ${playerWins} - ${aiWins} AI`;\n const scoreX = gameLeft + Math.floor((GAME_WIDTH - scoreLine.length) / 2) + 1;\n output += `\\x1b[${overY + 1};${scoreX}H${themeColor}${scoreLine}\\x1b[0m`;\n\n const restart = '\\u255a [R] RESTART [Q] QUIT \\u255d';\n const restartX = gameLeft + Math.floor((GAME_WIDTH - restart.length) / 2) + 1;\n output += `\\x1b[${overY + 2};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n\n // Draw particles\n output = renderParticles(output, renderLeft, renderTop);\n }\n // GAMEPLAY\n else {\n // Draw trails\n for (const pos of player.trail) {\n if (pos.x > arenaMinX && pos.x < arenaMaxX && pos.y > arenaMinY && pos.y < arenaMaxY) {\n output += `\\x1b[${renderTop + 1 + pos.y};${renderLeft + 1 + pos.x}H\\x1b[2m${player.color}\\u2502\\x1b[0m`;\n }\n }\n for (const pos of ai.trail) {\n if (pos.x > arenaMinX && pos.x < arenaMaxX && pos.y > arenaMinY && pos.y < arenaMaxY) {\n output += `\\x1b[${renderTop + 1 + pos.y};${renderLeft + 1 + pos.x}H\\x1b[2m${ai.color}\\u2502\\x1b[0m`;\n }\n }\n\n // Draw cycles\n if (player.alive) {\n output += `\\x1b[${renderTop + 1 + player.y};${renderLeft + 1 + player.x}H\\x1b[1m${player.color}${player.char}\\x1b[0m`;\n }\n if (ai.alive) {\n output += `\\x1b[${renderTop + 1 + ai.y};${renderLeft + 1 + ai.x}H\\x1b[1m${ai.color}${ai.char}\\x1b[0m`;\n }\n\n // Draw particles\n output = renderParticles(output, renderLeft, renderTop);\n }\n\n // Bottom hint\n const hint = gameStarted && !gameOver && !paused\n ? `SPEED: ${Math.round((1 - gameSpeed / BASE_SPEED) * 100) + 100}% [ ESC ] MENU`\n : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${gameTop + GAME_HEIGHT + 3};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n function renderTrailsAndCycles(output: string, renderLeft: number, renderTop: number): string {\n // Draw trails\n for (const pos of player.trail) {\n output += `\\x1b[${renderTop + 1 + pos.y};${renderLeft + 1 + pos.x}H\\x1b[2m${player.color}\\u2502\\x1b[0m`;\n }\n for (const pos of ai.trail) {\n output += `\\x1b[${renderTop + 1 + pos.y};${renderLeft + 1 + pos.x}H\\x1b[2m${ai.color}\\u2502\\x1b[0m`;\n }\n\n // Draw cycles (if alive)\n if (player.alive) {\n output += `\\x1b[${renderTop + 1 + player.y};${renderLeft + 1 + player.x}H\\x1b[1m${player.color}${player.char}\\x1b[0m`;\n }\n if (ai.alive) {\n output += `\\x1b[${renderTop + 1 + ai.y};${renderLeft + 1 + ai.x}H\\x1b[1m${ai.color}${ai.char}\\x1b[0m`;\n }\n\n return output;\n }\n\n function renderParticles(output: string, renderLeft: number, renderTop: number): string {\n for (const p of particles) {\n const screenX = Math.round(renderLeft + 1 + p.x);\n const screenY = Math.round(renderTop + 1 + p.y);\n if (screenX > renderLeft && screenX < renderLeft + GAME_WIDTH + 1 &&\n screenY > renderTop && screenY < renderTop + GAME_HEIGHT + 1) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n return output;\n }\n\n // -------------------------------------------------------------------------\n // GAME LOOP\n // -------------------------------------------------------------------------\n\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const particleInterval = setInterval(() => {\n if (!running) { clearInterval(particleInterval); return; }\n // Update particles even when paused for visual continuity\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.03;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // ESC toggles pause\n if (key === 'escape') {\n paused = !paused;\n if (paused) {\n pauseMenuSelection = 0;\n stopGameLoop();\n } else if (roundInProgress) {\n startGameLoop();\n }\n return;\n }\n\n // Q to quit from pause/game over/start screen\n if (key === 'q' && (paused || gameOver || !gameStarted)) {\n if (countdownTimer) clearInterval(countdownTimer);\n stopGameLoop();\n clearInterval(renderInterval);\n clearInterval(particleInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n\n // Start screen - any key starts\n if (!gameStarted && !paused) {\n gameStarted = true;\n initRound();\n return;\n }\n\n // Game over - R to restart\n if (gameOver) {\n if (key === 'r') {\n initGame();\n gameStarted = true;\n initRound();\n }\n return;\n }\n\n // Round end (not match over) - space for next round\n if (!roundInProgress && !matchOver && gameStarted && !paused) {\n if (key === ' ' || domEvent.key === ' ') {\n nextRound();\n }\n return;\n }\n\n // Pause menu navigation\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n if (roundInProgress) startGameLoop();\n break;\n case 1: // Restart\n initGame();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n if (countdownTimer) clearInterval(countdownTimer);\n stopGameLoop();\n clearInterval(renderInterval);\n clearInterval(particleInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n if (countdownTimer) clearInterval(countdownTimer);\n stopGameLoop();\n clearInterval(renderInterval);\n clearInterval(particleInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n if (countdownTimer) clearInterval(countdownTimer);\n stopGameLoop();\n clearInterval(renderInterval);\n clearInterval(particleInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcuts\n if (key === 'r') {\n initGame();\n gameStarted = true;\n paused = false;\n } else if (key === 'l') {\n if (countdownTimer) clearInterval(countdownTimer);\n stopGameLoop();\n clearInterval(renderInterval);\n clearInterval(particleInterval);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (key === 'n') {\n if (countdownTimer) clearInterval(countdownTimer);\n stopGameLoop();\n clearInterval(renderInterval);\n clearInterval(particleInterval);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n // GAMEPLAY INPUT - arrow keys to turn\n if (roundInProgress && player.alive) {\n const opposite: Record<Direction, Direction> = {\n 'up': 'down',\n 'down': 'up',\n 'left': 'right',\n 'right': 'left',\n };\n\n let newDir: Direction | null = null;\n\n switch (domEvent.key) {\n case 'ArrowUp':\n case 'w':\n newDir = 'up';\n break;\n case 'ArrowDown':\n case 's':\n newDir = 'down';\n break;\n case 'ArrowLeft':\n case 'a':\n newDir = 'left';\n break;\n case 'ArrowRight':\n case 'd':\n newDir = 'right';\n break;\n }\n\n // Can't reverse direction\n if (newDir && newDir !== opposite[player.direction]) {\n nextPlayerDirection = newDir;\n }\n }\n });\n\n // Clean up on stop\n const originalStop = controller.stop;\n controller.stop = () => {\n if (countdownTimer) clearInterval(countdownTimer);\n stopGameLoop();\n clearInterval(renderInterval);\n clearInterval(particleInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Typing Test\n *\n * Cyberpunk-themed typing speed test with glitchy effects,\n * neon visuals, and theme-aware colors.\n * Tests WPM (words per minute) and accuracy.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor, getVerticalAnchor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Typing Test Game Controller\n */\nexport interface TypingTestController {\n stop: () => void;\n isRunning: boolean;\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\n// Word lists for different difficulty levels\nconst WORDS_EASY = [\n 'the', 'be', 'to', 'of', 'and', 'a', 'in', 'that', 'have', 'it',\n 'for', 'not', 'on', 'with', 'he', 'as', 'you', 'do', 'at', 'this',\n 'but', 'his', 'by', 'from', 'they', 'we', 'say', 'her', 'she', 'or',\n 'an', 'will', 'my', 'one', 'all', 'would', 'there', 'their', 'what',\n 'so', 'up', 'out', 'if', 'about', 'who', 'get', 'which', 'go', 'me',\n];\n\nconst WORDS_CYBER = [\n 'hack', 'code', 'data', 'byte', 'node', 'link', 'sync', 'scan', 'port',\n 'wire', 'grid', 'core', 'disk', 'chip', 'loop', 'ping', 'host', 'root',\n 'shell', 'queue', 'cache', 'stack', 'proxy', 'query', 'parse', 'debug',\n 'input', 'output', 'array', 'index', 'string', 'float', 'class', 'yield',\n 'async', 'await', 'spawn', 'forge', 'trace', 'patch', 'flush', 'crash',\n 'neural', 'matrix', 'cipher', 'vector', 'binary', 'kernel', 'daemon',\n 'buffer', 'socket', 'thread', 'signal', 'stream', 'packet', 'router',\n 'firewall', 'protocol', 'encrypt', 'decrypt', 'compile', 'runtime',\n];\n\n// Sentence templates for harder mode\nconst SENTENCES = [\n 'The quick brown fox jumps over the lazy dog',\n 'Pack my box with five dozen liquor jugs',\n 'How vexingly quick daft zebras jump',\n 'The five boxing wizards jump quickly',\n 'Sphinx of black quartz judge my vow',\n 'Two driven jocks help fax my big quiz',\n 'The system is online and ready for input',\n 'Neural network processing data packets',\n 'Executing quantum encryption protocol',\n 'Compiling source code into binary',\n 'Initializing secure connection tunnel',\n 'Decrypting incoming transmission stream',\n 'Accessing mainframe through backdoor',\n 'Uploading virus payload to target system',\n 'Bypassing firewall security measures',\n 'Tracing network route to server node',\n];\n\n/**\n * Cyberpunk Typing Test\n */\nexport function runTypingTest(terminal: Terminal): TypingTestController {\n const themeColor = getCurrentThemeColor();\n\n // Game dimensions\n const GAME_WIDTH = 60;\n\n // Minimum terminal size (reduced for tolerance)\n const MIN_COLS = 40;\n const MIN_ROWS = 18;\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n\n // Game settings\n let mode: 'words' | 'sentences' = 'words';\n let duration = 30; // seconds\n\n // Test state\n let currentText = '';\n let typedText = '';\n let startTime = 0;\n let timeRemaining = duration;\n let correctChars = 0;\n let totalChars = 0;\n let wordsCompleted = 0;\n let words: string[] = [];\n\n // Stats\n let wpm = 0;\n let accuracy = 100;\n let highWpm = 0;\n\n // Game area positioning\n let gameTop = 5;\n\n // Visual effects\n let glitchFrame = 0;\n let cursorBlink = 0;\n let resultAnimation = 0;\n let isNewBest = false;\n\n // Juicy effects\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let correctStreak = 0;\n let screenShake = 0;\n let borderFlash = 0;\n let errorFlash = 0;\n\n const controller: TypingTestController = {\n stop: () => {\n if (!running) return;\n running = false;\n // Note: Buffer exit is handled by TerminalPool via dispatchGameQuit\n },\n get isRunning() { return running; }\n };\n\n // ASCII art title\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ ▀█▀ █▄█ █▀█ █ █▄ █ █▀▀',\n '█▀█ █ █▀▀ ██▄ █▀▄ █ █ █▀▀ █ █ ▀█ █▄█',\n ];\n\n function updateLayout(rows: number) {\n // Gameplay body spans stats/progress/text/hints area.\n gameTop = getVerticalAnchor(rows, 10, {\n headerRows: 3,\n footerRows: 2,\n minTop: 5,\n });\n }\n\n function generateText() {\n if (mode === 'sentences') {\n // Pick random sentences\n const shuffled = [...SENTENCES].sort(() => Math.random() - 0.5);\n currentText = shuffled.slice(0, 3).join(' ');\n } else {\n // Generate word list\n const allWords = [...WORDS_EASY, ...WORDS_CYBER];\n words = [];\n for (let i = 0; i < 50; i++) {\n words.push(allWords[Math.floor(Math.random() * allWords.length)]);\n }\n currentText = words.join(' ');\n }\n }\n\n function initGame() {\n generateText();\n typedText = '';\n startTime = 0;\n timeRemaining = duration;\n correctChars = 0;\n totalChars = 0;\n wordsCompleted = 0;\n wpm = 0;\n accuracy = 100;\n gameOver = false;\n paused = false;\n resultAnimation = 0;\n isNewBest = false;\n // Reset juicy effects\n particles = [];\n scorePopups = [];\n correctStreak = 0;\n screenShake = 0;\n borderFlash = 0;\n errorFlash = 0;\n }\n\n // Spawn particles at position\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['✦', '★', '◆', '●']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.2 + Math.random() * 0.3;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5 - 0.15,\n life: 10 + Math.floor(Math.random() * 6),\n });\n }\n }\n\n // Add score popup\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 18, color });\n }\n\n function calculateStats() {\n if (startTime === 0) return;\n\n const elapsed = (Date.now() - startTime) / 1000;\n timeRemaining = Math.max(0, duration - elapsed);\n\n // Calculate WPM: (characters / 5) / minutes\n // A \"word\" in typing tests is standardized as 5 characters\n const minutes = elapsed / 60;\n if (minutes > 0) {\n wpm = Math.round((correctChars / 5) / minutes);\n }\n\n // Calculate accuracy\n if (totalChars > 0) {\n accuracy = Math.round((correctChars / totalChars) * 100);\n }\n\n if (timeRemaining <= 0) {\n gameOver = true;\n isNewBest = wpm > highWpm;\n if (isNewBest) highWpm = wpm;\n resultAnimation = 40; // Start result animation\n }\n }\n\n function handleChar(char: string) {\n if (gameOver || paused) return;\n\n // Start timer on first keypress\n if (startTime === 0) {\n startTime = Date.now();\n }\n\n const expectedChar = currentText[typedText.length];\n totalChars++;\n\n // Calculate cursor position for effects\n const cols = terminal.cols;\n const displayWidth = Math.min(60, cols - 4);\n const textStartX = Math.floor((cols - displayWidth) / 2);\n const cursorX = textStartX + Math.min(typedText.length, displayWidth / 2);\n const textY = gameTop + 4;\n\n if (char === expectedChar) {\n correctChars++;\n typedText += char;\n correctStreak++;\n\n // Effects based on streak\n if (correctStreak >= 5 && correctStreak % 5 === 0) {\n // Milestone streak effects\n borderFlash = 6;\n spawnParticles(cursorX, textY, 4 + Math.floor(correctStreak / 5), '\\x1b[1;92m', ['✦', '★', '◆']);\n addScorePopup(cursorX, textY - 1, `${correctStreak}!`, '\\x1b[1;96m');\n } else if (correctStreak >= 10) {\n // High streak - continuous small particles\n if (Math.random() < 0.3) {\n spawnParticles(cursorX, textY, 2, '\\x1b[1;92m', ['·', '•', '○']);\n }\n }\n\n // Count completed words\n if (char === ' ' || typedText.length === currentText.length) {\n wordsCompleted++;\n // Word complete effect\n spawnParticles(cursorX - 2, textY, 3, '\\x1b[1;96m', ['✦', '·', '○']);\n }\n\n // Check if we need more text\n if (typedText.length >= currentText.length - 20) {\n // Extend the text\n if (mode === 'words') {\n const allWords = [...WORDS_EASY, ...WORDS_CYBER];\n for (let i = 0; i < 20; i++) {\n words.push(allWords[Math.floor(Math.random() * allWords.length)]);\n }\n currentText = words.join(' ');\n }\n }\n } else {\n // Wrong character - still add it but it won't count as correct\n typedText += char;\n correctStreak = 0; // Reset streak on error\n errorFlash = 6;\n screenShake = 3;\n // Error particles\n spawnParticles(cursorX, textY, 3, '\\x1b[1;91m', ['✗', '×', '·']);\n }\n }\n\n function handleBackspace() {\n if (typedText.length > 0 && !gameOver && !paused && startTime > 0) {\n // Check if the character we're deleting was correct\n const removedChar = typedText[typedText.length - 1];\n const expectedChar = currentText[typedText.length - 1];\n if (removedChar === expectedChar) {\n correctChars--;\n }\n totalChars--;\n typedText = typedText.slice(0, -1);\n }\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Update effect timers\n if (screenShake > 0) screenShake--;\n if (borderFlash > 0) borderFlash--;\n if (errorFlash > 0) errorFlash--;\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.025;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.15;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = '';\n if (needWidth && needHeight) {\n hint = 'Make pane larger';\n } else if (needWidth) {\n hint = 'Make pane wider →';\n } else {\n hint = 'Make pane taller ↓';\n }\n const msg2 = `Need: ${MIN_COLS}×${MIN_ROWS} Have: ${cols}×${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n updateLayout(rows);\n\n // Glitchy title\n glitchFrame = (glitchFrame + 1) % 60;\n cursorBlink = (cursorBlink + 1) % 20;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n const titleTop = Math.max(1, gameTop - 3);\n output += `\\x1b[${titleTop};${titleX}H`;\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n if (paused) {\n const pauseMsg = '══ PAUSED ══';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseY = Math.floor(rows / 2) - 3;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted) {\n // Show start screen\n const startMsg = '[ PRESS ANY KEY TO START ]';\n const startX = Math.floor((cols - startMsg.length) / 2);\n const startY = Math.floor(rows / 2) - 2;\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const modeMsg = `MODE: ${mode.toUpperCase()} DURATION: ${duration}s`;\n const modeX = Math.floor((cols - modeMsg.length) / 2);\n output += `\\x1b[${startY + 2};${modeX}H${themeColor}${modeMsg}\\x1b[0m`;\n\n const controls1 = 'M: MODE 1/2/3: TIME (30/60/120s)';\n const ctrlX1 = Math.floor((cols - controls1.length) / 2);\n output += `\\x1b[${startY + 4};${ctrlX1}H\\x1b[2m${themeColor}${controls1}\\x1b[0m`;\n\n const controls2 = 'ESC: MENU';\n const ctrlX2 = Math.floor((cols - controls2.length) / 2);\n output += `\\x1b[${startY + 5};${ctrlX2}H\\x1b[2m${themeColor}${controls2}\\x1b[0m`;\n\n // High score\n if (highWpm > 0) {\n const highMsg = `BEST: ${highWpm} WPM`;\n const highX = Math.floor((cols - highMsg.length) / 2);\n output += `\\x1b[${startY + 7};${highX}H\\x1b[93m${highMsg}\\x1b[0m`;\n }\n } else if (gameOver) {\n // Show results with animation\n const overY = gameTop + 2;\n\n // Animated header based on performance\n const sparkles = ['✦', '✧', '★', '☆', '·'];\n const colors = ['\\x1b[92m', '\\x1b[96m', '\\x1b[93m', '\\x1b[95m'];\n const sparkleColor = colors[Math.floor(glitchFrame / 5) % colors.length];\n\n // Add sparkles for good performance\n if (wpm >= 40 && resultAnimation > 0) {\n for (let i = 0; i < 4; i++) {\n const sx = Math.floor(cols / 2) + Math.floor(Math.cos(glitchFrame * 0.3 + i) * 12);\n const sy = overY + Math.floor(Math.sin(glitchFrame * 0.2 + i) * 2);\n const sparkle = sparkles[Math.floor(Math.random() * sparkles.length)];\n output += `\\x1b[${sy};${sx}H${sparkleColor}${sparkle}\\x1b[0m`;\n }\n }\n\n const overMsg = resultAnimation > 20 ? '═══ TIME UP! ═══' : '══ TIME UP! ══';\n const overMsgColor = resultAnimation > 0 && Math.floor(glitchFrame / 3) % 2 === 0 ? '\\x1b[1;96m' : `\\x1b[1m${themeColor}`;\n const overX = Math.floor((cols - overMsg.length) / 2);\n output += `\\x1b[${overY};${overX}H${overMsgColor}${overMsg}\\x1b[0m`;\n\n // Results box with glow effect\n const boxColor = resultAnimation > 0 && Math.floor(glitchFrame / 4) % 2 === 0 ? '\\x1b[96m' : themeColor;\n const results = [\n `┌────────────────────────┐`,\n `│ TYPING RESULTS │`,\n `├────────────────────────┤`,\n `│ WPM: ${wpm.toString().padStart(5)} │`,\n `│ ACCURACY: ${accuracy.toString().padStart(4)}% │`,\n `│ WORDS: ${wordsCompleted.toString().padStart(5)} │`,\n `│ CHARS: ${correctChars.toString().padStart(5)} │`,\n `└────────────────────────┘`,\n ];\n\n const resultY = overY + 2;\n for (let i = 0; i < results.length; i++) {\n const lineX = Math.floor((cols - results[i].length) / 2);\n output += `\\x1b[${resultY + i};${lineX}H${boxColor}${results[i]}\\x1b[0m`;\n }\n\n // Rating with animation\n let rating = '';\n let ratingColor = '';\n if (wpm >= 80) { rating = '★ ELITE HACKER ★'; ratingColor = '\\x1b[1;95m'; }\n else if (wpm >= 60) { rating = '◆ SKILLED CODER ◆'; ratingColor = '\\x1b[1;96m'; }\n else if (wpm >= 40) { rating = '▸ KEYBOARD NINJA ◂'; ratingColor = '\\x1b[1;92m'; }\n else if (wpm >= 25) { rating = '· TRAINEE ·'; ratingColor = '\\x1b[1;93m'; }\n else { rating = 'NEEDS PRACTICE'; ratingColor = '\\x1b[1;91m'; }\n\n // Pulse rating color\n if (resultAnimation > 0 && wpm >= 40) {\n const pulse = Math.floor(glitchFrame / 2) % 2 === 0;\n ratingColor = pulse ? ratingColor : '\\x1b[1;97m';\n }\n\n const ratingX = Math.floor((cols - rating.length) / 2);\n output += `\\x1b[${resultY + results.length + 1};${ratingX}H${ratingColor}${rating}\\x1b[0m`;\n\n // Best score celebration\n if (isNewBest && wpm > 0) {\n const celebChars = ['★', '✦', '✧', '◆'];\n const newBest = resultAnimation > 0\n ? `${celebChars[Math.floor(glitchFrame / 4) % celebChars.length]} NEW PERSONAL BEST! ${celebChars[(Math.floor(glitchFrame / 4) + 2) % celebChars.length]}`\n : '★ NEW PERSONAL BEST! ★';\n const newBestColor = resultAnimation > 0 && Math.floor(glitchFrame / 2) % 2 === 0 ? '\\x1b[1;93m' : '\\x1b[1;97m';\n const newBestX = Math.floor((cols - newBest.length) / 2);\n output += `\\x1b[${resultY + results.length + 3};${newBestX}H${newBestColor}${newBest}\\x1b[0m`;\n }\n\n const restart = '[ R ] RETRY [ ESC ] QUIT';\n const restartX = Math.floor((cols - restart.length) / 2);\n output += `\\x1b[${resultY + results.length + 5};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n } else {\n // Apply screen shake offset\n const shakeOffsetX = screenShake > 0 ? Math.floor((Math.random() - 0.5) * 2) : 0;\n const shakeOffsetY = screenShake > 0 ? Math.floor(Math.random() * 2) : 0;\n\n // Stats bar with effects\n const timeColor = timeRemaining <= 5 ? '\\x1b[91m' : (borderFlash > 0 && borderFlash % 4 < 2 ? '\\x1b[1;92m' : themeColor);\n const errorColor = errorFlash > 0 && errorFlash % 4 < 2 ? '\\x1b[1;91m' : '';\n const stats = `TIME: ${Math.ceil(timeRemaining).toString().padStart(3)}s WPM: ${wpm.toString().padStart(3)} ACC: ${accuracy}%`;\n const statsX = Math.floor((cols - stats.length) / 2) + shakeOffsetX;\n output += `\\x1b[${gameTop + shakeOffsetY};${statsX}H${errorColor || timeColor}${stats}\\x1b[0m`;\n\n // Progress bar\n const progress = Math.max(0, (duration - timeRemaining) / duration);\n const barWidth = GAME_WIDTH - 4;\n const filled = Math.floor(barWidth * progress);\n const empty = barWidth - filled;\n const progressBar = '█'.repeat(filled) + '░'.repeat(empty);\n const barX = Math.floor((cols - barWidth) / 2) + shakeOffsetX;\n output += `\\x1b[${gameTop + 1 + shakeOffsetY};${barX}H${timeColor}${progressBar}\\x1b[0m`;\n\n // Show streak if active\n if (correctStreak >= 10) {\n const streakMsg = correctStreak >= 25 ? `★ ${correctStreak} STREAK! ★` : `${correctStreak} STREAK!`;\n const streakColor = glitchFrame % 6 < 3 ? '\\x1b[1;93m' : '\\x1b[1;96m';\n const streakX = Math.floor((cols - streakMsg.length) / 2);\n output += `\\x1b[${gameTop + 2 + shakeOffsetY};${streakX}H${streakColor}${streakMsg}\\x1b[0m`;\n }\n\n // Text display area\n const textY = gameTop + 4 + shakeOffsetY;\n const displayWidth = Math.min(GAME_WIDTH, cols - 4);\n const textStartX = Math.floor((cols - displayWidth) / 2) + shakeOffsetX;\n\n // Calculate visible text window\n const typedLen = typedText.length;\n const startIndex = Math.max(0, typedLen - Math.floor(displayWidth / 2));\n const visibleText = currentText.slice(startIndex, startIndex + displayWidth);\n const visibleTyped = typedText.slice(startIndex);\n\n // Draw text character by character\n output += `\\x1b[${textY};${textStartX}H`;\n for (let i = 0; i < visibleText.length; i++) {\n const char = visibleText[i];\n const typedChar = visibleTyped[i];\n\n if (typedChar === undefined) {\n // Not typed yet - show dimmed\n if (i === visibleTyped.length && cursorBlink < 10) {\n // Cursor position - flash on error\n const cursorColor = errorFlash > 0 ? '\\x1b[1;91m' : themeColor;\n output += `\\x1b[7m${cursorColor}${char}\\x1b[0m`;\n } else {\n output += `\\x1b[2m${themeColor}${char}\\x1b[0m`;\n }\n } else if (typedChar === char) {\n // Correct - show green (brighter during streak)\n const greenColor = correctStreak >= 10 ? '\\x1b[1;92m' : '\\x1b[92m';\n output += `${greenColor}${char}\\x1b[0m`;\n } else {\n // Wrong - show red with the typed char (flash on error)\n const redColor = errorFlash > 0 && errorFlash % 4 < 2 ? '\\x1b[1;97;41m' : '\\x1b[91m';\n output += `${redColor}${typedChar}\\x1b[0m`;\n }\n }\n\n // Draw particles\n for (const p of particles) {\n const px = Math.round(p.x);\n const py = Math.round(p.y);\n if (px > 0 && px < cols && py > 0 && py < rows) {\n const alpha = p.life > 4 ? '' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const px = Math.round(popup.x);\n const py = Math.round(popup.y);\n if (py > 0 && py < rows) {\n const alpha = popup.frames > 10 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n\n // Instructions\n const hint = startTime === 0 ? 'START TYPING TO BEGIN!' : '';\n if (hint) {\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${textY + 3};${hintX}H\\x1b[5m${themeColor}${hint}\\x1b[0m`;\n }\n }\n\n // Hint at bottom\n const hint = gameStarted && !gameOver && !paused ? '[ ESC ] MENU' : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${rows - 1};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n // Update animation counters\n if (resultAnimation > 0) resultAnimation--;\n\n terminal.write(output);\n }\n\n // Start game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) {\n clearInterval(renderInterval);\n return;\n }\n if (gameStarted && !gameOver && !paused) {\n calculateStats();\n }\n render();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener.dispose();\n return;\n }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key;\n const keyLower = key.toLowerCase();\n\n // Handle ESC key - toggle pause (works on start screen too)\n if (key === 'Escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Start screen - pre-game controls (ESC handled above)\n // Skip if paused (ESC menu open on start screen)\n if (!gameStarted && !paused) {\n // Mode toggle\n if (keyLower === 'm') {\n mode = mode === 'words' ? 'sentences' : 'words';\n initGame();\n return;\n }\n if (key === '1') { duration = 30; initGame(); return; }\n if (key === '2') { duration = 60; initGame(); return; }\n if (key === '3') { duration = 120; initGame(); return; }\n\n // Any other key starts the game\n if (key.length === 1 || key === 'Enter' || key === ' ') {\n gameStarted = true;\n initGame();\n // If it's a typeable character, process it\n if (key.length === 1 && /[a-zA-Z0-9 .,!?;:'\"-]/.test(key)) {\n handleChar(key);\n }\n }\n return;\n }\n\n // Game over - R to restart\n if (gameOver) {\n if (keyLower === 'r') {\n initGame();\n gameStarted = true;\n }\n return;\n }\n\n // Pause menu actions\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n keyLower,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n initGame();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n clearInterval(renderInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n clearInterval(renderInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n clearInterval(renderInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (keyLower === 'r') {\n initGame();\n gameStarted = true;\n paused = false;\n } else if (keyLower === 'l') {\n clearInterval(renderInterval);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (keyLower === 'n') {\n clearInterval(renderInterval);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n // Handle typing\n if (key === 'Backspace') {\n handleBackspace();\n } else if (key.length === 1) {\n // Regular character\n handleChar(key);\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 50);\n\n return controller;\n}\n","/**\n * Hyper Wordle\n *\n * Classic 5-letter word guessing game with cyberpunk aesthetics.\n * Crack the cipher in 6 attempts. Green = correct, Yellow = wrong position, Gray = absent.\n * Features on-screen keyboard, statistics tracking, and particle celebrations.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Wordle Game Controller\n */\nexport interface WordleController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\ntype LetterState = 'correct' | 'present' | 'absent' | 'unused';\n\ninterface Statistics {\n gamesPlayed: number;\n gamesWon: number;\n currentStreak: number;\n maxStreak: number;\n guessDistribution: number[]; // index 0 = won in 1, etc.\n}\n\n// ============================================================================\n// WORD LIST - ~200 common 5-letter words\n// ============================================================================\n\nconst WORDS = [\n // Common everyday words\n 'ABOUT', 'ABOVE', 'AFTER', 'AGAIN', 'ALIEN', 'ALLOW', 'ALONE', 'ALONG',\n 'ANGEL', 'ANGRY', 'APPLE', 'ARENA', 'ARGUE', 'ARISE', 'ARRAY', 'ASIDE',\n 'AVOID', 'AWAKE', 'AWARD', 'BASIC', 'BEACH', 'BEAST', 'BEGIN', 'BEING',\n 'BELOW', 'BIRTH', 'BLACK', 'BLADE', 'BLAME', 'BLANK', 'BLAST', 'BLAZE',\n 'BLEED', 'BLEND', 'BLIND', 'BLOCK', 'BLOOD', 'BOARD', 'BOOST', 'BOUND',\n 'BRAIN', 'BRAND', 'BRAVE', 'BREAD', 'BREAK', 'BRICK', 'BRIDE', 'BRIEF',\n 'BRING', 'BROAD', 'BROKE', 'BROWN', 'BUILD', 'BUILT', 'BURST', 'BUYER',\n 'CABLE', 'CARRY', 'CATCH', 'CAUSE', 'CHAIN', 'CHAIR', 'CHAOS', 'CHARM',\n 'CHART', 'CHASE', 'CHEAP', 'CHECK', 'CHESS', 'CHEST', 'CHIEF', 'CHILD',\n 'CHILL', 'CLAIM', 'CLASS', 'CLEAN', 'CLEAR', 'CLIMB', 'CLOCK', 'CLOSE',\n 'CLOUD', 'COACH', 'COAST', 'CORAL', 'COUNT', 'COURT', 'COVER', 'CRAFT',\n 'CRASH', 'CRAZY', 'CREAM', 'CRIME', 'CROSS', 'CROWD', 'CROWN', 'CRUEL',\n 'CRUSH', 'DANCE', 'DEATH', 'DEBUT', 'DECAY', 'DEPTH', 'DIARY', 'DIRTY',\n 'DOUBT', 'DOZEN', 'DRAFT', 'DRAIN', 'DRAMA', 'DRANK', 'DRAWN', 'DREAM',\n 'DRESS', 'DRINK', 'DRIVE', 'DROWN', 'EARLY', 'EARTH', 'EIGHT', 'ELECT',\n 'ELITE', 'EMPTY', 'ENEMY', 'ENJOY', 'ENTER', 'ENTRY', 'EQUAL', 'ERROR',\n 'EVENT', 'EVERY', 'EXACT', 'EXIST', 'EXTRA', 'FAINT', 'FAITH', 'FALSE',\n 'FANCY', 'FATAL', 'FAULT', 'FEAST', 'FIBER', 'FIELD', 'FIFTH', 'FIFTY',\n 'FIGHT', 'FINAL', 'FIRST', 'FIXED', 'FLAME', 'FLASH', 'FLESH', 'FLOAT',\n 'FLOOD', 'FLOOR', 'FLOUR', 'FLUID', 'FOCUS', 'FORCE', 'FORGE', 'FORTH',\n 'FORTY', 'FORUM', 'FOUND', 'FRAME', 'FRANK', 'FRAUD', 'FRESH', 'FRONT',\n 'FROST', 'FRUIT', 'GHOST', 'GIANT', 'GIVEN', 'GLASS', 'GLOBE', 'GLORY',\n 'GRACE', 'GRADE', 'GRAIN', 'GRAND', 'GRANT', 'GRAPE', 'GRAPH', 'GRASP',\n 'GRASS', 'GRAVE', 'GREAT', 'GREEN', 'GRIND', 'GROUP', 'GROVE', 'GROWN',\n 'GUARD', 'GUESS', 'GUEST', 'GUIDE', 'GUILD', 'HABIT', 'HANDS', 'HAPPY',\n 'HARSH', 'HASTE', 'HAUNT', 'HEART', 'HEAVY', 'HENCE', 'HONEY', 'HONOR',\n 'HORSE', 'HOTEL', 'HOUSE', 'HUMAN', 'IDEAL', 'IMAGE', 'INDEX', 'INNER',\n 'INPUT', 'IRONY', 'ISSUE', 'IVORY', 'JOINT', 'JONES', 'JUDGE', 'JUICE',\n 'KNIFE', 'KNOCK', 'KNOWN', 'LABEL', 'LABOR', 'LARGE', 'LASER', 'LATER',\n 'LAUGH', 'LAYER', 'LEARN', 'LEAST', 'LEAVE', 'LEGAL', 'LEVEL', 'LIGHT',\n 'LIMIT', 'LINKS', 'LIVER', 'LOCAL', 'LOGIC', 'LOOSE', 'LOVER', 'LOWER',\n 'LUCKY', 'LUNCH', 'LYING', 'MAGIC', 'MAJOR', 'MAKER', 'MARCH', 'MATCH',\n 'MAYBE', 'MAYOR', 'MEANS', 'MEDAL', 'MEDIA', 'MERCY', 'MERGE', 'METAL',\n 'METER', 'MIGHT', 'MINOR', 'MINUS', 'MIXED', 'MODEL', 'MONEY', 'MONTH',\n 'MORAL', 'MOTOR', 'MOUNT', 'MOUSE', 'MOUTH', 'MOVIE', 'MUSIC', 'NAIVE',\n 'NAKED', 'NERVE', 'NEVER', 'NEWLY', 'NIGHT', 'NINTH', 'NOBLE', 'NOISE',\n 'NORTH', 'NOVEL', 'NURSE', 'OCCUR', 'OCEAN', 'OFFER', 'OFTEN', 'OLIVE',\n 'ORDER', 'OTHER', 'OUGHT', 'OUTER', 'OWNED', 'OWNER', 'OXIDE', 'OZONE',\n];\n\n// ============================================================================\n// MAIN GAME FUNCTION\n// ============================================================================\n\nexport function runWordleGame(terminal: Terminal): WordleController {\n const themeColor = getCurrentThemeColor();\n\n // -------------------------------------------------------------------------\n // CONSTANTS\n // -------------------------------------------------------------------------\n const MIN_COLS = 36;\n const MIN_ROWS = 20;\n const MAX_GUESSES = 6;\n const WORD_LENGTH = 5;\n\n // Keyboard layout\n const KEYBOARD_ROWS = [\n ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'],\n ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'],\n ['Z', 'X', 'C', 'V', 'B', 'N', 'M'],\n ];\n\n // -------------------------------------------------------------------------\n // STATE\n // -------------------------------------------------------------------------\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let won = false;\n let showStats = false;\n\n // Game state\n let targetWord = '';\n let guesses: string[] = [];\n let currentGuess = '';\n let letterStates: Map<string, LetterState> = new Map();\n\n // Statistics\n let stats: Statistics = {\n gamesPlayed: 0,\n gamesWon: 0,\n currentStreak: 0,\n maxStreak: 0,\n guessDistribution: [0, 0, 0, 0, 0, 0],\n };\n\n // Positioning\n let cols = terminal.cols;\n let rows = terminal.rows;\n\n // Visual effects\n let glitchFrame = 0;\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let shakeFrames = 0;\n let shakeIntensity = 0;\n let revealRow = -1;\n let revealCol = -1;\n let revealFrame = 0;\n let borderFlash = 0;\n\n // -------------------------------------------------------------------------\n // CONTROLLER\n // -------------------------------------------------------------------------\n const controller: WordleController = {\n stop: () => {\n if (!running) return;\n running = false;\n },\n get isRunning() { return running; }\n };\n\n // -------------------------------------------------------------------------\n // ASCII ART TITLE\n // -------------------------------------------------------------------------\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ █ █ █ █▀█ █▀█ █▀▄ █ █▀▀',\n '█▀█ █ █▀▀ ██▄ █▀▄ ▀▄▀▄▀ █▄█ █▀▄ █▄▀ █▄▄ ██▄',\n ];\n\n // -------------------------------------------------------------------------\n // EFFECTS\n // -------------------------------------------------------------------------\n\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['*', '+', 'o', '.']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.3 + Math.random() * 0.5;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5 - 0.2,\n life: 15 + Math.floor(Math.random() * 10),\n });\n }\n }\n\n function spawnFirework(x: number, y: number) {\n const colors = ['\\x1b[1;92m', '\\x1b[1;93m', '\\x1b[1;96m', '\\x1b[1;95m'];\n const color = colors[Math.floor(Math.random() * colors.length)];\n const chars = ['*', '+', 'o', '.', '`', \"'\"];\n for (let i = 0; i < 12; i++) {\n const angle = (Math.PI * 2 * i) / 12;\n const speed = 0.4 + Math.random() * 0.3;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.6 - 0.1,\n life: 20 + Math.floor(Math.random() * 10),\n });\n }\n }\n\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 25, color });\n }\n\n function triggerShake(frames: number, intensity: number) {\n shakeFrames = frames;\n shakeIntensity = intensity;\n }\n\n // -------------------------------------------------------------------------\n // GAME LOGIC\n // -------------------------------------------------------------------------\n\n function initGame() {\n targetWord = WORDS[Math.floor(Math.random() * WORDS.length)];\n guesses = [];\n currentGuess = '';\n letterStates = new Map();\n gameOver = false;\n won = false;\n paused = false;\n showStats = false;\n revealRow = -1;\n revealCol = -1;\n revealFrame = 0;\n\n particles = [];\n scorePopups = [];\n shakeFrames = 0;\n borderFlash = 0;\n }\n\n function checkGuess(guess: string): LetterState[] {\n const result: LetterState[] = new Array(WORD_LENGTH).fill('absent');\n const targetChars = targetWord.split('');\n const guessChars = guess.split('');\n const used = new Array(WORD_LENGTH).fill(false);\n\n // First pass: exact matches\n for (let i = 0; i < WORD_LENGTH; i++) {\n if (guessChars[i] === targetChars[i]) {\n result[i] = 'correct';\n used[i] = true;\n }\n }\n\n // Second pass: present but wrong position\n for (let i = 0; i < WORD_LENGTH; i++) {\n if (result[i] === 'correct') continue;\n const idx = targetChars.findIndex((c, j) => c === guessChars[i] && !used[j]);\n if (idx !== -1) {\n result[i] = 'present';\n used[idx] = true;\n }\n }\n\n return result;\n }\n\n function updateLetterStates(guess: string, result: LetterState[]) {\n for (let i = 0; i < WORD_LENGTH; i++) {\n const letter = guess[i];\n const currentState = letterStates.get(letter);\n const newState = result[i];\n\n // Only upgrade state, never downgrade\n if (!currentState || currentState === 'unused') {\n letterStates.set(letter, newState);\n } else if (currentState === 'absent' && (newState === 'present' || newState === 'correct')) {\n letterStates.set(letter, newState);\n } else if (currentState === 'present' && newState === 'correct') {\n letterStates.set(letter, newState);\n }\n }\n }\n\n function submitGuess() {\n if (currentGuess.length !== WORD_LENGTH) {\n triggerShake(4, 2);\n addScorePopup(Math.floor(cols / 2), 8, 'NOT ENOUGH LETTERS', '\\x1b[1;91m');\n return;\n }\n\n const result = checkGuess(currentGuess);\n guesses.push(currentGuess);\n updateLetterStates(currentGuess, result);\n\n // Start reveal animation\n revealRow = guesses.length - 1;\n revealCol = 0;\n revealFrame = 0;\n\n const allCorrect = result.every(r => r === 'correct');\n const correctCount = result.filter(r => r === 'correct').length;\n const presentCount = result.filter(r => r === 'present').length;\n\n const centerX = Math.floor(cols / 2);\n const guessY = 6 + guesses.length * 2;\n\n if (allCorrect) {\n won = true;\n gameOver = true;\n stats.gamesPlayed++;\n stats.gamesWon++;\n stats.currentStreak++;\n if (stats.currentStreak > stats.maxStreak) {\n stats.maxStreak = stats.currentStreak;\n }\n stats.guessDistribution[guesses.length - 1]++;\n\n // Celebration effects\n borderFlash = 20;\n triggerShake(10, 3);\n\n const messages = ['CIPHER BREACHED!', 'CODE CRACKED!', 'DECRYPTED!', 'BRILLIANT!'];\n addScorePopup(centerX, guessY - 2, messages[Math.floor(Math.random() * messages.length)], '\\x1b[1;92m');\n\n // Fireworks\n setTimeout(() => {\n if (running) {\n for (let i = 0; i < 5; i++) {\n setTimeout(() => {\n if (running && won) {\n spawnFirework(\n 10 + Math.random() * (cols - 20),\n 5 + Math.random() * 10\n );\n }\n }, i * 200);\n }\n }\n }, 500);\n } else if (guesses.length >= MAX_GUESSES) {\n gameOver = true;\n stats.gamesPlayed++;\n stats.currentStreak = 0;\n\n triggerShake(8, 4);\n borderFlash = 15;\n addScorePopup(centerX, guessY - 2, 'DECRYPTION FAILED', '\\x1b[1;91m');\n spawnParticles(centerX, guessY, 10, '\\x1b[1;91m', ['X', 'x', '.', '*']);\n } else {\n // Feedback for partial matches\n if (correctCount > 0 || presentCount > 0) {\n const hint = correctCount > 0 ? `${correctCount} EXACT` : `${presentCount} CLOSE`;\n addScorePopup(centerX, guessY - 1, hint, correctCount > 0 ? '\\x1b[1;92m' : '\\x1b[1;93m');\n spawnParticles(centerX, guessY, 3 + correctCount * 2, correctCount > 0 ? '\\x1b[1;92m' : '\\x1b[1;93m');\n }\n }\n\n currentGuess = '';\n }\n\n function update() {\n if (!gameStarted || paused || showStats) return;\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.02;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.15;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n // Update reveal animation\n if (revealRow >= 0 && revealCol < WORD_LENGTH) {\n revealFrame++;\n if (revealFrame >= 4) {\n revealCol++;\n revealFrame = 0;\n }\n }\n }\n\n // -------------------------------------------------------------------------\n // RENDERING\n // -------------------------------------------------------------------------\n\n function getLetterColor(state: LetterState): string {\n switch (state) {\n case 'correct': return '\\x1b[1;42;97m'; // Green bg, white text\n case 'present': return '\\x1b[1;43;30m'; // Yellow bg, black text\n case 'absent': return '\\x1b[2;100;97m'; // Dark gray bg\n default: return themeColor;\n }\n }\n\n function getLetterBorderColor(state: LetterState): string {\n switch (state) {\n case 'correct': return '\\x1b[1;32m';\n case 'present': return '\\x1b[1;33m';\n case 'absent': return '\\x1b[2m';\n default: return themeColor;\n }\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Update dimensions\n cols = terminal.cols;\n rows = terminal.rows;\n\n // Effect timers\n if (shakeFrames > 0) shakeFrames--;\n if (borderFlash > 0) borderFlash--;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = needWidth && needHeight ? 'Make pane larger'\n : needWidth ? 'Make pane wider' : 'Make pane taller';\n const msg2 = `Need: ${MIN_COLS}x${MIN_ROWS} Have: ${cols}x${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Calculate shake offset\n let shakeX = 0, shakeY = 0;\n if (shakeFrames > 0) {\n shakeX = Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n shakeY = Math.floor((Math.random() - 0.5) * shakeIntensity);\n }\n\n const centerX = Math.floor(cols / 2);\n\n // Glitch title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset + shakeX;\n\n let titleColor = themeColor;\n if (borderFlash > 0 && borderFlash % 4 < 2) {\n titleColor = won ? '\\x1b[1;92m' : '\\x1b[1;91m';\n }\n\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[1;${Math.max(1, titleX)}H\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${Math.max(1, titleX + 1)}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `\\x1b[1;${Math.max(1, titleX)}H${titleColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${Math.max(1, titleX)}H${titleColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n // PAUSE MENU\n if (paused) {\n const pauseMsg = '== PAUSED ==';\n const pauseY = 8;\n const pauseMsgX = centerX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = 'Use arrows, ENTER to select';\n const navHintX = centerX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n }\n // STATS SCREEN\n else if (showStats) {\n const statsY = 5;\n const boxWidth = 32;\n const boxX = centerX - Math.floor(boxWidth / 2);\n\n output += `\\x1b[${statsY};${boxX}H${themeColor}+${'='.repeat(boxWidth - 2)}+\\x1b[0m`;\n output += `\\x1b[${statsY + 1};${boxX}H${themeColor}| CIPHER STATISTICS |\\x1b[0m`;\n output += `\\x1b[${statsY + 2};${boxX}H${themeColor}+${'='.repeat(boxWidth - 2)}+\\x1b[0m`;\n\n const winPct = stats.gamesPlayed > 0 ? Math.round((stats.gamesWon / stats.gamesPlayed) * 100) : 0;\n\n output += `\\x1b[${statsY + 4};${boxX + 2}H${themeColor}Games Played: ${stats.gamesPlayed}\\x1b[0m`;\n output += `\\x1b[${statsY + 5};${boxX + 2}H${themeColor}Win Rate: ${winPct}%\\x1b[0m`;\n output += `\\x1b[${statsY + 6};${boxX + 2}H${themeColor}Current Streak: ${stats.currentStreak}\\x1b[0m`;\n output += `\\x1b[${statsY + 7};${boxX + 2}H${themeColor}Max Streak: ${stats.maxStreak}\\x1b[0m`;\n\n output += `\\x1b[${statsY + 9};${boxX + 2}H${themeColor}GUESS DISTRIBUTION:\\x1b[0m`;\n\n const maxDist = Math.max(...stats.guessDistribution, 1);\n for (let i = 0; i < 6; i++) {\n const count = stats.guessDistribution[i];\n const barLen = Math.round((count / maxDist) * 15);\n const bar = '#'.repeat(Math.max(barLen, count > 0 ? 1 : 0));\n const barColor = i === guesses.length - 1 && won ? '\\x1b[1;92m' : themeColor;\n output += `\\x1b[${statsY + 10 + i};${boxX + 2}H${themeColor}${i + 1}: ${barColor}${bar}\\x1b[0m ${count}`;\n }\n\n output += `\\x1b[${statsY + 17};${boxX}H${themeColor}+${'='.repeat(boxWidth - 2)}+\\x1b[0m`;\n\n const hint = '[ ENTER ] New Game [ Q ] Quit';\n output += `\\x1b[${statsY + 19};${centerX - Math.floor(hint.length / 2)}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n }\n // START SCREEN\n else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO CRACK THE CIPHER ]';\n const startY = Math.floor(rows / 2) - 2;\n const startX = centerX - Math.floor(startMsg.length / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const rules = [\n 'Guess the 5-letter cipher in 6 tries',\n '',\n '\\x1b[42;97m G \\x1b[0m = Correct position',\n '\\x1b[43;30m Y \\x1b[0m = Wrong position',\n '\\x1b[100;97m X \\x1b[0m = Not in word',\n ];\n\n for (let i = 0; i < rules.length; i++) {\n const ruleX = centerX - 15;\n output += `\\x1b[${startY + 3 + i};${ruleX}H${rules[i]}\\x1b[0m`;\n }\n\n const controls = 'A-Z type ENTER submit BACKSPACE delete ESC menu';\n output += `\\x1b[${rows - 2};${centerX - Math.floor(controls.length / 2)}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n }\n // MAIN GAMEPLAY\n else {\n const gridY = 4 + shakeY;\n const gridX = centerX - 8 + shakeX;\n\n // Draw guess grid\n for (let row = 0; row < MAX_GUESSES; row++) {\n const y = gridY + row * 2;\n\n for (let col = 0; col < WORD_LENGTH; col++) {\n const x = gridX + col * 4;\n\n let letter = ' ';\n let state: LetterState = 'unused';\n let isRevealing = false;\n\n if (row < guesses.length) {\n letter = guesses[row][col];\n const result = checkGuess(guesses[row]);\n\n // Check if this cell is being revealed\n if (row === revealRow && col <= revealCol) {\n state = result[col];\n } else if (row === revealRow) {\n isRevealing = true;\n } else {\n state = result[col];\n }\n } else if (row === guesses.length && col < currentGuess.length) {\n letter = currentGuess[col];\n }\n\n // Draw cell\n const cellColor = getLetterBorderColor(state);\n const bgColor = getLetterColor(state);\n\n if (isRevealing) {\n // Flip animation - show back of card\n output += `\\x1b[${y};${x}H${themeColor}[?]\\x1b[0m`;\n } else if (letter !== ' ') {\n output += `\\x1b[${y};${x}H${cellColor}[\\x1b[0m${bgColor} ${letter} \\x1b[0m${cellColor}]\\x1b[0m`;\n } else {\n output += `\\x1b[${y};${x}H${themeColor}[ ]\\x1b[0m`;\n }\n }\n }\n\n // Draw on-screen keyboard\n const kbY = gridY + MAX_GUESSES * 2 + 1;\n\n for (let rowIdx = 0; rowIdx < KEYBOARD_ROWS.length; rowIdx++) {\n const kbRow = KEYBOARD_ROWS[rowIdx];\n const rowOffset = rowIdx === 1 ? 1 : rowIdx === 2 ? 3 : 0;\n const rowX = centerX - Math.floor(kbRow.length * 2 / 2) + rowOffset + shakeX;\n\n for (let i = 0; i < kbRow.length; i++) {\n const key = kbRow[i];\n const state = letterStates.get(key) || 'unused';\n const keyColor = getLetterColor(state);\n\n output += `\\x1b[${kbY + rowIdx};${rowX + i * 2}H${keyColor}${key}\\x1b[0m`;\n }\n }\n\n // Game over overlay\n if (gameOver) {\n const overY = kbY + 4;\n\n if (won) {\n const winMsg = 'CIPHER CRACKED!';\n output += `\\x1b[${overY};${centerX - Math.floor(winMsg.length / 2)}H\\x1b[1;92m${winMsg}\\x1b[0m`;\n } else {\n const loseMsg = 'DECRYPTION FAILED';\n output += `\\x1b[${overY};${centerX - Math.floor(loseMsg.length / 2)}H\\x1b[1;91m${loseMsg}\\x1b[0m`;\n const wordMsg = `The cipher was: ${targetWord}`;\n output += `\\x1b[${overY + 1};${centerX - Math.floor(wordMsg.length / 2)}H${themeColor}${wordMsg}\\x1b[0m`;\n }\n\n const restartHint = '[ ENTER ] Stats [ R ] New Game [ Q ] Quit';\n output += `\\x1b[${overY + 3};${centerX - Math.floor(restartHint.length / 2)}H\\x1b[2m${themeColor}${restartHint}\\x1b[0m`;\n }\n\n // Draw particles\n for (const p of particles) {\n const px = Math.round(p.x);\n const py = Math.round(p.y);\n if (px > 0 && px < cols && py > 0 && py < rows) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const px = Math.round(popup.x - popup.text.length / 2);\n const py = Math.round(popup.y);\n if (py > 0 && py < rows && px > 0) {\n const alpha = popup.frames > 15 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${py};${Math.max(1, px)}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n\n // Bottom hint\n if (!gameOver) {\n const hint = `Attempt ${guesses.length + 1}/${MAX_GUESSES} | [ ESC ] Menu`;\n output += `\\x1b[${rows - 1};${centerX - Math.floor(hint.length / 2)}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n }\n }\n\n // Border flash effect\n if (borderFlash > 0) {\n const flashColor = won ? '\\x1b[32m' : '\\x1b[31m';\n const flashChar = borderFlash % 4 < 2 ? '#' : '=';\n for (let x = 1; x <= cols; x += 4) {\n output += `\\x1b[1;${x}H${flashColor}${flashChar}\\x1b[0m`;\n output += `\\x1b[${rows};${x}H${flashColor}${flashChar}\\x1b[0m`;\n }\n }\n\n terminal.write(output);\n }\n\n // -------------------------------------------------------------------------\n // GAME LOOP\n // -------------------------------------------------------------------------\n\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) { clearInterval(gameInterval); return; }\n update();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key;\n const keyLower = key.toLowerCase();\n\n // ESC toggles pause\n if (key === 'Escape') {\n if (showStats) {\n showStats = false;\n } else {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n }\n return;\n }\n\n // Stats screen\n if (showStats) {\n if (key === 'Enter') {\n initGame();\n gameStarted = true;\n showStats = false;\n }\n return;\n }\n\n // Start screen - any key starts\n if (!gameStarted && !paused) {\n gameStarted = true;\n return;\n }\n\n // Game over\n if (gameOver && !showStats) {\n if (keyLower === 'r') {\n initGame();\n gameStarted = true;\n } else if (key === 'Enter') {\n showStats = true;\n }\n return;\n }\n\n // Pause menu navigation\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n keyLower,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: paused = false; break;\n case 1: initGame(); gameStarted = true; paused = false; break;\n case 2:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcuts\n if (keyLower === 'r') { initGame(); gameStarted = true; paused = false; }\n else if (keyLower === 'l') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGamesMenu(terminal); }\n else if (keyLower === 'n') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGameSwitch(terminal); }\n return;\n }\n\n // GAMEPLAY INPUT\n if (key === 'Backspace') {\n currentGuess = currentGuess.slice(0, -1);\n } else if (key === 'Enter') {\n submitGuess();\n } else if (key.length === 1 && /[a-zA-Z]/.test(key) && currentGuess.length < WORD_LENGTH) {\n currentGuess += key.toUpperCase();\n // Small typing feedback\n spawnParticles(\n Math.floor(cols / 2) - 8 + currentGuess.length * 4,\n 4 + guesses.length * 2,\n 2,\n themeColor,\n ['.', '*']\n );\n }\n });\n\n // Clean up on stop\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Games Menu\n *\n * Interactive game selection menu accessible via ::games command\n * or by pressing L in any game's pause menu.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor, isLightTheme, enterAlternateBuffer, exitAlternateBuffer, forceExitAlternateBuffer, isTerminalValid } from './utils';\nimport { games } from './index';\nimport { playSelectTransition } from './gameTransitions';\n\nexport interface GamesMenuController {\n stop: () => void;\n isRunning: boolean;\n}\n\nexport interface GamesMenuOptions {\n onGameSelect?: (gameId: string) => void;\n onQuit?: () => void;\n}\n\n/**\n * Show interactive games menu\n */\nexport function showGamesMenu(terminal: Terminal, optionsOrCallback?: GamesMenuOptions | ((gameId: string) => void)): GamesMenuController {\n // Support both options object and simple callback for backwards compatibility\n const options: GamesMenuOptions = typeof optionsOrCallback === 'function'\n ? { onGameSelect: optionsOrCallback }\n : optionsOrCallback || {};\n const { onGameSelect, onQuit } = options;\n const themeColor = getCurrentThemeColor();\n const lightTheme = isLightTheme();\n\n let running = true;\n let selectedIndex = 0;\n let scrollOffset = 0;\n\n const controller: GamesMenuController = {\n stop: () => {\n if (!running) return;\n running = false;\n },\n get isRunning() { return running; }\n };\n\n const title = [\n '\\u2588\\u2580\\u2580 \\u2584\\u2580\\u2588 \\u2588\\u2580\\u2584\\u2580\\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2580',\n '\\u2588\\u2584\\u2588 \\u2588\\u2580\\u2588 \\u2588 \\u2580 \\u2588 \\u2588\\u2588\\u2584 \\u2584\\u2588',\n ];\n\n function render(): void {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Title\n const titleX = Math.floor((cols - title[0].length) / 2);\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[3;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n\n // Subtitle with game count\n const subtitle = `Select a game to play (${games.length} games)`;\n output += `\\x1b[5;${Math.floor((cols - subtitle.length) / 2)}H\\x1b[2m${subtitle}\\x1b[0m`;\n\n // Determine if we should use 2 columns\n const boxWidth = 38;\n const columnGap = 2;\n const twoColumnWidth = boxWidth * 2 + columnGap;\n const useTwoColumns = cols >= twoColumnWidth + 8; // 8 for margins\n\n const listStartY = 6;\n const availableRows = rows - listStartY - 4;\n const maxVisibleGames = Math.max(1, Math.floor(availableRows / 2));\n\n if (useTwoColumns) {\n renderTwoColumns(output, cols, rows, boxWidth, columnGap, listStartY, maxVisibleGames);\n } else {\n renderSingleColumn(output, cols, rows, boxWidth, listStartY, maxVisibleGames);\n }\n }\n\n function renderSingleColumn(\n baseOutput: string,\n cols: number,\n rows: number,\n boxWidth: number,\n listStartY: number,\n maxVisibleGames: number\n ): void {\n let output = baseOutput;\n const boxX = Math.floor((cols - boxWidth) / 2);\n const visibleGames = Math.min(maxVisibleGames, games.length);\n\n // Adjust scroll offset to keep selected item visible\n if (selectedIndex < scrollOffset) {\n scrollOffset = selectedIndex;\n } else if (selectedIndex >= scrollOffset + visibleGames) {\n scrollOffset = selectedIndex - visibleGames + 1;\n }\n scrollOffset = Math.max(0, Math.min(scrollOffset, games.length - visibleGames));\n\n const hasScrollUp = scrollOffset > 0;\n const hasScrollDown = scrollOffset + visibleGames < games.length;\n\n // Top border\n const topScrollIndicator = hasScrollUp ? ' \\u25b2 more ' : '\\u2550'.repeat(8);\n const topBorderWidth = boxWidth - 2 - topScrollIndicator.length;\n const topLeftPad = Math.floor(topBorderWidth / 2);\n const topRightPad = topBorderWidth - topLeftPad;\n output += `\\x1b[${listStartY};${boxX}H${themeColor}\\u2554${'\\u2550'.repeat(topLeftPad)}${hasScrollUp ? '\\x1b[33m' : ''}${topScrollIndicator}${hasScrollUp ? themeColor : ''}${'\\u2550'.repeat(topRightPad)}\\u2557\\x1b[0m`;\n\n // Render visible games\n for (let vi = 0; vi < visibleGames; vi++) {\n const i = scrollOffset + vi;\n const game = games[i];\n const y = listStartY + 1 + vi * 2;\n const isSelected = i === selectedIndex;\n\n output += renderGameEntry(game, i, isSelected, y, boxX, boxWidth);\n }\n\n // Bottom border\n const bottomY = listStartY + 1 + visibleGames * 2;\n const bottomScrollIndicator = hasScrollDown ? ' \\u25bc more ' : '\\u2550'.repeat(8);\n const bottomBorderWidth = boxWidth - 2 - bottomScrollIndicator.length;\n const bottomLeftPad = Math.floor(bottomBorderWidth / 2);\n const bottomRightPad = bottomBorderWidth - bottomLeftPad;\n output += `\\x1b[${bottomY};${boxX}H${themeColor}\\u255a${'\\u2550'.repeat(bottomLeftPad)}${hasScrollDown ? '\\x1b[33m' : ''}${bottomScrollIndicator}${hasScrollDown ? themeColor : ''}${'\\u2550'.repeat(bottomRightPad)}\\u255d\\x1b[0m`;\n\n // Controls\n const controls = `\\u2191\\u2193 Navigate | ENTER Select | 1-9 Quick | Q Quit`;\n output += `\\x1b[${rows - 1};${Math.floor((cols - controls.length) / 2)}H\\x1b[2m${controls}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n function renderTwoColumns(\n baseOutput: string,\n cols: number,\n rows: number,\n boxWidth: number,\n columnGap: number,\n listStartY: number,\n maxVisibleGames: number\n ): void {\n let output = baseOutput;\n\n // With 2 columns, we can show 2x as many games\n const gamesPerColumn = Math.min(maxVisibleGames, Math.ceil(games.length / 2));\n\n // Calculate scroll based on rows of 2 games\n const selectedRow = Math.floor(selectedIndex / 2);\n if (selectedRow < scrollOffset) {\n scrollOffset = selectedRow;\n } else if (selectedRow >= scrollOffset + gamesPerColumn) {\n scrollOffset = selectedRow - gamesPerColumn + 1;\n }\n const maxScroll = Math.max(0, Math.ceil(games.length / 2) - gamesPerColumn);\n scrollOffset = Math.max(0, Math.min(scrollOffset, maxScroll));\n\n const hasScrollUp = scrollOffset > 0;\n const hasScrollDown = (scrollOffset + gamesPerColumn) * 2 < games.length;\n\n // Calculate positions for two columns\n const totalWidth = boxWidth * 2 + columnGap;\n const startX = Math.floor((cols - totalWidth) / 2);\n const leftBoxX = startX;\n const rightBoxX = startX + boxWidth + columnGap;\n\n // Top borders\n const topScrollIndicator = hasScrollUp ? ' \\u25b2 ' : '\\u2550\\u2550\\u2550';\n const topBorderContent = boxWidth - 2 - topScrollIndicator.length;\n const topLeft = Math.floor(topBorderContent / 2);\n const topRight = topBorderContent - topLeft;\n\n output += `\\x1b[${listStartY};${leftBoxX}H${themeColor}\\u2554${'\\u2550'.repeat(topLeft)}${hasScrollUp ? '\\x1b[33m' : ''}${topScrollIndicator}${hasScrollUp ? themeColor : ''}${'\\u2550'.repeat(topRight)}\\u2557\\x1b[0m`;\n output += `\\x1b[${listStartY};${rightBoxX}H${themeColor}\\u2554${'\\u2550'.repeat(topLeft)}${hasScrollUp ? '\\x1b[33m' : ''}${topScrollIndicator}${hasScrollUp ? themeColor : ''}${'\\u2550'.repeat(topRight)}\\u2557\\x1b[0m`;\n\n // Render games in two columns\n for (let row = 0; row < gamesPerColumn; row++) {\n const leftIdx = (scrollOffset + row) * 2;\n const rightIdx = leftIdx + 1;\n const y = listStartY + 1 + row * 2;\n\n // Left column\n if (leftIdx < games.length) {\n output += renderGameEntry(games[leftIdx], leftIdx, leftIdx === selectedIndex, y, leftBoxX, boxWidth);\n } else {\n // Empty slot\n output += `\\x1b[${y};${leftBoxX}H${themeColor}\\u2551${' '.repeat(boxWidth - 2)}\\u2551\\x1b[0m`;\n output += `\\x1b[${y + 1};${leftBoxX}H${themeColor}\\u2551${' '.repeat(boxWidth - 2)}\\u2551\\x1b[0m`;\n }\n\n // Right column\n if (rightIdx < games.length) {\n output += renderGameEntry(games[rightIdx], rightIdx, rightIdx === selectedIndex, y, rightBoxX, boxWidth);\n } else {\n // Empty slot\n output += `\\x1b[${y};${rightBoxX}H${themeColor}\\u2551${' '.repeat(boxWidth - 2)}\\u2551\\x1b[0m`;\n output += `\\x1b[${y + 1};${rightBoxX}H${themeColor}\\u2551${' '.repeat(boxWidth - 2)}\\u2551\\x1b[0m`;\n }\n }\n\n // Bottom borders\n const bottomY = listStartY + 1 + gamesPerColumn * 2;\n const bottomScrollIndicator = hasScrollDown ? ' \\u25bc ' : '\\u2550\\u2550\\u2550';\n const bottomBorderContent = boxWidth - 2 - bottomScrollIndicator.length;\n const bottomLeft = Math.floor(bottomBorderContent / 2);\n const bottomRight = bottomBorderContent - bottomLeft;\n\n output += `\\x1b[${bottomY};${leftBoxX}H${themeColor}\\u255a${'\\u2550'.repeat(bottomLeft)}${hasScrollDown ? '\\x1b[33m' : ''}${bottomScrollIndicator}${hasScrollDown ? themeColor : ''}${'\\u2550'.repeat(bottomRight)}\\u255d\\x1b[0m`;\n output += `\\x1b[${bottomY};${rightBoxX}H${themeColor}\\u255a${'\\u2550'.repeat(bottomLeft)}${hasScrollDown ? '\\x1b[33m' : ''}${bottomScrollIndicator}${hasScrollDown ? themeColor : ''}${'\\u2550'.repeat(bottomRight)}\\u255d\\x1b[0m`;\n\n // Controls\n const controls = `\\u2191\\u2193\\u2190\\u2192 Navigate | ENTER Select | 1-9 Quick | Q Quit`;\n output += `\\x1b[${rows - 1};${Math.floor((cols - controls.length) / 2)}H\\x1b[2m${controls}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n function renderGameEntry(\n game: typeof games[number],\n index: number,\n isSelected: boolean,\n y: number,\n boxX: number,\n boxWidth: number\n ): string {\n let output = '';\n const contentWidth = boxWidth - 2; // Account for box borders on each side\n\n const prefix = isSelected ? '\\u25b6' : ' ';\n const highlight = isSelected ? (lightTheme ? '\\x1b[1;7;97m' : '\\x1b[1;7m') : '';\n const keyColor = isSelected ? '' : '\\x1b[33m';\n const keyNum = index + 1;\n const keyDisplay = keyNum <= 9 ? `${keyNum}` : ' ';\n\n // Build the line content\n const lineContent = `${prefix} [${keyDisplay}] ${game.name}`;\n const padding = Math.max(0, contentWidth - lineContent.length);\n\n output += `\\x1b[${y};${boxX}H${themeColor}\\u2551\\x1b[0m${highlight}${keyColor}${lineContent}${' '.repeat(padding)}\\x1b[0m${themeColor}\\u2551\\x1b[0m`;\n\n // Description line\n const descContent = ` ${game.description}`;\n const descPadding = Math.max(0, contentWidth - descContent.length);\n const descColor = isSelected ? (lightTheme ? '\\x1b[2;7;97m' : '\\x1b[2;7m') : '\\x1b[2m';\n\n output += `\\x1b[${y + 1};${boxX}H${themeColor}\\u2551\\x1b[0m${descColor}${descContent}${' '.repeat(descPadding)}\\x1b[0m${themeColor}\\u2551\\x1b[0m`;\n\n return output;\n }\n\n // Start menu\n setTimeout(() => {\n if (!running) return;\n\n // Verify terminal is still valid before proceeding\n if (!isTerminalValid(terminal)) {\n console.warn('[GamesMenu] Terminal became invalid before menu could start');\n running = false;\n return;\n }\n\n let keyListener: ReturnType<typeof terminal.onKey> | null = null;\n\n try {\n // Enter alternate buffer\n enterAlternateBuffer(terminal, 'games-menu');\n\n render();\n\n keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener?.dispose();\n return;\n }\n\n try {\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key;\n const keyLower = key.toLowerCase();\n const cols = terminal.cols;\n const boxWidth = 38;\n const columnGap = 2;\n const twoColumnWidth = boxWidth * 2 + columnGap;\n const useTwoColumns = cols >= twoColumnWidth + 8;\n\n // Quit\n if (key === 'Escape' || keyLower === 'q') {\n keyListener?.dispose();\n controller.stop();\n exitAlternateBuffer(terminal, 'games-menu-quit');\n if (onQuit) {\n onQuit();\n }\n return;\n }\n\n // Navigate\n if (key === 'ArrowUp') {\n if (useTwoColumns) {\n selectedIndex = Math.max(0, selectedIndex - 2);\n } else {\n selectedIndex = (selectedIndex - 1 + games.length) % games.length;\n }\n render();\n return;\n }\n if (key === 'ArrowDown') {\n if (useTwoColumns) {\n selectedIndex = Math.min(games.length - 1, selectedIndex + 2);\n } else {\n selectedIndex = (selectedIndex + 1) % games.length;\n }\n render();\n return;\n }\n if (key === 'ArrowLeft' && useTwoColumns) {\n if (selectedIndex % 2 === 1) {\n selectedIndex--;\n }\n render();\n return;\n }\n if (key === 'ArrowRight' && useTwoColumns) {\n if (selectedIndex % 2 === 0 && selectedIndex + 1 < games.length) {\n selectedIndex++;\n }\n render();\n return;\n }\n\n // Helper to launch game with transition\n const launchGame = async (game: typeof games[number]) => {\n keyListener?.dispose();\n running = false;\n // Exit alternate buffer BEFORE transition so menu stops drawing\n exitAlternateBuffer(terminal, 'games-menu-launch');\n\n try {\n await playSelectTransition(terminal, game.name);\n if (onGameSelect) {\n onGameSelect(game.id);\n }\n } catch (err) {\n console.error('[GamesMenu] Failed to launch game:', err);\n // Ensure terminal is in usable state on error\n forceExitAlternateBuffer(terminal, 'games-menu-launch-error');\n terminal.write(`\\x1b[91mError launching game: ${err}\\x1b[0m\\r\\n`);\n }\n };\n\n // Select\n if (key === 'Enter') {\n launchGame(games[selectedIndex]).catch(err => {\n console.error('[GamesMenu] Unhandled launch error:', err);\n });\n return;\n }\n\n // Quick select by number (1-9)\n const numKey = parseInt(key);\n if (numKey >= 1 && numKey <= games.length && numKey <= 9) {\n launchGame(games[numKey - 1]).catch(err => {\n console.error('[GamesMenu] Unhandled launch error:', err);\n });\n return;\n }\n } catch (err) {\n console.error('[GamesMenu] Key handler error:', err);\n controller.stop();\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n keyListener?.dispose();\n exitAlternateBuffer(terminal, 'games-menu-stop');\n originalStop();\n };\n } catch (err) {\n console.error('[GamesMenu] Failed to initialize menu:', err);\n forceExitAlternateBuffer(terminal, 'games-menu-init-error');\n running = false;\n }\n }, 50);\n\n return controller;\n}\n","/**\n * @hypersocial/cli-games\n *\n * Terminal games for xterm.js and CLI\n *\n * Usage:\n * 1. Set the theme: setTheme('cyan')\n * 2. Run a game: games.snake.run(terminal)\n * 3. Handle game events: listen for GAME_EVENTS on window\n */\n\n// Re-export utilities\nexport {\n setTheme,\n getTheme,\n getCurrentThemeColor,\n isLightTheme,\n getSubtleBackgroundColor,\n getVerticalAnchor,\n getThemeColorCode,\n enterAlternateBuffer,\n exitAlternateBuffer,\n isInAlternateBuffer,\n forceExitAlternateBuffer,\n isTerminalValid,\n} from './utils';\n\nexport type { PhosphorMode } from './utils';\n\n// Re-export transitions\nexport {\n GAME_EVENTS,\n playBootTransition,\n playExitTransition,\n playSwitchTransition,\n playQuickBoot,\n playSelectTransition,\n dispatchGameQuit,\n dispatchGameSwitch,\n dispatchGamesMenu,\n dispatchLaunchGame,\n} from './gameTransitions';\n\n// Re-export menu utilities\nexport {\n createMenuState,\n menuUp,\n menuDown,\n menuReset,\n menuConfirm,\n handleMenuInput,\n renderMenu,\n createPauseMenuItems,\n createGameOverMenuItems,\n createModeSelectMenuItems,\n navigateMenu,\n checkShortcut,\n renderSimpleMenu,\n PAUSE_MENU_ITEMS,\n MODE_SELECT_ITEMS,\n} from './shared/menu';\n\nexport type {\n MenuItem,\n MenuState,\n RenderMenuOptions,\n SimpleMenuItem,\n} from './shared/menu';\n\n// Import game modules\nimport { run2048Game } from './2048';\nimport { runAsteroidsGame } from './asteroids';\nimport { runBreakoutGame } from './breakout';\nimport { runCourierGame } from './chopper';\nimport { runCrackGame } from './crack';\nimport { runFroggerGame } from './frogger';\nimport { runHangmanGame } from './hangman';\nimport { runMinesweeperGame } from './minesweeper';\nimport { runPongGame } from './pong';\nimport { runRunnerGame } from './runner';\nimport { runSimonGame } from './simon';\nimport { runSnakeGame } from './snake';\nimport { runSpaceInvadersGame } from './spaceinvaders';\nimport { runTetrisGame } from './tetris';\nimport { runTowerGame } from './tower';\nimport { runTronGame } from './tron';\nimport { runTypingTest } from './typingtest';\nimport { runWordleGame } from './wordle';\n\n/**\n * Game registry with metadata\n */\nexport interface GameInfo {\n id: string;\n name: string;\n description: string;\n run: (terminal: import('@xterm/xterm').Terminal) => { stop: () => void; isRunning: boolean };\n}\n\nexport const games: GameInfo[] = [\n // Ordered for first-time discovery enjoyment (most accessible first).\n { id: 'tetris', name: 'Tetris', description: 'Stack the blocks', run: runTetrisGame },\n { id: 'snake', name: 'Snake', description: 'Eat and grow', run: runSnakeGame },\n { id: '2048', name: '2048', description: 'Slide and combine tiles', run: run2048Game },\n { id: 'runner', name: 'Runner', description: 'Jump and duck', run: runRunnerGame },\n { id: 'pong', name: 'Pong', description: 'Classic paddle game', run: runPongGame },\n { id: 'wordle', name: 'Wordle', description: 'Guess the word', run: runWordleGame },\n { id: 'minesweeper', name: 'Minesweeper', description: 'Clear the mines', run: runMinesweeperGame },\n { id: 'hangman', name: 'Hangman', description: 'Guess the word', run: runHangmanGame },\n { id: 'spaceinvaders', name: 'Space Invaders', description: 'Defend Earth', run: runSpaceInvadersGame },\n { id: 'tower', name: 'Tower', description: 'Build a tower', run: runTowerGame },\n { id: 'simon', name: 'Simon', description: 'Memory game', run: runSimonGame },\n { id: 'frogger', name: 'Frogger', description: 'Cross the road', run: runFroggerGame },\n { id: 'breakout', name: 'Breakout', description: 'Break all the bricks', run: runBreakoutGame },\n { id: 'asteroids', name: 'Asteroids', description: 'Shoot the rocks', run: runAsteroidsGame },\n { id: 'typingtest', name: 'Typing Test', description: 'Test your speed', run: runTypingTest },\n { id: 'tron', name: 'Tron', description: 'Light cycle battle', run: runTronGame },\n { id: 'crack', name: 'Crack', description: 'Hack the system', run: runCrackGame },\n { id: 'chopper', name: 'Chopper', description: 'Deliver passengers', run: runCourierGame },\n];\n\n/**\n * Get a game by ID\n */\nexport function getGame(id: string): GameInfo | undefined {\n return games.find(g => g.id === id);\n}\n\n/**\n * Get a random game\n */\nexport function getRandomGame(): GameInfo {\n return games[Math.floor(Math.random() * games.length)];\n}\n\n/**\n * Run a game by ID\n */\nexport function runGame(\n id: string,\n terminal: import('@xterm/xterm').Terminal\n): { stop: () => void; isRunning: boolean } | undefined {\n const game = getGame(id);\n return game?.run(terminal);\n}\n\n// Also export individual game runners for direct imports\nexport {\n run2048Game,\n runAsteroidsGame,\n runBreakoutGame,\n runCourierGame,\n runCrackGame,\n runFroggerGame,\n runHangmanGame,\n runMinesweeperGame,\n runPongGame,\n runRunnerGame,\n runSimonGame,\n runSnakeGame,\n runSpaceInvadersGame,\n runTetrisGame,\n runTowerGame,\n runTronGame,\n runTypingTest,\n runWordleGame,\n};\n\n// Re-export games menu\nexport { showGamesMenu } from './gamesMenu';\nexport type { GamesMenuController, GamesMenuOptions } from './gamesMenu';\n\n// Re-export effects\nexport {\n runMatrixEffect,\n startMatrixRain,\n getActiveMatrixController,\n isMatrixWaitingForKey,\n handleMatrixKeypress,\n runHackEffect,\n runRebootEffect,\n} from './effects';\nexport type { MatrixController, HackController, RebootController } from './effects';\n","/**\n * CLI entry point for @hypersocial/cli-games\n *\n * Provides a Node.js terminal adapter that maps stdin/stdout\n * to an xterm.js-compatible Terminal interface, allowing all\n * games to run directly in any terminal emulator.\n */\n\n// ---------------------------------------------------------------------------\n// Window polyfill — MUST run before any game code is imported.\n// Games use window.addEventListener('keydown'/'keyup'), window.dispatchEvent,\n// and new CustomEvent.\n// ---------------------------------------------------------------------------\n\ntype EventHandler = (event: Event) => void;\nconst eventListeners = new Map<string, Set<EventHandler>>();\n\nconst windowPolyfill = {\n addEventListener(type: string, handler: EventHandler) {\n if (!eventListeners.has(type)) eventListeners.set(type, new Set());\n eventListeners.get(type)!.add(handler);\n },\n removeEventListener(type: string, handler: EventHandler) {\n eventListeners.get(type)?.delete(handler);\n },\n dispatchEvent(event: Event): boolean {\n const handlers = eventListeners.get(event.type);\n if (handlers) {\n for (const handler of handlers) {\n handler(event);\n }\n }\n return true;\n },\n};\n\nif (typeof globalThis.window === 'undefined') {\n (globalThis as Record<string, unknown>).window = windowPolyfill;\n}\n\n// Now safe to import game code\nimport { games, setTheme, showGamesMenu, type GameInfo, GAME_EVENTS } from './games';\nimport type { PhosphorMode } from './themes';\n\n// ---------------------------------------------------------------------------\n// Node Terminal Adapter\n// ---------------------------------------------------------------------------\n\ninterface KeyEvent {\n key: string;\n domEvent: {\n key: string;\n code: string;\n keyCode: number;\n preventDefault: () => void;\n stopPropagation: () => void;\n };\n}\n\ninterface Disposable {\n dispose: () => void;\n}\n\ninterface NodeTerminal {\n write: (data: string) => void;\n cols: number;\n rows: number;\n element: object;\n onKey: (callback: (event: KeyEvent) => void) => Disposable;\n onData: (callback: (data: string) => void) => Disposable;\n onResize: (callback: (size: { cols: number; rows: number }) => void) => Disposable;\n}\n\n/**\n * Map of key names to approximate keyCodes (for games that check keyCode)\n */\nconst KEY_CODES: Record<string, number> = {\n ArrowUp: 38, ArrowDown: 40, ArrowLeft: 37, ArrowRight: 39,\n Enter: 13, Escape: 27, ' ': 32, Backspace: 8, Tab: 9,\n a: 65, b: 66, c: 67, d: 68, e: 69, f: 70, g: 71, h: 72,\n i: 73, j: 74, k: 75, l: 76, m: 77, n: 78, o: 79, p: 80,\n q: 81, r: 82, s: 83, t: 84, u: 85, v: 86, w: 87, x: 88,\n y: 89, z: 90, '1': 49, '2': 50, '3': 51, '4': 52, '5': 53,\n '6': 54, '7': 55, '8': 56, '9': 57, '0': 48,\n};\n\n/**\n * Parse raw stdin escape sequences into key names\n * compatible with DOM KeyboardEvent.key values\n */\nfunction parseKey(data: string): string {\n if (data === '\\x1b[A' || data === '\\x1bOA') return 'ArrowUp';\n if (data === '\\x1b[B' || data === '\\x1bOB') return 'ArrowDown';\n if (data === '\\x1b[C' || data === '\\x1bOC') return 'ArrowRight';\n if (data === '\\x1b[D' || data === '\\x1bOD') return 'ArrowLeft';\n if (data === '\\r' || data === '\\n') return 'Enter';\n if (data === '\\x1b') return 'Escape';\n if (data === ' ') return ' ';\n if (data === '\\x7f' || data === '\\b') return 'Backspace';\n if (data === '\\t') return 'Tab';\n if (data === '\\x03') return 'c';\n if (data.length === 1) return data;\n return data;\n}\n\nfunction createDomEvent(key: string) {\n const keyCode = KEY_CODES[key] || KEY_CODES[key.toLowerCase()] || 0;\n return {\n key,\n code: key.length === 1 ? `Key${key.toUpperCase()}` : key,\n keyCode,\n which: keyCode,\n preventDefault: () => {},\n stopPropagation: () => {},\n stopImmediatePropagation: () => {},\n // Properties games might check\n ctrlKey: false,\n shiftKey: false,\n altKey: false,\n metaKey: false,\n repeat: false,\n type: 'keydown',\n };\n}\n\n// Track held keys for keyup simulation\nconst heldKeys = new Map<string, ReturnType<typeof setTimeout>>();\n\nfunction createNodeTerminal(): NodeTerminal {\n const keyListeners: ((event: KeyEvent) => void)[] = [];\n const dataListeners: ((data: string) => void)[] = [];\n const resizeListeners: ((size: { cols: number; rows: number }) => void)[] = [];\n\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n }\n process.stdin.resume();\n process.stdin.setEncoding('utf8');\n\n process.stdin.on('data', (data: string) => {\n if (data === '\\x03') {\n cleanup();\n process.exit(0);\n }\n\n const key = parseKey(data);\n const domEvent = createDomEvent(key);\n\n // Dispatch keydown on window (Tetris/Chopper use this)\n // Can't Object.assign onto Event (type is read-only getter), so use a plain object\n const keydownEvent = { ...domEvent, type: 'keydown' } as unknown as Event;\n windowPolyfill.dispatchEvent(keydownEvent);\n\n // Simulate keyup after a short delay (no key-release in raw stdin)\n if (heldKeys.has(key)) {\n clearTimeout(heldKeys.get(key)!);\n }\n heldKeys.set(key, setTimeout(() => {\n const keyupEvent = { ...domEvent, type: 'keyup' } as unknown as Event;\n windowPolyfill.dispatchEvent(keyupEvent);\n heldKeys.delete(key);\n }, 80));\n\n // Fire terminal.onKey listeners\n for (const listener of [...keyListeners]) {\n listener({ key, domEvent });\n }\n\n for (const listener of [...dataListeners]) {\n listener(data);\n }\n });\n\n process.stdout.on('resize', () => {\n const size = { cols: process.stdout.columns || 80, rows: process.stdout.rows || 24 };\n for (const listener of [...resizeListeners]) {\n listener(size);\n }\n });\n\n function cleanup() {\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n process.stdin.pause();\n process.stdout.write('\\x1b[?1049l');\n process.stdout.write('\\x1b[?25h');\n process.stdout.write('\\x1b[0m');\n }\n\n // Synchronized output: wrap writes with DEC sync sequences so the\n // terminal batches clear + redraw into a single atomic paint.\n // Supported by Warp, iTerm2, kitty, foot, WezTerm, etc.\n const SYNC_START = '\\x1b[?2026h';\n const SYNC_END = '\\x1b[?2026l';\n\n const terminal: NodeTerminal = {\n write: (data: string) => {\n process.stdout.write(SYNC_START + data + SYNC_END);\n },\n get cols() { return process.stdout.columns || 80; },\n get rows() { return process.stdout.rows || 24; },\n element: {}, // Truthy for isTerminalValid check\n onKey: (callback: (event: KeyEvent) => void): Disposable => {\n keyListeners.push(callback);\n return {\n dispose: () => {\n const idx = keyListeners.indexOf(callback);\n if (idx !== -1) keyListeners.splice(idx, 1);\n }\n };\n },\n onData: (callback: (data: string) => void): Disposable => {\n dataListeners.push(callback);\n return {\n dispose: () => {\n const idx = dataListeners.indexOf(callback);\n if (idx !== -1) dataListeners.splice(idx, 1);\n }\n };\n },\n onResize: (callback: (size: { cols: number; rows: number }) => void): Disposable => {\n resizeListeners.push(callback);\n return {\n dispose: () => {\n const idx = resizeListeners.indexOf(callback);\n if (idx !== -1) resizeListeners.splice(idx, 1);\n }\n };\n },\n };\n\n process.on('exit', cleanup);\n process.on('SIGINT', () => { cleanup(); process.exit(0); });\n process.on('SIGTERM', () => { cleanup(); process.exit(0); });\n\n return terminal;\n}\n\n// ---------------------------------------------------------------------------\n// Game lifecycle\n// ---------------------------------------------------------------------------\n\nfunction setupGameEvents(terminal: NodeTerminal) {\n // Listen for game quit/switch/menu events dispatched via window\n windowPolyfill.addEventListener(GAME_EVENTS.QUIT, () => {\n setTimeout(() => openMenu(terminal), 100);\n });\n windowPolyfill.addEventListener(GAME_EVENTS.SWITCH, () => {\n // Launch a random game\n const randomGame = games[Math.floor(Math.random() * games.length)];\n setTimeout(() => launchGame(terminal, randomGame), 100);\n });\n windowPolyfill.addEventListener(GAME_EVENTS.GAMES_MENU, () => {\n setTimeout(() => openMenu(terminal), 100);\n });\n windowPolyfill.addEventListener(GAME_EVENTS.LAUNCH_GAME, ((event: CustomEvent) => {\n const gameId = event.detail?.gameId;\n const game = games.find(g => g.id === gameId);\n if (game) {\n setTimeout(() => launchGame(terminal, game), 100);\n }\n }) as EventHandler);\n}\n\nfunction openMenu(terminal: NodeTerminal) {\n // Use the exact same games menu from the library\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n showGamesMenu(terminal as any, {\n onGameSelect: (gameId: string) => {\n const game = games.find(g => g.id === gameId);\n if (game) launchGame(terminal, game);\n },\n onQuit: () => {\n process.exit(0);\n },\n });\n}\n\nfunction launchGame(terminal: NodeTerminal, game: GameInfo) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n game.run(terminal as any);\n}\n\n// ---------------------------------------------------------------------------\n// Main\n// ---------------------------------------------------------------------------\n\nfunction main() {\n const args = process.argv.slice(2);\n\n let theme: PhosphorMode = 'cyan';\n const themeIdx = args.indexOf('--theme');\n if (themeIdx !== -1 && args[themeIdx + 1]) {\n theme = args[themeIdx + 1] as PhosphorMode;\n args.splice(themeIdx, 2);\n }\n setTheme(theme);\n\n const terminal = createNodeTerminal();\n setupGameEvents(terminal);\n\n // Direct game launch: cli-games snake\n const gameName = args[0];\n if (gameName) {\n const game = games.find(g => g.id === gameName || g.name.toLowerCase() === gameName.toLowerCase());\n if (!game) {\n console.error(`Unknown game: ${gameName}`);\n console.error(`Available games: ${games.map(g => g.id).join(', ')}`);\n process.exit(1);\n return;\n }\n launchGame(terminal, game);\n return;\n }\n\n openMenu(terminal);\n}\n\nmain();\n"],"mappings":";;;AAgEO,IAAM,SAA4C;AAAA,EACvD,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,EACf;AAAA,EACA,WAAW;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,YAAY;AAAA;AAAA,EACd;AAAA,EACA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,EACf;AAAA,EACA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,EACf;AAAA,EACA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,EACf;AAAA,EACA,SAAS;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,EACf;AAAA,EACA,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,YAAY;AAAA;AAAA,EACd;AAAA,EACA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,EACf;AAAA,EACA,KAAK;AAAA,IACH,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,EACf;AAAA,EACA,UAAU;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,YAAY;AAAA;AAAA,EACd;AAAA,EACA,aAAa;AAAA,IACX,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,EACf;AAAA,EACA,kBAAkB;AAAA,IAChB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,YAAY;AAAA;AAAA,EACd;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,EACf;AAAA,EACA,WAAW;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,YAAY;AAAA;AAAA,EACd;AAAA,EACA,UAAU;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,YAAY;AAAA;AAAA,EACd;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,EACf;AAAA,EACA,aAAa;AAAA,IACX,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,YAAY;AAAA;AAAA,EACd;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,EACf;AAAA,EACA,WAAW;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,YAAY;AAAA;AAAA,EACd;AAAA,EACA,gBAAgB;AAAA,IACd,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,YAAY;AAAA;AAAA,EACd;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,EACf;AAAA,EACA,WAAW;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,YAAY;AAAA;AAAA,EACd;AAAA,EACA,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,EACf;AAAA,EACA,mBAAmB;AAAA,IACjB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,YAAY;AAAA;AAAA,EACd;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,EACf;AAAA,EACA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,YAAY;AAAA,EACd;AACF;AAKA,IAAM,YAA0C;AAAA,EAC9C,MAAM;AAAA,EACN,WAAW;AAAA,EACX,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,SAAS;AAAA,EACT,cAAc;AAAA,EACd,OAAO;AAAA,EACP,KAAK;AAAA,EACL,UAAU;AAAA,EACV,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,MAAM;AAAA,EACN,WAAW;AAAA,EACX,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,MAAM;AAAA,EACN,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,MAAM;AAAA,EACN,WAAW;AAAA,EACX,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,QAAQ;AAAA,EACR,OAAO;AACT;AAKA,IAAM,cAAiC,oBAAI,IAAI;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAKD,IAAM,eAAsD;AAAA,EAC1D,WAAW;AAAA,EACX,cAAc;AAAA,EACd,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,WAAW;AAAA,EACX,mBAAmB;AAAA,EACnB,OAAO;AAAA,EACP,MAAM;AAAA,EACN,cAAc;AAChB;AAgBO,SAAS,aAAa,MAA4B;AACvD,SAAO,UAAU,IAAI,KAAK;AAC5B;AAKO,SAAS,aAAa,MAA6B;AACxD,SAAO,YAAY,IAAI,IAAI;AAC7B;AAKO,SAAS,eAAe,MAA4B;AACzD,SAAO,aAAa,IAAI,KAAK;AAC/B;AASA,IAAM,oBAAoB,IAAI,IAAY,OAAO,KAAK,MAAM,CAAC;;;ACxa7D,IAAI,eAA6B;AAM1B,SAAS,SAAS,MAA0B;AACjD,iBAAe;AACjB;AAiBA,IAAM,uBAAuB,oBAAI,QAAyD;AAKnF,SAAS,gBAAgB,UAA6D;AAC3F,MAAI,CAAC,SAAU,QAAO;AAEtB,MAAI;AACF,WAAO,SAAS,YAAY;AAAA,EAC9B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAUO,SAAS,qBAAqB,UAAoB,QAAyB;AAChF,MAAI,CAAC,gBAAgB,QAAQ,GAAG;AAC9B,YAAQ,KAAK,6DAA6D,MAAM,GAAG;AACnF,WAAO;AAAA,EACT;AAEA,MAAI,qBAAqB,IAAI,QAAQ,GAAG;AACtC,UAAM,WAAW,qBAAqB,IAAI,QAAQ;AAClD,YAAQ,KAAK,oDAAoD,SAAS,MAAM,oBAAoB,MAAM,EAAE;AAC5G,WAAO;AAAA,EACT;AAEA,WAAS,MAAM,aAAa;AAC5B,WAAS,MAAM,WAAW;AAC1B,WAAS,MAAM,eAAe;AAE9B,uBAAqB,IAAI,UAAU,EAAE,QAAQ,WAAW,KAAK,IAAI,EAAE,CAAC;AACpE,SAAO;AACT;AAUO,SAAS,oBAAoB,UAAoB,QAAyB;AAC/E,MAAI,CAAC,gBAAgB,QAAQ,GAAG;AAC9B,YAAQ,KAAK,4DAA4D,MAAM,GAAG;AAClF,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,qBAAqB,IAAI,QAAQ,GAAG;AACvC,YAAQ,KAAK,iEAAiE,MAAM,EAAE;AACtF,WAAO;AAAA,EACT;AAEA,WAAS,MAAM,aAAa;AAC5B,WAAS,MAAM,WAAW;AAE1B,uBAAqB,OAAO,QAAQ;AACpC,SAAO;AACT;AAaO,SAAS,yBAAyB,UAAoB,QAAsB;AACjF,MAAI,CAAC,gBAAgB,QAAQ,GAAG;AAC9B,YAAQ,KAAK,kEAAkE,MAAM,GAAG;AACxF;AAAA,EACF;AAEA,WAAS,MAAM,aAAa;AAC5B,WAAS,MAAM,WAAW;AAC1B,uBAAqB,OAAO,QAAQ;AACpC,UAAQ,KAAK,2CAA2C,MAAM,GAAG;AACnE;AAgBO,SAAS,uBAA+B;AAC7C,SAAO,aAAa,YAAY;AAClC;AAKO,SAASA,gBAAwB;AACtC,SAAO,aAAgB,YAAY;AACrC;AAMO,SAAS,2BAAmC;AACjD,SAAO,eAAe,YAAY;AACpC;AAeO,SAAS,kBACd,cACA,aACA,UAAiC,CAAC,GAC1B;AACR,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,SAAS,KAAK,IAAI,GAAG,QAAQ,UAAU,CAAC;AAE9C,QAAM,gBAAgB,eAAe,aAAa;AAClD,QAAM,cAAc,aAAa,KAAK,OAAO,gBAAgB,eAAe,CAAC,IAAI;AAEjF,SAAO,KAAK,IAAI,QAAQ,WAAW;AACrC;;;AChJA,IAAM,eAAe;AAuBrB,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,aAAW,WAAW,SAAS,EAAE,CAAC;AACvD;AA+KA,eAAsB,qBAAqB,UAAoB,UAAiC;AAC9F,QAAM,aAAa,qBAAqB;AACxC,QAAM,OAAO,SAAS;AACtB,QAAM,OAAO,SAAS;AACtB,QAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,QAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AAGnC,WAAS,MAAM,eAAe;AAC9B,WAAS,MAAM,iBAAiB,IAAI,OAAO,OAAO,IAAI,CAAC,SAAS;AAChE,QAAM,MAAM,EAAE;AACd,WAAS,MAAM,eAAe;AAC9B,QAAM,MAAM,EAAE;AAGd,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,SAAS,IAAI;AAEnB,QAAI,UAAU,SAAS,GAAG;AACxB,eAAS,MAAM,QAAQ,UAAU,MAAM,MAAM,UAAU,GAAG,SAAI,OAAO,IAAI,CAAC,SAAS;AAAA,IACrF;AACA,QAAI,UAAU,UAAU,MAAM;AAC5B,eAAS,MAAM,QAAQ,UAAU,MAAM,MAAM,UAAU,GAAG,SAAI,OAAO,IAAI,CAAC,SAAS;AAAA,IACrF;AACA,UAAM,MAAM,EAAE;AAEd,QAAI,IAAI,GAAG;AACT,YAAM,aAAa,IAAI;AACvB,UAAI,UAAU,aAAa,GAAG;AAC5B,iBAAS,MAAM,QAAQ,UAAU,UAAU,MAAM,IAAI,OAAO,IAAI,CAAC,EAAE;AAAA,MACrE;AACA,UAAI,UAAU,cAAc,MAAM;AAChC,iBAAS,MAAM,QAAQ,UAAU,UAAU,MAAM,IAAI,OAAO,IAAI,CAAC,EAAE;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AAGA,WAAS,MAAM,eAAe;AAG9B,QAAM,cAAc,UAAK,QAAQ;AACjC,QAAM,QAAQ,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,YAAY,SAAS,CAAC,CAAC;AAGtE,WAAS,QAAQ,GAAG,QAAQ,GAAG,SAAS;AACtC,QAAI,WAAW;AACf,aAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;AAC3C,UAAI,SAAS,KAAK,KAAK,OAAO,IAAI,QAAQ,GAAG;AAC3C,oBAAY,YAAY,CAAC;AAAA,MAC3B,OAAO;AACL,oBAAY,aAAa,KAAK,MAAM,KAAK,OAAO,IAAI,aAAa,MAAM,CAAC;AAAA,MAC1E;AAAA,IACF;AACA,aAAS,MAAM,QAAQ,OAAO,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ,SAAS;AAChF,UAAM,MAAM,EAAE;AAAA,EAChB;AAGA,WAAS,MAAM,QAAQ,OAAO,IAAI,KAAK,aAAa,UAAU,GAAG,WAAW,SAAS;AACrF,QAAM,MAAM,GAAG;AAGf,QAAM,aAAa;AACnB,QAAM,WAAW,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,WAAW,SAAS,CAAC,CAAC;AACxE,WAAS,MAAM,QAAQ,UAAU,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,UAAU,SAAS;AAGzF,QAAM,WAAW;AACjB,QAAM,OAAO,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,WAAW,CAAC,IAAI,CAAC;AAC/D,WAAS,IAAI,GAAG,KAAK,UAAU,KAAK;AAClC,UAAM,SAAS,SAAI,OAAO,CAAC;AAC3B,UAAM,QAAQ,SAAI,OAAO,WAAW,CAAC;AACrC,aAAS,MAAM,QAAQ,UAAU,CAAC,IAAI,IAAI,IAAI,UAAU,IAAI,MAAM,GAAG,KAAK,UAAU;AACpF,UAAM,MAAM,EAAE;AAAA,EAChB;AAEA,QAAM,MAAM,GAAG;AAGf,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAS,MAAM,eAAe;AAC9B,UAAM,MAAM,EAAE;AACd,aAAS,MAAM,QAAQ,OAAO,IAAI,KAAK,WAAW,UAAU,GAAG,WAAW,SAAS;AACnF,UAAM,MAAM,EAAE;AAAA,EAChB;AAEA,WAAS,MAAM,eAAe;AAC9B,QAAM,MAAM,EAAE;AAChB;AAGO,IAAM,cAAc;AAAA;AAAA,EAEzB,MAAM;AAAA;AAAA,EAEN,QAAQ;AAAA;AAAA,EAER,YAAY;AAAA;AAAA,EAEZ,aAAa;AACf;AAMO,SAAS,iBAAiB,UAA0B;AACzD,SAAO,cAAc,IAAI,YAAY,YAAY,MAAM;AAAA,IACrD,QAAQ,EAAE,SAAS;AAAA,EACrB,CAAC,CAAC;AACJ;AAMO,SAAS,mBAAmB,UAA0B;AAC3D,SAAO,cAAc,IAAI,YAAY,YAAY,QAAQ;AAAA,IACvD,QAAQ,EAAE,SAAS;AAAA,EACrB,CAAC,CAAC;AACJ;AAMO,SAAS,kBAAkB,UAA0B;AAC1D,SAAO,cAAc,IAAI,YAAY,YAAY,YAAY;AAAA,IAC3D,QAAQ,EAAE,SAAS;AAAA,EACrB,CAAC,CAAC;AACJ;;;AC5IO,SAAS,aACd,kBACA,WACA,KACA,UAC8C;AAC9C,MAAI,eAAe;AACnB,MAAI,YAAY;AAEhB,MAAI,SAAS,QAAQ,aAAa,QAAQ,KAAK;AAC7C,oBAAgB,mBAAmB,IAAI,aAAa;AAAA,EACtD,WAAW,SAAS,QAAQ,eAAe,QAAQ,KAAK;AACtD,oBAAgB,mBAAmB,KAAK;AAAA,EAC1C,WAAW,SAAS,QAAQ,WAAW,SAAS,QAAQ,KAAK;AAC3D,gBAAY;AAAA,EACd;AAEA,SAAO,EAAE,cAAc,UAAU;AACnC;AAuBO,SAAS,iBACd,OACA,WACA,SAKQ;AACR,QAAM,aAAa,qBAAqB;AACxC,QAAM,EAAE,SAAS,QAAQ,gBAAgB,KAAK,IAAI;AAElD,MAAI,SAAS;AAEb,QAAM,QAAQ,CAAC,MAAM,MAAM;AACzB,UAAM,aAAa,MAAM;AAEzB,QAAI,cAAc,KAAK;AACvB,QAAI,iBAAiB,KAAK,UAAU;AAClC,qBAAe,KAAK,KAAK,QAAQ;AAAA,IACnC;AAEA,UAAM,OAAO,aAAa,UAAK,WAAW,YAAO,KAAK,WAAW;AACjE,UAAM,QAAQ,aAAa,eAAe,UAAU,UAAU;AAE9D,UAAM,QAAQ,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC;AAClD,cAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,IAAI,KAAK,GAAG,IAAI;AAAA,EACvD,CAAC;AAED,SAAO;AACT;AAKO,IAAM,mBAAqC;AAAA,EAChD,EAAE,OAAO,UAAU,UAAU,MAAM;AAAA,EACnC,EAAE,OAAO,WAAW,UAAU,IAAI;AAAA,EAClC,EAAE,OAAO,QAAQ,UAAU,IAAI;AAAA,EAC/B,EAAE,OAAO,cAAc,UAAU,IAAI;AAAA,EACrC,EAAE,OAAO,aAAa,UAAU,IAAI;AACtC;AAKO,IAAM,oBAAsC;AAAA,EACjD,EAAE,OAAO,YAAY,UAAU,IAAI;AAAA,EACnC,EAAE,OAAO,QAAQ,UAAU,IAAI;AACjC;;;AC3TO,SAAS,MAAM,KAAe,WAAmB,GAAgB;AAEtE,QAAM,WAAW,IAAI,OAAO,OAAK,MAAM,CAAC;AACxC,QAAM,SAAoB,CAAC;AAC3B,QAAM,SAAmB,CAAC;AAG1B,MAAI,QAAQ,IAAI,KAAK,CAAC,GAAGC,OAAM,MAAM,KAAKA,MAAK,SAAS,MAAM;AAC9D,MAAI,aAAa;AAGjB,MAAI,IAAI;AACR,SAAO,IAAI,SAAS,QAAQ;AAC1B,QAAI,IAAI,IAAI,SAAS,UAAU,SAAS,CAAC,MAAM,SAAS,IAAI,CAAC,GAAG;AAE9D,YAAM,SAAS,SAAS,CAAC,IAAI;AAC7B,aAAO,KAAK,MAAM;AAClB,aAAO,KAAK,IAAI;AAChB,oBAAc;AACd,cAAQ;AACR,WAAK;AAAA,IACP,OAAO;AAEL,aAAO,KAAK,SAAS,CAAC,CAAC;AACvB,aAAO,KAAK,KAAK;AACjB;AAAA,IACF;AAAA,EACF;AAGA,SAAO,OAAO,SAAS,UAAU;AAC/B,WAAO,KAAK,CAAC;AACb,WAAO,KAAK,KAAK;AAAA,EACnB;AAGA,MAAI,CAAC,OAAO;AACV,YAAQ,IAAI,KAAK,CAAC,GAAG,QAAQ,MAAM,OAAO,GAAG,CAAC;AAAA,EAChD;AAEA,SAAO,EAAE,QAAQ,QAAQ,OAAO,WAAW;AAC7C;AAQO,SAAS,YAAY,MAA2B;AACrD,QAAM,OAAO,KAAK;AAGlB,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,UAAI,KAAK,CAAC,EAAE,CAAC,MAAM,EAAG,QAAO;AAAA,IAC/B;AAAA,EACF;AAGA,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,YAAM,MAAM,KAAK,CAAC,EAAE,CAAC;AAErB,UAAI,IAAI,OAAO,KAAK,KAAK,CAAC,EAAE,IAAI,CAAC,MAAM,IAAK,QAAO;AAEnD,UAAI,IAAI,OAAO,KAAK,KAAK,IAAI,CAAC,EAAE,CAAC,MAAM,IAAK,QAAO;AAAA,IACrD;AAAA,EACF;AAEA,SAAO;AACT;AASO,SAAS,iBAAiB,MAAkB,SAAiB,MAAe;AACjF,aAAW,OAAO,MAAM;AACtB,eAAW,QAAQ,KAAK;AACtB,UAAI,QAAQ,OAAQ,QAAO;AAAA,IAC7B;AAAA,EACF;AACA,SAAO;AACT;;;ACvDA,IAAM,cAAsC;AAAA,EAC1C,GAAG;AAAA;AAAA,EACH,GAAG;AAAA;AAAA,EACH,GAAG;AAAA;AAAA,EACH,IAAI;AAAA;AAAA,EACJ,IAAI;AAAA;AAAA,EACJ,IAAI;AAAA;AAAA,EACJ,KAAK;AAAA;AAAA,EACL,KAAK;AAAA;AAAA,EACL,KAAK;AAAA;AAAA,EACL,MAAM;AAAA;AAAA,EACN,MAAM;AAAA;AAAA,EACN,MAAM;AAAA;AAAA,EACN,MAAM;AAAA;AACR;AAEA,IAAM,aAAqC;AAAA,EACzC,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AACR;AAEA,IAAM,iBAAyC;AAAA,EAC7C,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AACR;AAMO,SAAS,YAAY,UAAwC;AAClE,QAAM,aAAa,qBAAqB;AAKxC,QAAM,WAAW;AACjB,QAAM,WAAW;AACjB,QAAM,YAAY;AAClB,QAAM,aAAa;AACnB,QAAM,cAAc;AACpB,QAAM,aAAa,YAAY,aAAa;AAC5C,QAAM,cAAc,YAAY,cAAc;AAC9C,QAAM,YAAY;AAKlB,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,qBAAqB;AACzB,MAAI,MAAM;AACV,MAAI,oBAAoB;AACxB,MAAI,QAAQ;AACZ,MAAI,YAAY;AAEhB,MAAI,OAAmB,CAAC;AACxB,MAAI,YAAyB,CAAC;AAC9B,MAAI,iBAAiB;AAErB,MAAI,WAAW;AACf,MAAI,UAAU;AAEd,MAAI,cAAc;AAClB,MAAI,YAAwB,CAAC;AAC7B,MAAI,cAA4B,CAAC;AACjC,MAAI,cAAc;AAClB,MAAI,iBAAiB;AAKrB,QAAM,aAAiC;AAAA,IACrC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IACZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAKA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAMA,WAASC,gBAAe,GAAW,GAAW,OAAe,OAAe,QAAkB,CAAC,UAAU,UAAU,UAAU,QAAQ,GAAG;AACtI,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ;AAAA,QAC9B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,oBAAoB,OAAe,OAAe,OAAe;AACxE,UAAM,UAAU,QAAQ,aAAa,aAAa;AAClD,UAAM,UAAU,QAAQ,cAAc,cAAc;AACpD,UAAM,QAAQ,YAAY,KAAK,KAAK;AACpC,UAAM,YAAY,CAAC,UAAU,UAAU,UAAU,UAAU,UAAU,QAAQ;AAC7E,IAAAA,gBAAe,SAAS,SAAS,GAAG,OAAO,SAAS;AAAA,EACtD;AAEA,WAAS,cAAc,GAAW,GAAW,MAAc,QAAgB,cAAc;AACvF,gBAAY,KAAK,EAAE,GAAG,GAAG,MAAM,QAAQ,IAAI,MAAM,CAAC;AAAA,EACpD;AAEA,WAAS,aAAa,QAAgB,WAAmB;AACvD,kBAAc;AACd,qBAAiB;AAAA,EACnB;AAMA,WAAS,kBAA8B;AACrC,WAAO,MAAM,SAAS,EAAE,KAAK,IAAI,EAAE,IAAI,MAAM,MAAM,SAAS,EAAE,KAAK,CAAC,CAAC;AAAA,EACvE;AAEA,WAAS,SAAS,GAA2B;AAC3C,WAAO,EAAE,IAAI,SAAO,CAAC,GAAG,GAAG,CAAC;AAAA,EAC9B;AAEA,WAAS,gBAAoC;AAC3C,UAAM,QAA4B,CAAC;AACnC,aAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,eAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,YAAI,KAAK,CAAC,EAAE,CAAC,MAAM,GAAG;AACpB,gBAAM,KAAK,CAAC,GAAG,CAAC,CAAC;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,WAAS,YAAY;AACnB,UAAM,QAAQ,cAAc;AAC5B,QAAI,MAAM,WAAW,EAAG;AACxB,UAAM,CAAC,GAAG,CAAC,IAAI,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAC7D,SAAK,CAAC,EAAE,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,IAAI;AAAA,EACzC;AAGA,WAAS,UAAmB;AAC1B,WAAO,YAAY,IAAI;AAAA,EACzB;AAGA,WAAS,UAAmB;AAC1B,WAAO,iBAAiB,MAAM,IAAI;AAAA,EACpC;AAMA,WAAS,YAAY;AACnB,QAAI,UAAU,UAAU,WAAW;AACjC,gBAAU,MAAM;AAAA,IAClB;AACA,cAAU,KAAK;AAAA,MACb,MAAM,SAAS,IAAI;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,WAAS,OAAO;AACd,QAAI,UAAU,WAAW,KAAK,kBAAkB,EAAG,QAAO;AAC1D,UAAM,QAAQ,UAAU,IAAI;AAC5B,WAAO,MAAM;AACb,YAAQ,MAAM;AACd;AACA,eAAW;AACX,UAAM;AACN,WAAO;AAAA,EACT;AAGA,WAASC,OAAM,KAAe;AAC5B,WAAO,MAAW,KAAK,SAAS;AAAA,EAClC;AAEA,WAAS,KAAK,WAAsD;AAClE,QAAI,kBAAkB;AACtB,QAAI,WAAW;AAEf,QAAI,cAAc,QAAQ;AACxB,eAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,cAAM,EAAE,QAAQ,QAAQ,OAAO,WAAW,IAAIA,OAAM,KAAK,CAAC,CAAC;AAC3D,YAAI,MAAO,YAAW;AACtB,2BAAmB;AACnB,iBAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,cAAI,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,GAAG;AAC9B,gCAAoB,GAAG,GAAG,OAAO,CAAC,CAAC;AACnC,0BAAc,IAAI,aAAa,aAAa,GAAG,IAAI,cAAc,GAAG,IAAI,OAAO,CAAC,CAAC,IAAI,YAAY,OAAO,CAAC,CAAC,CAAC;AAAA,UAC7G;AAAA,QACF;AACA,aAAK,CAAC,IAAI;AAAA,MACZ;AAAA,IACF,WAAW,cAAc,SAAS;AAChC,eAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,cAAM,WAAW,CAAC,GAAG,KAAK,CAAC,CAAC,EAAE,QAAQ;AACtC,cAAM,EAAE,QAAQ,QAAQ,OAAO,WAAW,IAAIA,OAAM,QAAQ;AAC5D,YAAI,MAAO,YAAW;AACtB,2BAAmB;AACnB,cAAM,WAAW,OAAO,QAAQ;AAChC,cAAM,cAAc,OAAO,QAAQ;AACnC,iBAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,cAAI,YAAY,CAAC,KAAK,SAAS,CAAC,IAAI,GAAG;AACrC,gCAAoB,GAAG,GAAG,SAAS,CAAC,CAAC;AACrC,0BAAc,IAAI,aAAa,aAAa,GAAG,IAAI,cAAc,GAAG,IAAI,SAAS,CAAC,CAAC,IAAI,YAAY,SAAS,CAAC,CAAC,CAAC;AAAA,UACjH;AAAA,QACF;AACA,aAAK,CAAC,IAAI;AAAA,MACZ;AAAA,IACF,WAAW,cAAc,MAAM;AAC7B,eAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,cAAM,MAAM,CAAC;AACb,iBAAS,IAAI,GAAG,IAAI,WAAW,IAAK,KAAI,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;AACvD,cAAM,EAAE,QAAQ,QAAQ,OAAO,WAAW,IAAIA,OAAM,GAAG;AACvD,YAAI,MAAO,YAAW;AACtB,2BAAmB;AACnB,iBAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,cAAI,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,GAAG;AAC9B,gCAAoB,GAAG,GAAG,OAAO,CAAC,CAAC;AACnC,0BAAc,IAAI,aAAa,aAAa,GAAG,IAAI,cAAc,GAAG,IAAI,OAAO,CAAC,CAAC,IAAI,YAAY,OAAO,CAAC,CAAC,CAAC;AAAA,UAC7G;AACA,eAAK,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC;AAAA,QACvB;AAAA,MACF;AAAA,IACF,WAAW,cAAc,QAAQ;AAC/B,eAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,cAAM,MAAM,CAAC;AACb,iBAAS,IAAI,GAAG,IAAI,WAAW,IAAK,KAAI,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;AACvD,cAAM,WAAW,IAAI,QAAQ;AAC7B,cAAM,EAAE,QAAQ,QAAQ,OAAO,WAAW,IAAIA,OAAM,QAAQ;AAC5D,YAAI,MAAO,YAAW;AACtB,2BAAmB;AACnB,cAAM,WAAW,OAAO,QAAQ;AAChC,cAAM,cAAc,OAAO,QAAQ;AACnC,iBAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,cAAI,YAAY,CAAC,KAAK,SAAS,CAAC,IAAI,GAAG;AACrC,gCAAoB,GAAG,GAAG,SAAS,CAAC,CAAC;AACrC,0BAAc,IAAI,aAAa,aAAa,GAAG,IAAI,cAAc,GAAG,IAAI,SAAS,CAAC,CAAC,IAAI,YAAY,SAAS,CAAC,CAAC,CAAC;AAAA,UACjH;AACA,eAAK,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,UAAU;AACZ,eAAS;AACT,UAAI,kBAAkB,GAAG;AACvB,qBAAa,GAAG,CAAC;AAAA,MACnB;AACA,gBAAU;AAEV,UAAI,CAAC,OAAO,CAAC,qBAAqB,QAAQ,GAAG;AAC3C,cAAM;AACN,YAAI,QAAQ,UAAW,aAAY;AACnC,qBAAa,GAAG,CAAC;AACjB,iBAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,mBAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,gBAAI,KAAK,CAAC,EAAE,CAAC,MAAM,MAAM;AACvB,kCAAoB,GAAG,GAAG,IAAI;AAC9B,kCAAoB,GAAG,GAAG,IAAI;AAAA,YAChC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,UAAI,CAAC,QAAQ,GAAG;AACd,mBAAW;AACX,YAAI,QAAQ,UAAW,aAAY;AAAA,MACrC;AAEA,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAMA,WAAS,WAAW;AAClB,WAAO,gBAAgB;AACvB,YAAQ;AACR,eAAW;AACX,UAAM;AACN,wBAAoB;AACpB,aAAS;AACT,gBAAY,CAAC;AACb,qBAAiB;AAEjB,gBAAY,CAAC;AACb,kBAAc,CAAC;AACf,kBAAc;AAEd,cAAU;AACV,cAAU;AAAA,EACZ;AAEA,WAAS,SAAS;AAChB,QAAI,CAAC,eAAgB,YAAY,CAAC,OAAQ,OAAQ;AAElD,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAM,IAAI,UAAU,CAAC;AACrB,QAAE,KAAK,EAAE;AACT,QAAE,KAAK,EAAE;AACT,QAAE,MAAM;AACR,QAAE;AACF,UAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,IACxC;AAEA,aAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAM,QAAQ,YAAY,CAAC;AAC3B,YAAM,KAAK;AACX,YAAM;AACN,UAAI,MAAM,UAAU,EAAG,aAAY,OAAO,GAAG,CAAC;AAAA,IAChD;AAAA,EACF;AAMA,WAAS,WAAW,OAAe,SAAiB,SAAyB;AAC3E,QAAI,UAAU,GAAG;AACf,UAAIC,UAAS;AACb,YAAM,YAAY;AAClB,eAAS,MAAM,GAAG,MAAM,aAAa,OAAO;AAC1C,QAAAA,WAAU,QAAQ,UAAU,GAAG,IAAI,OAAO;AAC1C,iBAAS,MAAM,GAAG,MAAM,YAAY,OAAO;AACzC,UAAAA,WAAU;AAAA,QACZ;AACA,QAAAA,WAAU;AAAA,MACZ;AACA,aAAOA;AAAA,IACT;AAEA,UAAM,QAAQ,YAAY,KAAK,KAAK;AACpC,UAAM,UAAU,eAAe,KAAK,KAAK;AACzC,UAAM,OAAO,WAAW,KAAK,KAAK,MAAM,SAAS;AAEjD,QAAI,SAAS;AAEb,cAAU,QAAQ,OAAO,IAAI,OAAO,IAAI,OAAO,GAAG,KAAK;AACvD,cAAU,SAAS,OAAO,UAAU;AACpC,cAAU;AAEV,cAAU,QAAQ,UAAU,CAAC,IAAI,OAAO,IAAI,OAAO,GAAG,KAAK;AAC3D,UAAM,cAAc,KAAK,UAAU,aAAa,IAAI,OAAO,MAAM,SAAS;AAC1E,UAAM,UAAU,KAAK,OAAO,aAAa,YAAY,UAAU,CAAC;AAChE,cAAU,IAAI,OAAO,OAAO,IAAI,cAAc,IAAI,OAAO,aAAa,UAAU,YAAY,MAAM;AAClG,cAAU;AAEV,cAAU,QAAQ,UAAU,CAAC,IAAI,OAAO,IAAI,OAAO,GAAG,KAAK;AAC3D,cAAU,SAAS,OAAO,UAAU;AACpC,cAAU;AAEV,WAAO;AAAA,EACT;AAEA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,cAAU;AAEV,QAAI,cAAc,EAAG;AAErB,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AAEtB,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,OAAO;AACb,YAAM,YAAY,OAAO;AACzB,YAAM,aAAa,OAAO;AAC1B,UAAIC,QAAO,aAAa,aAAa,qBACjC,YAAY,uBAAuB;AACvC,YAAM,OAAO,SAAS,QAAQ,IAAI,QAAQ,WAAW,IAAI,IAAI,IAAI;AACjE,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI;AACxG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI;AAClG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAMA,MAAK,SAAS,CAAC,CAAC,CAAC,WAAW,UAAU,GAAGA,KAAI;AAC/G,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAEA,eAAW,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,cAAc,CAAC,CAAC;AAC1D,cAAU,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,cAAc,KAAK,CAAC,CAAC;AAE9D,QAAI,aAAa;AACjB,QAAI,YAAY;AAChB,QAAI,cAAc,GAAG;AACnB,oBAAc,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,iBAAiB,CAAC;AACnE,mBAAa,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,cAAc;AAAA,IAChE;AAEA,mBAAe,cAAc,KAAK;AAClC,UAAM,eAAe,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC7E,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI;AAE1D,QAAI,eAAe,MAAM,cAAc,IAAI;AACzC,gBAAU,UAAU,MAAM,YAAY,MAAM,CAAC,CAAC;AAC9C,gBAAU,UAAU,SAAS,CAAC,YAAY,MAAM,CAAC,CAAC;AAAA,IACpD,OAAO;AACL,gBAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAC1D,gBAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,IAC5D;AAEA,UAAM,QAAQ,UAAU,MAAM,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,WAAW,UAAU,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,WAAW,cAAc,IAAI,SAAS;AAC/I,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,UAAU,CAAC;AACnD,cAAU,QAAQ,UAAU,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,KAAK;AAE7D,UAAM,cAAc;AACpB,cAAU,QAAQ,SAAS,IAAI,UAAU,IAAI,UAAU,SAAS,SAAS,OAAO,WAAW,CAAC;AAC5F,aAAS,IAAI,GAAG,IAAI,cAAc,GAAG,KAAK;AACxC,gBAAU,QAAQ,YAAY,IAAI,CAAC,IAAI,UAAU,IAAI,UAAU;AAC/D,gBAAU,QAAQ,YAAY,IAAI,CAAC,IAAI,aAAa,cAAc,CAAC,IAAI,UAAU;AAAA,IACnF;AACA,cAAU,QAAQ,YAAY,cAAc,CAAC,IAAI,UAAU,IAAI,UAAU,SAAS,SAAS,OAAO,WAAW,CAAC;AAE9G,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,eAAe,KAAK,MAAM,OAAO,CAAC;AACxC,YAAM,SAAS,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACvD,YAAM,YAAY,eAAe,KAAK,MAAM,SAAS,SAAS,CAAC;AAC/D,gBAAU,QAAQ,MAAM,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ;AAErE,gBAAU,iBAAiB,kBAAkB,oBAAoB;AAAA,QAC/D,SAAS;AAAA,QACT,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,WAAW,eAAe,KAAK,MAAM,QAAQ,SAAS,CAAC;AAC7D,gBAAU,QAAQ,SAAS,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACzE,WACS,CAAC,aAAa;AACrB,eAAS,KAAK,GAAG,KAAK,WAAW,MAAM;AACrC,iBAAS,KAAK,GAAG,KAAK,WAAW,MAAM;AACrC,gBAAM,QAAQ,aAAa,IAAI,KAAK;AACpC,gBAAM,QAAQ,YAAY,IAAI,KAAK;AACnC,oBAAU,WAAW,GAAG,OAAO,KAAK;AAAA,QACtC;AAAA,MACF;AAEA,YAAM,WAAW;AACjB,YAAM,SAAS,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC;AACtD,YAAM,SAAS,UAAU,KAAK,MAAM,cAAc,CAAC;AACnD,gBAAU,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ;AAElE,YAAM,WAAW;AACjB,YAAM,QAAQ,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC;AACrD,gBAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ;AAErE,YAAM,OAAO;AACb,YAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,UAAU,CAAC;AACjD,gBAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,IAAI;AAAA,IACnE,WACS,OAAO,CAAC,mBAAmB;AAClC,eAAS,KAAK,GAAG,KAAK,WAAW,MAAM;AACrC,iBAAS,KAAK,GAAG,KAAK,WAAW,MAAM;AACrC,gBAAM,QAAQ,aAAa,IAAI,KAAK;AACpC,gBAAM,QAAQ,YAAY,IAAI,KAAK;AACnC,oBAAU,WAAW,KAAK,EAAE,EAAE,EAAE,GAAG,OAAO,KAAK;AAAA,QACjD;AAAA,MACF;AAEA,YAAM,SAAS;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,YAAM,WAAW,OAAO,CAAC,EAAE;AAC3B,YAAM,OAAO,KAAK,OAAO,OAAO,YAAY,CAAC;AAC7C,YAAM,OAAO,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AAErD,eAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,cAAM,YAAY,MAAM,IAAI,eAAe;AAC3C,kBAAU,QAAQ,OAAO,CAAC,IAAI,IAAI,IAAI,SAAS,GAAG,OAAO,CAAC,CAAC;AAAA,MAC7D;AAAA,IACF,WACS,UAAU;AACjB,eAAS,KAAK,GAAG,KAAK,WAAW,MAAM;AACrC,iBAAS,KAAK,GAAG,KAAK,WAAW,MAAM;AACrC,gBAAM,QAAQ,aAAa,IAAI,KAAK;AACpC,gBAAM,QAAQ,YAAY,IAAI,KAAK;AACnC,oBAAU,WAAW,KAAK,EAAE,EAAE,EAAE,GAAG,OAAO,KAAK;AAAA,QACjD;AAAA,MACF;AAEA,YAAM,UAAU;AAChB,YAAM,QAAQ,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC;AACpD,YAAM,QAAQ,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACtD,gBAAU,QAAQ,KAAK,IAAI,KAAK,cAAc,OAAO;AAErD,YAAM,YAAY,UAAU,KAAK,WAAW,SAAS;AACrD,YAAM,SAAS,KAAK,OAAO,OAAO,UAAU,UAAU,CAAC;AACvD,gBAAU,QAAQ,QAAQ,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,SAAS;AAE/D,YAAM,WAAW,iBAAiB,IAAI,eAAe;AACrD,YAAM,UAAU,+BAA+B,QAAQ;AACvD,YAAM,WAAW,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC;AACvD,gBAAU,QAAQ,QAAQ,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACxE,OACK;AACH,eAAS,KAAK,GAAG,KAAK,WAAW,MAAM;AACrC,iBAAS,KAAK,GAAG,KAAK,WAAW,MAAM;AACrC,gBAAM,QAAQ,aAAa,IAAI,KAAK;AACpC,gBAAM,QAAQ,YAAY,IAAI,KAAK;AACnC,oBAAU,WAAW,KAAK,EAAE,EAAE,EAAE,GAAG,OAAO,KAAK;AAAA,QACjD;AAAA,MACF;AAEA,iBAAW,KAAK,WAAW;AACzB,cAAM,UAAU,KAAK,MAAM,aAAa,IAAI,EAAE,CAAC;AAC/C,cAAM,UAAU,KAAK,MAAM,YAAY,IAAI,EAAE,CAAC;AAC9C,YAAI,UAAU,cAAc,UAAU,aAAa,cAC/C,UAAU,aAAa,UAAU,YAAY,aAAa;AAC5D,gBAAM,QAAQ,EAAE,OAAO,IAAI,KAAK;AAChC,oBAAU,QAAQ,OAAO,IAAI,OAAO,IAAI,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,QAClE;AAAA,MACF;AAEA,iBAAW,SAAS,aAAa;AAC/B,cAAM,UAAU,KAAK,MAAM,aAAa,IAAI,MAAM,CAAC;AACnD,cAAM,UAAU,KAAK,MAAM,YAAY,IAAI,MAAM,CAAC;AAClD,YAAI,UAAU,aAAa,UAAU,YAAY,aAAa;AAC5D,gBAAM,QAAQ,MAAM,SAAS,KAAK,YAAY;AAC9C,oBAAU,QAAQ,OAAO,IAAI,OAAO,IAAI,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM,IAAI;AAAA,QAC1E;AAAA,MACF;AAAA,IACF;AAEA,UAAM,OAAO,eAAe,CAAC,YAAY,CAAC,UAAU,CAAC,MACjD,0BAA0B,cAAc,iBACxC;AACJ,UAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,UAAU,CAAC;AACjD,cAAU,QAAQ,UAAU,cAAc,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,IAAI;AAEhF,aAAS,MAAM,MAAM;AAAA,EACvB;AAMA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,aAAS;AACT,kBAAc;AAEd,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AAAE,sBAAc,cAAc;AAAG;AAAA,MAAQ;AACvD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,eAAe,YAAY,MAAM;AACrC,UAAI,CAAC,SAAS;AAAE,sBAAc,YAAY;AAAG;AAAA,MAAQ;AACrD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AAAE,oBAAY,QAAQ;AAAG;AAAA,MAAQ;AAE/C,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS,IAAI,YAAY;AAErC,UAAI,QAAQ,UAAU;AACpB,YAAI,OAAO,CAAC,kBAAmB;AAC/B,iBAAS,CAAC;AACV,YAAI,OAAQ,sBAAqB;AACjC;AAAA,MACF;AAEA,UAAI,QAAQ,QAAQ,UAAU,YAAY,CAAC,eAAgB,OAAO,CAAC,oBAAqB;AACtF,sBAAc,cAAc;AAC5B,sBAAc,YAAY;AAC1B,mBAAW,KAAK;AAChB,yBAAiB,QAAQ;AACzB;AAAA,MACF;AAEA,UAAI,CAAC,eAAe,CAAC,QAAQ;AAC3B,kBAAU;AACV,sBAAc;AACd;AAAA,MACF;AAEA,UAAI,OAAO,CAAC,mBAAmB;AAC7B,YAAI,QAAQ,KAAK;AACf,8BAAoB;AACpB,gBAAM;AACN;AAAA,QACF;AACA,YAAI,QAAQ,KAAK;AACf,cAAI,QAAQ,UAAW,aAAY;AACnC,mBAAS;AACT,wBAAc;AACd;AAAA,QACF;AACA;AAAA,MACF;AAEA,UAAI,UAAU;AACZ,YAAI,QAAQ,KAAK;AACf,cAAI,QAAQ,UAAW,aAAY;AACnC,mBAAS;AACT,wBAAc;AAAA,QAChB,WAAW,QAAQ,KAAK;AACtB,eAAK;AAAA,QACP;AACA;AAAA,MACF;AAEA,UAAI,QAAQ;AACV,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AAAG,uBAAS;AAAO;AAAA,YACxB,KAAK;AAAG,uBAAS;AAAG,4BAAc;AAAM,uBAAS;AAAO;AAAA,YACxD,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,yBAAW,KAAK;AAChB,+BAAiB,QAAQ;AACzB;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,gCAAkB,QAAQ;AAC1B;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,iCAAmB,QAAQ;AAC3B;AAAA,UACJ;AACA;AAAA,QACF;AAEA,YAAI,QAAQ,KAAK;AAAE,mBAAS;AAAG,wBAAc;AAAM,mBAAS;AAAA,QAAO,WAC1D,QAAQ,KAAK;AAAE,wBAAc,cAAc;AAAG,wBAAc,YAAY;AAAG,oBAAU;AAAO,4BAAkB,QAAQ;AAAA,QAAG,WACzH,QAAQ,KAAK;AAAE,wBAAc,cAAc;AAAG,wBAAc,YAAY;AAAG,oBAAU;AAAO,6BAAmB,QAAQ;AAAA,QAAG;AACnI;AAAA,MACF;AAEA,cAAQ,SAAS,KAAK;AAAA,QACpB,KAAK;AAAA,QACL,KAAK;AACH,oBAAU;AACV,eAAK,MAAM;AACX;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,oBAAU;AACV,eAAK,OAAO;AACZ;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,oBAAU;AACV,eAAK,IAAI;AACT;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,oBAAU;AACV,eAAK,MAAM;AACX;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,eAAK;AACL;AAAA,MACJ;AAAA,IACF,CAAC;AAED,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,oBAAc,cAAc;AAC5B,oBAAc,YAAY;AAC1B,kBAAY,QAAQ;AACpB,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;AC7uBO,SAAS,iBAAiB,UAAyC;AACxE,QAAM,aAAa,qBAAqB;AAGxC,QAAM,WAAW;AACjB,QAAM,WAAW;AAGjB,MAAI,aAAa;AACjB,MAAI,cAAc;AAGlB,QAAM,kBAAkB;AACxB,QAAM,cAAc;AACpB,QAAM,gBAAgB;AACtB,QAAM,iBAAiB;AACvB,QAAM,eAAe;AACrB,QAAM,cAAc;AACpB,QAAM,iBAAiB;AAGvB,QAAM,kBAAkB,EAAE,OAAO,MAAM,QAAQ,KAAK,OAAO,KAAK;AAChE,QAAM,kBAAkB,EAAE,OAAO,IAAI,QAAQ,IAAI,OAAO,IAAI;AAC5D,QAAM,kBAAkB,EAAE,OAAO,GAAG,QAAQ,KAAK,OAAO,EAAE;AAG1D,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,qBAAqB;AACzB,MAAI,QAAQ;AACZ,MAAI,YAAY;AAChB,MAAI,QAAQ;AACZ,MAAI,OAAO;AACX,MAAI,sBAAsB;AAC1B,MAAI,gBAAgB;AACpB,MAAI,cAAc;AAClB,MAAI,cAAc;AAClB,MAAI,iBAAiB;AAErB,MAAI,WAAW;AACf,MAAI,UAAU;AAEd,MAAI,OAAa,EAAE,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,KAAK,GAAG,WAAW,MAAM;AACnF,MAAI,WAAwB,oBAAI,IAAI;AACpC,MAAI,UAAoB,CAAC;AACzB,MAAI,YAAwB,CAAC;AAC7B,MAAI,YAAwB,CAAC;AAE7B,QAAM,aAAkC;AAAA,IACtC,MAAM,MAAM;AAAE,UAAI,QAAS,WAAU;AAAA,IAAO;AAAA,IAC5C,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAGA,QAAM,aAAa,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AAE1D,QAAM,iBAAiB,EAAE,OAAO,UAAK,QAAQ,UAAK,OAAO,SAAI;AAE7D,QAAM,QAAQ;AAAA,IAAC;AAAA,IACA;AAAA,EAAiC;AAEhD,WAAS,WAAW;AAClB,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AACtB,iBAAa,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC;AAChD,kBAAc,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC;AAEjD,YAAQ;AACR,YAAQ;AACR,WAAO;AACP,eAAW;AACX,aAAS;AAET,WAAO;AAAA,MACL,GAAG,aAAa;AAAA,MAChB,GAAG,cAAc;AAAA,MACjB,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,OAAO,CAAC,KAAK,KAAK;AAAA,MAClB,WAAW;AAAA,IACb;AAEA,aAAS,MAAM;AACf,cAAU,CAAC;AACX,gBAAY,CAAC;AACb,gBAAY,CAAC;AACb,0BAAsB;AACtB,oBAAgB;AAEhB,cAAU;AAAA,EACZ;AAEA,WAAS,YAAY;AACnB,UAAM,QAAQ,IAAI;AAClB,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAI,GAAG;AAEP,SAAG;AACD,YAAI,KAAK,OAAO,IAAI;AACpB,YAAI,KAAK,OAAO,IAAI;AAAA,MACtB,SAAS,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI;AAE5D,YAAM,QAAQ,KAAK,OAAO,IAAI,KAAK,KAAK;AACxC,YAAM,QAAQ,gBAAgB,SAAS,MAAM,KAAK,OAAO,IAAI;AAC7D,gBAAU,KAAK;AAAA,QACb;AAAA,QAAG;AAAA,QACH,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ;AAAA,QAC9B,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,KAAK,OAAe,KAAqB;AAChD,QAAI,QAAQ,EAAG,QAAO,MAAM;AAC5B,QAAI,SAAS,IAAK,QAAO,QAAQ;AACjC,WAAO;AAAA,EACT;AAEA,WAAS,aAAa,QAAgB,WAAmB;AACvD,kBAAc;AACd,qBAAiB;AAAA,EACnB;AAEA,WAASC,gBAAe,GAAW,GAAW,OAAe,OAAe;AAC1E,UAAM,QAAQ,CAAC,KAAK,KAAK,KAAK,MAAG;AACjC,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QAAG;AAAA,QACH,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ;AAAA,QAC9B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,QAAQ;AACf,QAAI,gBAAgB,EAAG;AACvB,oBAAgB;AAEhB,UAAM,UAAU,KAAK,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI;AAChD,UAAM,UAAU,KAAK,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI;AAEhD,YAAQ,KAAK;AAAA,MACX,GAAG;AAAA,MACH,GAAG;AAAA,MACH,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,eAAe,KAAK,KAAK;AAAA,MACpD,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,eAAe,MAAM,KAAK,KAAK;AAAA,MAC1D,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,WAAS,UAAU;AACjB,QAAI,sBAAsB,EAAG;AAE7B;AACA,IAAAA,gBAAe,KAAK,GAAG,KAAK,GAAG,IAAI,UAAU;AAC7C,iBAAa,IAAI,CAAC;AAElB,QAAI,SAAS,GAAG;AACd,iBAAW;AACX,UAAI,QAAQ,UAAW,aAAY;AAAA,IACrC,OAAO;AAEL,WAAK,IAAI,aAAa;AACtB,WAAK,IAAI,cAAc;AACvB,WAAK,KAAK;AACV,WAAK,KAAK;AACV,4BAAsB;AAAA,IACxB;AAAA,EACF;AAEA,WAAS,cAAc,UAAoB;AACzC,IAAAA,gBAAe,SAAS,GAAG,SAAS,GAAG,GAAG,UAAU;AACpD,aAAS,gBAAgB,SAAS,IAAI;AAEtC,QAAI,SAAS,SAAS,SAAS;AAC7B,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,cAAM,QAAQ,KAAK,OAAO,IAAI,KAAK,KAAK;AACxC,kBAAU,KAAK;AAAA,UACb,GAAG,SAAS;AAAA,UACZ,GAAG,SAAS;AAAA,UACZ,IAAI,KAAK,IAAI,KAAK,IAAI,gBAAgB;AAAA,UACtC,IAAI,KAAK,IAAI,KAAK,IAAI,gBAAgB,SAAS;AAAA,UAC/C,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,IACF,WAAW,SAAS,SAAS,UAAU;AACrC,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,cAAM,QAAQ,KAAK,OAAO,IAAI,KAAK,KAAK;AACxC,kBAAU,KAAK;AAAA,UACb,GAAG,SAAS;AAAA,UACZ,GAAG,SAAS;AAAA,UACZ,IAAI,KAAK,IAAI,KAAK,IAAI,gBAAgB;AAAA,UACtC,IAAI,KAAK,IAAI,KAAK,IAAI,gBAAgB,QAAQ;AAAA,UAC9C,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,WAAS,SAAS;AAChB,QAAI,UAAU,CAAC,eAAe,SAAU;AAExC,mBAAe,cAAc,KAAK;AAClC,QAAI,sBAAsB,EAAG;AAC7B,QAAI,gBAAgB,EAAG;AAGvB,QAAI,SAAS,IAAI,WAAW,KAAK,SAAS,IAAI,GAAG,EAAG,MAAK,SAAS;AAClE,QAAI,SAAS,IAAI,YAAY,KAAK,SAAS,IAAI,GAAG,EAAG,MAAK,SAAS;AAEnE,SAAK,YAAY,SAAS,IAAI,SAAS,KAAK,SAAS,IAAI,GAAG;AAC5D,QAAI,KAAK,WAAW;AAClB,WAAK,MAAM,KAAK,IAAI,KAAK,KAAK,IAAI;AAClC,WAAK,MAAM,KAAK,IAAI,KAAK,KAAK,IAAI,cAAc;AAAA,IAClD;AAEA,QAAI,SAAS,IAAI,GAAG,EAAG,OAAM;AAG7B,SAAK,MAAM;AACX,SAAK,MAAM;AAEX,UAAM,QAAQ,KAAK,KAAK,KAAK,MAAM,IAAI,KAAK,MAAM,CAAC;AACnD,QAAI,QAAQ,gBAAgB;AAC1B,WAAK,KAAM,KAAK,KAAK,QAAS;AAC9B,WAAK,KAAM,KAAK,KAAK,QAAS;AAAA,IAChC;AAEA,SAAK,IAAI,KAAK,KAAK,IAAI,KAAK,IAAI,UAAU;AAC1C,SAAK,IAAI,KAAK,KAAK,IAAI,KAAK,IAAI,WAAW;AAG3C,aAAS,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;AAC5C,YAAM,SAAS,QAAQ,CAAC;AACxB,aAAO,IAAI,KAAK,OAAO,IAAI,OAAO,IAAI,UAAU;AAChD,aAAO,IAAI,KAAK,OAAO,IAAI,OAAO,IAAI,WAAW;AACjD,aAAO;AACP,UAAI,OAAO,QAAQ,EAAG,SAAQ,OAAO,GAAG,CAAC;AAAA,IAC3C;AAGA,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAM,MAAM,UAAU,CAAC;AACvB,UAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,UAAU;AACvC,UAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,WAAW;AAGxC,YAAM,SAAS,gBAAgB,IAAI,IAAI;AACvC,eAAS,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;AAC5C,cAAM,SAAS,QAAQ,CAAC;AACxB,cAAM,KAAK,OAAO,IAAI,IAAI;AAC1B,cAAM,MAAM,OAAO,IAAI,IAAI,KAAK;AAChC,YAAI,KAAK,KAAK,KAAK,KAAK,SAAS,QAAQ;AACvC,kBAAQ,OAAO,GAAG,CAAC;AACnB,wBAAc,GAAG;AACjB,oBAAU,OAAO,GAAG,CAAC;AACrB,uBAAa,GAAG,CAAC;AACjB;AAAA,QACF;AAAA,MACF;AAGA,UAAI,uBAAuB,GAAG;AAC5B,cAAM,KAAK,KAAK,IAAI,IAAI;AACxB,cAAM,MAAM,KAAK,IAAI,IAAI,KAAK;AAC9B,YAAI,KAAK,KAAK,KAAK,MAAM,SAAS,QAAQ,SAAS,MAAM;AACvD,kBAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAGA,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAM,IAAI,UAAU,CAAC;AACrB,QAAE,KAAK,EAAE;AACT,QAAE,KAAK,EAAE;AACT,QAAE,MAAM;AACR,QAAE;AACF,UAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,IACxC;AAGA,QAAI,UAAU,WAAW,GAAG;AAC1B;AACA,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,QAAI,cAAc,EAAG;AAErB,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AAEtB,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,MAAM;AACZ,YAAM,OAAO,SAAS,QAAQ,OAAI,QAAQ,WAAW,IAAI,OAAI,IAAI;AACjE,gBAAU,QAAQ,KAAK,MAAM,OAAK,CAAC,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,OAAO,OAAK,IAAI,UAAQ,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,GAAG;AACxG,gBAAU,QAAQ,KAAK,MAAM,OAAK,CAAC,IAAE,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,OAAO,OAAK,KAAK,UAAQ,CAAC,CAAC,CAAC,WAAW,IAAI;AACtG,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAEA,eAAW,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,aAAa,KAAK,CAAC,CAAC;AAC9D,cAAU,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,cAAc,KAAK,CAAC,CAAC;AAE9D,QAAI,aAAa;AACjB,QAAI,YAAY;AAChB,QAAI,cAAc,GAAG;AACnB,oBAAc,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,iBAAiB,CAAC;AACnE,mBAAa,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,cAAc;AAAA,IAChE;AAGA,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC;AACtD,cAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAC1D,cAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAG1D,UAAM,QAAQ,UAAU,MAAM,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,WAAW,IAAI,KAAK,SAAI,OAAO,KAAK,CAAC;AAC9F,cAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,OAAO,OAAO,MAAM,UAAU,CAAC,CAAC,IAAI,UAAU,GAAG,KAAK;AAG5F,cAAU,QAAQ,SAAS,IAAI,UAAU,IAAI,UAAU,SAAI,SAAI,OAAO,UAAU,CAAC;AACjF,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,gBAAU,QAAQ,YAAY,IAAI,CAAC,IAAI,UAAU,IAAI,UAAU;AAC/D,gBAAU,QAAQ,YAAY,IAAI,CAAC,IAAI,aAAa,aAAa,CAAC,IAAI,UAAU;AAAA,IAClF;AACA,cAAU,QAAQ,YAAY,cAAc,CAAC,IAAI,UAAU,IAAI,UAAU,SAAI,SAAI,OAAO,UAAU,CAAC;AAGnG,QAAI,QAAQ;AACV,YAAM,SAAS,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACvD,gBAAU,QAAQ,MAAM,IAAI,KAAK,MAAM,OAAK,CAAC,IAAI,CAAC,WAAW,UAAU;AACvE,gBAAU,iBAAiB,kBAAkB,oBAAoB;AAAA,QAC/D,SAAS,KAAK,MAAM,OAAO,CAAC;AAAA,QAC5B,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAAA,IACH,WAES,CAAC,aAAa;AACrB,YAAM,MAAM;AACZ,gBAAU,QAAQ,UAAU,KAAK,MAAM,cAAY,CAAC,CAAC,IAAI,WAAW,KAAK,OAAO,aAAa,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,UAAU,GAAG,GAAG;AAC5I,YAAM,OAAO;AACb,gBAAU,QAAQ,UAAU,KAAK,MAAM,cAAY,CAAC,IAAI,CAAC,IAAI,WAAW,KAAK,OAAO,aAAa,KAAK,UAAU,CAAC,IAAI,CAAC,WAAW,UAAU,GAAG,IAAI;AAAA,IACpJ,WAES,UAAU;AACjB,YAAM,QAAQ,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACtD,gBAAU,QAAQ,KAAK,IAAI,WAAW,KAAK,OAAO,aAAa,MAAM,CAAC,IAAI,CAAC;AAC3E,gBAAU,QAAQ,QAAQ,CAAC,IAAI,WAAW,KAAK,OAAO,aAAa,MAAM,CAAC,IAAI,CAAC,IAAI,UAAU,UAAU,KAAK,WAAW,SAAS;AAChI,gBAAU,QAAQ,QAAQ,CAAC,IAAI,WAAW,KAAK,OAAO,aAAa,MAAM,CAAC,IAAI,CAAC,WAAW,UAAU;AAAA,IACtG,OAEK;AAEH,iBAAW,OAAO,WAAW;AAC3B,cAAM,KAAK,aAAa,IAAI,KAAK,MAAM,IAAI,CAAC;AAC5C,cAAM,KAAK,YAAY,IAAI,KAAK,MAAM,IAAI,CAAC;AAC3C,YAAI,KAAK,cAAc,KAAK,aAAa,aAAa,KAAK,KAAK,aAAa,KAAK,YAAY,cAAc,GAAG;AAC7G,gBAAM,QAAQ,IAAI,SAAS,UAAU,aAAa,IAAI,SAAS,WAAW,aAAa;AACvF,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,GAAG,eAAe,IAAI,IAAI,CAAC;AAAA,QAChE;AAAA,MACF;AAGA,iBAAW,KAAK,SAAS;AACvB,cAAM,KAAK,aAAa,IAAI,KAAK,MAAM,EAAE,CAAC;AAC1C,cAAM,KAAK,YAAY,IAAI,KAAK,MAAM,EAAE,CAAC;AACzC,YAAI,KAAK,cAAc,KAAK,aAAa,aAAa,KAAK,KAAK,aAAa,KAAK,YAAY,cAAc,GAAG;AAC7G,oBAAU,QAAQ,EAAE,IAAI,EAAE;AAAA,QAC5B;AAAA,MACF;AAGA,iBAAW,KAAK,WAAW;AACzB,cAAM,KAAK,aAAa,IAAI,KAAK,MAAM,EAAE,CAAC;AAC1C,cAAM,KAAK,YAAY,IAAI,KAAK,MAAM,EAAE,CAAC;AACzC,YAAI,KAAK,cAAc,KAAK,aAAa,aAAa,KAAK,KAAK,aAAa,KAAK,YAAY,cAAc,GAAG;AAC7G,gBAAM,QAAQ,EAAE,OAAO,IAAI,KAAK;AAChC,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,QACxD;AAAA,MACF;AAGA,YAAM,WAAW,uBAAuB,KAAK,KAAK,MAAM,cAAc,CAAC,IAAI,MAAM;AACjF,UAAI,UAAU;AACZ,cAAM,KAAK,aAAa,IAAI,KAAK,MAAM,KAAK,CAAC;AAC7C,cAAM,KAAK,YAAY,IAAI,KAAK,MAAM,KAAK,CAAC;AAC5C,YAAI,KAAK,cAAc,KAAK,aAAa,aAAa,KAAK,KAAK,aAAa,KAAK,YAAY,cAAc,GAAG;AAE7G,gBAAM,OAAQ,KAAK,MAAM,KAAK,SAAS,KAAK,KAAK,EAAE,IAAI,IAAK,KAAK;AACjE,gBAAM,WAAW,WAAW,GAAG;AAC/B,gBAAM,YAAY,KAAK,YAAY,eAAe;AAClD,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,SAAS,GAAG,QAAQ;AAGlD,cAAI,KAAK,WAAW;AAClB,kBAAM,SAAS,KAAK,KAAK,MAAM,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG;AACzD,kBAAM,SAAS,KAAK,KAAK,MAAM,KAAK,IAAI,KAAK,KAAK,IAAI,IAAI;AAC1D,gBAAI,SAAS,cAAc,SAAS,aAAa,aAAa,KAAK,SAAS,aAAa,SAAS,YAAY,cAAc,GAAG;AAC7H,wBAAU,QAAQ,MAAM,IAAI,MAAM,YAAY,KAAK,OAAO,IAAI,MAAM,MAAM,GAAG;AAAA,YAC/E;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,OAAO,SAAS,SAAS;AAC/B,cAAU,QAAQ,UAAU,cAAc,CAAC,IAAI,KAAK,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,WAAW,UAAU,GAAG,IAAI;AAE/G,aAAS,MAAM,MAAM;AAAA,EACvB;AAGA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,sBAAsB;AACrC,aAAS;AACT,kBAAc;AAEd,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AAAE,sBAAc,cAAc;AAAG;AAAA,MAAQ;AACvD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,eAAe,YAAY,MAAM;AACrC,UAAI,CAAC,SAAS;AAAE,sBAAc,YAAY;AAAG;AAAA,MAAQ;AACrD,aAAO;AAAA,IACT,GAAG,EAAE;AAGL,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AAAE,oBAAY,QAAQ;AAAG;AAAA,MAAQ;AAC/C,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS;AACrB,YAAM,WAAW,IAAI,YAAY;AAGjC,eAAS,IAAI,GAAG;AAChB,iBAAW,MAAM,SAAS,OAAO,GAAG,GAAG,GAAG;AAE1C,UAAI,QAAQ;AACV,cAAM,EAAE,cAAc,UAAU,IAAI,aAAa,oBAAoB,iBAAiB,QAAQ,KAAK,QAAQ;AAC3G,YAAI,iBAAiB,oBAAoB;AAAE,+BAAqB;AAAc;AAAA,QAAQ;AACtF,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AAAG,uBAAS;AAAO;AAAA,YACxB,KAAK;AAAG,uBAAS;AAAG,4BAAc;AAAM,uBAAS;AAAO;AAAA,YACxD,KAAK;AAAG,yBAAW,KAAK;AAAG,+BAAiB,QAAQ;AAAG;AAAA,YACvD,KAAK;AAAG,yBAAW,KAAK;AAAG,gCAAkB,QAAQ;AAAG;AAAA,YACxD,KAAK;AAAG,yBAAW,KAAK;AAAG,iCAAmB,QAAQ;AAAG;AAAA,UAC3D;AACA;AAAA,QACF;AACA;AAAA,MACF;AAEA,UAAI,UAAU;AACZ,YAAI,aAAa,KAAK;AAAE,mBAAS;AAAG,wBAAc;AAAM;AAAA,QAAQ;AAChE,YAAI,aAAa,OAAO,QAAQ,UAAU;AAAE,qBAAW,KAAK;AAAG,2BAAiB,QAAQ;AAAG;AAAA,QAAQ;AACnG;AAAA,MACF;AAEA,UAAI,QAAQ,UAAU;AAAE,iBAAS;AAAM,6BAAqB;AAAG;AAAA,MAAQ;AAEvE,UAAI,CAAC,eAAe,QAAQ,KAAK;AAAE,sBAAc;AAAM;AAAA,MAAQ;AAAA,IACjE,CAAC;AAED,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,kBAAY,QAAQ;AACpB,oBAAc,cAAc;AAC5B,oBAAc,YAAY;AAC1B,eAAS,MAAM,sBAAsB;AACrC,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;ACvdO,SAAS,gBAAgB,UAAwC;AACtE,QAAM,aAAa,qBAAqB;AAExC,QAAM,WAAW;AACjB,QAAM,WAAW;AACjB,QAAM,aAAa;AACnB,QAAM,cAAc;AACpB,QAAM,sBAAsB;AAC5B,QAAM,oBAAoB;AAC1B,QAAM,cAAc;AACpB,QAAM,eAAe;AACrB,QAAM,aAAa;AACnB,QAAM,aAAa;AACnB,QAAM,aAAa;AACnB,QAAM,iBAAiB;AAEvB,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,qBAAqB;AACzB,MAAI,MAAM;AACV,MAAI,QAAQ;AACZ,MAAI,YAAY;AAChB,MAAI,QAAQ;AACZ,MAAI,QAAQ;AAEZ,MAAI,WAAW;AACf,MAAI,UAAU;AAEd,MAAI,UAAU,aAAa;AAC3B,MAAI,cAAc;AAClB,MAAI,mBAAmB;AAEvB,MAAI,QAAgB,CAAC;AACrB,MAAI,SAAkB,CAAC;AACvB,MAAI,WAAsB,CAAC;AAC3B,MAAI,SAAkB,CAAC;AACvB,MAAI,cAAc;AAClB,MAAI,aAAa;AACjB,MAAI,gBAAgB;AACpB,MAAI,aAAa;AACjB,MAAI,YAAY;AAEhB,MAAI,cAAc;AAClB,MAAI,YAAwB,CAAC;AAC7B,MAAI,cAA4B,CAAC;AACjC,MAAI,cAAc;AAClB,MAAI,iBAAiB;AACrB,MAAI,aAAa;AACjB,MAAI,aAAa;AACjB,MAAI,cAAc;AAClB,MAAI,eAAe;AAEnB,QAAM,aAAiC;AAAA,IACrC,MAAM,MAAM;AAAE,UAAI,CAAC,QAAS;AAAQ,gBAAU;AAAA,IAAO;AAAA,IACrD,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAEA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAEA,QAAM,cAAc,CAAC,cAAc,cAAc,cAAc,cAAc,YAAY;AACzF,QAAM,cAAc,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE;AAEvC,WAASC,gBAAe,GAAW,GAAW,OAAe,OAAe,QAAkB,CAAC,UAAU,UAAU,UAAU,QAAQ,GAAG;AACtI,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK,EAAE,GAAG,GAAG,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC,GAAG,OAAO,IAAI,KAAK,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ,KAAK,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,EAAE,CAAC;AAAA,IACjM;AAAA,EACF;AAEA,WAAS,cAAc,GAAW,GAAW,MAAc,QAAgB,cAAc;AACvF,gBAAY,KAAK,EAAE,GAAG,GAAG,MAAM,QAAQ,IAAI,MAAM,CAAC;AAAA,EACpD;AAEA,WAAS,aAAa,QAAgB,WAAmB;AACvD,kBAAc;AACd,qBAAiB;AAAA,EACnB;AAEA,WAAS,WAAW;AAClB,YAAQ,MAAM,QAAQ;AACtB,YAAQ,MAAM,QAAQ;AACtB,eAAW;AACX,UAAM;AACN,aAAS;AACT,cAAU,aAAa;AACvB,kBAAc;AACd,uBAAmB;AACnB,eAAW,CAAC;AACZ,aAAS,CAAC;AACV,kBAAc;AACd,iBAAa;AACb,oBAAgB;AAChB,iBAAa;AACb,gBAAY;AACZ,gBAAY,CAAC;AACb,kBAAc,CAAC;AACf,kBAAc;AACd,iBAAa;AACb,iBAAa;AACb,kBAAc;AACd,mBAAe;AACf,YAAQ,CAAC,EAAE,GAAG,SAAS,GAAG,cAAc,GAAG,IAAI,GAAG,IAAI,GAAG,QAAQ,KAAK,CAAC;AACvE,eAAW;AAAA,EACb;AAEA,WAAS,aAAa;AACpB,aAAS,CAAC;AACV,UAAM,SAAS,KAAK,OAAO,aAAa,aAAa,eAAe,CAAC;AACrE,UAAM,SAAS;AACf,aAAS,MAAM,GAAG,MAAM,YAAY,OAAO;AACzC,eAAS,MAAM,GAAG,MAAM,YAAY,OAAO;AACzC,cAAM,OAAO;AACb,cAAM,OAAO,SAAS,KAAK,QAAQ,IAAI,IAAI;AAC3C,eAAO,KAAK,EAAE,GAAG,SAAS,MAAM,aAAa,GAAG,SAAS,OAAO,eAAe,IAAI,OAAO,cAAc,GAAG,OAAO,MAAM,MAAM,KAAK,CAAC;AAAA,MACtI;AAAA,IACF;AAAA,EACF;AAEA,WAAS,aAAa;AACpB,QAAI,CAAC,gBAAgB,MAAM,WAAW,EAAG;AACzC,mBAAe;AACf,UAAM,OAAO,MAAM,CAAC;AACpB,UAAM,QAAQ,CAAC,KAAK,KAAK,KAAK,KAAK,OAAO,IAAI,OAAO,KAAK,KAAK;AAC/D,UAAM,QAAQ,cAAc,QAAQ,KAAK;AACzC,SAAK,KAAK,KAAK,IAAI,KAAK,IAAI;AAC5B,SAAK,KAAK,KAAK,IAAI,KAAK,IAAI;AAAA,EAC9B;AAEA,WAAS,aAAa,GAAW,GAAW;AAC1C,QAAI,KAAK,OAAO,IAAI,IAAK;AACzB,UAAM,QAA2B,CAAC,aAAa,QAAQ,SAAS,QAAQ,OAAO;AAC/E,aAAS,KAAK,EAAE,GAAG,GAAG,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC;AAAA,EACzF;AAEA,WAAS,aAAa,MAAuB;AAC3C,iBAAa,GAAG,CAAC;AACjB,kBAAc;AACd,YAAQ,MAAM;AAAA,MACZ,KAAK,aAAa;AAChB,cAAM,cAAc,MAAM,OAAO,OAAK,EAAE,MAAM;AAC9C,YAAI,YAAY,SAAS,GAAG;AAC1B,gBAAM,MAAM,YAAY,CAAC;AACzB,mBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,kBAAM,SAAS,KAAK,OAAO,IAAI,OAAO,KAAK;AAC3C,kBAAM,QAAQ,KAAK,KAAK,IAAI,MAAM,IAAI,IAAI,MAAM,CAAC;AACjD,kBAAM,KAAK,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,IAAI,KAAK,IAAI,KAAK,IAAI,OAAO,IAAI,CAAC,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,GAAG,QAAQ,KAAK,CAAC;AAAA,UACtH;AAAA,QACF;AACA,sBAAc,SAAS,cAAc,GAAG,eAAe,YAAY;AACnE;AAAA,MACF;AAAA,MACA,KAAK;AAAQ,sBAAc;AAAmB,2BAAmB;AAAK,sBAAc,SAAS,cAAc,GAAG,gBAAgB,YAAY;AAAG;AAAA,MAC7I,KAAK;AAAS,sBAAc;AAAM,qBAAa;AAAK,sBAAc,SAAS,cAAc,GAAG,UAAU,YAAY;AAAG;AAAA,MACrH,KAAK;AAAQ,qBAAa;AAAM,oBAAY;AAAK,mBAAW,KAAK,OAAO;AAAE,YAAE,MAAM;AAAK,YAAE,MAAM;AAAA,QAAK;AAAE,sBAAc,SAAS,cAAc,GAAG,YAAY,YAAY;AAAG;AAAA,MACzK,KAAK;AAAS;AAAS,sBAAc,SAAS,cAAc,GAAG,YAAY,YAAY;AAAG;AAAA,IAC5F;AAAA,EACF;AAEA,WAAS,eAAe,MAA+B;AAAE,WAAO,SAAS,cAAc,MAAM,SAAS,SAAS,MAAM,SAAS,UAAU,MAAM,SAAS,SAAS,MAAM;AAAA,EAAK;AAC3K,WAAS,gBAAgB,MAA+B;AAAE,WAAO,SAAS,cAAc,eAAe,SAAS,SAAS,eAAe,SAAS,UAAU,eAAe,SAAS,SAAS,eAAe;AAAA,EAAc;AAEzN,WAAS,SAAS;AAChB,QAAI,CAAC,eAAe,YAAY,OAAQ;AACxC,UAAM,YAAY,aAAa,MAAM;AAErC,QAAI,mBAAmB,GAAG;AAAE;AAAoB,UAAI,qBAAqB,EAAG,eAAc;AAAA,IAAqB;AAC/G,QAAI,aAAa,GAAG;AAAE;AAAc,UAAI,eAAe,EAAG,eAAc;AAAA,IAAO;AAC/E,QAAI,YAAY,GAAG;AAAE;AAAa,UAAI,cAAc,GAAG;AAAE,qBAAa;AAAO,mBAAW,KAAK,OAAO;AAAE,gBAAM,IAAI,KAAK,KAAK,EAAE,MAAM,IAAI,EAAE,MAAM,CAAC;AAAG,cAAI,IAAI,GAAG;AAAE,kBAAM,IAAI,KAAK,IAAI,YAAY,IAAI,IAAI,IAAI;AAAG,cAAE,MAAM;AAAG,cAAE,MAAM;AAAA,UAAG;AAAA,QAAE;AAAA,MAAE;AAAA,IAAE;AACzO,QAAI,gBAAgB,EAAG;AACvB,QAAI,aAAa,GAAG;AAAE;AAAc,UAAI,eAAe,EAAG,cAAa;AAAA,IAAG;AAE1E,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAAE,YAAM,IAAI,UAAU,CAAC;AAAG,QAAE,KAAK,EAAE;AAAI,QAAE,KAAK,EAAE;AAAI,QAAE,MAAM;AAAM,QAAE;AAAQ,UAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,IAAG;AACrK,aAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAAE,YAAM,IAAI,YAAY,CAAC;AAAG,QAAE,KAAK;AAAM,QAAE;AAAU,UAAI,EAAE,UAAU,EAAG,aAAY,OAAO,GAAG,CAAC;AAAA,IAAG;AAEpJ,aAAS,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;AAC7C,YAAM,KAAK,SAAS,CAAC;AACrB,SAAG,KAAK,GAAG,KAAK;AAChB,YAAM,KAAK,UAAU,cAAc,GAAG,KAAK,UAAU,cAAc;AACnE,UAAI,GAAG,KAAK,cAAc,KAAK,GAAG,KAAK,cAAc,KAAK,GAAG,KAAK,MAAM,GAAG,KAAK,IAAI;AAAE,qBAAa,GAAG,IAAI;AAAG,iBAAS,OAAO,GAAG,CAAC;AAAG;AAAA,MAAU;AAC9I,UAAI,GAAG,KAAK,YAAa,UAAS,OAAO,GAAG,CAAC;AAAA,IAC/C;AAEA,aAAS,IAAI,OAAO,SAAS,GAAG,KAAK,GAAG,KAAK;AAC3C,YAAM,QAAQ,OAAO,CAAC;AACtB,YAAM,KAAK;AACX,iBAAW,SAAS,QAAQ;AAC1B,YAAI,CAAC,MAAM,MAAO;AAClB,YAAI,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,IAAI,gBAAgB,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,IAAI,MAAM,OAAO;AACrH,gBAAM;AACN,cAAI,MAAM,QAAQ,GAAG;AAAE,kBAAM,QAAQ;AAAO,kBAAM,MAAM,YAAY,MAAM,IAAI,KAAK;AAAI,qBAAS;AAAK,YAAAA,gBAAe,MAAM,IAAI,MAAM,QAAQ,GAAG,MAAM,GAAG,GAAG,YAAY,MAAM,IAAI,CAAC;AAAG,0BAAc,MAAM,IAAI,GAAG,MAAM,IAAI,GAAG,IAAI,GAAG,IAAI,YAAY,MAAM,IAAI,CAAC;AAAG,yBAAa,MAAM,IAAI,MAAM,QAAQ,GAAG,MAAM,CAAC;AAAA,UAAG;AACpT,iBAAO,OAAO,GAAG,CAAC;AAClB;AAAA,QACF;AAAA,MACF;AACA,UAAI,MAAM,IAAI,EAAG,QAAO,OAAO,GAAG,CAAC;AAAA,IACrC;AAEA,QAAI,gBAAgB,MAAM,SAAS,GAAG;AAAE,YAAM,CAAC,EAAE,IAAI;AAAS,YAAM,CAAC,EAAE,IAAI,cAAc;AAAA,IAAG;AAE5F,aAAS,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK;AAC1C,YAAM,OAAO,MAAM,CAAC;AACpB,UAAI,CAAC,KAAK,UAAU,aAAc;AAClC,WAAK,KAAK,KAAK,KAAK;AACpB,WAAK,KAAK,KAAK,KAAK;AAEpB,UAAI,KAAK,KAAK,GAAG;AAAE,aAAK,IAAI;AAAG,aAAK,KAAK,KAAK,IAAI,KAAK,EAAE;AAAG,QAAAA,gBAAe,GAAG,KAAK,GAAG,GAAG,YAAY,CAAC,QAAU,QAAQ,CAAC;AAAA,MAAG;AAC5H,UAAI,KAAK,KAAK,aAAa,GAAG;AAAE,aAAK,IAAI,aAAa;AAAG,aAAK,KAAK,CAAC,KAAK,IAAI,KAAK,EAAE;AAAG,QAAAA,gBAAe,aAAa,GAAG,KAAK,GAAG,GAAG,YAAY,CAAC,QAAU,QAAQ,CAAC;AAAA,MAAG;AACpK,UAAI,KAAK,KAAK,GAAG;AAAE,aAAK,IAAI;AAAG,aAAK,KAAK,KAAK,IAAI,KAAK,EAAE;AAAG,QAAAA,gBAAe,KAAK,GAAG,GAAG,GAAG,YAAY,CAAC,QAAU,QAAQ,CAAC;AAAA,MAAG;AAE5H,YAAM,KAAK,UAAU,cAAc,GAAG,KAAK,UAAU,cAAc,GAAG,KAAK,cAAc;AACzF,UAAI,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,OAAO,KAAK,KAAK,KAAK,OAAO,KAAK,KAAK,KAAK,OAAO,KAAK,KAAK,KAAK,KAAK;AACvG,cAAM,UAAU,KAAK,IAAI,YAAY,cAAc;AACnD,cAAM,QAAQ,SAAS,KAAK,KAAK;AACjC,cAAM,WAAW,KAAK,KAAK,KAAK,MAAM,IAAI,KAAK,MAAM,CAAC;AACtD,cAAM,WAAW,KAAK,IAAI,gBAAgB,WAAW,IAAI;AACzD,aAAK,KAAK,KAAK,IAAI,KAAK,IAAI;AAC5B,aAAK,KAAK,CAAC,KAAK,IAAI,KAAK,IAAI;AAC7B,aAAK,IAAI,KAAK;AACd,QAAAA,gBAAe,KAAK,GAAG,IAAI,GAAG,YAAY,CAAC,UAAU,QAAQ,CAAC;AAAA,MAChE;AAEA,iBAAW,SAAS,QAAQ;AAC1B,YAAI,CAAC,MAAM,MAAO;AAClB,cAAM,KAAK,MAAM,GAAG,KAAK,MAAM,IAAI,MAAM,OAAO,KAAK,MAAM,GAAG,KAAK,MAAM,IAAI;AAC7E,YAAI,KAAK,KAAK,KAAK,OAAO,KAAK,KAAK,KAAK,OAAO,KAAK,KAAK,KAAK,OAAO,KAAK,KAAK,KAAK,KAAK;AACxF,gBAAM,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI;AACtF,cAAI,SAAS,MAAO,MAAK,KAAK,CAAC,KAAK;AACpC,cAAI,SAAS,MAAO,MAAK,KAAK,CAAC,KAAK;AACpC,cAAI,CAAC,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,MAAO,MAAK,KAAK,CAAC,KAAK;AAC1D,gBAAM;AACN,cAAI,MAAM,QAAQ,GAAG;AACnB,kBAAM,QAAQ;AACd;AAAc,yBAAa;AAC3B,kBAAM,UAAU,YAAY,MAAM,IAAI,KAAK;AAC3C,kBAAM,aAAa,aAAa,IAAI,KAAK,MAAM,aAAa,CAAC,IAAI;AACjE,kBAAM,WAAW,UAAU;AAC3B,qBAAS;AACT,kBAAM,YAAY,KAAK,IAAI,YAAY,CAAC;AACxC,yBAAa,IAAI,WAAW,IAAI,KAAK,MAAM,YAAY,CAAC,CAAC;AACzD,YAAAA,gBAAe,MAAM,IAAI,MAAM,QAAQ,GAAG,MAAM,GAAG,IAAI,WAAW,YAAY,MAAM,IAAI,CAAC;AACzF,0BAAc,MAAM,IAAI,GAAG,MAAM,IAAI,GAAG,aAAa,IAAI,IAAI,QAAQ,MAAM,IAAI,QAAQ,IAAI,YAAY,MAAM,IAAI,CAAC;AAClH,yBAAa,MAAM,IAAI,MAAM,QAAQ,GAAG,MAAM,CAAC;AAAA,UACjD,OAAO;AACL,YAAAA,gBAAe,KAAK,GAAG,KAAK,GAAG,GAAG,YAAY,YAAY,MAAM,IAAI,GAAG,CAAC,QAAU,GAAG,CAAC;AAAA,UACxF;AACA;AAAA,QACF;AAAA,MACF;AAEA,UAAI,KAAK,KAAK,YAAa,MAAK,SAAS;AAAA,IAC3C;AAEA,YAAQ,MAAM,OAAO,OAAK,EAAE,MAAM;AAElC,QAAI,MAAM,WAAW,KAAK,CAAC,cAAc;AACvC;AACA,UAAI,SAAS,GAAG;AAAE,mBAAW;AAAM,YAAI,QAAQ,UAAW,aAAY;AAAO,qBAAa,IAAI,CAAC;AAAG,QAAAA,gBAAe,SAAS,cAAc,GAAG,IAAI,cAAc,CAAC,UAAU,UAAU,QAAU,QAAQ,CAAC;AAAA,MAAG,OACnM;AAAE,uBAAe;AAAM,gBAAQ,CAAC,EAAE,GAAG,SAAS,GAAG,cAAc,GAAG,IAAI,GAAG,IAAI,GAAG,QAAQ,KAAK,CAAC;AAAG,qBAAa,IAAI,CAAC;AAAA,MAAG;AAAA,IAC7H;AAEA,UAAM,cAAc,OAAO,OAAO,OAAK,EAAE,KAAK;AAC9C,QAAI,YAAY,WAAW,GAAG;AAC5B,YAAM;AAAM,iBAAW;AAAM;AAAS,UAAI,QAAQ,UAAW,aAAY;AAAO,mBAAa,IAAI,CAAC;AAClG,eAAS,IAAI,GAAG,IAAI,GAAG,IAAK,YAAW,MAAMA,gBAAe,KAAK,OAAO,IAAI,YAAY,KAAK,OAAO,IAAI,cAAc,GAAG,IAAI,YAAY,KAAK,MAAM,KAAK,OAAO,IAAI,YAAY,MAAM,CAAC,GAAG,CAAC,UAAU,UAAU,UAAU,UAAU,QAAQ,CAAC,GAAG,IAAI,GAAG;AAAA,IACxP;AAAA,EACF;AAEA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,QAAI,cAAc,EAAG;AACrB,QAAI,cAAc,EAAG;AAErB,UAAM,OAAO,SAAS,MAAM,OAAO,SAAS;AAC5C,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,OAAO;AACb,YAAM,QAAQ,OAAO,UAAU,QAAQ,OAAO;AAC9C,YAAMC,QAAO,SAAS,QAAQ,qBAAqB,QAAQ,2BAA2B;AACtF,YAAM,OAAO,SAAS,QAAQ,OAAS,QAAQ,WAAW,IAAI,OAAS,IAAI;AAC3E,YAAM,KAAK,KAAK,MAAM,OAAO,CAAC,GAAG,KAAK,KAAK,MAAM,OAAO,CAAC;AACzD,gBAAU,QAAQ,KAAK,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI;AAC9F,gBAAU,QAAQ,KAAK,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI;AACxF,gBAAU,QAAQ,KAAK,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,KAAK,MAAMA,MAAK,SAAS,CAAC,CAAC,CAAC,WAAW,UAAU,GAAGA,KAAI;AACrG,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAEA,eAAW,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,aAAa,KAAK,CAAC,CAAC;AAC9D,cAAU,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,cAAc,KAAK,CAAC,CAAC;AAE9D,QAAI,KAAK,UAAU,KAAK;AACxB,QAAI,cAAc,GAAG;AAAE,YAAM,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,iBAAiB,CAAC;AAAG,YAAM,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,cAAc;AAAA,IAAG;AAE/I,mBAAe,cAAc,KAAK;AAClC,UAAM,YAAY,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC1E,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI;AAC1D,QAAI,eAAe,MAAM,cAAc,IAAI;AAAE,gBAAU,UAAU,MAAM,YAAY,MAAM,CAAC,CAAC,iBAAiB,SAAS,CAAC,YAAY,MAAM,CAAC,CAAC;AAAA,IAAW,OAChJ;AAAE,gBAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC,iBAAiB,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,IAAW;AAEnI,UAAM,YAAY,SAAS,OAAO,KAAK,IAAI,GAAG,KAAK,CAAC;AACpD,UAAM,QAAQ,UAAU,MAAM,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,UAAU,KAAK,KAAK,SAAS;AACtF,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,UAAU,CAAC;AACnD,cAAU,QAAQ,UAAU,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,KAAK;AAE7D,QAAI,MAAM;AACV,QAAI,mBAAmB,EAAG,QAAO;AACjC,QAAI,YAAa,QAAO;AACxB,QAAI,WAAY,QAAO;AACvB,QAAI,IAAK,WAAU,QAAQ,UAAU,CAAC,IAAI,SAAS,MAAM,SAAS,CAAC,WAAW,UAAU,GAAG,GAAG;AAE9F,UAAM,KAAK,cAAc,KAAK,cAAc,IAAI,IAAI,eAAe;AACnE,cAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,SAAI,OAAO,UAAU,CAAC;AAC/D,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AAAE,gBAAU,QAAQ,KAAK,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI,EAAE;AAAA,IAAiB;AAC7J,cAAU,QAAQ,KAAK,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,SAAI,OAAO,UAAU,CAAC;AAEjF,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,MAAM,KAAK,MAAM,OAAO,CAAC,GAAG,KAAK,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AAC/E,gBAAU,QAAQ,EAAE,IAAI,MAAM,KAAK,MAAM,SAAS,SAAS,CAAC,CAAC,WAAW,UAAU,GAAG,QAAQ;AAC7F,gBAAU,iBAAiB,kBAAkB,oBAAoB,EAAE,SAAS,KAAK,QAAQ,KAAK,GAAG,eAAe,MAAM,CAAC;AACvH,gBAAU,QAAQ,KAAK,CAAC,IAAI,MAAM,EAAE,WAAW,UAAU;AAAA,IAC3D,WAAW,CAAC,aAAa;AACvB,YAAM,WAAW;AACjB,YAAM,KAAK,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AACvE,YAAM,KAAK,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACnD,gBAAU,QAAQ,EAAE,IAAI,EAAE,WAAW,UAAU,GAAG,QAAQ;AAC1D,YAAM,WAAW;AACjB,gBAAU,QAAQ,KAAK,CAAC,IAAI,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI,CAAC,WAAW,UAAU,GAAG,QAAQ;AACzH,eAAS,kBAAkB,QAAQ,IAAI,EAAE;AAAA,IAC3C,WAAW,UAAU;AACnB,YAAM,UAAU,MAAM,0DAA0D;AAChF,YAAM,KAAK,WAAW,KAAK,OAAO,aAAa,QAAQ,UAAU,CAAC,IAAI;AACtE,YAAM,KAAK,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACnD,gBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,MAAM,eAAe,YAAY,GAAG,OAAO;AACzE,YAAM,YAAY,UAAU,KAAK,WAAW,SAAS;AACrD,gBAAU,QAAQ,KAAK,CAAC,IAAI,WAAW,KAAK,OAAO,aAAa,UAAU,UAAU,CAAC,IAAI,CAAC,IAAI,UAAU,GAAG,SAAS;AACpH,YAAM,UAAU,MAAM,2CAA2C;AACjE,gBAAU,QAAQ,KAAK,CAAC,IAAI,WAAW,KAAK,OAAO,aAAa,QAAQ,UAAU,CAAC,IAAI,CAAC,WAAW,UAAU,GAAG,OAAO;AACvH,eAAS,YAAY,QAAQ,IAAI,EAAE;AAAA,IACrC,OAAO;AACL,eAAS,kBAAkB,QAAQ,IAAI,EAAE;AAAA,IAC3C;AAEA,UAAM,OAAO,eAAe,CAAC,YAAY,CAAC,SAAS,SAAS,SAAS,mBAAmB;AACxF,cAAU,QAAQ,UAAU,cAAc,CAAC,IAAI,KAAK,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,WAAW,UAAU,GAAG,IAAI;AAC/G,aAAS,MAAM,MAAM;AAAA,EACvB;AAEA,WAAS,kBAAkB,QAAgB,IAAY,IAAoB;AACzE,eAAW,SAAS,QAAQ;AAAE,UAAI,CAAC,MAAM,MAAO;AAAU,YAAM,KAAK,KAAK,IAAI,MAAM,GAAG,KAAK,KAAK,IAAI,MAAM;AAAG,YAAM,IAAI,YAAY,MAAM,IAAI,KAAK;AAAY,YAAM,KAAK,MAAM,OAAO,IAAI,WAAW;AAAU,gBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,GAAG,OAAO,MAAM,KAAK,CAAC;AAAA,IAAW;AACnR,eAAW,MAAM,UAAU;AAAE,YAAM,KAAK,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC;AAAG,UAAI,KAAK,MAAM,KAAK,KAAK,cAAc,EAAG,WAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,gBAAgB,GAAG,IAAI,CAAC,IAAI,eAAe,GAAG,IAAI,CAAC;AAAA,IAAY;AAC1O,eAAW,SAAS,QAAQ;AAAE,YAAM,KAAK,KAAK,IAAI,KAAK,MAAM,MAAM,CAAC,GAAG,KAAK,KAAK,IAAI,KAAK,MAAM,MAAM,CAAC;AAAG,UAAI,KAAK,MAAM,KAAK,KAAK,cAAc,EAAG,WAAU,QAAQ,EAAE,IAAI,EAAE;AAAA,IAA4B;AAC1M,UAAM,MAAM,KAAK,IAAI,KAAK,MAAM,UAAU,cAAc,CAAC,GAAG,MAAM,KAAK,cAAc;AACrF,UAAM,MAAM,cAAc,WAAW;AACrC,cAAU,QAAQ,GAAG,IAAI,GAAG,IAAI,UAAU,GAAG,IAAI,OAAO,KAAK,KAAK,WAAW,CAAC,CAAC;AAC/E,QAAI,aAAa;AAAE,gBAAU,QAAQ,GAAG,IAAI,GAAG,gCAAgC,GAAG,IAAI,MAAM,KAAK,KAAK,WAAW,IAAI,CAAC;AAAA,IAA4B;AAClJ,eAAW,QAAQ,OAAO;AAAE,UAAI,CAAC,KAAK,OAAQ;AAAU,YAAM,KAAK,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC;AAAG,UAAI,KAAK,MAAM,KAAK,KAAK,aAAa,KAAK,KAAK,MAAM,KAAK,KAAK,cAAc,GAAG;AAAE,cAAM,MAAM,KAAK,KAAK,KAAK,MAAM,IAAI,KAAK,MAAM,CAAC;AAAG,kBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,MAAM,MAAM,eAAe,YAAY;AAAA,MAAiB;AAAA,IAAE;AACjW,QAAI,cAAc,GAAG;AAAE,YAAM,WAAW,cAAc,IAAI,UAAU,UAAU,oBAAoB,GAAG,UAAU;AAAY,YAAM,SAAS,KAAK,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAAG,gBAAU,QAAQ,KAAK,cAAc,CAAC,IAAI,MAAM,IAAI,cAAc,IAAI,IAAI,eAAe,YAAY,GAAG,QAAQ;AAAA,IAAW;AAC9T,WAAO,YAAY,QAAQ,IAAI,EAAE;AAAA,EACnC;AAEA,WAAS,YAAY,QAAgB,IAAY,IAAoB;AACnE,eAAW,KAAK,WAAW;AAAE,YAAM,KAAK,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,GAAG,KAAK,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC;AAAG,UAAI,KAAK,MAAM,KAAK,KAAK,aAAa,KAAK,KAAK,MAAM,KAAK,KAAK,cAAc,EAAG,WAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,IAAI,KAAK,SAAS,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,IAAW;AACzQ,eAAW,SAAS,aAAa;AAAE,YAAM,KAAK,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,GAAG,KAAK,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC;AAAG,UAAI,KAAK,MAAM,KAAK,KAAK,cAAc,EAAG,WAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,MAAM,SAAS,KAAK,YAAY,SAAS,GAAG,MAAM,KAAK,GAAG,MAAM,IAAI;AAAA,IAAW;AACtQ,WAAO;AAAA,EACT;AAEA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AACd,aAAS,MAAM,sBAAsB;AACrC,aAAS;AACT,kBAAc;AAEd,UAAM,iBAAiB,YAAY,MAAM;AAAE,UAAI,CAAC,SAAS;AAAE,sBAAc,cAAc;AAAG;AAAA,MAAQ;AAAE,aAAO;AAAA,IAAG,GAAG,EAAE;AACnH,UAAM,eAAe,YAAY,MAAM;AAAE,UAAI,CAAC,SAAS;AAAE,sBAAc,YAAY;AAAG;AAAA,MAAQ;AAAE,aAAO;AAAA,IAAG,GAAG,EAAE;AAE/G,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AAAE,oBAAY,QAAQ;AAAG;AAAA,MAAQ;AAC/C,eAAS,eAAe;AACxB,eAAS,gBAAgB;AACzB,YAAM,MAAM,SAAS,IAAI,YAAY;AAErC,UAAI,QAAQ,UAAU;AAAE,iBAAS,CAAC;AAAQ,YAAI,OAAQ,sBAAqB;AAAG;AAAA,MAAQ;AACtF,UAAI,QAAQ,QAAQ,UAAU,YAAY,CAAC,cAAc;AAAE,sBAAc,cAAc;AAAG,sBAAc,YAAY;AAAG,mBAAW,KAAK;AAAG,yBAAiB,QAAQ;AAAG;AAAA,MAAQ;AAC9K,UAAI,CAAC,eAAe,CAAC,QAAQ;AAAE,YAAI,SAAS,QAAQ,KAAK;AAAE,wBAAc;AAAM,qBAAW;AAAA,QAAG;AAAE;AAAA,MAAQ;AACvG,UAAI,UAAU;AAAE,YAAI,QAAQ,KAAK;AAAE,cAAI,QAAQ,UAAW,aAAY;AAAO,cAAI,IAAK,UAAS;AAAA,eAAQ;AAAE,oBAAQ;AAAG,qBAAS;AAAA,UAAG;AAAE,wBAAc;AAAM,qBAAW;AAAA,QAAG;AAAE;AAAA,MAAQ;AAE9K,UAAI,QAAQ;AACV,cAAM,EAAE,cAAc,UAAU,IAAI,aAAa,oBAAoB,iBAAiB,QAAQ,KAAK,QAAQ;AAC3G,YAAI,iBAAiB,oBAAoB;AAAE,+BAAqB;AAAc;AAAA,QAAQ;AACtF,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AAAG,uBAAS;AAAO;AAAA,YACxB,KAAK;AAAG,sBAAQ;AAAG,uBAAS;AAAG,4BAAc;AAAM,yBAAW;AAAG,uBAAS;AAAO;AAAA,YACjF,KAAK;AAAG,4BAAc,cAAc;AAAG,4BAAc,YAAY;AAAG,yBAAW,KAAK;AAAG,+BAAiB,QAAQ;AAAG;AAAA,YACnH,KAAK;AAAG,4BAAc,cAAc;AAAG,4BAAc,YAAY;AAAG,wBAAU;AAAO,gCAAkB,QAAQ;AAAG;AAAA,YAClH,KAAK;AAAG,4BAAc,cAAc;AAAG,4BAAc,YAAY;AAAG,wBAAU;AAAO,iCAAmB,QAAQ;AAAG;AAAA,UACrH;AACA;AAAA,QACF;AACA,YAAI,QAAQ,KAAK;AAAE,kBAAQ;AAAG,mBAAS;AAAG,wBAAc;AAAM,qBAAW;AAAG,mBAAS;AAAA,QAAO,WACnF,QAAQ,KAAK;AAAE,wBAAc,cAAc;AAAG,wBAAc,YAAY;AAAG,oBAAU;AAAO,4BAAkB,QAAQ;AAAA,QAAG,WACzH,QAAQ,KAAK;AAAE,wBAAc,cAAc;AAAG,wBAAc,YAAY;AAAG,oBAAU;AAAO,6BAAmB,QAAQ;AAAA,QAAG;AACnI;AAAA,MACF;AAEA,YAAM,YAAY;AAClB,cAAQ,SAAS,KAAK;AAAA,QACpB,KAAK;AAAA,QAAa,KAAK;AAAK,oBAAU,KAAK,IAAI,cAAc,GAAG,UAAU,SAAS;AAAG;AAAA,QACtF,KAAK;AAAA,QAAc,KAAK;AAAK,oBAAU,KAAK,IAAI,aAAa,cAAc,GAAG,UAAU,SAAS;AAAG;AAAA,QACpG,KAAK;AAAK,cAAI,aAAc,YAAW;AAAA,mBAAY,eAAe,kBAAkB,GAAG;AAAE,mBAAO,KAAK,EAAE,GAAG,UAAU,cAAc,IAAI,KAAK,GAAG,cAAc,EAAE,CAAC;AAAG,mBAAO,KAAK,EAAE,GAAG,UAAU,cAAc,IAAI,KAAK,GAAG,cAAc,EAAE,CAAC;AAAG,4BAAgB;AAAA,UAAG;AAAE;AAAA,MAClQ;AAAA,IACF,CAAC;AAED,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AAAE,oBAAc,cAAc;AAAG,oBAAc,YAAY;AAAG,kBAAY,QAAQ;AAAG,mBAAa;AAAA,IAAG;AAAA,EAC/H,GAAG,EAAE;AAEL,SAAO;AACT;;;ACtdO,IAAM,kBAA2B;AAAA;AAAA,EAEtC;AAAA,IACE,MAAM;AAAA,IACN,YAAY;AAAA;AAAA,IACZ,WAAW;AAAA,MACT,EAAE,GAAG,GAAG,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,MACzB,EAAE,GAAG,IAAI,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,IAC5B;AAAA,IACA,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,MACT,EAAE,GAAG,GAAG,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,MACzB,EAAE,GAAG,IAAI,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,IAC5B;AAAA,IACA,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,MACT,EAAE,GAAG,GAAG,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,MACzB,EAAE,GAAG,IAAI,GAAG,GAAG,OAAO,GAAG;AAAA;AAAA,IAC3B;AAAA,IACA,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AACF;AAEO,IAAM,SAAkB;AAAA;AAAA,EAE7B;AAAA,IACE,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,MACT,EAAE,GAAG,GAAG,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,MACzB,EAAE,GAAG,IAAI,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,MAC1B,EAAE,GAAG,IAAI,GAAG,GAAG,OAAO,GAAG;AAAA;AAAA,IAC3B;AAAA,IACA,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,MACT,EAAE,GAAG,GAAG,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,MACzB,EAAE,GAAG,IAAI,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,MAC1B,EAAE,GAAG,IAAI,GAAG,GAAG,OAAO,GAAG;AAAA;AAAA,IAC3B;AAAA,IACA,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,MACT,EAAE,GAAG,GAAG,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,MACzB,EAAE,GAAG,IAAI,GAAG,GAAG,OAAO,GAAG;AAAA;AAAA,MACzB,EAAE,GAAG,IAAI,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,IAC5B;AAAA,IACA,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,MACT,EAAE,GAAG,GAAG,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,MACzB,EAAE,GAAG,IAAI,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,MAC1B,EAAE,GAAG,IAAI,GAAG,GAAG,OAAO,GAAG;AAAA;AAAA,IAC3B;AAAA,IACA,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,MACT,EAAE,GAAG,GAAG,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,MACzB,EAAE,GAAG,IAAI,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,MAC1B,EAAE,GAAG,IAAI,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,IAC5B;AAAA,IACA,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,MACT,EAAE,GAAG,GAAG,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,MACzB,EAAE,GAAG,IAAI,GAAG,GAAG,OAAO,GAAG;AAAA;AAAA,MACzB,EAAE,GAAG,IAAI,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,IAC5B;AAAA,IACA,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,MACT,EAAE,GAAG,GAAG,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,MACzB,EAAE,GAAG,IAAI,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,MAC1B,EAAE,GAAG,IAAI,GAAG,GAAG,OAAO,GAAG;AAAA;AAAA,IAC3B;AAAA,IACA,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAAA;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,MACT,EAAE,GAAG,GAAG,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,MACzB,EAAE,GAAG,IAAI,GAAG,GAAG,OAAO,GAAG;AAAA;AAAA,MACzB,EAAE,GAAG,IAAI,GAAG,IAAI,OAAO,GAAG;AAAA;AAAA,IAC5B;AAAA,IACA,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AACF;;;ACjJO,IAAM,gBAAgB;AAGtB,IAAM,oBAAoB;AAAA,EAC/B;AAAA,EAAS;AAAA,EAAY;AAAA,EAAY;AAAA,EAAU;AAAA,EAC3C;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAc;AAAA,EAAW;AAC5C;AAKO,SAAS,eACd,WACA,GACA,GACA,OACA,OACA,QAAkB,CAAC,UAAK,QAAK,QAAG,GAC1B;AACN,MAAI,UAAU,UAAU,cAAe;AAEvC,QAAM,cAAc,KAAK,IAAI,OAAO,gBAAgB,UAAU,MAAM;AACpE,WAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,UAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,UAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,cAAU,KAAK;AAAA,MACb;AAAA,MACA;AAAA,MACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,MACpD;AAAA,MACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,MACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ;AAAA,MAC9B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC;AAAA,IACzC,CAAC;AAAA,EACH;AACF;AAKO,SAAS,cACd,WACA,GACA,GACA,YAAoB,GACd;AACN,QAAM,SAAS,CAAC,cAAc,cAAc,cAAc,cAAc,cAAc,YAAY;AAClG,QAAM,QAAQ,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AAG/D,WAAS,IAAI,GAAG,IAAI,KAAK,WAAW,KAAK;AACvC,UAAM,QAAS,KAAK,KAAK,IAAI,KAAM,KAAK;AACxC,UAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,UAAM,QAAQ,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,OAAO,MAAM,CAAC;AAC9D,UAAM,OAAO,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAC3D,cAAU,KAAK;AAAA,MACb;AAAA,MAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,MACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ;AAAA,MAC9B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA,IAC1C,CAAC;AAAA,EACH;AAGA,WAAS,IAAI,GAAG,IAAI,IAAI,WAAW,KAAK;AACtC,UAAM,QAAS,KAAK,KAAK,IAAI,KAAM,IAAI,aAAa,KAAK,OAAO,IAAI;AACpE,UAAM,OAAO,MAAM,KAAK,OAAO;AAC/B,cAAU,KAAK;AAAA,MACb,GAAG,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,MACzB,GAAG,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,MACzB,MAAM;AAAA,MACN,OAAO;AAAA,MACP,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,MACtB,IAAI,KAAK,IAAI,KAAK,IAAI,OAAO;AAAA,MAC7B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA,IAC1C,CAAC;AAAA,EACH;AACF;AAKO,SAAS,SACd,QACA,GACA,GACA,MACA,QAAgB,cACV;AACN,SAAO,KAAK,EAAE,GAAG,GAAG,MAAM,QAAQ,IAAI,MAAM,CAAC;AAC/C;AAKO,SAAS,gBAAgB,WAAuB,cAAsB,GAAS;AACpF,WAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,UAAM,IAAI,UAAU,CAAC;AACrB,MAAE,KAAK,EAAE;AACT,MAAE,KAAK,EAAE;AACT,MAAE,MAAM,OAAO;AACf,MAAE;AACF,QAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,EACxC;AACF;AAKO,SAAS,aAAa,QAAuB;AAClD,WAAS,IAAI,OAAO,SAAS,GAAG,KAAK,GAAG,KAAK;AAC3C,UAAM,QAAQ,OAAO,CAAC;AACtB,UAAM,KAAK;AACX,UAAM;AACN,QAAI,MAAM,UAAU,EAAG,QAAO,OAAO,GAAG,CAAC;AAAA,EAC3C;AACF;AAKO,SAAS,kBACd,WACA,GACA,GACA,QAAgB,GAChB,QAAgB,cACV;AACN,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,cAAU,KAAK;AAAA,MACb,GAAG,KAAK,KAAK,OAAO,IAAI,OAAO;AAAA,MAC/B;AAAA,MACA,MAAM,CAAC,UAAK,UAAK,QAAG,EAAE,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,CAAC;AAAA,MACnD;AAAA,MACA,KAAK,KAAK,OAAO,IAAI,OAAO;AAAA,MAC5B,IAAI,OAAO,KAAK,OAAO,IAAI;AAAA,MAC3B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA,IAC1C,CAAC;AAAA,EACH;AACF;AAKO,SAAS,YACd,WACA,GACA,QACA,YAAoB,GACd;AACN,QAAM,QAAQ,KAAK,MAAM,KAAK,SAAS;AACvC,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,UAAU,KAAK,OAAO,IAAI,OAAO,KAAK;AAC5C,cAAU,KAAK;AAAA,MACb,GAAG,IAAI;AAAA,MACP,GAAG,SAAS;AAAA,MACZ,MAAM,CAAC,KAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG,EAAE,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,CAAC;AAAA,MAC5E,OAAO,KAAK,OAAO,IAAI,MAAM,aAAa;AAAA,MAC1C,IAAI,SAAS;AAAA,MACb,IAAI,OAAO,KAAK,OAAO,IAAI;AAAA,MAC3B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA,IAC1C,CAAC;AAAA,EACH;AACF;AAKO,SAAS,2BAAmC;AACjD,SAAO,kBAAkB,KAAK,MAAM,KAAK,OAAO,IAAI,kBAAkB,MAAM,CAAC;AAC/E;;;AC3JA,IAAM,UAAU;AAChB,IAAM,aAAa;AACnB,IAAM,eAAe;AACrB,IAAM,iBAAiB;AACvB,IAAM,iBAAiB;AACvB,IAAM,aAAa;AACnB,IAAM,aAAa;AAGnB,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AACxB,IAAM,oBAAoB;AAC1B,IAAM,qBAAqB;AAC3B,IAAM,0BAA0B;AAMzB,SAAS,eAAe,UAAuC;AACpE,QAAM,aAAa,qBAAqB;AAGxC,QAAM,WAAW;AACjB,QAAM,WAAW;AAEjB,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,iBAAiB;AACrB,MAAI,SAAS;AACb,MAAI,gBAAgB;AAGpB,MAAI,oBAAoB;AACxB,MAAI,gBAAgB;AACpB,MAAI,qBAAqB;AAGzB,MAAI,eAAe;AACnB,MAAI,qBAAqB;AACzB,MAAI,eAAe;AACnB,MAAI,sBAAsB;AAG1B,MAAI,cAAc;AAClB,MAAI,eAAe;AAGnB,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,MAAI,WAAW;AAGf,MAAI,aAAa;AACjB,MAAI,aAAa;AACjB,MAAI,cAAc;AAClB,MAAI,cAAc;AAClB,MAAI,eAAe;AAGnB,MAAI,eAAe;AACnB,MAAI,gBAAgB;AACpB,MAAI,QAAQ;AACZ,MAAI,qBAAqB;AACzB,MAAI,kBAAkB;AAGtB,MAAI,sBAAsB;AAC1B,MAAI,uBAAuB;AAC3B,MAAI,gBAAgB;AACpB,MAAI,kBAAkB;AACtB,MAAI,yBAAyB;AAC7B,MAAI,sBAAsB;AAG1B,MAAI,uBAAuB;AAG3B,MAAI,YAAwB,CAAC;AAC7B,MAAI,SAAkB,CAAC;AACvB,MAAI,cAAc;AAClB,MAAI,cAAc;AAGlB,MAAI,oBAAoB;AACxB,MAAI,mBAAmB;AAGvB,MAAI,eAAe;AACnB,MAAI,gBAAgB;AACpB,MAAI,aAAa;AAGjB,MAAI,YAAY;AAChB,MAAI,aAAa;AACjB,MAAI,kBAAkB;AACtB,MAAI,oBAAoB;AAGxB,MAAI,oBAAoB;AAGxB,QAAM,kBAAmD,CAAC;AAG1D,QAAM,SAAS;AAGf,MAAI,iBAAwD;AAC5D,MAAI,eAAsD;AAC1D,MAAI,cAA8C;AAGlD,MAAI,YAAY;AAEhB,MAAI,uBAAuB;AAK3B,WAAS,gBAAgB,UAAsB,OAAqB;AAClE,UAAM,KAAK,WAAW,MAAM;AAE1B,YAAM,MAAM,gBAAgB,QAAQ,EAAE;AACtC,UAAI,QAAQ,GAAI,iBAAgB,OAAO,KAAK,CAAC;AAE7C,UAAI,QAAS,UAAS;AAAA,IACxB,GAAG,KAAK;AACR,oBAAgB,KAAK,EAAE;AAAA,EACzB;AAKA,WAAS,UAAgB;AACvB,QAAI,UAAW;AACf,gBAAY;AAGZ,oBAAgB,QAAQ,QAAM,aAAa,EAAE,CAAC;AAC9C,oBAAgB,SAAS;AAGzB,QAAI,eAAgB,eAAc,cAAc;AAChD,QAAI,aAAc,eAAc,YAAY;AAG5C,QAAI,YAAa,aAAY,QAAQ;AAGrC,QAAI,wBAAwB,kBAAkB,cAAc;AAC1D,aAAO,oBAAoB,WAAW,cAAc;AACpD,aAAO,oBAAoB,SAAS,YAAY;AAChD,6BAAuB;AAAA,IACzB;AAEA,cAAU;AAAA,EACZ;AAGA,MAAI;AACJ,MAAI;AAEJ,QAAM,aAAgC;AAAA,IACpC,MAAM,MAAM;AACV,cAAQ;AAAA,IACV;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAGA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAEA,QAAM,WAAW;AAKjB,WAAS,iBAA0B;AAEjC,QAAI,eAAe,KAAK,gBAAgB,OAAO,QAAQ;AACrD,cAAQ,MAAM,kCAAkC,YAAY,EAAE;AAC9D,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,OAAO,YAAY;AACjC,UAAM,eAAe,MAAM,UAAU;AAGrC,QAAI,eAAe,GAAG;AACpB,cAAQ,MAAM,mBAAmB,YAAY,6BAA6B;AAC1E,aAAO;AAAA,IACT;AAGA,0BAAsB,KAAK,MAAM,KAAK,OAAO,IAAI,YAAY;AAG7D,OAAG;AACD,6BAAuB,KAAK,MAAM,KAAK,OAAO,IAAI,YAAY;AAAA,IAChE,SAAS,yBAAyB;AAGlC,oBAAgB;AAGhB,UAAM,SAAS,MAAM,UAAU,mBAAmB;AAClD;AAAA,MACE;AAAA,MACA,OAAO,IAAI,KAAK,MAAM,OAAO,QAAQ,CAAC;AAAA,MACtC,OAAO,IAAI;AAAA,MACX;AAAA,MACA;AAAA,MACA,CAAC,UAAK,UAAK,QAAG;AAAA,IAChB;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,WAAW;AAClB,eAAW;AACX,aAAS;AACT,oBAAgB;AAChB,YAAQ;AACR,yBAAqB;AACrB,mBAAe;AACf,mBAAe;AACf,mBAAe;AACf,cAAU;AAAA,EACZ;AAEA,WAAS,eAAe;AACtB,eAAW;AACX,aAAS;AACT,oBAAgB;AAChB,YAAQ;AACR,yBAAqB;AACrB,mBAAe;AACf,yBAAqB;AACrB,mBAAe;AACf,0BAAsB;AACtB,sBAAkB;AAAA,EACpB;AAEA,WAAS,oBAA6B;AACpC,UAAM,QAAQ,gBAAgB,kBAAkB;AAChD,QAAI,CAAC,OAAO;AACV,cAAQ,MAAM,qCAAqC,kBAAkB,EAAE;AACvE,aAAO;AAAA,IACT;AAGA,mBAAe;AACf,0BAAsB;AAGtB,UAAM,gBAAgB,MAAM,UAAU,CAAC;AACvC,WAAO,cAAc,IAAI,KAAK,MAAM,cAAc,QAAQ,CAAC;AAC3D,WAAO,cAAc,IAAI;AACzB,YAAQ;AACR,YAAQ;AACR,eAAW;AAGX,wBAAoB;AACpB,uBAAmB;AAGnB,QAAI,uBAAuB,GAAG;AAE5B,4BAAsB;AACtB,6BAAuB;AACvB,qBAAe;AACf,wBAAkB;AAAA,IACpB,WAAW,uBAAuB,GAAG;AAEnC,4BAAsB;AACtB,6BAAuB;AACvB,qBAAe;AACf,wBAAkB;AAAA,IACpB,WAAW,uBAAuB,GAAG;AAEnC,4BAAsB;AACtB,6BAAuB;AACvB,qBAAe;AACf,wBAAkB;AAAA,IACpB;AAGA,iBAAa;AACb,iBAAa,OAAO;AACpB,kBAAc;AACd,kBAAc;AACd,2BAAuB;AACvB,wBAAoB;AACpB,oBAAgB;AAGhB,gBAAY,CAAC;AACb,aAAS,CAAC;AACV,kBAAc;AACd,0BAAsB;AAGtB,oBAAgB,MAAM;AACtB,yBAAqB;AAErB,oBAAgB;AAEhB,WAAO;AAAA,EACT;AAEA,WAAS,YAAqB;AAE5B,QAAI,eAAe,KAAK,gBAAgB,OAAO,QAAQ;AACrD,cAAQ,MAAM,kCAAkC,YAAY,EAAE;AAC9D,iBAAW;AACX,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,OAAO,YAAY;AAGjC,QAAI,MAAM,UAAU,SAAS,GAAG;AAC9B,cAAQ,MAAM,mBAAmB,YAAY,6BAA6B;AAC1E,iBAAW;AACX,aAAO;AAAA,IACT;AAIA,0BAAsB,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,UAAU,MAAM;AACvE,OAAG;AACD,6BAAuB,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,UAAU,MAAM;AAAA,IAC1E,SAAS,yBAAyB;AAGlC,QAAI,aAAa;AACjB,aAAS,IAAI,GAAG,IAAI,MAAM,UAAU,QAAQ,KAAK;AAC/C,UAAI,MAAM,uBAAuB,MAAM,sBAAsB;AAC3D,qBAAa;AACb;AAAA,MACF;AAAA,IACF;AACA,UAAM,gBAAgB,MAAM,UAAU,UAAU;AAGhD,WAAO,cAAc,IAAI,KAAK,MAAM,cAAc,QAAQ,CAAC;AAC3D,WAAO,cAAc,IAAI;AACzB,YAAQ;AACR,YAAQ;AACR,eAAW;AAGX,wBAAoB;AACpB,uBAAmB;AAGnB,mBAAe;AACf,iBAAa;AACb,iBAAa,OAAO;AACpB,kBAAc;AACd,kBAAc;AACd,2BAAuB;AACvB,wBAAoB;AACpB,oBAAgB;AAGhB,gBAAY,CAAC;AACb,aAAS,CAAC;AACV,kBAAc;AACd,0BAAsB;AAGtB,oBAAgB,MAAM;AACtB,yBAAqB;AAErB,oBAAgB;AAEhB,WAAO;AAAA,EACT;AAGA,WAAS,SAAS;AAChB,QAAI,eAAe,EAAG;AAEtB,YAAQ,CAAC;AACT,mBAAe;AACf,oBAAgB;AAGhB,mBAAe,WAAW,MAAM,OAAO,GAAG,GAAG,YAAY,CAAC,QAAK,QAAG,CAAC;AAAA,EACrE;AAGA,QAAM,QAAQ,CAAC,GAAW,GAAW,OAAe,OAAe,UACjE,eAAe,WAAW,GAAG,GAAG,OAAO,OAAO,KAAK;AACrD,QAAM,WAAW,CAAC,GAAW,GAAW,cACtC,cAAc,WAAW,GAAG,GAAG,SAAS;AAC1C,QAAM,QAAQ,CAAC,GAAW,GAAW,MAAc,UACjD,SAAS,QAAQ,GAAG,GAAG,MAAM,KAAK;AACpC,QAAM,eAAe,CAAC,GAAW,GAAW,OAAgB,UAC1D,kBAAkB,WAAW,GAAG,GAAG,OAAO,KAAK;AACjD,QAAM,SAAS,CAAC,GAAW,QAAgB,cACzC,YAAY,WAAW,GAAG,QAAQ,SAAS;AAE7C,WAAS,uBAAuB,GAAW,GAAyD;AAClG,UAAM,QAAQ,OAAO,YAAY;AACjC,aAAS,IAAI,GAAG,IAAI,MAAM,UAAU,QAAQ,KAAK;AAC/C,YAAM,OAAO,MAAM,UAAU,CAAC;AAE9B,UAAI,KAAK,KAAK,KAAK,IAAI,KAAK,IAAI,KAAK,SACjC,KAAK,KAAK,IAAI,KAAK,KAAK,KAAK,GAAG;AAClC,eAAO,EAAE,UAAU,MAAM,OAAO,EAAE;AAAA,MACpC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,WAAS,oBAAoB,GAAoB;AAC/C,UAAM,QAAQ,OAAO,YAAY;AACjC,WAAO,KAAK,MAAM;AAAA,EACpB;AAEA,WAAS,iBAAiB;AACxB;AACA,UAAM,YAAY,KAAK,MAAM,gBAAgB,CAAC;AAC9C,UAAM,aAAa;AACnB,UAAM,SAAS,aAAa;AAC5B,aAAS;AAET,mBAAe;AAKf,kBAAc;AAGd,aAAS,YAAY,YAAY,GAAG;AAGpC,UAAM,KAAK;AACX,UAAM,KAAK;AACX,oBAAgB,MAAM,SAAS,KAAK,GAAG,KAAK,GAAG,GAAG,GAAG,EAAE;AACvD,oBAAgB,MAAM,SAAS,KAAK,GAAG,KAAK,GAAG,GAAG,GAAG,GAAG;AAGxD,UAAM,aAAa,GAAG,aAAa,GAAG,IAAI,MAAM,IAAI,YAAY;AAGhE,UAAM,MAAM,yBAAyB;AACrC,UAAM,aAAa,KAAK,MAAM,IAAI,SAAS,CAAC,GAAG,aAAa,GAAG,KAAK,YAAY;AAGhF,QAAI,cAAc;AAChB,UAAI,uBAAuB,KAAK,iBAAiB,GAAG;AAElD,uBAAe;AACf,8BAAsB;AAAA,MACxB,WAAW,uBAAuB,KAAK,iBAAiB,GAAG;AAEzD,uBAAe;AACf,8BAAsB;AAAA,MACxB;AAAA,IACF;AAGA,QAAI,qBAAqB,GAAG;AAC1B,YAAM,YAAY,GAAG,kBAAkB;AACvC,YAAM,aAAa,KAAK,MAAM,UAAU,SAAS,CAAC,GAAG,aAAa,GAAG,WAAW,YAAY;AAAA,IAC9F;AAGA,iBAAa,YAAY,UAAU;AAGnC,QAAI,sBAAsB,iBAAiB;AACzC,sBAAgB;AAChB,+BAAyB;AACzB,oBAAc;AAGd,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,cAAM,QAAQ,IAAI;AAClB,wBAAgB,MAAM;AACpB,cAAI,eAAe;AACjB,kBAAM,KAAK,IAAI,KAAK,OAAO,KAAK,cAAc;AAC9C,kBAAM,KAAK,IAAI,KAAK,OAAO,KAAK,eAAe;AAC/C,qBAAS,IAAI,IAAI,GAAG;AAAA,UACtB;AAAA,QACF,GAAG,KAAK;AAAA,MACV;AAEA,YAAM,cAAc,IAAI,GAAG,eAAe,IAAI,GAAG,8BAAoB,YAAY;AAAA,IACnF,OAAO;AAEL,4BAAsB;AACtB,6BAAuB;AACvB,wBAAkB;AAGlB,YAAM,cAAc,IAAI,GAAG,eAAe,GAAG,2BAAiB,YAAY;AAAA,IAC5E;AAAA,EACF;AAEA,WAAS,SAAS;AAChB,QAAI,CAAC,eAAe,YAAY,OAAQ;AAGxC,QAAI,eAAe;AAEjB,sBAAgB,SAAS;AACzB,mBAAa,MAAM;AAEnB,UAAI,yBAAyB,GAAG;AAC9B;AACA,YAAI,yBAAyB,MAAM,GAAG;AAEpC,gBAAM,SAAS,IAAI,KAAK,OAAO,KAAK,cAAc;AAClD,gBAAM,SAAS,IAAI,KAAK,OAAO,KAAK,eAAe;AACnD;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA,CAAC,YAAY,YAAY,YAAY,YAAY,UAAU,EAAE,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,CAAC;AAAA,YAC1F,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AAAA,UAC/B;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,QAAQ,eAAe,gBAAgB,kBAAkB,IAAI,OAAO,YAAY;AAGtF,QAAI,cAAc;AAChB,UAAI,uBAAuB,GAAG;AAE5B,gBAAQ,cAAc;AAAA,UACpB,KAAK;AACH,gBAAI,OAAO,MAAM,UAAU,CAAC,EAAE,IAAI,KAAK,QAAQ,GAAG;AAChD,6BAAe;AACf,oBAAM,MAAM,OAAO,GAAG,SAAS,YAAY;AAAA,YAC7C;AACA;AAAA,UACF,KAAK;AACH,gBAAI,KAAK,IAAI,KAAK,IAAI,KAAK;AACzB,6BAAe;AACf,oBAAM,MAAM,OAAO,GAAG,SAAS,YAAY;AAAA,YAC7C;AACA;AAAA,UACF,KAAK;AACH,gBAAI,OAAO,MAAM,UAAU,CAAC,EAAE,KAAK,OAAO,MAAM,UAAU,CAAC,EAAE,IAAI,MAAM,UAAU,CAAC,EAAE,OAAO;AACzF,6BAAe;AACf,oBAAM,MAAM,OAAO,GAAG,YAAY,YAAY;AAAA,YAChD;AACA;AAAA,UACF,KAAK;AACH;AACA,gBAAI,sBAAsB,IAAI;AAC5B,8BAAgB;AAChB,uCAAyB;AACzB,4BAAc;AACd,uBAAS,cAAc,GAAG,eAAe,GAAG,GAAG;AAAA,YACjD;AACA;AAAA,QACJ;AAAA,MACF,WAAW,uBAAuB,GAAG;AAEnC,gBAAQ,cAAc;AAAA,UACpB,KAAK;AACH,gBAAI,OAAO,MAAM,UAAU,CAAC,EAAE,IAAI,GAAG;AACnC,6BAAe;AACf,oBAAM,MAAM,OAAO,GAAG,OAAO,YAAY;AAAA,YAC3C;AACA;AAAA,UACF,KAAK;AACH,gBAAI,cAAc;AAChB,6BAAe;AACf,oBAAM,MAAM,OAAO,GAAG,WAAW,YAAY;AAAA,YAC/C;AACA;AAAA,UACF,KAAK;AACH;AAAA,UACF,KAAK;AACH,gBAAI,CAAC,eAAe;AAClB,8BAAgB;AAChB,uCAAyB;AACzB,4BAAc;AACd,uBAAS,cAAc,GAAG,eAAe,GAAG,GAAG;AAAA,YACjD;AACA;AAAA,QACJ;AAAA,MACF,WAAW,uBAAuB,GAAG;AAEnC,gBAAQ,cAAc;AAAA,UACpB,KAAK;AACH;AACA,gBAAI,sBAAsB,IAAI;AAC5B,6BAAe;AACf,oCAAsB;AAAA,YACxB;AACA;AAAA,UACF,KAAK;AACH,gBAAI,mBAAmB,oBAAoB,kBAAkB,GAAG;AAC9D,6BAAe;AACf,oBAAM,MAAM,OAAO,GAAG,SAAS,YAAY;AAAA,YAC7C;AACA;AAAA,UACF,KAAK;AACH,gBAAI,mBAAmB;AACrB,6BAAe;AACf,oBAAM,MAAM,OAAO,GAAG,SAAS,YAAY;AAAA,YAC7C;AACA;AAAA,UACF,KAAK;AACH;AAAA,UACF,KAAK;AACH,gBAAI,CAAC,eAAe;AAClB,8BAAgB;AAChB,uCAAyB;AACzB,4BAAc;AAEd,uBAAS,cAAc,GAAG,eAAe,GAAG,CAAC;AAC7C,uBAAS,cAAc,GAAG,eAAe,GAAG,GAAG;AAC/C,uBAAS,cAAc,IAAI,GAAG,eAAe,GAAG,GAAG;AAAA,YACrD;AACA;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAGA,QAAI,iBAAiB,GAAG;AACtB;AAEA,sBAAgB,WAAW,GAAG;AAC9B,mBAAa,MAAM;AACnB,UAAI,cAAc,EAAG;AAErB,UAAI,mBAAmB,GAAG;AACxB,mBAAW;AAAA,MACb;AACA;AAAA,IACF;AAGA,QAAI,oBAAoB,EAAG;AAC3B,QAAI,mBAAmB,EAAG;AAG1B,QAAI,sBAAsB,GAAG;AAC3B;AAGA,UAAI,cAAc;AAChB,uBAAe;AACf,sBAAc;AAAA,MAChB;AAGA,YAAM,WAAW,IAAK,sBAAsB;AAG5C,YAAM,YAAY,sBAAsB,KAAK,KAAK,sBAAsB,KAAK,IAAI;AACjF,UAAI,sBAAsB,cAAc,KAAK,cAAc;AAEzD,cAAM,SAAS,KAAK,uBAAuB;AAC3C,cAAM,SAAS,IAAI,WAAW;AAC9B,kBAAU,KAAK;AAAA,UACb,GAAG,aAAa,KAAK,IAAI,KAAK,IAAI;AAAA,UAClC,GAAG,aAAa;AAAA,UAChB,MAAM,CAAC,UAAK,UAAK,UAAK,QAAG,EAAE,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,CAAC;AAAA,UACxD,OAAO,WAAW,MAAM,eAAe;AAAA,UACvC,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,UACtB,IAAI,OAAO,WAAW;AAAA,UACtB,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC;AAAA,QACzC,CAAC;AAAA,MACH;AAGA,UAAI,wBAAwB,MAAM,cAAc;AAC9C,cAAM,aAAa,GAAG,aAAa,GAAG,eAAe,YAAY;AAAA,MACnE;AACA,UAAI,wBAAwB,MAAM,cAAc;AAC9C,cAAM,aAAa,GAAG,aAAa,GAAG,aAAa,YAAY;AAE/D,iBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,gBAAM,IAAK,KAAK,KAAK,IAAI,IAAK;AAC9B,oBAAU,KAAK;AAAA,YACb,GAAG,aAAa,KAAK,IAAI,CAAC,IAAI;AAAA,YAC9B,GAAG,aAAa,KAAK,IAAI,CAAC,IAAI;AAAA,YAC9B,MAAM;AAAA,YACN,OAAO;AAAA,YACP,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;AAAA,YACnB,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;AAAA,YACnB,MAAM;AAAA,UACR,CAAC;AAAA,QACH;AAAA,MACF;AAGA,UAAI,wBAAwB,KAAK,cAAc;AAC7C,uBAAe;AAAA,MACjB;AAAA,IACF;AAGA,QAAI,kBAAkB,GAAG;AACvB;AACA,UAAI,oBAAoB,GAAG;AAEzB,uBAAe;AACf,cAAM,cAAc,IAAI,GAAG,eAAe,GAAG,gBAAgB,YAAY;AAAA,MAC3E;AAAA,IACF;AAGA,QAAI,sBAAsB,GAAG;AAC3B,uBAAiB,IAAI;AACrB,UAAI,iBAAiB,GAAG;AACtB,mBAAW;AACX,cAAM,MAAM,OAAO,GAAG,YAAY,UAAU;AAC5C;AAAA,MACF;AAAA,IACF;AAGA,QAAI,eAAe,EAAG;AACtB,QAAI,gBAAgB,EAAG;AACvB,kBAAc,aAAa,KAAK;AAGhC,QAAI,mBAAmB,CAAC,mBAAmB;AACzC,0BAAoB,KAAK,IAAI,iBAAiB,oBAAoB,iBAAiB;AAAA,IACrF,WAAW,mBAAmB;AAC5B,0BAAoB,KAAK,IAAI,iBAAiB,oBAAoB,uBAAuB;AAAA,IAC3F,OAAO;AACL,0BAAoB,KAAK,IAAI,iBAAiB,oBAAoB,kBAAkB;AAAA,IACtF;AAGA,QAAI,WAAW;AACb,eAAS;AACT,iBAAW,KAAK,IAAI,KAAK,WAAW,CAAC;AAAA,IACvC;AACA,QAAI,YAAY;AACd,eAAS;AACT,iBAAW,KAAK,IAAI,IAAI,WAAW,CAAC;AAAA,IACtC;AAGA,QAAI,CAAC,aAAa,CAAC,YAAY;AAC7B,kBAAY;AAAA,IACd;AAGA,aAAS;AAGT,aAAS;AACT,aAAS;AAGT,YAAQ,KAAK,IAAI,CAAC,gBAAgB,KAAK,IAAI,gBAAgB,KAAK,CAAC;AACjE,YAAQ,KAAK,IAAI,CAAC,gBAAgB,KAAK,IAAI,gBAAgB,KAAK,CAAC;AAGjE,YAAQ;AACR,YAAQ;AAGR,WAAO,KAAK,IAAI,GAAG,KAAK,IAAI,cAAc,GAAG,IAAI,CAAC;AAClD,WAAO,KAAK,IAAI,GAAG,IAAI;AAGvB,UAAM,oBAAoB,uBAAuB,MAAM,OAAO,CAAC;AAC/D,QAAI,qBAAqB,QAAQ,GAAG;AAClC,YAAM,EAAE,UAAU,aAAa,OAAO,iBAAiB,IAAI;AAC3D,YAAM,iBAAiB;AACvB,aAAO,YAAY,IAAI;AACvB,cAAQ,CAAC,QAAQ;AAGjB,UAAI,iBAAiB,KAAK;AACxB,sBAAc,KAAK,IAAI,GAAG,KAAK,MAAM,iBAAiB,CAAC,CAAC;AACxD,cAAM,MAAM,OAAO,GAAG,KAAK,MAAM,iBAAiB,CAAC,GAAG,YAAY,CAAC,QAAK,QAAG,CAAC;AAAA,MAC9E;AAIA,UAAI,qBAAqB,uBAAuB,CAAC,gBAAgB,sBAAsB,GAAG;AACxF,uBAAe;AACf,qBAAa;AACb,qBAAa,OAAO;AACpB,sBAAc,QAAQ;AACtB,sBAAc,QAAQ;AACtB,+BAAuB;AACvB,cAAM,MAAM,OAAO,GAAG,GAAG,YAAY,CAAC,UAAK,QAAG,CAAC;AAC/C,cAAM,OAAO,GAAG,OAAO,GAAG,WAAW,YAAY;AAGjD,wBAAgB;AAChB,cAAM,cAAc,MAAM,UAAU,oBAAoB;AACxD,cAAM,QAAQ,YAAY,IAAI,KAAK,MAAM,YAAY,QAAQ,CAAC;AAC9D,cAAM,QAAQ,YAAY,IAAI;AAC9B,cAAM,QAAQ,GAAG,OAAO,cAAc,YAAY;AAClD,cAAM,OAAO,QAAQ,GAAG,GAAG,YAAY,CAAC,UAAK,UAAK,QAAG,CAAC;AAAA,MACxD;AAAA,IACF;AAGA,QAAI,oBAAoB,OAAO,CAAC,GAAG;AACjC,UAAI,mBAAmB,GAAG;AAExB,eAAO,MAAM,aAAa;AAC1B,gBAAQ;AACR,sBAAc;AACd,cAAM,MAAM,MAAM,WAAW,UAAU;AAAA,MACzC,OAAO;AAEL,yBAAiB;AACjB,sBAAc;AAEd,eAAO,MAAM,MAAM,YAAY,IAAI;AAEnC,cAAM,MAAM,MAAM,IAAI,YAAY,CAAC,UAAK,QAAK,UAAK,UAAK,KAAK,GAAG,CAAC;AAChE,cAAM,OAAO,GAAG,OAAO,GAAG,+BAAiB,YAAY;AACvD;AAAA,MACF;AAAA,IACF;AAGA,QAAI,cAAc;AAEhB,UAAI,uBAAuB,EAAG;AAG9B,qBAAe,UAAU;AAGzB,YAAM,KAAK,aAAa;AACxB,YAAM,KAAK,cAAc,OAAO;AAChC,YAAM,OAAO,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AAGxC,UAAI,OAAO,QAAQ,OAAO,mBAAmB;AAC3C,cAAM,KAAK,KAAK;AAChB,cAAM,KAAK,KAAK;AAChB,cAAM,UAAU,OAAO;AAGvB,uBAAe,KAAK,UAAU;AAC9B,uBAAe,KAAK,UAAU;AAG9B,iBAAS,KAAK,UAAU;AACxB,iBAAS,KAAK,UAAU;AAAA,MAC1B;AAGA,qBAAe;AACf,qBAAe;AAGf,oBAAc,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,WAAW,CAAC;AACnD,oBAAc,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,WAAW,CAAC;AAGnD,oBAAc;AACd,oBAAc;AAGd,mBAAa,KAAK,IAAI,GAAG,KAAK,IAAI,cAAc,GAAG,UAAU,CAAC;AAG9D,YAAM,qBAAqB,uBAAuB,YAAY,UAAU;AACxE,UAAI,sBAAsB,cAAc,GAAG;AACzC,cAAM,EAAE,UAAU,cAAc,OAAO,kBAAkB,IAAI;AAC7D,qBAAa,aAAa,IAAI;AAC9B,sBAAc,CAAC,cAAc;AAC7B,uBAAe;AAGf,YAAI,sBAAsB,wBAAwB,KAAK,IAAI,WAAW,IAAI,OAAO,wBAAwB,GAAG;AAE1G,gCAAsB;AACtB,gBAAM,YAAY,aAAa,GAAG,GAAG,cAAc,CAAC,UAAK,UAAK,QAAG,CAAC;AAClE,gBAAM,aAAa,GAAG,aAAa,GAAG,aAAa,YAAY;AAAA,QACjE;AAAA,MACF;AAGA,UAAI,oBAAoB,UAAU,KAAK,yBAAyB,GAAG;AACjE,uBAAe;AACf,yBAAiB;AACjB,sBAAc;AAEd,eAAO,YAAY,MAAM,YAAY,CAAC;AACtC,cAAM,aAAa,GAAG,aAAa,GAAG,qCAAuB,YAAY;AACzE;AAAA,MACF;AAAA,IACF;AAGA,oBAAgB,SAAS;AACzB,iBAAa,MAAM;AAGnB,QAAI,cAAc,EAAG;AAAA,EACvB;AAEA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,cAAU;AAEV,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AAGtB,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,MAAM,QAAQ,QAAQ,OAAI,QAAQ,UAAU,IAAI,OAAI,IAAI;AAC9D,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,gBAAU,QAAQ,OAAO,IAAI,KAAK,IAAI,GAAG,UAAU,IAAI,SAAS,CAAC,CAAC,IAAI,UAAU,GAAG,GAAG;AACtF,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAGA,kBAAc,KAAK,IAAI,OAAO,GAAG,EAAE;AACnC,mBAAe,KAAK,IAAI,OAAO,GAAG,EAAE;AAEpC,UAAM,WAAW,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,cAAc,KAAK,CAAC,CAAC;AACrE,UAAM,UAAU,kBAAkB,MAAM,eAAe,GAAG;AAAA,MACxD,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,QAAQ;AAAA,IACV,CAAC;AAGD,UAAM,SAAS,cAAc,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AACrE,UAAM,SAAS,cAAc,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI;AACjE,UAAM,cAAc,WAAW;AAC/B,UAAM,aAAa,UAAU;AAG7B,mBAAe,cAAc,KAAK;AAClC,UAAM,eAAe,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC7E,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI;AAE1D,QAAI,eAAe,oBAAoB,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,eAAe;AAElF,YAAM,YAAY;AAClB,YAAM,YAAY;AAClB,YAAM,SAAS,KAAK,OAAO,OAAO,UAAU,UAAU,CAAC;AACvD,YAAM,SAAS,KAAK,OAAO,OAAO,UAAU,UAAU,CAAC;AACvD,YAAM,OAAO,oBAAoB,KAAK,YAAY;AAClD,gBAAU,UAAU,MAAM,IAAI,IAAI,GAAG,UAAU,GAAG,SAAS;AAC3D,gBAAU,UAAU,MAAM,IAAI,IAAI,GAAG,UAAU,GAAG,SAAS;AAC3D,YAAM,eAAe,SAAI,OAAO,KAAK,KAAK,oBAAoB,EAAE,CAAC,IAAI,SAAI,OAAO,IAAI,KAAK,KAAK,oBAAoB,EAAE,CAAC;AACrH,YAAM,OAAO,KAAK,OAAO,OAAO,aAAa,UAAU,CAAC;AACxD,gBAAU,UAAU,IAAI,WAAW,UAAU,GAAG,YAAY;AAAA,IAC9D,OAAO;AAEL,gBAAU,UAAU,MAAM;AAC1B,UAAI,eAAe,MAAM,cAAc,IAAI;AACzC,kBAAU,WAAW,MAAM,CAAC,CAAC;AAC7B,kBAAU,UAAU,SAAS,CAAC,YAAY,MAAM,CAAC,CAAC;AAAA,MACpD,OAAO;AACL,kBAAU,GAAG,UAAU,UAAU,MAAM,CAAC,CAAC;AACzC,kBAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,MAC5D;AAEA,YAAM,YAAY,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC;AACzD,gBAAU,UAAU,SAAS,WAAW,UAAU,GAAG,QAAQ;AAAA,IAC/D;AAGA,cAAU,QAAQ,UAAU,IAAI,WAAW,IAAI,UAAU,SAAI,SAAI,OAAO,WAAW,CAAC;AACpF,aAAS,IAAI,GAAG,IAAI,cAAc,KAAK;AACrC,gBAAU,QAAQ,aAAa,IAAI,CAAC,IAAI,WAAW,IAAI,UAAU;AACjE,gBAAU,QAAQ,aAAa,IAAI,CAAC,IAAI,cAAc,cAAc,CAAC,IAAI,UAAU;AAAA,IACrF;AACA,cAAU,QAAQ,aAAa,eAAe,CAAC,IAAI,WAAW,IAAI,UAAU,SAAI,SAAI,OAAO,WAAW,CAAC;AAEvG,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,eAAe,WAAW,KAAK,MAAM,cAAc,CAAC,IAAI;AAC9D,YAAM,SAAS,UAAU,KAAK,MAAM,eAAe,CAAC,IAAI;AACxD,YAAM,YAAY,eAAe,KAAK,MAAM,SAAS,SAAS,CAAC;AAC/D,gBAAU,QAAQ,MAAM,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ;AAGrE,gBAAU,iBAAiB,kBAAkB,oBAAoB;AAAA,QAC/D,SAAS;AAAA,QACT,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,WAAW,eAAe,KAAK,MAAM,QAAQ,SAAS,CAAC;AAC7D,gBAAU,QAAQ,SAAS,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACzE,WAAW,CAAC,eAAe,mBAAmB;AAE5C,YAAM,cAAc,WAAW,KAAK,MAAM,cAAc,CAAC,IAAI;AAC7D,YAAM,aAAa,UAAU,KAAK,MAAM,eAAe,CAAC,IAAI;AAE5D,YAAM,YAAY;AAClB,YAAM,UAAU,cAAc,KAAK,MAAM,UAAU,SAAS,CAAC;AAC7D,gBAAU,QAAQ,UAAU,IAAI,OAAO,WAAW,UAAU,GAAG,SAAS;AAGxE,gBAAU,iBAAiB,mBAAmB,eAAe;AAAA,QAC3D,SAAS;AAAA,QACT,QAAQ,aAAa;AAAA,QACrB,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,WAAW,cAAc,KAAK,MAAM,QAAQ,SAAS,CAAC;AAC5D,gBAAU,QAAQ,aAAa,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAE3E,YAAM,OAAO;AACb,YAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,UAAU,CAAC;AACjD,gBAAU,QAAQ,aAAa,CAAC,IAAI,KAAK,aAAa,UAAU,GAAG,IAAI;AAAA,IACzE,WAAW,CAAC,aAAa;AAEvB,YAAM,WAAW;AACjB,YAAM,SAAS,WAAW,KAAK,OAAO,cAAc,SAAS,UAAU,CAAC,IAAI;AAC5E,YAAM,SAAS,UAAU,KAAK,MAAM,eAAe,CAAC;AACpD,gBAAU,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ;AAElE,YAAM,WAAW;AACjB,YAAM,QAAQ,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC;AACrD,gBAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ;AAErE,YAAM,OAAO;AACb,YAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,UAAU,CAAC;AACjD,gBAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,aAAa,UAAU,GAAG,IAAI;AAAA,IACrE,WAAW,eAAe;AACxB,YAAM,OAAO,UAAU,KAAK,MAAM,eAAe,CAAC,IAAI;AAEtD,UAAI,cAAc;AAChB,cAAM,WAAW,gBAAgB,kBAAkB;AACnD,cAAM,eAAe,sBAAsB,gBAAgB,SAAS;AAEpE,YAAI,cAAc;AAEhB,gBAAM,cAAc;AACpB,gBAAM,OAAO,WAAW,KAAK,OAAO,cAAc,YAAY,UAAU,CAAC,IAAI;AAC7E,oBAAU,QAAQ,IAAI,IAAI,IAAI,cAAc,WAAW;AAEvD,gBAAM,cAAc;AACpB,gBAAM,YAAY,WAAW,KAAK,OAAO,cAAc,YAAY,UAAU,CAAC,IAAI;AAClF,oBAAU,QAAQ,OAAO,CAAC,IAAI,SAAS,IAAI,UAAU,GAAG,WAAW;AAEnE,gBAAM,cAAc;AACpB,gBAAM,YAAY,WAAW,KAAK,OAAO,cAAc,YAAY,UAAU,CAAC,IAAI;AAClF,oBAAU,QAAQ,OAAO,CAAC,IAAI,SAAS,WAAW,UAAU,GAAG,WAAW;AAE1E,gBAAM,WAAW;AACjB,gBAAM,QAAQ,WAAW,KAAK,OAAO,cAAc,SAAS,UAAU,CAAC,IAAI;AAC3E,oBAAU,QAAQ,OAAO,CAAC,IAAI,KAAK,IAAI,UAAU,GAAG,QAAQ;AAAA,QAC9D,OAAO;AAEL,gBAAM,cAAc,UAAK,SAAS,IAAI;AACtC,gBAAM,OAAO,WAAW,KAAK,OAAO,cAAc,YAAY,UAAU,CAAC,IAAI;AAC7E,oBAAU,QAAQ,IAAI,IAAI,IAAI,cAAc,WAAW;AAEvD,gBAAM,gBAAgB,gBAAgB,qBAAqB,CAAC,GAAG,QAAQ;AACvE,gBAAM,gBAAgB,SAAS,aAAa;AAC5C,gBAAM,cAAc,WAAW,KAAK,OAAO,cAAc,cAAc,UAAU,CAAC,IAAI;AACtF,oBAAU,QAAQ,OAAO,CAAC,IAAI,WAAW,IAAI,UAAU,GAAG,aAAa;AAEvE,gBAAM,cAAc,UAAU,qBAAqB,CAAC,OAAO,gBAAgB,MAAM;AACjF,gBAAM,YAAY,WAAW,KAAK,OAAO,cAAc,YAAY,UAAU,CAAC,IAAI;AAClF,oBAAU,QAAQ,OAAO,CAAC,IAAI,SAAS,WAAW,UAAU,GAAG,WAAW;AAE1E,gBAAM,WAAW;AACjB,gBAAM,QAAQ,WAAW,KAAK,OAAO,cAAc,SAAS,UAAU,CAAC,IAAI;AAC3E,oBAAU,QAAQ,OAAO,CAAC,IAAI,KAAK,IAAI,UAAU,GAAG,QAAQ;AAAA,QAC9D;AAAA,MACF,OAAO;AAEL,cAAM,QAAQ,OAAO,YAAY;AACjC,cAAM,YAAY,gBAAgB,MAAM;AACxC,cAAM,QAAQ,iBAAiB,MAAM,UAAU,IAAI,YAAY,MAAM,IAAI;AAEzE,cAAM,cAAc;AACpB,cAAM,OAAO,WAAW,KAAK,OAAO,cAAc,YAAY,UAAU,CAAC,IAAI;AAC7E,kBAAU,QAAQ,IAAI,IAAI,IAAI,cAAc,WAAW;AAEvD,cAAM,WAAW,UAAU,KAAK;AAChC,cAAM,SAAS,WAAW,KAAK,OAAO,cAAc,SAAS,UAAU,CAAC,IAAI;AAC5E,kBAAU,QAAQ,OAAO,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,QAAQ;AAE7D,cAAM,cAAc,SAAI,OAAO,KAAK,IAAI,SAAI,OAAO,IAAI,KAAK;AAC5D,cAAM,QAAQ,WAAW,KAAK,OAAO,cAAc,YAAY,UAAU,CAAC,IAAI;AAC9E,kBAAU,QAAQ,OAAO,CAAC,IAAI,KAAK,cAAc,WAAW;AAE5D,cAAM,WAAW,eAAe,OAAO,SAAS,IAAI,gCAAgC;AACpF,cAAM,QAAQ,WAAW,KAAK,OAAO,cAAc,SAAS,UAAU,CAAC,IAAI;AAC3E,kBAAU,QAAQ,OAAO,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ;AAAA,MACrE;AAAA,IACF,WAAW,UAAU;AACnB,YAAM,UAAU;AAChB,YAAM,QAAQ,WAAW,KAAK,OAAO,cAAc,QAAQ,UAAU,CAAC,IAAI;AAC1E,YAAM,QAAQ,UAAU,KAAK,MAAM,eAAe,CAAC,IAAI;AACvD,gBAAU,QAAQ,KAAK,IAAI,KAAK,cAAc,OAAO;AAErD,YAAM,WAAW,UAAU,KAAK;AAChC,YAAM,SAAS,WAAW,KAAK,OAAO,cAAc,SAAS,UAAU,CAAC,IAAI;AAC5E,gBAAU,QAAQ,QAAQ,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,QAAQ;AAE9D,YAAM,UAAU;AAChB,YAAM,WAAW,WAAW,KAAK,OAAO,cAAc,QAAQ,UAAU,CAAC,IAAI;AAC7E,gBAAU,QAAQ,QAAQ,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACxE,OAAO;AACL,YAAM,QAAQ,OAAO,YAAY;AAGjC,eAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AAEpC,cAAM,cAAc,IAAI,eAAe,MAAM,IAAI,WAAM;AACvD,kBAAU,QAAQ,aAAa,IAAI,MAAM,UAAU,IAAI,cAAc,IAAI,CAAC,YAAY,UAAU;AAEhG,iBAAS,KAAK,MAAM,aAAa,GAAG,KAAK,cAAc,MAAM;AAC3D,gBAAM,aAAa,IAAI,KAAK,eAAe,MAAM,IAAI,WAAM;AAC3D,gBAAM,aAAa,OAAO,MAAM,aAAa,IAAI,aAAa;AAC9D,oBAAU,QAAQ,aAAa,IAAI,EAAE,IAAI,cAAc,IAAI,CAAC,IAAI,UAAU,GAAG,SAAS;AAAA,QACxF;AAAA,MACF;AAGA,eAAS,YAAY,GAAG,YAAY,MAAM,UAAU,QAAQ,aAAa;AACvE,cAAM,OAAO,MAAM,UAAU,SAAS;AACtC,cAAM,kBAAkB,cAAc;AACtC,cAAM,mBAAmB,cAAc;AAGvC,cAAM,YAAY;AAGlB,iBAAS,KAAK,GAAG,KAAK,KAAK,OAAO,MAAM;AACtC,gBAAM,UAAU,KAAK,IAAI;AACzB,gBAAM,UAAU,KAAK;AACrB,cAAI,WAAW,KAAK,UAAU,eAAe,WAAW,KAAK,UAAU,cAAc;AACnF,sBAAU,QAAQ,aAAa,IAAI,OAAO,IAAI,cAAc,IAAI,OAAO,IAAI,SAAS;AAEpF,gBAAI,UAAU,IAAI,gBAAgB,UAAU,IAAI,MAAM,YAAY;AAChE,wBAAU,QAAQ,aAAa,IAAI,OAAO,IAAI,cAAc,IAAI,OAAO,IAAI,SAAS;AAAA,YACtF;AAAA,UACF;AAAA,QACF;AAGA,cAAM,YAAY;AAClB,cAAM,QAAQ,KAAK,IAAI,KAAK,MAAM,KAAK,QAAQ,CAAC,IAAI,KAAK,MAAM,YAAY,CAAC;AAC5E,cAAM,SAAS,KAAK,IAAI;AACxB,cAAM,SAAS,KAAK,IAAI;AACxB,cAAM,SAAS,KAAK,IAAI;AAGxB,cAAM,YAAY,yBAAyB;AAG3C,cAAM,WAAW;AACjB,YAAI,SAAS,KAAK,QAAQ,YAAY,IAAI,eAAe,UAAU,KAAK,SAAS,cAAc;AAC7F,oBAAU,QAAQ,aAAa,IAAI,MAAM,IAAI,cAAc,IAAI,KAAK,IAAI,SAAS,GAAG,QAAQ;AAAA,QAC9F;AACA,YAAI,SAAS,KAAK,QAAQ,YAAY,IAAI,eAAe,UAAU,KAAK,SAAS,cAAc;AAC7F,oBAAU,QAAQ,aAAa,IAAI,MAAM,IAAI,cAAc,IAAI,KAAK,IAAI,SAAS,GAAG,QAAQ;AAAA,QAC9F;AACA,YAAI,SAAS,KAAK,QAAQ,YAAY,IAAI,eAAe,UAAU,KAAK,SAAS,cAAc;AAC7F,oBAAU,QAAQ,aAAa,IAAI,MAAM,IAAI,cAAc,IAAI,KAAK,IAAI,SAAS,GAAG,QAAQ;AAAA,QAC9F;AAGA,YAAI,mBAAmB,CAAC,cAAc;AACpC,gBAAM,WAAW,QAAQ,KAAK,MAAM,YAAY,CAAC;AACjD,gBAAM,WAAW,KAAK,IAAI;AAC1B,cAAI,YAAY,KAAK,WAAW,eAAe,YAAY,KAAK,WAAW,cAAc;AACvF,kBAAM,UAAU,gBAAgB,KAAK,gBAAgB,IAAI,IAAI,WAAM;AACnE,sBAAU,QAAQ,aAAa,IAAI,QAAQ,IAAI,cAAc,IAAI,QAAQ,cAAc,OAAO;AAAA,UAChG;AAAA,QACF;AAGA,YAAI,oBAAoB,cAAc;AACpC,gBAAM,UAAU,QAAQ,KAAK,MAAM,YAAY,CAAC;AAChD,gBAAM,UAAU,SAAS;AACzB,cAAI,WAAW,KAAK,UAAU,eAAe,WAAW,KAAK,UAAU,cAAc;AACnF,kBAAM,SAAS,gBAAgB,KAAK,gBAAgB,IAAI,IAAI,WAAM;AAClE,sBAAU,QAAQ,aAAa,IAAI,OAAO,IAAI,cAAc,IAAI,OAAO,cAAc,MAAM;AAAA,UAC7F;AAAA,QACF;AAAA,MACF;AAGA,UAAI,gBAAgB,EAAG;AAGvB,UAAI,cAAc;AAChB,cAAM,KAAK,aAAa;AACxB,cAAM,KAAK,cAAc,OAAO;AAChC,cAAM,OAAO,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AACxC,cAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC;AAE1C,iBAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,gBAAM,IAAI,IAAI;AACd,gBAAM,KAAK,KAAK,MAAM,OAAO,KAAK,CAAC;AACnC,gBAAM,KAAK,KAAK,MAAO,OAAO,IAAK,KAAK,CAAC;AACzC,cAAI,MAAM,KAAK,KAAK,eAAe,MAAM,KAAK,KAAK,cAAc;AAC/D,sBAAU,QAAQ,aAAa,IAAI,EAAE,IAAI,cAAc,IAAI,EAAE,WAAW,UAAU;AAAA,UACpF;AAAA,QACF;AAGA,cAAM,WAAW,KAAK,MAAM,UAAU;AACtC,cAAM,WAAW,KAAK,MAAM,UAAU;AACtC,YAAI,YAAY,KAAK,WAAW,eAAe,YAAY,KAAK,WAAW,cAAc;AACvF,oBAAU,QAAQ,aAAa,IAAI,QAAQ,IAAI,cAAc,IAAI,QAAQ;AAAA,QAC3E;AAAA,MACF;AAGA,YAAM,aAAa,KAAK,MAAM,IAAI;AAClC,YAAM,aAAa,KAAK,MAAM,IAAI;AAClC,UAAI,cAAc,KAAK,aAAa,cAAc,KAAK,cAAc,KAAK,aAAa,eAAe,GAAG;AAEvG,cAAM,aAAa,mBAAmB,KAAK,KAAK,MAAM,mBAAmB,CAAC,IAAI,MAAM;AACpF,cAAM,YAAY,aAAa,YAAY,aAAa,YAAY;AAGpE,cAAM,cAAc,CAAC,iBAAO,QAAQ,iBAAO,MAAM;AACjD,cAAM,QAAQ,YAAY,KAAK,MAAM,aAAa,GAAG,IAAI,YAAY,MAAM;AAC3E,kBAAU,QAAQ,aAAa,IAAI,UAAU,IAAI,cAAc,UAAU,IAAI,SAAS,GAAG,KAAK;AAG9F,YAAI;AACJ,YAAI,gBAAgB,GAAG;AACrB,iBAAO;AAAA,QACT,WAAW,WAAW,IAAI;AACxB,iBAAO;AAAA,QACT,WAAW,WAAW,GAAG;AACvB,iBAAO;AAAA,QACT,OAAO;AACL,iBAAO;AAAA,QACT;AACA,kBAAU,QAAQ,aAAa,IAAI,UAAU,IAAI,cAAc,UAAU,IAAI,SAAS,GAAG,IAAI;AAG7F,kBAAU,QAAQ,aAAa,IAAI,UAAU,IAAI,cAAc,UAAU,IAAI,SAAS;AAAA,MACxF;AAGA,iBAAW,KAAK,WAAW;AACzB,cAAM,KAAK,KAAK,MAAM,EAAE,CAAC;AACzB,cAAM,KAAK,KAAK,MAAM,EAAE,CAAC;AACzB,YAAI,MAAM,KAAK,KAAK,eAAe,MAAM,KAAK,KAAK,cAAc;AAC/D,gBAAM,QAAQ,EAAE,OAAO,IAAI,KAAK;AAChC,oBAAU,QAAQ,aAAa,IAAI,EAAE,IAAI,cAAc,IAAI,EAAE,IAAI,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,QAC3F;AAAA,MACF;AAGA,iBAAWC,UAAS,QAAQ;AAC1B,cAAM,KAAK,KAAK,MAAMA,OAAM,CAAC;AAC7B,cAAM,KAAK,KAAK,MAAMA,OAAM,CAAC;AAC7B,YAAI,MAAM,KAAK,KAAK,cAAcA,OAAM,KAAK,UAAU,MAAM,KAAK,KAAK,cAAc;AACnF,gBAAM,QAAQA,OAAM,SAAS,KAAK,YAAY;AAC9C,oBAAU,QAAQ,aAAa,IAAI,EAAE,IAAI,cAAc,IAAI,EAAE,IAAI,KAAK,GAAGA,OAAM,KAAK,GAAGA,OAAM,IAAI;AAAA,QACnG;AAAA,MACF;AAGA,UAAI,gBAAgB,CAAC,eAAe;AAClC,cAAM,eAAe,KAAK,MAAM,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,IAAI,YAAY;AAC1E,YAAI,eAAe;AAEnB,YAAI,uBAAuB,GAAG;AAC5B,kBAAQ,cAAc;AAAA,YACpB,KAAK;AAAG,6BAAe;AAAuB;AAAA,YAC9C,KAAK;AAAG,6BAAe;AAAwB;AAAA,YAC/C,KAAK;AAAG,6BAAe;AAA6B;AAAA,UACtD;AAAA,QACF,WAAW,uBAAuB,GAAG;AACnC,kBAAQ,cAAc;AAAA,YACpB,KAAK;AAAG,6BAAe;AAAiB;AAAA,YACxC,KAAK;AAAG,6BAAe;AAA6B;AAAA,YACpD,KAAK;AAAG,6BAAe;AAA4B;AAAA,UACrD;AAAA,QACF,WAAW,uBAAuB,GAAG;AACnC,kBAAQ,cAAc;AAAA,YACpB,KAAK;AAAG,6BAAe;AAAqB;AAAA,YAC5C,KAAK;AAAG,6BAAe;AAA0B;AAAA,YACjD,KAAK;AAAG,6BAAe;AAA0B;AAAA,YACjD,KAAK;AAAG,6BAAe;AAAgC;AAAA,UACzD;AAAA,QACF;AAEA,YAAI,cAAc;AAChB,gBAAM,UAAU,cAAc,KAAK,OAAO,cAAc,aAAa,UAAU,CAAC,IAAI;AACpF,gBAAM,UAAU,aAAa;AAE7B,gBAAM,QAAQ,SAAI,OAAO,aAAa,SAAS,CAAC;AAChD,oBAAU,QAAQ,UAAU,CAAC,IAAI,UAAU,CAAC,WAAW,UAAU,GAAG,KAAK;AACzE,oBAAU,QAAQ,OAAO,IAAI,OAAO,IAAI,YAAY,aAAa,YAAY;AAC7E,oBAAU,QAAQ,UAAU,CAAC,IAAI,UAAU,CAAC,WAAW,UAAU,GAAG,KAAK;AAAA,QAC3E;AAAA,MACF;AAAA,IACF;AAGA,QAAI,eAAe,CAAC,iBAAiB,CAAC,YAAY,CAAC,QAAQ;AACzD,YAAM,QAAQ,eAAe,gBAAgB,kBAAkB,IAAI,OAAO,YAAY;AACtF,YAAM,OAAO,aAAa,eAAe;AAEzC,UAAI,cAAc;AAEhB,cAAM,gBAAgB,sBAAO,MAAM,IAAI,KAAK,qBAAqB,CAAC;AAClE,cAAMC,UAAS,WAAW,KAAK,OAAO,cAAc,cAAc,UAAU,CAAC,IAAI;AACjF,kBAAU,QAAQ,IAAI,IAAIA,OAAM,cAAc,aAAa;AAG3D,cAAM,eAAe,KAAK,MAAM,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,IAAI,YAAY;AAE1E,YAAI,eAAe;AACnB,YAAI,uBAAuB,GAAG;AAE5B,kBAAQ,cAAc;AAAA,YACpB,KAAK;AACH,6BAAe;AACf;AAAA,YACF,KAAK;AACH,6BAAe;AACf;AAAA,YACF,KAAK;AACH,6BAAe;AACf;AAAA,YACF,KAAK;AACH,6BAAe;AACf;AAAA,UACJ;AAAA,QACF,WAAW,uBAAuB,GAAG;AAEnC,kBAAQ,cAAc;AAAA,YACpB,KAAK;AACH,6BAAe;AACf;AAAA,YACF,KAAK;AACH,6BAAe;AACf;AAAA,YACF,KAAK;AACH,6BAAe;AACf;AAAA,YACF,KAAK;AACH,6BAAe;AACf;AAAA,UACJ;AAAA,QACF,WAAW,uBAAuB,GAAG;AAEnC,kBAAQ,cAAc;AAAA,YACpB,KAAK;AACH,6BAAe;AACf;AAAA,YACF,KAAK;AACH,6BAAe;AACf;AAAA,YACF,KAAK;AACH,6BAAe;AACf;AAAA,YACF,KAAK;AACH,6BAAe;AACf;AAAA,YACF,KAAK;AACH,6BAAe;AACf;AAAA,UACJ;AAAA,QACF;AACA,cAAM,QAAQ,WAAW,KAAK,OAAO,cAAc,aAAa,UAAU,CAAC,IAAI;AAC/E,kBAAU,QAAQ,OAAO,CAAC,IAAI,KAAK,IAAI,YAAY,GAAG,UAAU,GAAG,YAAY;AAG/E,cAAM,WAAW,uBAAuB,IAAI,IAAI;AAChD,cAAM,WAAW,QAAQ,KAAK,IAAI,eAAe,GAAG,QAAQ,CAAC,IAAI,QAAQ;AACzE,cAAM,YAAY,WAAW,KAAK,OAAO,cAAc,SAAS,UAAU,CAAC,IAAI;AAC/E,kBAAU,QAAQ,OAAO,CAAC,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ;AAAA,MACzE,OAAO;AAGL,cAAM,YAAY,OAAO,eAAe,CAAC,KAAK,MAAM,IAAI;AACxD,kBAAU,QAAQ,IAAI,IAAI,WAAW,CAAC,IAAI,UAAU,GAAG,SAAS;AAEhE,cAAM,YAAY,gBAAgB,KAAK,aAAa,gBAAgB,KAAK,aAAa;AACtF,cAAM,cAAc,SAAS,KAAK,KAAK,aAAa,CAAC;AACrD,kBAAU,QAAQ,IAAI,IAAI,WAAW,cAAc,YAAY,SAAS,CAAC,IAAI,SAAS,GAAG,WAAW;AAGpG,cAAM,iBAAiB,eAAe,kBAAkB,IAAI,eAAe,eAAe,KAAK;AAC/F,cAAM,YAAY,WAAW,KAAK,OAAO,cAAc,eAAe,UAAU,CAAC,IAAI;AACrF,kBAAU,QAAQ,OAAO,CAAC,IAAI,SAAS,IAAI,UAAU,GAAG,cAAc;AAGtE,YAAI,OAAO;AACX,YAAI,CAAC,cAAc;AACjB,iBAAO;AAAA,QACT,OAAO;AACL,iBAAO;AAAA,QACT;AACA,cAAM,QAAQ,WAAW,KAAK,OAAO,cAAc,KAAK,UAAU,CAAC,IAAI;AACvE,kBAAU,QAAQ,OAAO,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,IAAI;AAAA,MACjE;AAAA,IACF;AAGA,QAAI,CAAC,eAAe,UAAU,YAAY,eAAe;AACvD,YAAM,WAAW;AACjB,YAAM,QAAQ,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC;AACrD,gBAAU,QAAQ,OAAO,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ;AAAA,IACrE;AAEA,aAAS,MAAM,MAAM;AAAA,EACvB;AAGA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,aAAS;AACT,kBAAc;AAEd,qBAAiB,YAAY,MAAM;AACjC,UAAI,CAAC,SAAS;AACZ,sBAAc,cAAe;AAC7B;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,mBAAe,YAAY,MAAM;AAC/B,UAAI,CAAC,SAAS;AACZ,sBAAc,YAAa;AAC3B;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,qBAAiB,CAAC,MAAqB;AACrC,UAAI,CAAC,WAAW,CAAC,eAAe,UAAU,YAAY,cAAe;AAErE,cAAQ,EAAE,KAAK;AAAA,QACb,KAAK;AAAA,QACL,KAAK;AACH,sBAAY;AACZ;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,uBAAa;AACb;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,iBAAO;AACP;AAAA,QACF,KAAK;AACH,4BAAkB;AAClB;AAAA,QACF,KAAK;AACH,8BAAoB;AACpB;AAAA,MACJ;AAAA,IACF;AAEA,mBAAe,CAAC,MAAqB;AACnC,cAAQ,EAAE,KAAK;AAAA,QACb,KAAK;AAAA,QACL,KAAK;AACH,sBAAY;AACZ;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,uBAAa;AACb;AAAA,QACF,KAAK;AACH,4BAAkB;AAClB;AAAA,QACF,KAAK;AACH,8BAAoB;AACpB;AAAA,MACJ;AAAA,IACF;AAEA,WAAO,iBAAiB,WAAW,cAAc;AACjD,WAAO,iBAAiB,SAAS,YAAY;AAC7C,2BAAuB;AAEvB,kBAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AAC7C,UAAI,CAAC,SAAS;AACZ,qBAAa,QAAQ;AACrB;AAAA,MACF;AAEA,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS,IAAI,YAAY;AAGrC,UAAI,QAAQ,UAAU;AACpB,iBAAS,CAAC;AACV,YAAI,OAAQ,sBAAqB;AACjC;AAAA,MACF;AAGA,UAAI,QAAQ,KAAK;AACf,YAAI,UAAU,YAAY,CAAC,eAAe,eAAe;AACvD,kBAAQ;AACR,2BAAiB,QAAQ;AACzB;AAAA,QACF;AAAA,MACF;AAGA,UAAI,CAAC,eAAe,qBAAqB,CAAC,QAAQ;AAEhD,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,kBAAkB;AAAA,UAClB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,eAAe;AAClC,0BAAgB;AAChB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,8BAAoB;AACpB,cAAI,kBAAkB,GAAG;AACvB,yBAAa;AAAA,UACf,OAAO;AACL,qBAAS;AAAA,UACX;AACA,wBAAc;AACd;AAAA,QACF;AAGA,YAAI,QAAQ,KAAK;AACf,8BAAoB;AACpB,uBAAa;AACb,wBAAc;AACd;AAAA,QACF;AACA,YAAI,QAAQ,KAAK;AACf,8BAAoB;AACpB,mBAAS;AACT,wBAAc;AACd;AAAA,QACF;AACA;AAAA,MACF;AAGA,UAAI,CAAC,eAAe,CAAC,QAAQ;AAC3B,4BAAoB;AACpB,iBAAS;AACT,sBAAc;AACd;AAAA,MACF;AAGA,UAAI,eAAe;AACjB,YAAI,SAAS,QAAQ,KAAK;AACxB,cAAI,cAAc;AAEhB,gBAAI,qBAAqB,gBAAgB,SAAS,GAAG;AAEnD;AACA,gCAAkB;AAClB,8BAAgB;AAAA,YAClB,OAAO;AAEL,6BAAe;AACf,uBAAS;AACT,8BAAgB;AAAA,YAClB;AAAA,UACF,WAAW,eAAe,OAAO,SAAS,GAAG;AAC3C;AACA,sBAAU;AACV,4BAAgB;AAAA,UAClB;AAAA,QACF,WAAW,QAAQ,KAAK;AACtB,cAAI,cAAc;AAChB,yBAAa;AAAA,UACf,OAAO;AACL,qBAAS;AAAA,UACX;AACA,wBAAc;AAAA,QAChB;AACA;AAAA,MACF;AAGA,UAAI,UAAU;AACZ,YAAI,QAAQ,KAAK;AACf,oBAAU;AACV,wBAAc;AACd,qBAAW;AAAA,QACb;AACA;AAAA,MACF;AAGA,UAAI,QAAQ;AAEV,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AACH,uBAAS;AACT;AAAA,YACF,KAAK;AACH,wBAAU;AACV,4BAAc;AACd,uBAAS;AACT;AAAA,YACF,KAAK;AACH,sBAAQ;AACR,+BAAiB,QAAQ;AACzB;AAAA,YACF,KAAK;AACH,sBAAQ;AACR,gCAAkB,QAAQ;AAC1B;AAAA,YACF,KAAK;AACH,sBAAQ;AACR,iCAAmB,QAAQ;AAC3B;AAAA,UACJ;AACA;AAAA,QACF;AAGA,YAAI,QAAQ,KAAK;AACf,oBAAU;AACV,wBAAc;AACd,mBAAS;AAAA,QACX,WAAW,QAAQ,KAAK;AACtB,kBAAQ;AACR,4BAAkB,QAAQ;AAAA,QAC5B,WAAW,QAAQ,KAAK;AACtB,kBAAQ;AACR,6BAAmB,QAAQ;AAAA,QAC7B;AACA;AAAA,MACF;AAGA,UAAI,SAAS,QAAQ,aAAa,QAAQ,KAAK;AAC7C,eAAO;AAAA,MACT;AAEA,UAAI,SAAS,QAAQ,eAAe,QAAQ,KAAK;AAC/C,iBAAS;AACT,mBAAW,KAAK,IAAI,KAAK,WAAW,CAAC;AAAA,MACvC;AACA,UAAI,SAAS,QAAQ,gBAAgB,QAAQ,KAAK;AAChD,iBAAS;AACT,mBAAW,KAAK,IAAI,IAAI,WAAW,CAAC;AAAA,MACtC;AAEA,UAAI,SAAS,QAAQ,KAAK;AACxB,0BAAkB;AAAA,MACpB;AAAA,IACF,CAAC;AAAA,EACH,GAAG,EAAE;AAEL,SAAO;AACT;;;ACnsDA,IAAM,yBAA2C;AAAA,EAC/C,EAAE,OAAO,UAAU,UAAU,MAAM;AAAA,EACnC,EAAE,OAAO,WAAW,UAAU,IAAI;AAAA,EAClC,EAAE,OAAO,QAAQ,UAAU,IAAI;AAAA,EAC/B,EAAE,OAAO,QAAQ,UAAU,IAAI;AAAA,EAC/B,EAAE,OAAO,cAAc,UAAU,IAAI;AAAA,EACrC,EAAE,OAAO,aAAa,UAAU,IAAI;AACtC;AAWA,IAAM,YAAY;AAAA;AAAA,EAEhB;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAE/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAE/D;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAC5D;AAAA,EAAS;AAAA,EAAW;AAAA,EAAS;AAAA,EAAS;AAAA,EAAU;AAAA,EAAU;AAC5D,EAAE,OAAO,OAAK,EAAE,WAAW,CAAC;AAG5B,IAAM,eAAe;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,WAAW;AAAA,EACf;AAAA,EAAiB;AAAA,EAAa;AAAA,EAAe;AAAA,EAC7C;AAAA,EAAiB;AAAA,EAAiB;AAAA,EAAgB;AACpD;AAGA,IAAM,eAAe;AAAA,EACnB,SAAS;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAyBO,SAAS,aAAa,UAAqC;AAChE,QAAM,aAAa,qBAAqB;AAGxC,QAAM,WAAW;AACjB,QAAM,WAAW;AAEjB,MAAI,OAAO,SAAS;AACpB,MAAI,OAAO,SAAS;AAEpB,QAAM,mBAAmB,MAAM;AAC7B,WAAO,SAAS;AAChB,WAAO,SAAS;AAAA,EAClB;AAEA,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,MAAM;AACV,MAAI,SAAS;AACb,MAAI,qBAAqB;AACzB,MAAI,WAAW;AAGf,MAAI,eAAe;AACnB,QAAM,cAAc;AACpB,MAAI,iBAAiB;AACrB,MAAI,UAAoB,CAAC;AACzB,MAAI,eAAe;AACnB,MAAI,aAAa;AACjB,MAAI,WAAW;AACf,MAAI,WAAW,KAAK,IAAI;AAGxB,MAAI,cAAc;AAClB,MAAI,cAAwB,CAAC;AAC7B,MAAI,aAAa;AACjB,MAAI,WAAW;AACf,MAAI,YAAY;AAChB,MAAI,gBAAgB;AACpB,MAAI,aAAa,EAAE,KAAK,GAAG,KAAK,EAAE;AAGlC,MAAI,YAAwB,CAAC;AAC7B,MAAI,cAA4B,CAAC;AACjC,MAAI,cAAc;AAClB,MAAI,iBAAiB;AACrB,MAAI,cAAc;AAClB,MAAI,eAAe;AACnB,MAAI,aAAa;AACjB,MAAI,mBAAmB;AAGvB,WAAS,qBAA2B;AAClC,iBAAa;AAAA,MACX,MAAM,KAAK,OAAO,IAAI,MAAM,IAAI,QAAQ,CAAC;AAAA,MACzC,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,QAAQ,CAAC;AAAA,IAC5C;AAAA,EACF;AAGA,WAASC,gBACP,GACA,GACA,OACA,OACA,QAAkB,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG,GAC9C;AACN,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,KAAK,KAAK,OAAO,IAAI,OAAO;AAAA,QAC5B,KAAK,KAAK,OAAO,IAAI,OAAO;AAAA,QAC5B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF;AAGA,WAAS,cAAc,GAAW,GAAW,MAAc,OAAqB;AAC9E,gBAAY,KAAK,EAAE,GAAG,GAAG,MAAM,QAAQ,IAAI,MAAM,CAAC;AAAA,EACpD;AAEA,QAAM,aAA8B;AAAA,IAClC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IAEZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAEA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAEA,WAAS,eAAuB;AAC9B,WAAO,UAAU,KAAK,MAAM,KAAK,OAAO,IAAI,UAAU,MAAM,CAAC;AAAA,EAC/D;AAEA,WAAS,aAAmB;AAC1B,iBAAa,aAAa,KAAK,MAAM,KAAK,OAAO,IAAI,aAAa,MAAM,CAAC;AACzE,eAAW,SAAS,KAAK,MAAM,KAAK,OAAO,IAAI,SAAS,MAAM,CAAC;AAAA,EACjE;AAEA,WAAS,OAAO,UAA2C;AACzD,UAAM,WAAW,aAAa,QAAQ;AACtC,UAAM,MAAM,SAAS,KAAK,MAAM,KAAK,OAAO,IAAI,SAAS,MAAM,CAAC;AAChE,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY,EAAE,OAAO,IAAI,CAAC;AACvD,gBAAY,QAAQ,IAAI,SAAS,KAAK,GAAG,EAAE;AAC3C,QAAI,YAAY,SAAS,EAAG,aAAY,IAAI;AAAA,EAC9C;AAEA,WAAS,WAAiB;AACxB,mBAAe;AACf,qBAAiB,aAAa;AAC9B,cAAU,CAAC;AACX,mBAAe;AACf,eAAW;AACX,eAAW,KAAK,IAAI;AACpB,eAAW;AACX,UAAM;AACN,aAAS;AACT,kBAAc,CAAC;AACf,eAAW;AACX,WAAO,SAAS;AAAA,EAClB;AAEA,WAAS,YAAkB;AACzB,qBAAiB,aAAa;AAC9B,cAAU,CAAC;AACX,mBAAe;AACf,WAAO,SAAS;AAAA,EAClB;AAGA,WAAS,WAAW,OAAqD;AACvE,UAAM,SAA+C,CAAC;AACtD,UAAM,cAAc,eAAe,MAAM,EAAE;AAC3C,UAAM,aAAa,MAAM,MAAM,EAAE;AACjC,UAAM,OAAO,IAAI,MAAM,CAAC,EAAE,KAAK,KAAK;AAGpC,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAI,WAAW,CAAC,MAAM,YAAY,CAAC,GAAG;AACpC,eAAO,CAAC,IAAI;AACZ,aAAK,CAAC,IAAI;AAAA,MACZ;AAAA,IACF;AAGA,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAI,OAAO,CAAC,EAAG;AACf,YAAM,MAAM,YAAY,UAAU,CAAC,GAAG,MAAM,MAAM,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC3E,UAAI,QAAQ,IAAI;AACd,eAAO,CAAC,IAAI;AACZ,aAAK,GAAG,IAAI;AAAA,MACd,OAAO;AACL,eAAO,CAAC,IAAI;AAAA,MACd;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,cAAoB;AAC3B,QAAI,aAAa,WAAW,EAAG;AAE/B,UAAM,SAAS,WAAW,YAAY;AACtC,YAAQ,KAAK,YAAY;AAEzB,UAAM,aAAa,OAAO,MAAM,OAAK,MAAM,SAAS;AACpD,UAAM,eAAe,OAAO,OAAO,OAAK,MAAM,SAAS,EAAE;AACzD,UAAM,eAAe,OAAO,OAAO,OAAK,MAAM,SAAS,EAAE;AACzD,UAAM,aAAa,eAAe,KAAK,eAAe;AAGtD,UAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,UAAM,UAAU,KAAK,QAAQ;AAE7B,QAAI,YAAY;AACd,aAAO,SAAS;AAEhB,qBAAe;AACf,oBAAc;AACd,yBAAmB;AACnB,oBAAc;AACd,uBAAiB;AAGjB,MAAAA,gBAAe,SAAS,SAAS,IAAI,cAAc,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG,CAAC;AACjF,MAAAA,gBAAe,UAAU,GAAG,SAAS,IAAI,cAAc,CAAC,UAAK,UAAK,QAAG,CAAC;AACtE,MAAAA,gBAAe,UAAU,GAAG,SAAS,IAAI,cAAc,CAAC,UAAK,UAAK,QAAG,CAAC;AAEtE,UAAI,gBAAgB,aAAa;AAC/B,cAAM;AACN,mBAAW;AACX,sBAAc,SAAS,UAAU,GAAG,oCAA0B,YAAY;AAE1E,iBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,qBAAW,MAAM;AACf,gBAAI,SAAS;AACX,cAAAA;AAAA,gBACE,KAAK,MAAM,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO;AAAA,gBAC9C,IAAI,KAAK,OAAO,IAAI;AAAA,gBACpB;AAAA,gBACA;AAAA,gBACA,CAAC,UAAK,UAAK,UAAK,QAAG;AAAA,cACrB;AAAA,YACF;AAAA,UACF,GAAG,IAAI,GAAG;AAAA,QACZ;AAAA,MACF,OAAO;AACL,sBAAc,SAAS,UAAU,GAAG,SAAS,YAAY,cAAc,YAAY;AACnF;AACA,mBAAW,MAAM;AACf,cAAI,WAAW,CAAC,SAAU,WAAU;AAAA,QACtC,GAAG,GAAI;AAAA,MACT;AAAA,IACF,WAAW,QAAQ,UAAU,YAAY;AACvC,aAAO,WAAW;AAElB,mBAAa;AACb,oBAAc;AACd,oBAAc;AACd,uBAAiB;AACjB,iBAAW;AACX,sBAAgB;AAChB,yBAAmB;AAGnB,MAAAA,gBAAe,SAAS,SAAS,IAAI,cAAc,CAAC,UAAK,UAAK,UAAK,KAAK,KAAK,GAAG,CAAC;AACjF,oBAAc,SAAS,UAAU,GAAG,wBAAc,YAAY;AAAA,IAChE,WAAW,YAAY;AACrB,aAAO,SAAS;AAEhB,qBAAe,IAAI,eAAe;AAClC,oBAAc,KAAK,IAAI,eAAe,GAAG,CAAC;AAC1C,uBAAiB;AAGjB,UAAI,eAAe,GAAG;AACpB,QAAAA,gBAAe,SAAS,SAAS,IAAI,eAAe,GAAG,cAAc,CAAC,UAAK,UAAK,QAAG,CAAC;AACpF,sBAAc,SAAS,UAAU,GAAG,GAAG,YAAY,WAAW,YAAY;AAAA,MAC5E;AACA,UAAI,eAAe,GAAG;AACpB,QAAAA,gBAAe,UAAU,GAAG,SAAS,IAAI,cAAc,cAAc,CAAC,UAAK,UAAK,QAAG,CAAC;AACpF,YAAI,iBAAiB,GAAG;AACtB,wBAAc,SAAS,UAAU,GAAG,GAAG,YAAY,UAAU,YAAY;AAAA,QAC3E;AAAA,MACF;AAAA,IACF,OAAO;AACL,aAAO,OAAO;AAEd,mBAAa;AACb,oBAAc;AACd,uBAAiB;AAGjB,MAAAA,gBAAe,SAAS,SAAS,GAAG,YAAY,CAAC,UAAK,UAAK,QAAK,MAAG,CAAC;AACpE,oBAAc,SAAS,UAAU,GAAG,UAAU,YAAY;AAAA,IAC5D;AAEA,mBAAe;AAAA,EACjB;AAEA,WAAS,SAAe;AACtB,QAAI,SAAS;AACb,cAAU;AAGV,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,OAAO;AACb,YAAM,OAAO,SAAS,QAAQ,IAAI,QAAQ,WAAW,IAAI,IAAI,IAAI;AACjE,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,gBAAU,QAAQ,OAAO,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI;AACpG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI;AAClG,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAGA,QAAI,eAAe;AACnB,QAAI,eAAe;AACnB,QAAI,cAAc,GAAG;AACnB,qBAAe,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,iBAAiB,CAAC;AACpE,qBAAe,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,cAAc;AAChE;AAAA,IACF;AAGA,QAAI,cAAc,EAAG;AACrB,QAAI,eAAe,EAAG;AACtB,QAAI,aAAa,EAAG;AACpB,QAAI,mBAAmB,EAAG;AAG1B,gBAAY,UAAU,OAAO,OAAK;AAChC,QAAE,KAAK,EAAE;AACT,QAAE,KAAK,EAAE;AACT,QAAE,MAAM;AACR,QAAE;AACF,aAAO,EAAE,OAAO;AAAA,IAClB,CAAC;AAGD,kBAAc,YAAY,OAAO,QAAM;AACrC,SAAG,KAAK;AACR,SAAG;AACH,aAAO,GAAG,SAAS;AAAA,IACrB,CAAC;AAED,mBAAe,cAAc,KAAK;AAClC,iBAAa,YAAY,KAAK;AAG9B,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI;AAC1D,UAAM,SAAS,IAAI;AACnB,UAAM,eAAe,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAG7E,QAAI,aAAa;AACjB,QAAI,mBAAmB,KAAK,mBAAmB,IAAI,GAAG;AACpD,mBAAa;AAAA,IACf,WAAW,aAAa,KAAK,aAAa,IAAI,GAAG;AAC/C,mBAAa;AAAA,IACf,WAAW,eAAe,KAAK,eAAe,IAAI,GAAG;AACnD,mBAAa;AAAA,IACf;AAEA,QAAI,eAAe,MAAM,cAAc,IAAI;AACzC,gBAAU,QAAQ,KAAK,IAAI,GAAG,MAAM,CAAC,IAAI,KAAK,IAAI,GAAG,SAAS,YAAY,CAAC,YAAY,MAAM,CAAC,CAAC;AAC/F,gBAAU,QAAQ,KAAK,IAAI,GAAG,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,GAAG,SAAS,eAAe,CAAC,CAAC,YAAY,MAAM,CAAC,CAAC;AAAA,IACzG,OAAO;AACL,gBAAU,QAAQ,KAAK,IAAI,GAAG,MAAM,CAAC,IAAI,KAAK,IAAI,GAAG,MAAM,CAAC,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAC5F,gBAAU,QAAQ,KAAK,IAAI,GAAG,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,GAAG,MAAM,CAAC,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,IAClG;AAEA,QAAI,QAAQ;AAEV,YAAM,SAAS;AACf,YAAM,WAAW;AACjB,YAAM,eAAe,KAAK,MAAM,OAAO,CAAC;AACxC,YAAM,YAAY,eAAe,KAAK,MAAM,SAAS,SAAS,CAAC;AAC/D,gBAAU,QAAQ,MAAM,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ;AAErE,gBAAU,iBAAiB,wBAAwB,oBAAoB;AAAA,QACrE,SAAS;AAAA,QACT,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,WAAW,eAAe,KAAK,MAAM,QAAQ,SAAS,CAAC;AAC7D,gBAAU,QAAQ,SAAS,EAAE,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IAC1E,WAAW,CAAC,aAAa;AAEvB,YAAM,SAAS;AAGf,gBAAU,QAAQ,MAAM,MAAM,UAAU;AACxC,gBAAU,QAAQ,SAAS,CAAC,aAAa,UAAU,gBAAM,cAAc,YAAY;AACnF,gBAAU,QAAQ,SAAS,CAAC,aAAa,UAAU,oBAAU,YAAY,iBAAiB;AAG1F,YAAM,WAAW,SAAS;AAC1B,gBAAU,QAAQ,QAAQ,MAAM,UAAU;AAC1C,gBAAU,QAAQ,WAAW,CAAC,aAAa,UAAU,SAAS,WAAW;AACzE,gBAAU,QAAQ,WAAW,CAAC,aAAa,UAAU;AACrD,gBAAU,QAAQ,WAAW,CAAC,aAAa,UAAU,YAAY,UAAU;AAG3E,YAAM,UAAU,WAAW;AAC3B,gBAAU,QAAQ,OAAO,MAAM,UAAU;AACzC,gBAAU,QAAQ,UAAU,CAAC;AAC7B,gBAAU,QAAQ,UAAU,CAAC;AAC7B,gBAAU,QAAQ,UAAU,CAAC;AAG7B,YAAM,WAAW;AACjB,YAAM,SAAS,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC;AACtD,gBAAU,QAAQ,OAAO,CAAC,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ;AAEpE,YAAM,WAAW;AACjB,gBAAU,QAAQ,OAAO,CAAC,aAAa,UAAU,GAAG,QAAQ;AAAA,IAC9D,WAAW,UAAU;AAEnB,YAAM,QAAQ;AAEd,UAAI,KAAK;AAEP,cAAM,gBAAgB;AACtB,cAAM,YAAgB;AACtB,cAAM,eAAgB;AACtB,cAAM,OAAO,KAAK,OAAO,OAAO,cAAc,UAAU,CAAC;AAEzD,kBAAU,QAAQ,KAAK,IAAI,IAAI,cAAc,aAAa;AAC1D,kBAAU,QAAQ,QAAQ,CAAC,IAAI,IAAI,cAAc,SAAS;AAC1D,kBAAU,QAAQ,QAAQ,CAAC,IAAI,IAAI,cAAc,YAAY;AAE7D,kBAAU,QAAQ,QAAQ,CAAC,IAAI,IAAI,IAAI,UAAU,WAAW,UAAU;AACtE,kBAAU,QAAQ,QAAQ,CAAC,IAAI,IAAI,IAAI,UAAU;AACjD,kBAAU,QAAQ,QAAQ,CAAC,IAAI,IAAI,IAAI,UAAU,2BAA2B,QAAQ;AACpF,kBAAU,QAAQ,QAAQ,CAAC,IAAI,IAAI,IAAI,UAAU,4BAA4B,WAAW,IAAI,WAAW;AAGvG,cAAM,aAAa,KAAK,IAAI,gBAAgB,GAAG,GAAG;AAClD,cAAM,QAAQ,SAAI,OAAO,KAAK,MAAM,aAAa,CAAC,CAAC,IAAI,SAAI,OAAO,KAAK,KAAK,MAAM,aAAa,CAAC,CAAC;AACjG,kBAAU,QAAQ,QAAQ,CAAC,IAAI,IAAI,iCAAiC,KAAK,KAAK,UAAU;AAExF,YAAI,cAAc,KAAK;AACrB,oBAAU,QAAQ,QAAQ,EAAE,IAAI,IAAI;AACpC,oBAAU,QAAQ,QAAQ,EAAE,IAAI,IAAI;AACpC,oBAAU,QAAQ,QAAQ,EAAE,IAAI,IAAI;AAAA,QACtC;AAAA,MACF,OAAO;AAEL,cAAM,gBAAgB,gBAAgB,IAAI;AAC1C,cAAM,aAAa,gBAAgB,WAAM;AAGzC,cAAM,eAAe,gBAAgB,IAAI,IAAI,eAAe;AAC5D,cAAM,gBAAgB,GAAG,UAAU,GAAG,UAAU,uBAAuB,UAAU,GAAG,UAAU;AAC9F,kBAAU,QAAQ,KAAK,IAAI,KAAK,OAAO,OAAO,cAAc,UAAU,CAAC,CAAC,IAAI,YAAY,GAAG,aAAa;AAGxG,cAAM,UAAU;AAAA,UACd;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,cAAM,OAAO,KAAK,OAAO,OAAO,QAAQ,CAAC,EAAE,UAAU,CAAC;AAEtD,iBAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,oBAAU,QAAQ,QAAQ,IAAI,CAAC,IAAI,IAAI,YAAY,QAAQ,CAAC,CAAC;AAAA,QAC/D;AAGA,kBAAU,QAAQ,QAAQ,CAAC,IAAI,IAAI;AACnC,kBAAU,QAAQ,QAAQ,CAAC,IAAI,IAAI,+CAA0C,WAAW,GAAG,KAAK,WAAW,GAAG;AAC9G,kBAAU,QAAQ,QAAQ,CAAC,IAAI,IAAI;AACnC,kBAAU,QAAQ,QAAQ,CAAC,IAAI,IAAI;AACnC,kBAAU,QAAQ,QAAQ,CAAC,IAAI,IAAI;AAGnC,kBAAU,QAAQ,QAAQ,EAAE,IAAI,IAAI,WAAW,UAAU,mBAAmB,eAAe,CAAC,IAAI,WAAW;AAC3G,kBAAU,QAAQ,QAAQ,EAAE,IAAI,IAAI,WAAW,UAAU,yBAAyB,cAAc;AAGhG,YAAI,gBAAgB,MAAM,GAAG;AAC3B,gBAAM,cAAc;AACpB,mBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,kBAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,IAAI;AAC1C,kBAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,IAAI;AAC1C,kBAAM,KAAK,YAAY,KAAK,MAAM,KAAK,OAAO,IAAI,YAAY,MAAM,CAAC;AACrE,sBAAU,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE;AAAA,UAC1C;AAAA,QACF;AAAA,MACF;AAEA,YAAM,aAAa;AACnB,gBAAU,QAAQ,OAAO,CAAC,IAAI,KAAK,OAAO,OAAO,WAAW,UAAU,CAAC,CAAC,WAAW,UAAU,GAAG,UAAU;AAAA,IAC5G,WAAW,UAAU;AAEnB,YAAM,QAAQ;AACd,YAAM,UAAU;AAAA,QACd;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,YAAM,QAAQ,KAAK,OAAO,OAAO,QAAQ,CAAC,EAAE,UAAU,CAAC;AACvD,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,kBAAU,QAAQ,QAAQ,CAAC,IAAI,KAAK,IAAI,UAAU,GAAG,QAAQ,CAAC,CAAC;AAAA,MACjE;AACA,gBAAU,QAAQ,QAAQ,QAAQ,SAAS,CAAC,IAAI,QAAQ,CAAC;AAAA,IAC3D,OAAO;AAEL,YAAM,QAAQ;AAGd,gBAAU,QAAQ,KAAK,MAAM,UAAU,wBAAc,UAAU;AAC/D,gBAAU,QAAQ,QAAQ,CAAC,MAAM,UAAU,qBAAgB,QAAQ;AACnE,gBAAU,QAAQ,QAAQ,CAAC,MAAM,UAAU,+BAA0B,YAAY,IAAI,WAAW;AAGhG,YAAM,aAAa,YAAY,KAAK,eAAe,YAAY,KAAK,aAAa;AACjF,YAAM,aAAa,YAAY,KAAK,YAAY;AAChD,gBAAU,QAAQ,QAAQ,CAAC,MAAM,UAAU,wBAAmB,UAAU,GAAG,UAAU,GAAG,QAAQ;AAChG,gBAAU,QAAQ,QAAQ,CAAC,MAAM,UAAU,SAAI,SAAI,OAAO,EAAE,CAAC;AAG7D,YAAM,OAAO,QAAQ;AACrB,gBAAU,QAAQ,IAAI,MAAM,UAAU;AAGtC,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,cAAM,QAAQ,QAAQ,CAAC;AACvB,cAAM,SAAS,WAAW,KAAK;AAC/B,YAAI,eAAe;AACnB,iBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,gBAAM,OAAO,MAAM,CAAC;AACpB,cAAI,OAAO,CAAC,MAAM,WAAW;AAC3B,4BAAgB,aAAa,IAAI;AAAA,UACnC,WAAW,OAAO,CAAC,MAAM,WAAW;AAClC,4BAAgB,aAAa,IAAI;AAAA,UACnC,OAAO;AACL,4BAAgB,UAAU,IAAI;AAAA,UAChC;AAAA,QACF;AACA,kBAAU,QAAQ,OAAO,IAAI,CAAC,MAAM,YAAY;AAAA,MAClD;AAGA,YAAM,SAAS,OAAO,IAAI,QAAQ;AAClC,UAAI,eAAe;AACnB,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAI,IAAI,aAAa,QAAQ;AAC3B,0BAAgB,GAAG,UAAU,UAAU,aAAa,CAAC,CAAC;AAAA,QACxD,WAAW,MAAM,aAAa,QAAQ;AAEpC,gBAAM,aAAa,cAAc,KAAK,KAAK,WAAM;AACjD,0BAAgB,GAAG,UAAU,GAAG,UAAU;AAAA,QAC5C,OAAO;AACL,0BAAgB;AAAA,QAClB;AAAA,MACF;AACA,gBAAU,QAAQ,MAAM,MAAM,YAAY;AAG1C,YAAM,eAAe,aAAa,QAAQ;AAC1C,gBAAU,QAAQ,SAAS,CAAC,uBAAuB,YAAY,IAAI,UAAU;AAG7E,YAAM,OAAO;AACb,YAAM,OAAO;AACb,gBAAU,QAAQ,IAAI,IAAI,IAAI,IAAI,UAAU;AAC5C,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,cAAM,SAAS,YAAY,CAAC,KAAK;AACjC,cAAM,YAAY,OAAO,UAAU,GAAG,OAAO,OAAO,CAAC;AACrD,kBAAU,QAAQ,OAAO,IAAI,CAAC,IAAI,IAAI,IAAI,UAAU,wBAAmB,SAAS;AAAA,MAClF;AACA,gBAAU,QAAQ,OAAO,CAAC,IAAI,IAAI,IAAI,UAAU,SAAI,SAAI,OAAO,EAAE,CAAC;AAGlE,gBAAU,QAAQ,OAAO,CAAC,aAAa,UAAU;AAAA,IACnD;AAGA,eAAW,KAAK,WAAW;AACzB,YAAM,KAAK,KAAK,MAAM,EAAE,CAAC,IAAI;AAC7B,YAAM,KAAK,KAAK,MAAM,EAAE,CAAC,IAAI;AAC7B,UAAI,MAAM,KAAK,KAAK,QAAQ,MAAM,KAAK,KAAK,MAAM;AAChD,cAAM,OAAO,EAAE,OAAO,KAAK,KAAK;AAChC,kBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI,GAAG,EAAE,IAAI;AAAA,MACvD;AAAA,IACF;AAGA,eAAW,MAAM,aAAa;AAC5B,YAAM,KAAK,KAAK,MAAM,GAAG,IAAI,GAAG,KAAK,SAAS,CAAC,IAAI;AACnD,YAAM,KAAK,KAAK,MAAM,GAAG,CAAC,IAAI;AAC9B,UAAI,MAAM,KAAK,KAAK,QAAQ,MAAM,GAAG;AACnC,cAAM,OAAO,GAAG,SAAS,KAAK,KAAK,GAAG,SAAS,IAAI,YAAY;AAC/D,kBAAU,QAAQ,EAAE,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,GAAG,IAAI;AAAA,MACtE;AAAA,IACF;AAGA,QAAI,cAAc,GAAG;AACnB,YAAM,aAAa,aAAa,IAAI,aAAa;AACjD,YAAM,YAAY,cAAc,IAAI,IAAI,WAAM;AAE9C,eAAS,IAAI,GAAG,KAAK,MAAM,KAAK,GAAG;AACjC,YAAI,KAAK,OAAO,IAAI,KAAK;AACvB,oBAAU,UAAU,CAAC,IAAI,UAAU,GAAG,SAAS;AAC/C,oBAAU,QAAQ,IAAI,IAAI,CAAC,IAAI,UAAU,GAAG,SAAS;AAAA,QACvD;AAAA,MACF;AAEA,eAAS,IAAI,GAAG,KAAK,MAAM,KAAK,GAAG;AACjC,YAAI,KAAK,OAAO,IAAI,KAAK;AACvB,oBAAU,QAAQ,CAAC,MAAM,UAAU,GAAG,SAAS;AAC/C,oBAAU,QAAQ,CAAC,IAAI,IAAI,IAAI,UAAU,GAAG,SAAS;AAAA,QACvD;AAAA,MACF;AAAA,IACF;AAEA,aAAS,MAAM,MAAM;AAAA,EACvB;AAEA,WAAS,SAAe;AACtB,QAAI,CAAC,eAAe,YAAY,OAAQ;AAGxC,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,MAAM,YAAY,KAAM;AAC1B;AACA,iBAAW;AAGX,UAAI,YAAY,MAAM,WAAW,GAAG;AAClC,sBAAc;AACd,yBAAiB;AACjB,sBAAc;AACd,qBAAa;AAEb,YAAI,WAAW,MAAM,GAAG;AACtB,UAAAA,gBAAe,KAAK,OAAO,IAAI,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,UAAK,QAAG,CAAC;AAAA,QAC1E;AAAA,MACF;AAEA,UAAI,YAAY,GAAG;AACjB,eAAO,WAAW;AAClB,mBAAW;AACX,wBAAgB;AAChB,2BAAmB;AAEnB,sBAAc;AACd,yBAAiB;AACjB,qBAAa;AACb,sBAAc;AACd,cAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,cAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,QAAAA,gBAAe,SAAS,SAAS,IAAI,cAAc,CAAC,UAAK,UAAK,UAAK,KAAK,KAAK,KAAK,MAAG,CAAC;AACtF,sBAAc,SAAS,UAAU,GAAG,4CAAwB,YAAY;AAAA,MAC1E;AAAA,IACF;AAGA,QAAI,UAAU;AACZ;AAAA,IACF;AAAA,EACF;AAGA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,eAAW;AACX,aAAS;AACT,kBAAc;AAEd,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AACZ,sBAAc,cAAc;AAC5B;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,eAAe,YAAY,MAAM;AACrC,UAAI,CAAC,SAAS;AACZ,sBAAc,YAAY;AAC1B;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,GAAG;AAEN,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AACZ,oBAAY,QAAQ;AACpB;AAAA,MACF;AAEA,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS;AACrB,YAAM,WAAW,IAAI,YAAY;AAGjC,UAAI,QAAQ,UAAU;AACpB,YAAI,UAAU;AACZ,qBAAW;AAAA,QACb,OAAO;AACL,mBAAS,CAAC;AACV,cAAI,OAAQ,sBAAqB;AAAA,QACnC;AACA;AAAA,MACF;AAGA,UAAI,CAAC,eAAe,CAAC,QAAQ;AAC3B,YAAI,QAAQ,SAAS;AACnB,wBAAc;AACd,mBAAS;AAAA,QACX;AACA;AAAA,MACF;AAGA,UAAI,UAAU;AACZ,YAAI,aAAa,KAAK;AACpB,mBAAS;AACT,wBAAc;AAAA,QAChB,WAAW,aAAa,KAAK;AAC3B,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,qBAAW,KAAK;AAChB,2BAAiB,QAAQ;AAAA,QAC3B,WAAW,aAAa,KAAK;AAC3B,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,oBAAU;AACV,6BAAmB,QAAQ;AAAA,QAC7B;AACA;AAAA,MACF;AAGA,UAAI,QAAQ;AAEV,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,uBAAuB;AAAA,UACvB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AACH,uBAAS;AACT;AAAA,YACF,KAAK;AACH,uBAAS;AACT,4BAAc;AACd,uBAAS;AACT;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,yBAAW,KAAK;AAChB,+BAAiB,QAAQ;AACzB;AAAA,YACF,KAAK;AACH,yBAAW;AACX,uBAAS;AACT;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,gCAAkB,QAAQ;AAC1B;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,iCAAmB,QAAQ;AAC3B;AAAA,UACJ;AACA;AAAA,QACF;AAGA,YAAI,aAAa,KAAK;AACpB,mBAAS;AACT,wBAAc;AACd,mBAAS;AAAA,QACX,WAAW,aAAa,KAAK;AAC3B,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,oBAAU;AACV,4BAAkB,QAAQ;AAAA,QAC5B,WAAW,aAAa,KAAK;AAC3B,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,oBAAU;AACV,6BAAmB,QAAQ;AAAA,QAC7B,WAAW,aAAa,KAAK;AAC3B,qBAAW;AACX,mBAAS;AAAA,QACX;AACA;AAAA,MACF;AAGA,UAAI,UAAU;AACZ;AAAA,MACF;AAGA,UAAI,QAAQ,aAAa;AACvB,uBAAe,aAAa,MAAM,GAAG,EAAE;AAAA,MACzC,WAAW,QAAQ,SAAS;AAC1B,oBAAY;AAAA,MACd,WAAW,IAAI,WAAW,KAAK,WAAW,KAAK,GAAG,KAAK,aAAa,SAAS,GAAG;AAC9E,wBAAgB,IAAI,YAAY;AAEhC,cAAM,SAAS,IAAI,aAAa,SAAS;AACzC,cAAM,SAAS,KAAK,QAAQ;AAC5B,QAAAA,gBAAe,QAAQ,QAAQ,GAAG,YAAY,CAAC,QAAK,QAAG,CAAC;AAExD,YAAI,aAAa,WAAW,GAAG;AAC7B,wBAAc;AACd,2BAAiB;AACjB,wBAAc;AAAA,QAChB;AAAA,MACF;AAAA,IACF,CAAC;AAED,UAAM,iBAAiB,SAAS,SAAS,MAAM;AAC7C,uBAAiB;AAAA,IACnB,CAAC;AAED,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,oBAAc,cAAc;AAC5B,oBAAc,YAAY;AAC1B,kBAAY,QAAQ;AACpB,qBAAe,QAAQ;AACvB,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;ACp4BO,SAAS,eAAe,UAAuC;AACpE,QAAM,aAAa,qBAAqB;AAKxC,QAAM,WAAW;AACjB,QAAM,WAAW;AACjB,QAAM,iBAAiB;AACvB,QAAM,aAAa;AACnB,QAAM,gBAAgB;AAKtB,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,qBAAqB;AACzB,MAAI,QAAQ;AACZ,MAAI,YAAY;AAChB,MAAI,QAAQ;AACZ,MAAI,QAAQ;AAGZ,MAAI,aAAa;AACjB,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,UAAU;AAGd,QAAM,aAAa;AACnB,QAAM,aAAa;AACnB,QAAM,WAAW;AACjB,QAAM,SAAS;AACf,QAAM,cAAc;AACpB,QAAM,YAAY;AAClB,QAAM,WAAW;AAEjB,MAAI,gBAAgB;AACpB,MAAI,iBAAiB,KAAK,IAAI;AAE9B,MAAI,UAAU;AACd,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,eAAe;AACnB,MAAI,YAAY;AAChB,MAAI,WAAW;AAEf,MAAI,WAAsB,CAAC,OAAO,OAAO,OAAO,OAAO,KAAK;AAC5D,MAAI,WAAqB,CAAC;AAC1B,MAAI,QAAgB,CAAC;AAErB,MAAI,YAAwB,CAAC;AAC7B,MAAI,cAAc;AAClB,MAAI,aAAa;AACjB,MAAI,WAAW;AAGf,QAAM,YAAY;AAClB,QAAM,WAAW;AACjB,QAAM,cAAc;AAGpB,QAAM,WAAW;AACjB,QAAM,YAAY;AAClB,QAAM,QAAQ;AACd,QAAM,aAAa;AAGnB,QAAM,WAAW;AACjB,QAAM,SAAS;AAKf,QAAM,aAAgC;AAAA,IACpC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IACZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAKA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAMA,WAASC,gBAAe,GAAW,GAAW,OAAe,OAAe,OAAiB;AAC3F,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QAAG;AAAA,QACH,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ;AAAA,QAC9B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAASC,aAAY,GAAW,GAAW;AACzC,IAAAD,gBAAe,GAAG,GAAG,GAAG,YAAY,CAAC,KAAK,UAAK,UAAK,QAAG,CAAC;AAAA,EAC1D;AAEA,WAAS,WAAW,GAAW,GAAW;AACxC,IAAAA,gBAAe,GAAG,GAAG,IAAI,YAAY,CAAC,KAAK,KAAK,QAAK,GAAG,CAAC;AAAA,EAC3D;AAEA,WAAS,aAAa,GAAW,GAAW;AAC1C,IAAAA,gBAAe,GAAG,GAAG,IAAI,YAAY,CAAC,KAAK,KAAK,UAAK,QAAG,CAAC;AAAA,EAC3D;AAMA,WAAS,oBAAoB;AAC3B,eAAW,CAAC;AACZ,UAAM,aAAa,KAAK,MAAM,cAAc,iBAAiB,EAAE;AAC/D,aAAS,IAAI,GAAG,IAAI,gBAAgB,KAAK;AACvC,eAAS,KAAK,cAAc,IAAI,KAAK,CAAC;AAAA,IACxC;AAAA,EACF;AAEA,WAAS,gBAAgB;AACvB,YAAQ,CAAC;AAGT,UAAM,YAAY,MAAM,QAAQ;AAChC,UAAM,mBAAmB,KAAK,IAAI,QAAQ,GAAG,CAAC;AAE9C,aAAS,MAAM,GAAG,OAAO,UAAU,OAAO;AACxC,UAAI,QAAQ,cAAc,QAAQ,QAAQ;AACxC,cAAM,KAAK,EAAE,MAAM,QAAQ,OAAO,EAAE,CAAC;AAAA,MACvC,WAAW,OAAO,cAAc,OAAO,UAAU;AAE/C,cAAM,YAAY,MAAM,MAAM,IAAI,IAAI;AACtC,cAAM,SAAS,QAAQ,KAAK,OAAO,IAAI,SAAS,YAAY;AAC5D,cAAM,OAAa,EAAE,MAAM,QAAQ,OAAO,UAAU,CAAC,EAAE;AAEvD,cAAM,eAAe,mBAAmB,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC;AACpE,cAAM,UAAU,aAAa;AAE7B,iBAAS,IAAI,GAAG,IAAI,cAAc,KAAK;AACrC,gBAAM,OAAO,KAAK,OAAO;AACzB,cAAI,QAAgB,OAAe;AAEnC,cAAI,OAAO,OAAO,SAAS,GAAG;AAE5B,qBAAS;AACT,oBAAQ;AACR,oBAAQ;AAAA,UACV,WAAW,OAAO,KAAK;AAErB,qBAAS;AACT,oBAAQ;AACR,oBAAQ;AAAA,UACV,OAAO;AAEL,qBAAS,YAAY,IAAI,YAAY;AACrC,oBAAQ;AACR,oBAAQ;AAAA,UACV;AAEA,eAAK,SAAU,KAAK;AAAA,YAClB,GAAG,IAAI,UAAU,KAAK,OAAO,KAAK,UAAU;AAAA,YAC5C;AAAA,YACA;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AACA,cAAM,KAAK,IAAI;AAAA,MACjB,WAAW,OAAO,eAAe,OAAO,WAAW;AAEjD,cAAM,YAAY,MAAM,MAAM,IAAI,IAAI;AACtC,cAAM,SAAS,OAAO,KAAK,OAAO,IAAI,QAAQ,YAAY;AAC1D,cAAM,OAAa,EAAE,MAAM,SAAS,OAAO,MAAM,CAAC,EAAE;AAEpD,cAAM,WAAW,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC;AACjD,cAAM,UAAU,aAAa;AAE7B,iBAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,gBAAM,WAAW,KAAK,OAAO,IAAI,OAAO,SAAS;AACjD,gBAAM,QAAQ,WAAW,IAAI,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC;AAE7D,eAAK,KAAM,KAAK;AAAA,YACd,GAAG,IAAI,UAAU,KAAK,OAAO,KAAK,UAAU;AAAA,YAC5C;AAAA,YACA,QAAQ,WAAW,OAAO,OAAO,CAAC,IAAI,SAAS,OAAO,KAAK;AAAA,YAC3D;AAAA,YACA,eAAe,WAAW,KAAK,OAAO,IAAI,MAAM;AAAA,UAClD,CAAC;AAAA,QACH;AACA,cAAM,KAAK,IAAI;AAAA,MACjB,WAAW,QAAQ,UAAU;AAC3B,cAAM,KAAK,EAAE,MAAM,QAAQ,OAAO,EAAE,CAAC;AAAA,MACvC,OAAO;AACL,cAAM,KAAK,EAAE,MAAM,QAAQ,OAAO,EAAE,CAAC;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAEA,WAAS,WAAW;AAClB,YAAQ;AACR,YAAQ;AACR,YAAQ;AACR,eAAW;AACX,aAAS;AACT,eAAW,CAAC,OAAO,OAAO,OAAO,OAAO,KAAK;AAC7C,oBAAgB;AAChB,qBAAiB,KAAK,IAAI;AAC1B,gBAAY,cAAc;AAE1B,gBAAY,CAAC;AACb,kBAAc;AACd,iBAAa;AACb,eAAW;AAEX,sBAAkB;AAClB,kBAAc;AACd,gBAAY;AAAA,EACd;AAEA,WAAS,cAAc;AACrB,cAAU,KAAK,MAAM,aAAa,CAAC;AACnC,cAAU,cAAc;AACxB,kBAAc;AACd,gBAAY,cAAc;AAC1B,oBAAgB;AAChB,qBAAiB,KAAK,IAAI;AAC1B,eAAW;AAAA,EACb;AAEA,WAAS,eAAe;AACtB;AACA,eAAW,CAAC,OAAO,OAAO,OAAO,OAAO,KAAK;AAC7C,oBAAgB;AAChB,qBAAiB,KAAK,IAAI;AAE1B,UAAM,QAAQ,QAAQ,MAAM,KAAK,MAAM,aAAa,IAAI;AACxD,aAAS;AACT,QAAI,QAAQ,UAAW,aAAY;AAEnC,eAAW;AACX,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,mBAAa,KAAK,OAAO,IAAI,YAAY,KAAK,OAAO,IAAI,WAAW;AAAA,IACtE;AAEA,kBAAc;AACd,gBAAY;AAAA,EACd;AAEA,WAAS,MAAM;AACb;AACA,eAAW,SAAS,OAAO;AAC3B,kBAAc;AACd,iBAAa;AAEb,QAAI,SAAS,GAAG;AACd,iBAAW;AACX,UAAI,QAAQ,UAAW,aAAY;AAAA,IACrC,OAAO;AACL,kBAAY;AAAA,IACd;AAAA,EACF;AAMA,WAAS,UAAU,GAAwB;AACzC,UAAM,MAAM,cAAc,IAAI;AAC9B,QAAI,MAAM,KAAK,OAAO,MAAM,OAAQ,QAAO;AAC3C,WAAO,MAAM,GAAG;AAAA,EAClB;AAEA,WAAS,wBAAiC;AACxC,UAAM,OAAO,UAAU,OAAO;AAC9B,QAAI,CAAC,QAAQ,KAAK,SAAS,UAAU,CAAC,KAAK,SAAU,QAAO;AAE5D,eAAW,KAAK,KAAK,UAAU;AAC7B,YAAM,QAAQ,EAAE;AAChB,YAAM,SAAS,EAAE,IAAI,EAAE;AACvB,UAAI,WAAW,SAAS,UAAU,QAAQ;AACxC,eAAO;AAAA,MACT;AAEA,UAAI,QAAQ,KAAK,WAAW,aAAa,MAAO,QAAO;AACvD,UAAI,SAAS,cAAc,UAAU,SAAS,WAAY,QAAO;AAAA,IACnE;AACA,WAAO;AAAA,EACT;AAEA,WAAS,mBAAqD;AAC5D,UAAM,OAAO,UAAU,OAAO;AAC9B,QAAI,CAAC,QAAQ,KAAK,SAAS,WAAW,CAAC,KAAK,MAAM;AAChD,aAAO,EAAE,MAAM,OAAO,OAAO,EAAE;AAAA,IACjC;AAEA,eAAW,OAAO,KAAK,MAAM;AAE3B,UAAI,IAAI,YAAY,IAAI,kBAAkB,UAAa,IAAI,gBAAgB,IAAI;AAC7E;AAAA,MACF;AAEA,YAAM,UAAU,IAAI;AACpB,YAAM,WAAW,IAAI,IAAI,IAAI;AAE7B,UAAI,WAAW,WAAW,UAAU,UAAU;AAC5C,eAAO,EAAE,MAAM,MAAM,OAAO,KAAK,MAAM;AAAA,MACzC;AAEA,UAAI,UAAU,KAAK,WAAW,aAAa,SAAS;AAClD,eAAO,EAAE,MAAM,MAAM,OAAO,KAAK,MAAM;AAAA,MACzC;AACA,UAAI,WAAW,cAAc,UAAU,WAAW,YAAY;AAC5D,eAAO,EAAE,MAAM,MAAM,OAAO,KAAK,MAAM;AAAA,MACzC;AAAA,IACF;AAEA,WAAO,EAAE,MAAM,OAAO,OAAO,EAAE;AAAA,EACjC;AAEA,WAAS,YAAY;AACnB,UAAM,MAAM,cAAc,IAAI;AAC9B,QAAI,QAAQ,SAAU;AAEtB,aAAS,IAAI,GAAG,IAAI,gBAAgB,KAAK;AACvC,YAAM,OAAO,SAAS,CAAC;AAGvB,YAAM,YAAY,OAAO;AACzB,UAAI,KAAK,IAAI,UAAU,SAAS,KAAK,GAAG;AACtC,YAAI,CAAC,SAAS,CAAC,GAAG;AAChB,mBAAS,CAAC,IAAI;AACd,gBAAM,QAAQ,MAAM,gBAAgB;AACpC,mBAAS;AACT,uBAAa,WAAW,OAAO;AAE/B,cAAI,SAAS,MAAM,OAAK,CAAC,GAAG;AAC1B,yBAAa;AACb;AAAA,UACF;AACA,sBAAY;AACZ;AAAA,QACF,OAAO;AAEL,cAAI;AACJ;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,IAAAC,aAAY,SAAS,OAAO;AAC5B,QAAI;AAAA,EACN;AAMA,WAAS,SAAS;AAChB,QAAI,CAAC,eAAe,YAAY,OAAQ;AAGxC,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,MAAM,kBAAkB,KAAM;AAChC;AACA,uBAAiB;AACjB,UAAI,iBAAiB,GAAG;AACtB,YAAI;AACJ;AAAA,MACF;AAAA,IACF;AAGA,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAM,IAAI,UAAU,CAAC;AACrB,QAAE,KAAK,EAAE;AACT,QAAE,KAAK,EAAE;AACT,QAAE,MAAM;AACR,QAAE;AACF,UAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,IACxC;AAGA,QAAI,cAAc,EAAG;AACrB,QAAI,aAAa,EAAG;AACpB,QAAI,WAAW,EAAG;AAGlB,QAAI,WAAW,EAAG;AAGlB,eAAWC,SAAQ,OAAO;AACxB,UAAIA,MAAK,SAAS,UAAUA,MAAK,UAAU;AACzC,mBAAW,KAAKA,MAAK,UAAU;AAC7B,YAAE,KAAKA,MAAK;AACZ,cAAI,EAAE,IAAI,WAAY,GAAE,IAAI,CAAC,EAAE;AAC/B,cAAI,EAAE,IAAI,EAAE,QAAQ,EAAG,GAAE,IAAI;AAAA,QAC/B;AAAA,MACF,WAAWA,MAAK,SAAS,WAAWA,MAAK,MAAM;AAC7C,mBAAW,OAAOA,MAAK,MAAM;AAC3B,cAAI,KAAKA,MAAK;AACd,cAAI,IAAI,IAAI,WAAY,KAAI,IAAI,CAAC,IAAI;AACrC,cAAI,IAAI,IAAI,IAAI,QAAQ,EAAG,KAAI,IAAI;AAGnC,cAAI,IAAI,YAAY,IAAI,kBAAkB,QAAW;AACnD,gBAAI;AACJ,gBAAI,IAAI,iBAAiB,GAAG;AAC1B,kBAAI,gBAAgB,MAAM,KAAK,OAAO,IAAI;AAAA,YAC5C;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,OAAO,UAAU,OAAO;AAC9B,QAAI,QAAQ,KAAK,SAAS,SAAS;AACjC,YAAM,aAAa,iBAAiB;AACpC,UAAI,WAAW,MAAM;AACnB,sBAAc;AACd,mBAAW,WAAW;AAEtB,YAAI,UAAU,KAAK,WAAW,YAAY;AACxC,UAAAD,aAAY,SAAS,OAAO;AAC5B,cAAI;AACJ;AAAA,QACF;AAAA,MACF,OAAO;AAEL,QAAAA,aAAY,SAAS,OAAO;AAC5B,YAAI;AACJ;AAAA,MACF;AAAA,IACF,OAAO;AACL,oBAAc;AAAA,IAChB;AAGA,QAAI,sBAAsB,GAAG;AAC3B,UAAI;AACJ;AAAA,IACF;AAGA,cAAU;AAAA,EACZ;AAMA,WAAS,WAAW,IAAY,IAAY;AAC1C,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,MAAM,eAAe,cAAe;AACxC,mBAAe;AAEf,UAAM,OAAO,UAAU;AACvB,UAAM,OAAO,UAAU;AAEvB,QAAI,OAAO,KAAK,QAAQ,WAAY;AACpC,QAAI,OAAO,KAAK,QAAQ,YAAa;AAErC,cAAU;AACV,cAAU;AACV,eAAW;AAGX,QAAI,KAAK,KAAK,UAAU,WAAW;AACjC,eAAS;AACT,kBAAY;AAAA,IACd;AAGA,UAAM,OAAO,UAAU,OAAO;AAE9B,QAAI,QAAQ,KAAK,SAAS,QAAQ;AAChC,UAAI,sBAAsB,GAAG;AAC3B,YAAI;AACJ;AAAA,MACF;AAAA,IACF;AAEA,QAAI,QAAQ,KAAK,SAAS,SAAS;AACjC,YAAM,aAAa,iBAAiB;AACpC,UAAI,CAAC,WAAW,MAAM;AACpB,QAAAA,aAAY,SAAS,OAAO;AAC5B,YAAI;AACJ;AAAA,MACF;AACA,oBAAc;AAAA,IAChB;AAEA,cAAU;AAAA,EACZ;AAMA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,cAAU;AAEV,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AAGtB,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,OAAO;AACb,YAAM,OAAO,SAAS,QAAQ,OAAI,QAAQ,WAAW,IAAI,OAAI,IAAI;AACjE,YAAME,QAAO,OAAO,YAAY,OAAO,WAAW,qBAC9C,OAAO,WAAW,2BAAsB;AAC5C,YAAM,KAAK,KAAK,MAAM,OAAO,CAAC;AAC9B,YAAM,KAAK,KAAK,MAAM,OAAO,CAAC;AAC9B,gBAAU,QAAQ,KAAK,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI;AAClF,gBAAU,QAAQ,KAAK,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,WAAW,IAAI;AAC5E,gBAAU,QAAQ,KAAK,CAAC,IAAI,KAAK,IAAI,GAAG,KAAKA,MAAK,SAAS,CAAC,CAAC,IAAI,UAAU,GAAGA,KAAI;AAClF,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAGA,iBAAa,KAAK,IAAI,OAAO,GAAG,EAAE;AAClC,kBAAc,KAAK,IAAI,OAAO,GAAG,EAAE;AACnC,eAAW,KAAK,OAAO,OAAO,aAAa,KAAK,CAAC;AACjD,cAAU,KAAK,OAAO,OAAO,cAAc,KAAK,CAAC,IAAI;AAGrD,QAAI,SAAS,WAAW,GAAG;AACzB,wBAAkB;AAAA,IACpB;AAGA,QAAI,aAAa;AACjB,QAAI,YAAY;AAChB,QAAI,cAAc,GAAG;AACnB,oBAAc,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,CAAC;AAClD,mBAAa,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,CAAC;AAAA,IACnD;AAGA,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC;AACtD,cAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAC1D,cAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAG1D,UAAM,SAAS,SAAI,OAAO,KAAK;AAC/B,UAAM,aAAa,iBAAiB,KAAK,aAAa;AACtD,UAAM,QAAQ,UAAU,MAAM,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,UAAU,KAAK,WAAW,UAAU,GAAG,cAAc,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,oBAAoB,MAAM;AACnK,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC;AACzC,cAAU,QAAQ,UAAU,CAAC,IAAI,MAAM,IAAI,KAAK;AAGhD,QAAI,cAAc;AAClB,QAAI,aAAa,KAAK,aAAa,IAAI,EAAG,eAAc;AACxD,QAAI,WAAW,KAAK,WAAW,IAAI,EAAG,eAAc;AAEpD,cAAU,QAAQ,SAAS,IAAI,UAAU,IAAI,WAAW,SAAI,SAAI,OAAO,UAAU,CAAC;AAClF,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,gBAAU,QAAQ,YAAY,IAAI,CAAC,IAAI,UAAU,IAAI,WAAW;AAChE,gBAAU,QAAQ,YAAY,IAAI,CAAC,IAAI,aAAa,aAAa,CAAC,IAAI,WAAW;AAAA,IACnF;AACA,cAAU,QAAQ,YAAY,cAAc,CAAC,IAAI,UAAU,IAAI,WAAW,SAAI,SAAI,OAAO,UAAU,CAAC;AAGpG,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,KAAK,KAAK,MAAM,OAAO,CAAC;AAC9B,YAAM,SAAS,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACvD,gBAAU,QAAQ,MAAM,IAAI,KAAK,SAAS,SAAS,CAAC,WAAW,UAAU,GAAG,QAAQ;AAEpF,gBAAU,iBAAiB,kBAAkB,oBAAoB;AAAA,QAC/D,SAAS;AAAA,QACT,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAAA,IACH,WAES,CAAC,aAAa;AACrB,YAAM,WAAW;AACjB,YAAM,SAAS,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC3E,YAAM,SAAS,UAAU,KAAK,MAAM,cAAc,CAAC;AACnD,gBAAU,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ;AAElE,YAAM,WAAW;AACjB,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC1E,gBAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,WAAW,QAAQ;AAExD,YAAM,OAAO;AACb,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,KAAK,UAAU,CAAC,IAAI;AACtE,gBAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,WAAW,IAAI;AAAA,IACtD,WAES,UAAU;AACjB,YAAM,UAAU;AAChB,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,QAAQ,UAAU,CAAC,IAAI;AACzE,YAAM,QAAQ,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACtD,gBAAU,QAAQ,KAAK,IAAI,KAAK,cAAc,OAAO;AAErD,YAAM,YAAY,UAAU,KAAK,WAAW,SAAS;AACrD,YAAM,SAAS,WAAW,KAAK,OAAO,aAAa,UAAU,UAAU,CAAC,IAAI;AAC5E,gBAAU,QAAQ,QAAQ,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,SAAS;AAE/D,YAAM,UAAU;AAChB,YAAM,WAAW,WAAW,KAAK,OAAO,aAAa,QAAQ,UAAU,CAAC,IAAI;AAC5E,gBAAU,QAAQ,QAAQ,CAAC,IAAI,QAAQ,WAAW,OAAO;AAAA,IAC3D,OAEK;AAEH,eAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,cAAM,MAAM,cAAc,IAAI;AAC9B,YAAI,MAAM,KAAK,OAAO,MAAM,OAAQ;AAEpC,cAAM,OAAO,MAAM,GAAG;AACtB,cAAM,UAAU,YAAY,IAAI;AAGhC,YAAI,UAAU;AACd,YAAI,SAAS;AAEb,YAAI,KAAK,SAAS,QAAQ;AACxB,oBAAU;AACV,mBAAS;AAAA,QACX,WAAW,KAAK,SAAS,SAAS;AAChC,oBAAU;AACV,mBAAS;AAAA,QACX,WAAW,KAAK,SAAS,QAAQ;AAC/B,oBAAU;AACV,mBAAS;AAAA,QACX;AAEA,kBAAU,QAAQ,OAAO,IAAI,aAAa,CAAC,IAAI,OAAO,WAAW,OAAO,OAAO,UAAU,CAAC;AAG1F,YAAI,KAAK,SAAS,QAAQ;AACxB,mBAAS,IAAI,GAAG,IAAI,gBAAgB,KAAK;AACvC,kBAAM,OAAO,SAAS,CAAC;AACvB,gBAAI,QAAQ,KAAK,OAAO,aAAa,GAAG;AACtC,oBAAM,UAAU,aAAa,IAAI;AACjC,kBAAI,SAAS,CAAC,GAAG;AACf,0BAAU,QAAQ,OAAO,IAAI,OAAO;AAAA,cACtC,OAAO;AACL,0BAAU,QAAQ,OAAO,IAAI,OAAO;AAAA,cACtC;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,YAAI,KAAK,SAAS,UAAU,KAAK,UAAU;AACzC,qBAAW,KAAK,KAAK,UAAU;AAC7B,kBAAM,KAAK,KAAK,MAAM,EAAE,CAAC;AACzB,gBAAI,MAAM,KAAK,KAAK,EAAE,SAAS,YAAY;AACzC,wBAAU,QAAQ,OAAO,IAAI,aAAa,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,EAAE,MAAM;AAAA,YACxE,WAAW,KAAK,GAAG;AAEjB,oBAAM,UAAU,EAAE,OAAO,MAAM,CAAC,EAAE;AAClC,kBAAI,QAAQ,SAAS,GAAG;AACtB,0BAAU,QAAQ,OAAO,IAAI,aAAa,CAAC,IAAI,EAAE,KAAK,GAAG,OAAO;AAAA,cAClE;AAAA,YACF,WAAW,KAAK,YAAY;AAE1B,oBAAM,UAAU,EAAE,OAAO,MAAM,GAAG,aAAa,EAAE;AACjD,wBAAU,QAAQ,OAAO,IAAI,aAAa,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO;AAAA,YACvE;AAAA,UACF;AAAA,QACF;AAGA,YAAI,KAAK,SAAS,WAAW,KAAK,MAAM;AACtC,qBAAW,OAAO,KAAK,MAAM;AAE3B,kBAAM,cAAc,IAAI,YAAY,IAAI,kBAAkB,UAAa,IAAI,gBAAgB;AAE3F,kBAAM,KAAK,KAAK,MAAM,IAAI,CAAC;AAC3B,kBAAM,WAAW,cAAc,aAAc,IAAI,WAAW,aAAa;AACzE,kBAAM,gBAAgB,cAAc,SAAI,OAAO,IAAI,KAAK,IAAI,IAAI;AAEhE,gBAAI,MAAM,KAAK,KAAK,IAAI,SAAS,YAAY;AAC3C,wBAAU,QAAQ,OAAO,IAAI,aAAa,IAAI,EAAE,IAAI,QAAQ,GAAG,cAAc,MAAM,GAAG,IAAI,KAAK,CAAC;AAAA,YAClG,WAAW,KAAK,GAAG;AACjB,oBAAM,UAAU,cAAc,MAAM,CAAC,IAAI,IAAI,KAAK;AAClD,kBAAI,QAAQ,SAAS,GAAG;AACtB,0BAAU,QAAQ,OAAO,IAAI,aAAa,CAAC,IAAI,QAAQ,GAAG,OAAO;AAAA,cACnE;AAAA,YACF,WAAW,KAAK,YAAY;AAC1B,oBAAM,UAAU,cAAc,MAAM,GAAG,aAAa,EAAE;AACtD,wBAAU,QAAQ,OAAO,IAAI,aAAa,IAAI,EAAE,IAAI,QAAQ,GAAG,OAAO;AAAA,YACxE;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,YAAM,cAAc,aAAa,IAAI,KAAK,MAAM,OAAO;AACvD,YAAM,cAAc,YAAY,IAAI;AACpC,UAAI,WAAW;AACf,UAAI,WAAW,EAAG,YAAW;AAAA,eACpB,YAAa,YAAW;AAEjC,YAAM,YAAY,aAAa,IAAI,aAAa;AAChD,gBAAU,QAAQ,WAAW,IAAI,WAAW,IAAI,SAAS,GAAG,QAAQ;AAGpE,iBAAW,KAAK,WAAW;AACzB,cAAM,KAAK,KAAK,MAAM,aAAa,IAAI,EAAE,CAAC;AAC1C,cAAM,KAAK,KAAK,MAAM,YAAY,IAAI,EAAE,CAAC;AACzC,YAAI,KAAK,cAAc,KAAK,aAAa,aAAa,KAClD,KAAK,aAAa,KAAK,YAAY,cAAc,GAAG;AACtD,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,QAChD;AAAA,MACF;AAAA,IACF;AAGA,UAAM,OAAO,eAAe,CAAC,YAAY,CAAC,SAAS,SAAS,SAAS,mBAAmB;AACxF,UAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,UAAU,CAAC;AACjD,cAAU,QAAQ,UAAU,cAAc,CAAC,IAAI,KAAK,WAAW,IAAI;AAEnE,aAAS,MAAM,MAAM;AAAA,EACvB;AAMA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,aAAS;AACT,kBAAc;AAEd,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AAAE,sBAAc,cAAc;AAAG;AAAA,MAAQ;AACvD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,eAAe,YAAY,MAAM;AACrC,UAAI,CAAC,SAAS;AAAE,sBAAc,YAAY;AAAG;AAAA,MAAQ;AACrD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AAAE,oBAAY,QAAQ;AAAG;AAAA,MAAQ;AAE/C,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS,IAAI,YAAY;AAErC,UAAI,QAAQ,UAAU;AACpB,iBAAS,CAAC;AACV,YAAI,OAAQ,sBAAqB;AACjC;AAAA,MACF;AAEA,UAAI,QAAQ,QAAQ,UAAU,YAAY,CAAC,cAAc;AACvD,sBAAc,cAAc;AAC5B,sBAAc,YAAY;AAC1B,mBAAW,KAAK;AAChB,yBAAiB,QAAQ;AACzB;AAAA,MACF;AAEA,UAAI,CAAC,eAAe,CAAC,QAAQ;AAC3B,sBAAc;AACd;AAAA,MACF;AAEA,UAAI,UAAU;AACZ,YAAI,QAAQ,KAAK;AACf,cAAI,QAAQ,UAAW,aAAY;AACnC,mBAAS;AACT,wBAAc;AAAA,QAChB;AACA;AAAA,MACF;AAEA,UAAI,QAAQ;AACV,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AAAG,uBAAS;AAAO;AAAA,YACxB,KAAK;AAAG,uBAAS;AAAG,4BAAc;AAAM,uBAAS;AAAO;AAAA,YACxD,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,yBAAW,KAAK;AAChB,+BAAiB,QAAQ;AACzB;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,gCAAkB,QAAQ;AAC1B;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,iCAAmB,QAAQ;AAC3B;AAAA,UACJ;AACA;AAAA,QACF;AAEA,YAAI,QAAQ,KAAK;AAAE,mBAAS;AAAG,wBAAc;AAAM,mBAAS;AAAA,QAAO,WAC1D,QAAQ,KAAK;AAAE,wBAAc,cAAc;AAAG,wBAAc,YAAY;AAAG,oBAAU;AAAO,4BAAkB,QAAQ;AAAA,QAAG,WACzH,QAAQ,KAAK;AAAE,wBAAc,cAAc;AAAG,wBAAc,YAAY;AAAG,oBAAU;AAAO,6BAAmB,QAAQ;AAAA,QAAG;AACnI;AAAA,MACF;AAGA,cAAQ,SAAS,KAAK;AAAA,QACpB,KAAK;AAAA,QACL,KAAK;AACH,qBAAW,IAAI,CAAC;AAChB;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,qBAAW,GAAG,CAAC;AACf;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,qBAAW,GAAG,EAAE;AAChB;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,qBAAW,GAAG,CAAC;AACf;AAAA,MACJ;AAAA,IACF,CAAC;AAED,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,oBAAc,cAAc;AAC5B,oBAAc,YAAY;AAC1B,kBAAY,QAAQ;AACpB,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;ACp4BA,IAAM,QAAQ;AAAA,EACZ;AAAA,EAAY;AAAA,EAAU;AAAA,EAAU;AAAA,EAAS;AAAA,EAAU;AAAA,EACnD;AAAA,EAAU;AAAA,EAAY;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EACvD;AAAA,EAAW;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EACnD;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAAW;AAAA,EACnD;AAAA,EAAU;AAAA,EAAU;AAAA,EAAS;AAAA,EAAU;AAAA,EAAU;AAAA,EACjD;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAClD;AAAA,EAAS;AAAA,EAAS;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAChD;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAQ;AAAA,EAC5C;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAU;AAAA,EAAS;AAAA,EAC9C;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAQ;AAC5C;AAGA,IAAM,iBAAiB;AAAA;AAAA,EAErB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA;AAAA,EAEA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA;AAAA,EAEA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA;AAAA,EAEA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA;AAAA,EAEA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA;AAAA,EAEA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA;AAAA,EAEA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKO,SAAS,eAAe,UAAuC;AACpE,QAAM,aAAa,qBAAqB;AAGxC,QAAM,aAAa;AAGnB,QAAM,WAAW;AACjB,QAAM,WAAW;AAEjB,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,qBAAqB;AACzB,MAAI,MAAM;AACV,MAAI,QAAQ;AACZ,MAAI,SAAS;AACb,MAAI,aAAa;AAGjB,MAAI,cAAc;AAClB,MAAI,iBAA8B,oBAAI,IAAI;AAC1C,MAAI,eAAe;AACnB,QAAM,YAAY;AAGlB,MAAI,WAAW;AACf,MAAI,UAAU;AAGd,MAAI,cAAc;AAClB,MAAI,aAAa;AACjB,MAAI,aAAa;AACjB,MAAI,eAAe;AACnB,MAAI,gBAAgB;AACpB,MAAI,cAAc;AAGlB,MAAI,YAAwB,CAAC;AAC7B,MAAI,cAA4B,CAAC;AACjC,MAAI,gBAAgB;AACpB,MAAI,cAAc;AAElB,QAAM,aAAgC;AAAA,IACpC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IAEZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAGA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAEA,WAAS,aAAa,MAAc;AAElC,cAAU,kBAAkB,MAAM,IAAI;AAAA,MACpC,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,WAAS,WAAW;AAElB,kBAAc,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAC5D,qBAAiB,oBAAI,IAAI;AACzB,mBAAe;AACf,eAAW;AACX,UAAM;AACN,aAAS;AACT,iBAAa;AACb,iBAAa;AAEb,gBAAY,CAAC;AACb,kBAAc,CAAC;AACf,oBAAgB;AAChB,kBAAc;AACd,kBAAc;AACd,mBAAe;AACf,oBAAgB;AAAA,EAClB;AAGA,WAASC,gBAAe,GAAW,GAAW,OAAe,OAAe,QAAkB,CAAC,UAAK,UAAK,UAAK,QAAG,GAAG;AAClH,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ,MAAM;AAAA,QACpC,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF;AAGA,WAAS,cAAc,GAAW,GAAW,MAAc,QAAgB,cAAc;AACvF,gBAAY,KAAK,EAAE,GAAG,GAAG,MAAM,QAAQ,IAAI,MAAM,CAAC;AAAA,EACpD;AAEA,WAAS,iBAAyB;AAChC,WAAO,YACJ,MAAM,EAAE,EACR,IAAI,YAAU,eAAe,IAAI,MAAM,IAAI,SAAS,GAAG,EACvD,KAAK,GAAG;AAAA,EACb;AAEA,WAAS,iBAAyB;AAChC,UAAM,QAAQ,CAAC,GAAG,cAAc,EAAE,OAAO,OAAK,CAAC,YAAY,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG;AACvF,WAAO,SAAS;AAAA,EAClB;AAEA,WAAS,WAAoB;AAC3B,WAAO,YAAY,MAAM,EAAE,EAAE,MAAM,YAAU,eAAe,IAAI,MAAM,CAAC;AAAA,EACzE;AAEA,WAAS,YAAY,QAAgB;AACnC,QAAI,YAAY,UAAU,eAAe,IAAI,MAAM,EAAG;AAEtD,mBAAe,IAAI,MAAM;AAEzB,QAAI,YAAY,SAAS,MAAM,GAAG;AAEhC,mBAAa;AACb,oBAAc;AACd;AACA,YAAM,cAAc,YAAY,MAAM,MAAM,EAAE,SAAS;AACvD,YAAM,SAAS,KAAK;AACpB,eAAS;AAGT,YAAM,kBAAkB,KAAK,IAAI,gBAAgB,aAAa,CAAC;AAC/D,oBAAc,IAAI,KAAK,MAAM,kBAAkB,CAAC;AAGhD,YAAM,UAAU,KAAK,MAAM,SAAS,OAAO,CAAC;AAC5C,YAAM,QAAQ,UAAU;AACxB,MAAAA,gBAAe,SAAS,OAAO,IAAI,iBAAiB,cAAc,CAAC,UAAK,UAAK,UAAK,QAAG,CAAC;AAGtF,YAAM,YAAY,cAAc,IAAI,IAAI,MAAM,MAAM,IAAI,MAAM;AAC9D,YAAM,aAAa,iBAAiB,IAAI,eAAe;AACvD,oBAAc,UAAU,GAAG,QAAQ,GAAG,WAAW,UAAU;AAG3D,UAAI,iBAAiB,GAAG;AACtB,sBAAc,UAAU,GAAG,QAAQ,GAAG,GAAG,aAAa,aAAa,YAAY;AAAA,MACjF;AAEA,UAAI,SAAS,GAAG;AACd,cAAM;AACN,mBAAW;AACX;AACA,YAAI,SAAS,WAAY,cAAa;AACtC,cAAM,QAAQ,KAAK,IAAI,GAAI,YAAY,YAAa,IAAI;AACxD,iBAAS;AACT,uBAAe;AACf,sBAAc;AAEd,QAAAA,gBAAe,SAAS,OAAO,IAAI,cAAc,CAAC,UAAK,UAAK,UAAK,UAAK,QAAG,CAAC;AAC1E,YAAI,QAAQ,GAAG;AACb,wBAAc,UAAU,GAAG,QAAQ,GAAG,IAAI,KAAK,WAAW,YAAY;AAAA,QACxE;AAAA,MACF;AAAA,IACF,OAAO;AAEL,mBAAa;AACb;AACA,sBAAgB;AAGhB,oBAAc,IAAI;AAGlB,YAAM,WAAW,WAAW;AAC5B,YAAM,WAAW,UAAU;AAC3B,MAAAA,gBAAe,UAAU,UAAU,GAAG,cAAc,CAAC,UAAK,QAAK,QAAK,QAAG,CAAC;AAExE,UAAI,gBAAgB,WAAW;AAC7B,mBAAW;AACX,iBAAS;AACT,wBAAgB;AAChB,sBAAc;AAEd,QAAAA,gBAAe,UAAU,UAAU,IAAI,cAAc,CAAC,UAAK,UAAK,QAAK,UAAK,QAAG,CAAC;AAC9E,sBAAc,WAAW,GAAG,WAAW,GAAG,WAAW,YAAY;AAAA,MACnE;AAAA,IACF;AAAA,EACF;AAEA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,cAAU;AAGV,QAAI,cAAc,EAAG;AAGrB,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAM,IAAI,UAAU,CAAC;AACrB,QAAE,KAAK,EAAE;AACT,QAAE,KAAK,EAAE;AACT,QAAE,MAAM;AACR,QAAE;AACF,UAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,IACxC;AAGA,aAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAM,QAAQ,YAAY,CAAC;AAC3B,YAAM,KAAK;AACX,YAAM;AACN,UAAI,MAAM,UAAU,EAAG,aAAY,OAAO,GAAG,CAAC;AAAA,IAChD;AAEA,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AAGtB,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,OAAO;AACb,YAAM,YAAY,OAAO;AACzB,YAAM,aAAa,OAAO;AAC1B,UAAIC,QAAO;AACX,UAAI,aAAa,YAAY;AAC3B,QAAAA,QAAO;AAAA,MACT,WAAW,WAAW;AACpB,QAAAA,QAAO;AAAA,MACT,OAAO;AACL,QAAAA,QAAO;AAAA,MACT;AACA,YAAM,OAAO,SAAS,QAAQ,OAAI,QAAQ,WAAW,IAAI,OAAI,IAAI;AACjE,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI;AACxG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI;AAClG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAMA,MAAK,SAAS,CAAC,CAAC,CAAC,WAAW,UAAU,GAAGA,KAAI;AAC/G,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAEA,iBAAa,IAAI;AAEjB,eAAW,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,cAAc,CAAC,CAAC;AAG1D,mBAAe,cAAc,KAAK;AAClC,UAAM,eAAe,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC7E,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI;AAE1D,UAAM,WAAW,KAAK,IAAI,GAAG,UAAU,CAAC;AACxC,cAAU,QAAQ,QAAQ,IAAI,MAAM;AACpC,QAAI,eAAe,MAAM,cAAc,IAAI;AACzC,gBAAU,WAAW,MAAM,CAAC,CAAC;AAC7B,gBAAU,QAAQ,WAAW,CAAC,IAAI,SAAS,CAAC,YAAY,MAAM,CAAC,CAAC;AAAA,IAClE,OAAO;AACL,gBAAU,GAAG,UAAU,UAAU,MAAM,CAAC,CAAC;AACzC,gBAAU,QAAQ,WAAW,CAAC,IAAI,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,IAC1E;AAEA,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,eAAe,KAAK,MAAM,OAAO,CAAC;AACxC,YAAM,SAAS,KAAK,MAAM,OAAO,CAAC,IAAI;AACtC,YAAM,YAAY,eAAe,KAAK,MAAM,SAAS,SAAS,CAAC;AAC/D,gBAAU,QAAQ,MAAM,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ;AAErE,gBAAU,iBAAiB,kBAAkB,oBAAoB;AAAA,QAC/D,SAAS;AAAA,QACT,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,WAAW,eAAe,KAAK,MAAM,QAAQ,SAAS,CAAC;AAC7D,gBAAU,QAAQ,SAAS,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACzE,WAAW,CAAC,aAAa;AAEvB,YAAM,WAAW;AACjB,YAAM,SAAS,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC;AACtD,YAAM,SAAS,KAAK,MAAM,OAAO,CAAC;AAClC,gBAAU,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ;AAElE,YAAM,WAAW;AACjB,YAAM,QAAQ,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC;AACrD,gBAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ;AAAA,IACvE,OAAO;AAEL,YAAM,eAAe,cAAc,IAAI,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,IAAI,aAAa,CAAC,CAAC,IAAI;AACtG,YAAM,eAAe,cAAc,IAAI,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,IAAI,cAAc,GAAG,CAAC,CAAC,IAAI;AAC1G,YAAM,aAAa,WAAW;AAC9B,YAAM,YAAY,UAAU;AAG5B,YAAM,aAAa,cAAc,KAAK,cAAc,IAAI,IAAI,eAAe;AAC3E,YAAM,QAAQ,UAAU,MAAM,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,aAAa,MAAM,WAAW,UAAU;AACjG,YAAM,SAAS,KAAK,OAAO,OAAO,MAAM,UAAU,CAAC,IAAI;AACvD,gBAAU,QAAQ,UAAU,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,KAAK;AAG7D,YAAM,eAAe,eAAe,KAAK,IAAI,cAAc,SAAS,CAAC;AACrE,YAAM,eAAe,aAAa,KAAK,aAAa,IAAI,IAAI,eAAe;AAC3E,eAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,kBAAU,QAAQ,YAAY,IAAI,CAAC,IAAI,UAAU,IAAI,YAAY,GAAG,aAAa,CAAC,CAAC;AAAA,MACrF;AAGA,YAAM,cAAc,eAAe;AACnC,YAAM,QAAQ,KAAK,OAAO,OAAO,YAAY,UAAU,CAAC,IAAI;AAC5D,YAAM,QAAQ,YAAY;AAC1B,YAAM,YAAY,aAAa,KAAK,aAAa,IAAI,IAAI,eAAe;AACxE,gBAAU,QAAQ,KAAK,IAAI,KAAK,IAAI,SAAS,UAAU,WAAW;AAGlE,YAAM,aAAa;AACnB,YAAM,eAAe,eAAe;AACpC,YAAM,SAAS,KAAK,OAAO,QAAQ,WAAW,SAAS,aAAa,WAAW,CAAC,IAAI;AACpF,YAAM,SAAS,QAAQ;AACvB,gBAAU,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,UAAU,WAAW,YAAY;AAG3F,YAAM,YAAY,iBAAiB,YAAY,YAAY;AAC3D,YAAM,aAAa,KAAK,OAAO,OAAO,UAAU,UAAU,CAAC,IAAI;AAC/D,gBAAU,QAAQ,SAAS,CAAC,IAAI,UAAU,WAAW,UAAU,GAAG,SAAS;AAG3E,iBAAW,KAAK,WAAW;AACzB,cAAM,KAAK,KAAK,MAAM,EAAE,CAAC;AACzB,cAAM,KAAK,KAAK,MAAM,EAAE,CAAC;AACzB,YAAI,KAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,KAAK,MAAM;AAC9C,gBAAM,QAAQ,EAAE,OAAO,IAAI,KAAK;AAChC,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,QACxD;AAAA,MACF;AAGA,iBAAW,SAAS,aAAa;AAC/B,cAAM,KAAK,KAAK,MAAM,MAAM,CAAC;AAC7B,cAAM,KAAK,KAAK,MAAM,MAAM,CAAC;AAC7B,YAAI,KAAK,KAAK,KAAK,MAAM;AACvB,gBAAM,QAAQ,MAAM,SAAS,KAAK,YAAY;AAC9C,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM,IAAI;AAAA,QAChE;AAAA,MACF;AAGA,UAAI,iBAAiB,KAAK,CAAC,UAAU;AACnC,cAAM,YAAY,iBAAiB,IAAI,UAAK,aAAa,qBAAgB,GAAG,aAAa;AACzF,cAAM,UAAU,KAAK,OAAO,OAAO,UAAU,UAAU,CAAC;AACxD,cAAM,cAAc,cAAc,IAAI,IAAI,eAAe;AACzD,kBAAU,QAAQ,OAAO,IAAI,OAAO,IAAI,WAAW,GAAG,SAAS;AAAA,MACjE;AAEA,UAAI,UAAU;AACZ,cAAM,QAAQ,UAAU;AAExB,YAAI,KAAK;AAEP,gBAAM,WAAW,CAAC,UAAK,UAAK,UAAK,UAAK,MAAG;AACzC,gBAAM,SAAS,CAAC,YAAY,YAAY,YAAY,UAAU;AAC9D,gBAAM,eAAe,OAAO,KAAK,MAAM,cAAc,CAAC,IAAI,OAAO,MAAM;AAGvE,cAAI,eAAe,GAAG;AACpB,qBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,oBAAM,KAAK,KAAK,MAAM,OAAO,CAAC,IAAI,KAAK,MAAM,KAAK,IAAI,cAAc,MAAM,CAAC,IAAI,EAAE;AACjF,oBAAM,KAAK,QAAQ,IAAI,KAAK,MAAM,KAAK,IAAI,cAAc,MAAM,CAAC,IAAI,CAAC;AACrE,oBAAM,UAAU,SAAS,KAAK,MAAM,KAAK,OAAO,IAAI,SAAS,MAAM,CAAC;AACpE,wBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,YAAY,GAAG,OAAO;AAAA,YACtD;AAAA,UACF;AAEA,gBAAM,UAAU,eAAe,KAAK,2BAAiB;AACrD,gBAAM,WAAW,eAAe,KAAK,KAAK,MAAM,cAAc,CAAC,IAAI,MAAM,IAAI,eAAe;AAC5F,gBAAM,QAAQ,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC;AACpD,oBAAU,QAAQ,KAAK,IAAI,KAAK,IAAI,QAAQ,GAAG,OAAO;AAAA,QACxD,OAAO;AAEL,gBAAM,SAAS,cAAc,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAGrE,cAAI,UAAU;AACd,cAAI,gBAAgB,IAAI;AAEtB,kBAAM,cAAc,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AACjD,sBAAU,QAAQ,MAAM,EAAE,EAAE;AAAA,cAAI,OAC9B,KAAK,OAAO,IAAI,MAAM,YAAY,KAAK,MAAM,KAAK,OAAO,IAAI,YAAY,MAAM,CAAC,IAAI;AAAA,YACtF,EAAE,KAAK,EAAE;AAAA,UACX;AAEA,gBAAM,YAAY,gBAAgB,KAAK,KAAK,MAAM,cAAc,CAAC,IAAI,MAAM,IAAI,aAAa;AAC5F,gBAAM,QAAQ,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC,IAAI;AACxD,oBAAU,QAAQ,KAAK,IAAI,KAAK,IAAI,SAAS,GAAG,OAAO;AAEvD,gBAAM,aAAa,SAAS,WAAW;AACvC,gBAAM,UAAU,KAAK,OAAO,OAAO,WAAW,UAAU,CAAC,IAAI;AAC7D,oBAAU,QAAQ,QAAQ,CAAC,IAAI,OAAO,IAAI,UAAU,GAAG,UAAU;AAAA,QACnE;AAEA,cAAM,UAAU;AAChB,cAAM,WAAW,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC;AACvD,kBAAU,QAAQ,QAAQ,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,MACxE;AAAA,IACF;AAGA,UAAM,OAAO,eAAe,CAAC,YAAY,CAAC,SAAS,iBAAiB;AACpE,UAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,UAAU,CAAC;AACjD,cAAU,QAAQ,OAAO,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,IAAI;AAG/D,QAAI,aAAa,EAAG;AACpB,QAAI,aAAa,EAAG;AACpB,QAAI,eAAe,EAAG;AACtB,QAAI,gBAAgB,EAAG;AACvB,QAAI,cAAc,EAAG;AAErB,aAAS,MAAM,MAAM;AAAA,EACvB;AAGA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,aAAS;AACT,kBAAc;AAEd,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AACZ,sBAAc,cAAc;AAC5B;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AACZ,oBAAY,QAAQ;AACpB;AAAA,MACF;AAEA,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS,IAAI,YAAY;AAGrC,UAAI,QAAQ,UAAU;AACpB,iBAAS,CAAC;AACV,YAAI,OAAQ,sBAAqB;AACjC;AAAA,MACF;AAIA,UAAI,CAAC,eAAe,CAAC,QAAQ;AAC3B,sBAAc;AACd;AAAA,MACF;AAGA,UAAI,UAAU;AACZ,YAAI,QAAQ,KAAK;AACf,mBAAS;AACT,wBAAc;AAAA,QAChB;AACA;AAAA,MACF;AAGA,UAAI,QAAQ;AAEV,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AACH,uBAAS;AACT;AAAA,YACF,KAAK;AACH,uBAAS;AACT,4BAAc;AACd,uBAAS;AACT;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,yBAAW,KAAK;AAChB,+BAAiB,QAAQ;AACzB;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,wBAAU;AACV,gCAAkB,QAAQ;AAC1B;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,wBAAU;AACV,iCAAmB,QAAQ;AAC3B;AAAA,UACJ;AACA;AAAA,QACF;AAGA,YAAI,QAAQ,KAAK;AACf,mBAAS;AACT,wBAAc;AACd,mBAAS;AAAA,QACX,WAAW,QAAQ,KAAK;AACtB,wBAAc,cAAc;AAC5B,oBAAU;AACV,4BAAkB,QAAQ;AAAA,QAC5B,WAAW,QAAQ,KAAK;AACtB,wBAAc,cAAc;AAC5B,oBAAU;AACV,6BAAmB,QAAQ;AAAA,QAC7B;AACA;AAAA,MACF;AAGA,UAAI,UAAU,KAAK,GAAG,GAAG;AACvB,oBAAY,IAAI,YAAY,CAAC;AAAA,MAC/B;AAAA,IACF,CAAC;AAED,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,oBAAc,cAAc;AAC5B,kBAAY,QAAQ;AACpB,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;AChnBA,IAAM,eAA6B;AAAA,EACjC,EAAE,MAAM,QAAQ,OAAO,GAAG,QAAQ,GAAG,OAAO,IAAI,SAAS,IAAI,SAAS,GAAG;AAAA,EACzE,EAAE,MAAM,UAAU,OAAO,IAAI,QAAQ,IAAI,OAAO,IAAI,SAAS,IAAI,SAAS,GAAG;AAAA,EAC7E,EAAE,MAAM,QAAQ,OAAO,IAAI,QAAQ,IAAI,OAAO,IAAI,SAAS,IAAI,SAAS,GAAG;AAC7E;AAGA,IAAM,cAAc;AACpB,IAAM,YAAY;AAClB,IAAM,YAAY;AAClB,IAAM,aAAa;AAGnB,IAAM,gBAAgB;AAAA,EACpB;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AACF;AAMO,SAAS,mBAAmB,UAA2C;AAC5E,QAAM,aAAa,qBAAqB;AAKxC,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,qBAAqB;AACzB,MAAI,MAAM;AACV,MAAI,aAAa;AAGjB,MAAI,kBAAkB;AACtB,MAAI,aAAa,aAAa,eAAe;AAC7C,MAAI,sBAAsB;AAC1B,MAAI,sBAAsB;AAG1B,MAAI,OAAiB,CAAC;AACtB,MAAI,UAAU;AACd,MAAI,UAAU;AAGd,MAAI,cAAc;AAClB,MAAI,gBAAgB;AACpB,MAAI,YAAY;AAChB,MAAI,cAAc;AAGlB,MAAI,cAAc;AAClB,MAAI,YAAwB,CAAC;AAC7B,MAAI,cAA4B,CAAC;AACjC,MAAI,cAAc;AAClB,MAAI,iBAAiB;AACrB,MAAI,YAAY;AAChB,MAAI,iBAAiB;AAGrB,MAAI,WAAW;AACf,MAAI,UAAU;AAKd,QAAM,aAAoC;AAAA,IACxC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IACZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAKA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAMA,WAASC,gBAAe,GAAW,GAAW,OAAe,OAAe,QAAkB,CAAC,KAAK,KAAK,KAAK,GAAG,GAAG;AAClH,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ;AAAA,QAC9B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,eAAe,GAAW,GAAW;AAE5C,UAAM,SAAS,CAAC,cAAc,cAAc,YAAY;AACxD,UAAM,QAAQ,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAC3C,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,KAAK,KAAK,OAAO,IAAI;AACvD,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD,OAAO,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,OAAO,MAAM,CAAC;AAAA,QACvD,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ,MAAM;AAAA,QACpC,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,cAAc,GAAW,GAAW,MAAc,QAAgB,cAAc;AACvF,gBAAY,KAAK,EAAE,GAAG,GAAG,MAAM,QAAQ,IAAI,MAAM,CAAC;AAAA,EACpD;AAEA,WAAS,aAAa,QAAgB,WAAmB;AACvD,kBAAc;AACd,qBAAiB;AAAA,EACnB;AAMA,WAAS,kBAA4B;AACnC,UAAM,UAAoB,CAAC;AAC3B,aAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,YAAM,MAAc,CAAC;AACrB,eAAS,IAAI,GAAG,IAAI,WAAW,OAAO,KAAK;AACzC,YAAI,KAAK;AAAA,UACP,QAAQ;AAAA,UACR,YAAY;AAAA,UACZ,WAAW;AAAA,UACX,eAAe;AAAA,QACjB,CAAC;AAAA,MACH;AACA,cAAQ,KAAK,GAAG;AAAA,IAClB;AACA,WAAO;AAAA,EACT;AAEA,WAAS,WAAW,OAAe,OAAe;AAEhD,QAAI,cAAc;AAClB,WAAO,cAAc,WAAW,OAAO;AACrC,YAAM,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,WAAW,KAAK;AACrD,YAAM,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,WAAW,MAAM;AAGtD,UAAI,KAAK,CAAC,EAAE,CAAC,EAAE,OAAQ;AAGvB,UAAI,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAG;AAE1D,WAAK,CAAC,EAAE,CAAC,EAAE,SAAS;AACpB;AAAA,IACF;AAGA,aAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,eAAS,IAAI,GAAG,IAAI,WAAW,OAAO,KAAK;AACzC,YAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,QAAQ;AACtB,eAAK,CAAC,EAAE,CAAC,EAAE,gBAAgB,mBAAmB,GAAG,CAAC;AAAA,QACpD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,WAAS,mBAAmB,GAAW,GAAmB;AACxD,QAAI,QAAQ;AACZ,aAAS,KAAK,IAAI,MAAM,GAAG,MAAM;AAC/B,eAAS,KAAK,IAAI,MAAM,GAAG,MAAM;AAC/B,YAAI,OAAO,KAAK,OAAO,EAAG;AAC1B,cAAM,KAAK,IAAI;AACf,cAAM,KAAK,IAAI;AACf,YAAI,MAAM,KAAK,KAAK,WAAW,SAAS,MAAM,KAAK,KAAK,WAAW,QAAQ;AACzE,cAAI,KAAK,EAAE,EAAE,EAAE,EAAE,OAAQ;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAMA,WAAS,WAAW;AAClB,iBAAa,aAAa,eAAe;AACzC,WAAO,gBAAgB;AACvB,cAAU,KAAK,MAAM,WAAW,QAAQ,CAAC;AACzC,cAAU,KAAK,MAAM,WAAW,SAAS,CAAC;AAC1C,kBAAc;AACd,oBAAgB;AAChB,gBAAY;AACZ,kBAAc;AACd,eAAW;AACX,UAAM;AACN,aAAS;AACT,iBAAa;AAGb,gBAAY,CAAC;AACb,kBAAc,CAAC;AACf,kBAAc;AACd,gBAAY;AACZ,qBAAiB;AAAA,EACnB;AAEA,WAAS,WAAW,GAAW,GAAW,UAAU,OAAO;AACzD,QAAI,IAAI,KAAK,KAAK,WAAW,SAAS,IAAI,KAAK,KAAK,WAAW,OAAQ;AACvE,UAAM,OAAO,KAAK,CAAC,EAAE,CAAC;AACtB,QAAI,KAAK,cAAc,KAAK,UAAW;AAGvC,QAAI,YAAY;AACd,iBAAW,GAAG,CAAC;AACf,mBAAa;AACb,kBAAY,KAAK,IAAI;AAGrB,kBAAY;AACZ,uBAAiB;AAAA,IACnB;AAEA,SAAK,aAAa;AAClB;AAGA,QAAI,KAAK,QAAQ;AACf,iBAAW;AACX,YAAM;AACN,mBAAa,IAAI,CAAC;AAClB,qBAAe,IAAI,IAAI,GAAG,CAAC;AAC3B,oBAAc,IAAI,GAAG,IAAI,GAAG,YAAY,YAAY;AACpD,qBAAe;AACf;AAAA,IACF;AAGA,QAAI,CAAC,SAAS;AACZ,MAAAA,gBAAe,IAAI,IAAI,GAAG,GAAG,GAAG,YAAY,CAAC,KAAK,KAAK,GAAG,CAAC;AAAA,IAC7D;AAGA,QAAI,KAAK,kBAAkB,GAAG;AAC5B,eAAS,KAAK,IAAI,MAAM,GAAG,MAAM;AAC/B,iBAAS,KAAK,IAAI,MAAM,GAAG,MAAM;AAC/B,cAAI,OAAO,KAAK,OAAO,GAAG;AAExB,uBAAW,MAAM;AACf,kBAAI,WAAW,CAAC,UAAU;AACxB,2BAAW,IAAI,IAAI,IAAI,IAAI,IAAI;AAAA,cACjC;AAAA,YACF,GAAG,EAAE;AAAA,UACP;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,aAAS;AAAA,EACX;AAEA,WAAS,WAAW,GAAW,GAAW;AACxC,UAAM,OAAO,KAAK,CAAC,EAAE,CAAC;AACtB,QAAI,KAAK,WAAY;AAErB,SAAK,YAAY,CAAC,KAAK;AACvB,QAAI,KAAK,WAAW;AAClB;AACA,MAAAA,gBAAe,IAAI,IAAI,GAAG,GAAG,GAAG,cAAc,CAAC,KAAK,KAAK,GAAG,CAAC;AAAA,IAC/D,OAAO;AACL;AAAA,IACF;AAAA,EACF;AAEA,WAAS,iBAAiB;AACxB,aAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,eAAS,IAAI,GAAG,IAAI,WAAW,OAAO,KAAK;AACzC,YAAI,KAAK,CAAC,EAAE,CAAC,EAAE,QAAQ;AACrB,eAAK,CAAC,EAAE,CAAC,EAAE,aAAa;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,WAAS,WAAW;AAElB,UAAM,gBAAgB,WAAW,QAAQ,WAAW,SAAS,WAAW;AACxE,QAAI,iBAAiB,eAAe;AAClC,iBAAW;AACX,YAAM;AACN,mBAAa,IAAI,CAAC;AAGlB,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,cAAM,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,WAAW,KAAK;AACrD,cAAM,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,WAAW,MAAM;AACtD,QAAAA,gBAAe,IAAI,IAAI,GAAG,GAAG,GAAG,cAAc,CAAC,KAAK,KAAK,GAAG,CAAC;AAAA,MAC/D;AACA,oBAAc,WAAW,OAAO,WAAW,SAAS,GAAG,gBAAgB,YAAY;AAAA,IACrF;AAAA,EACF;AAEA,WAAS,SAAS;AAChB,QAAI,CAAC,eAAe,YAAY,UAAU,oBAAqB;AAG/D,QAAI,YAAY,KAAK,CAAC,UAAU;AAC9B,oBAAc,KAAK,OAAO,KAAK,IAAI,IAAI,aAAa,GAAI;AAAA,IAC1D;AAGA,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAM,IAAI,UAAU,CAAC;AACrB,QAAE,KAAK,EAAE;AACT,QAAE,KAAK,EAAE;AACT,QAAE,MAAM;AACR,QAAE;AACF,UAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,IACxC;AAGA,aAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAM,QAAQ,YAAY,CAAC;AAC3B,YAAM,KAAK;AACX,YAAM;AACN,UAAI,MAAM,UAAU,EAAG,aAAY,OAAO,GAAG,CAAC;AAAA,IAChD;AAGA,QAAI,iBAAiB,GAAG;AACtB;AACA,kBAAY,KAAK,OAAO,KAAK,kBAAkB,KAAK,WAAW,MAAM;AACrE,UAAI,kBAAkB,GAAG;AACvB,oBAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAMA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,cAAU;AAGV,QAAI,cAAc,EAAG;AAErB,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AAEtB,UAAM,oBAAoB,aAAa,sBAAsB,sBAAsB,eAAe;AAClG,UAAM,UAAU,kBAAkB;AAClC,UAAM,UAAU,kBAAkB;AAGlC,QAAI,OAAO,WAAW,OAAO,SAAS;AACpC,YAAM,OAAO;AACb,YAAM,YAAY,OAAO;AACzB,YAAM,aAAa,OAAO;AAC1B,UAAIC,QAAO,aAAa,aAAa,qBACjC,YAAY,oBAAoB;AACpC,YAAM,OAAO,SAAS,OAAO,IAAI,OAAO,WAAW,IAAI,IAAI,IAAI;AAC/D,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI;AACxG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI;AAClG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAMA,MAAK,SAAS,CAAC,CAAC,CAAC,WAAW,UAAU,GAAGA,KAAI;AAC/G,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAGA,UAAM,YAAY,WAAW,QAAQ,IAAI;AACzC,UAAM,aAAa,WAAW,SAAS;AAGvC,eAAW,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,aAAa,CAAC,CAAC;AACzD,cAAU,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,aAAa,KAAK,CAAC,IAAI,CAAC;AAGjE,QAAI,aAAa;AACjB,QAAI,YAAY;AAChB,QAAI,cAAc,GAAG;AACnB,oBAAc,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,iBAAiB,CAAC;AACnE,mBAAa,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,cAAc;AAAA,IAChE;AAGA,mBAAe,cAAc,KAAK;AAClC,UAAM,eAAe,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC7E,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI;AAE1D,QAAI,eAAe,MAAM,cAAc,IAAI;AACzC,gBAAU,UAAU,MAAM,YAAY,MAAM,CAAC,CAAC;AAC9C,gBAAU,UAAU,SAAS,CAAC,YAAY,MAAM,CAAC,CAAC;AAAA,IACpD,OAAO;AACL,gBAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAC1D,gBAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,IAC5D;AAGA,QAAI,qBAAqB;AACvB,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC,IAAI;AACvC,YAAM,YAAY;AAClB,YAAM,UAAU,KAAK,OAAO,OAAO,UAAU,UAAU,CAAC;AACxD,gBAAU,QAAQ,OAAO,IAAI,OAAO,IAAI,UAAU,UAAU,SAAS;AAErE,eAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,cAAM,IAAI,aAAa,CAAC;AACxB,cAAM,aAAa,MAAM;AACzB,cAAM,QAAQ,GAAG,EAAE,IAAI,KAAK,EAAE,KAAK,IAAI,EAAE,MAAM,KAAK,EAAE,KAAK;AAC3D,cAAM,SAAS,KAAK,OAAO,OAAO,MAAM,SAAS,KAAK,CAAC;AACvD,cAAM,QAAQ,aAAa,eAAe,UAAU,UAAU;AAC9D,cAAM,SAAS,aAAa,OAAO;AACnC,cAAM,SAAS,aAAa,OAAO;AACnC,kBAAU,QAAQ,UAAU,IAAI,CAAC,IAAI,MAAM,IAAI,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM;AAAA,MAChF;AAEA,YAAMA,QAAO;AACb,YAAMC,SAAQ,KAAK,OAAO,OAAOD,MAAK,UAAU,CAAC;AACjD,gBAAU,QAAQ,UAAU,CAAC,IAAIC,MAAK,WAAW,UAAU,GAAGD,KAAI;AAElE,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAGA,UAAM,YAAY,WAAW,QAAQ;AACrC,UAAM,UAAU,WAAW,WAAW;AACtC,UAAM,QAAQ,YAAY,UAAU,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,WAAW,OAAO,MAAM,WAAW,IAAI;AACtG,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,UAAU,CAAC;AACnD,cAAU,QAAQ,YAAY,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,KAAK;AAG/D,UAAM,cAAc,YAAY,CAAC,MAAM,eAAe;AACtD,cAAU,QAAQ,SAAS,IAAI,UAAU,IAAI,WAAW,IAAI,IAAI,OAAO,WAAW,QAAQ,CAAC,CAAC;AAC5F,aAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,gBAAU,QAAQ,YAAY,IAAI,CAAC,IAAI,UAAU,IAAI,WAAW;AAChE,gBAAU,QAAQ,YAAY,IAAI,CAAC,IAAI,aAAa,WAAW,QAAQ,IAAI,CAAC,IAAI,WAAW;AAAA,IAC7F;AACA,cAAU,QAAQ,YAAY,WAAW,SAAS,CAAC,IAAI,UAAU,IAAI,WAAW,IAAI,IAAI,OAAO,WAAW,QAAQ,CAAC,CAAC;AAGpH,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,eAAe,KAAK,MAAM,OAAO,CAAC;AACxC,YAAM,SAAS,KAAK,MAAM,OAAO,CAAC,IAAI;AACtC,YAAM,YAAY,eAAe,KAAK,MAAM,SAAS,SAAS,CAAC;AAC/D,gBAAU,QAAQ,MAAM,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ;AAErE,gBAAU,iBAAiB,kBAAkB,oBAAoB;AAAA,QAC/D,SAAS;AAAA,QACT,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,WAAW,eAAe,KAAK,MAAM,QAAQ,SAAS,CAAC;AAC7D,gBAAU,QAAQ,SAAS,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACzE,WAES,CAAC,aAAa;AACrB,YAAM,WAAW;AACjB,YAAM,SAAS,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC;AACtD,YAAM,SAAS,KAAK,MAAM,OAAO,CAAC;AAClC,gBAAU,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ;AAElE,YAAM,WAAW;AACjB,YAAM,QAAQ,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC;AACrD,gBAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ;AAGrE,eAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,iBAAS,IAAI,GAAG,IAAI,WAAW,OAAO,KAAK;AACzC,gBAAM,QAAQ,aAAa,IAAI,IAAI;AACnC,gBAAM,QAAQ,YAAY,IAAI;AAC9B,oBAAU,QAAQ,KAAK,IAAI,KAAK,WAAW,UAAU,GAAG,WAAW;AAAA,QACrE;AAAA,MACF;AAAA,IACF,WAES,UAAU;AAEjB,gBAAU,WAAW,YAAY,WAAW,KAAK;AAEjD,YAAM,UAAU,MAAM,uBAAuB;AAC7C,YAAM,QAAQ,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC;AACpD,YAAM,QAAQ,KAAK,MAAM,OAAO,CAAC,IAAI;AACrC,gBAAU,QAAQ,KAAK,IAAI,KAAK,IAAI,MAAM,eAAe,YAAY,GAAG,OAAO;AAE/E,YAAM,UAAU,SAAS,WAAW,WAAW,CAAC;AAChD,YAAM,QAAQ,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC;AACpD,gBAAU,QAAQ,QAAQ,CAAC,IAAI,KAAK,IAAI,UAAU,GAAG,OAAO;AAE5D,YAAM,UAAU;AAChB,YAAM,WAAW,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC;AACvD,gBAAU,QAAQ,QAAQ,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACxE,OAEK;AACH,gBAAU,WAAW,YAAY,WAAW,IAAI;AAGhD,UAAI,aAAa,KAAK,YAAY,WAAW,QAAQ;AACnD,cAAM,QAAQ,aAAa;AAC3B,cAAM,QAAQ,YAAY,IAAI;AAC9B,kBAAU,QAAQ,KAAK,IAAI,KAAK,WAAW,UAAU,GAAG,IAAI,OAAO,WAAW,QAAQ,CAAC,CAAC;AAAA,MAC1F;AAGA,iBAAW,KAAK,WAAW;AACzB,cAAM,UAAU,KAAK,MAAM,aAAa,IAAI,EAAE,CAAC;AAC/C,cAAM,UAAU,KAAK,MAAM,YAAY,IAAI,EAAE,CAAC;AAC9C,YAAI,UAAU,cAAc,UAAU,aAAa,WAAW,QAAQ,IAAI,KACtE,UAAU,aAAa,UAAU,YAAY,WAAW,SAAS,GAAG;AACtE,gBAAM,QAAQ,EAAE,OAAO,IAAI,KAAK;AAChC,oBAAU,QAAQ,OAAO,IAAI,OAAO,IAAI,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,QAClE;AAAA,MACF;AAGA,iBAAW,SAAS,aAAa;AAC/B,cAAM,UAAU,KAAK,MAAM,aAAa,IAAI,MAAM,CAAC;AACnD,cAAM,UAAU,KAAK,MAAM,YAAY,IAAI,MAAM,CAAC;AAClD,YAAI,UAAU,aAAa,UAAU,YAAY,WAAW,SAAS,GAAG;AACtE,gBAAM,QAAQ,MAAM,SAAS,KAAK,YAAY;AAC9C,oBAAU,QAAQ,OAAO,IAAI,OAAO,IAAI,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM,IAAI;AAAA,QAC1E;AAAA,MACF;AAAA,IACF;AAGA,UAAM,OAAO,eAAe,CAAC,YAAY,CAAC,SACtC,aAAa,aAAa,IAAI,WAAW,QAAQ,WAAW,SAAS,WAAW,KAAK,mBACrF;AACJ,UAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,UAAU,CAAC;AACjD,cAAU,QAAQ,YAAY,WAAW,SAAS,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,IAAI;AAExF,aAAS,MAAM,MAAM;AAAA,EACvB;AAEA,WAAS,WAAW,YAAoB,WAAmB,YAA6B;AACtF,QAAI,SAAS;AAEb,aAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,eAAS,IAAI,GAAG,IAAI,WAAW,OAAO,KAAK;AACzC,cAAM,OAAO,KAAK,CAAC,EAAE,CAAC;AACtB,cAAM,QAAQ,aAAa,IAAI,IAAI;AACnC,cAAM,QAAQ,YAAY,IAAI;AAC9B,cAAM,WAAW,cAAc,MAAM,WAAW,MAAM;AAEtD,YAAI,WAAW;AACf,YAAI,YAAY;AAEhB,YAAI,KAAK,YAAY;AACnB,cAAI,KAAK,QAAQ;AACf,uBAAW;AACX,wBAAY;AAAA,UACd,WAAW,KAAK,gBAAgB,GAAG;AACjC,uBAAW,IAAI,KAAK,aAAa;AACjC,wBAAY,cAAc,KAAK,aAAa,KAAK;AAAA,UACnD,OAAO;AACL,uBAAW;AACX,wBAAY;AAAA,UACd;AAAA,QACF,WAAW,KAAK,WAAW;AACzB,qBAAW;AACX,sBAAY;AAAA,QACd,OAAO;AACL,qBAAW;AACX,sBAAY,UAAU,UAAU;AAAA,QAClC;AAEA,YAAI,UAAU;AAEZ,oBAAU,QAAQ,KAAK,IAAI,KAAK,WAAW,SAAS,GAAG,QAAQ;AAAA,QACjE,OAAO;AACL,oBAAU,QAAQ,KAAK,IAAI,KAAK,IAAI,SAAS,GAAG,QAAQ;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,WAAW,SAAyB;AAC3C,UAAM,OAAO,KAAK,MAAM,UAAU,EAAE;AACpC,UAAM,OAAO,UAAU;AACvB,WAAO,GAAG,KAAK,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,EAChF;AAMA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,aAAS;AACT,kBAAc;AACd,0BAAsB;AAEtB,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AAAE,sBAAc,cAAc;AAAG;AAAA,MAAQ;AACvD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,eAAe,YAAY,MAAM;AACrC,UAAI,CAAC,SAAS;AAAE,sBAAc,YAAY;AAAG;AAAA,MAAQ;AACrD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AAAE,oBAAY,QAAQ;AAAG;AAAA,MAAQ;AAE/C,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS,IAAI,YAAY;AAGrC,UAAI,QAAQ,YAAY,CAAC,qBAAqB;AAC5C,iBAAS,CAAC;AACV,YAAI,OAAQ,sBAAqB;AACjC;AAAA,MACF;AAGA,UAAI,QAAQ,QAAQ,UAAU,YAAY,CAAC,cAAc;AACvD,sBAAc,cAAc;AAC5B,sBAAc,YAAY;AAC1B,mBAAW,KAAK;AAChB,yBAAiB,QAAQ;AACzB;AAAA,MACF;AAGA,UAAI,qBAAqB;AACvB,YAAI,SAAS,QAAQ,WAAW;AAC9B,iCAAuB,sBAAsB,IAAI,aAAa,UAAU,aAAa;AAAA,QACvF,WAAW,SAAS,QAAQ,aAAa;AACvC,iCAAuB,sBAAsB,KAAK,aAAa;AAAA,QACjE,WAAW,SAAS,QAAQ,WAAW,SAAS,QAAQ,KAAK;AAC3D,4BAAkB;AAClB,gCAAsB;AACtB,mBAAS;AAAA,QACX,WAAW,QAAQ,KAAK;AACtB,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,qBAAW,KAAK;AAChB,2BAAiB,QAAQ;AAAA,QAC3B;AACA;AAAA,MACF;AAGA,UAAI,CAAC,eAAe,CAAC,QAAQ;AAC3B,sBAAc;AACd;AAAA,MACF;AAGA,UAAI,UAAU;AACZ,YAAI,QAAQ,KAAK;AACf,mBAAS;AACT,wBAAc;AAAA,QAChB,WAAW,QAAQ,KAAK;AACtB,gCAAsB;AACtB,gCAAsB;AAAA,QACxB;AACA;AAAA,MACF;AAGA,UAAI,QAAQ;AACV,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AAAG,uBAAS;AAAO;AAAA,YACxB,KAAK;AAAG,uBAAS;AAAG,4BAAc;AAAM,uBAAS;AAAO;AAAA,YACxD,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,yBAAW,KAAK;AAChB,+BAAiB,QAAQ;AACzB;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,gCAAkB,QAAQ;AAC1B;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,iCAAmB,QAAQ;AAC3B;AAAA,UACJ;AACA;AAAA,QACF;AAGA,YAAI,QAAQ,KAAK;AAAE,mBAAS;AAAG,wBAAc;AAAM,mBAAS;AAAA,QAAO,WAC1D,QAAQ,KAAK;AAAE,wBAAc,cAAc;AAAG,wBAAc,YAAY;AAAG,oBAAU;AAAO,4BAAkB,QAAQ;AAAA,QAAG,WACzH,QAAQ,KAAK;AAAE,wBAAc,cAAc;AAAG,wBAAc,YAAY;AAAG,oBAAU;AAAO,6BAAmB,QAAQ;AAAA,QAAG;AACnI;AAAA,MACF;AAGA,cAAQ,SAAS,KAAK;AAAA,QACpB,KAAK;AAAA,QACL,KAAK;AACH,oBAAU,KAAK,IAAI,GAAG,UAAU,CAAC;AACjC;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,oBAAU,KAAK,IAAI,WAAW,QAAQ,GAAG,UAAU,CAAC;AACpD;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,oBAAU,KAAK,IAAI,GAAG,UAAU,CAAC;AACjC;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,oBAAU,KAAK,IAAI,WAAW,SAAS,GAAG,UAAU,CAAC;AACrD;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AAEH,cAAI,CAAC,KAAK,OAAO,EAAE,OAAO,EAAE,WAAW;AACrC,uBAAW,SAAS,OAAO;AAAA,UAC7B;AACA;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AAEH,qBAAW,SAAS,OAAO;AAC3B;AAAA,MACJ;AAAA,IACF,CAAC;AAGD,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,oBAAc,cAAc;AAC5B,oBAAc,YAAY;AAC1B,kBAAY,QAAQ;AACpB,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;AC5yBO,SAAS,YAAY,UAAoC;AAC9D,QAAM,aAAa,qBAAqB;AAGxC,QAAM,WAAW;AACjB,QAAM,WAAW;AAIjB,QAAM,oBAAoB,MAAM;AAC9B,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AACtB,UAAM,QAAQ,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC;AACjD,UAAM,SAAS,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC;AAClD,WAAO,EAAE,OAAO,OAAO;AAAA,EACzB;AAEA,MAAI,EAAE,OAAO,YAAY,QAAQ,YAAY,IAAI,kBAAkB;AACnE,QAAM,gBAAgB,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,cAAc,CAAC,CAAC,CAAC;AAC1E,QAAM,gBAAgB;AAEtB,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,qBAAqB;AAGzB,MAAI,WAAW;AACf,MAAI,UAAU;AAGd,MAAI,cAAc;AAClB,MAAI,UAAU;AACd,QAAM,YAAY;AAGlB,MAAI,UAAU,KAAK,OAAO,cAAc,iBAAiB,CAAC;AAC1D,MAAI,MAAM,KAAK,OAAO,cAAc,iBAAiB,CAAC;AAGtD,MAAI,QAAQ,aAAa;AACzB,MAAI,QAAQ,cAAc;AAC1B,MAAI,SAAS;AACb,MAAI,SAAS;AACb,QAAM,aAAa;AACnB,QAAM,iBAAiB;AAGvB,MAAI,kBAAkB;AACtB,QAAM,oBAAoB;AAC1B,QAAM,WAAW;AAGjB,MAAI,cAAc;AAClB,MAAI,aAAa;AACjB,MAAI,YAAuD,CAAC;AAG5D,MAAI,cAAc;AAClB,MAAI,aAAqC;AACzC,MAAI,cAAc;AAClB,MAAI,gBAAyE,CAAC;AAC9E,MAAI,gBAAyC;AAG7C,MAAI,YAAwB,CAAC;AAC7B,MAAI,cAA4B,CAAC;AACjC,MAAI,iBAAiB;AACrB,MAAI,aAAa;AACjB,MAAI,eAAe;AAEnB,QAAM,aAA6B;AAAA,IACjC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IAEZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAGA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAEA,WAAS,WAAW;AAClB,cAAU,KAAK,OAAO,cAAc,iBAAiB,CAAC;AACtD,UAAM,KAAK,OAAO,cAAc,iBAAiB,CAAC;AAClD,cAAU,IAAI;AACd,eAAW;AACX,aAAS;AACT,iBAAa;AACb,gBAAY,CAAC;AACb,kBAAc;AACd,iBAAa;AACb,kBAAc;AACd,oBAAgB,CAAC;AACjB,oBAAgB;AAEhB,gBAAY,CAAC;AACb,kBAAc,CAAC;AACf,qBAAiB;AACjB,iBAAa;AACb,mBAAe;AAAA,EACjB;AAGA,WAASE,gBAAe,GAAW,GAAW,OAAe,OAAe,QAAkB,CAAC,UAAK,UAAK,UAAK,QAAG,GAAG;AAClH,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ;AAAA,QAC9B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,EACF;AAGA,WAAS,cAAc,GAAW,GAAW,MAAc,QAAgB,cAAc;AACvF,gBAAY,KAAK,EAAE,GAAG,GAAG,MAAM,QAAQ,IAAI,MAAM,CAAC;AAAA,EACpD;AAEA,WAAS,oBAAoB,MAAwB;AACnD,UAAM,IAAI,SAAS,SAAS,IAAI,aAAa;AAC7C,UAAM,QAAQ,CAAC,KAAK,KAAK,QAAU,UAAU,UAAU,QAAQ;AAC/D,UAAM,SAAS,CAAC,YAAY,YAAY,YAAY,YAAY,UAAU;AAE1E,oBAAgB,CAAC;AACjB,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,oBAAc,KAAK;AAAA,QACjB,GAAG,KAAK,KAAK,OAAO,IAAI,OAAO;AAAA,QAC/B,GAAG,KAAK,MAAM,cAAc,CAAC,KAAK,KAAK,OAAO,IAAI,OAAO,cAAc;AAAA,QACvE,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD,OAAO,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,OAAO,MAAM,CAAC;AAAA,MACzD,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,UAAU,eAAwB;AACzC,YAAQ,aAAa;AACrB,YAAQ,cAAc;AAGtB,UAAM,SAAS,KAAK,OAAO,IAAI,OAAO,KAAK,KAAK;AAChD,UAAM,YAAY,gBAAgB,KAAK;AAEvC,aAAS,KAAK,IAAI,KAAK,IAAI,aAAa;AACxC,aAAS,KAAK,IAAI,KAAK,IAAI;AAC3B,gBAAY,CAAC;AACb,iBAAa;AAAA,EACf;AAEA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,cAAU;AAGV,QAAI,iBAAiB,EAAG;AACxB,QAAI,eAAe,EAAG;AAGtB,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAM,IAAI,UAAU,CAAC;AACrB,QAAE,KAAK,EAAE;AACT,QAAE,KAAK,EAAE;AACT,QAAE,MAAM;AACR,QAAE;AACF,UAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,IACxC;AAGA,aAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAM,QAAQ,YAAY,CAAC;AAC3B,YAAM,KAAK;AACX,YAAM;AACN,UAAI,MAAM,UAAU,EAAG,aAAY,OAAO,GAAG,CAAC;AAAA,IAChD;AAEA,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AAGtB,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,OAAO;AACb,YAAM,YAAY,OAAO;AACzB,YAAM,aAAa,OAAO;AAC1B,UAAIC,QAAO;AACX,UAAI,aAAa,YAAY;AAC3B,QAAAA,QAAO;AAAA,MACT,WAAW,WAAW;AACpB,QAAAA,QAAO;AAAA,MACT,OAAO;AACL,QAAAA,QAAO;AAAA,MACT;AACA,YAAM,OAAO,SAAS,QAAQ,OAAS,QAAQ,WAAW,IAAI,OAAS,IAAI;AAC3E,YAAMC,WAAU,KAAK,MAAM,OAAO,CAAC;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAGA,WAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI;AACxG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAGA,WAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI;AAClG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAGA,WAAU,KAAK,MAAMD,MAAK,SAAS,CAAC,CAAC,CAAC,WAAW,UAAU,GAAGA,KAAI;AAC/G,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAGA,UAAM,UAAU,kBAAkB;AAClC,QAAI,QAAQ,UAAU,cAAc,QAAQ,WAAW,aAAa;AAElE,cAAS,QAAQ,aAAc,QAAQ;AACvC,cAAS,QAAQ,cAAe,QAAQ;AACxC,gBAAU,KAAK,IAAI,SAAS,QAAQ,SAAS,aAAa;AAC1D,YAAM,KAAK,IAAI,KAAK,QAAQ,SAAS,aAAa;AAClD,mBAAa,QAAQ;AACrB,oBAAc,QAAQ;AAAA,IACxB;AAEA,eAAW,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,aAAa,KAAK,CAAC,CAAC;AAC9D,cAAU,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,cAAc,KAAK,CAAC,CAAC;AAG9D,UAAM,eAAe,cAAc,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC3E,UAAM,eAAe,cAAc,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI;AACvE,UAAM,cAAc,WAAW;AAC/B,UAAM,aAAa,UAAU;AAG7B,mBAAe,cAAc,KAAK;AAClC,UAAM,eAAe,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC7E,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI;AAE1D,cAAU,UAAU,MAAM;AAC1B,QAAI,eAAe,MAAM,cAAc,IAAI;AACzC,gBAAU,WAAW,MAAM,CAAC,CAAC;AAC7B,gBAAU,UAAU,SAAS,CAAC,YAAY,MAAM,CAAC,CAAC;AAAA,IACpD,OAAO;AACL,gBAAU,GAAG,UAAU,UAAU,MAAM,CAAC,CAAC;AACzC,gBAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,IAC5D;AAGA,UAAM,aAAa,aAAa,IAAI,eAAe;AACnD,QAAI,aAAa,EAAG;AACpB,UAAM,eAAe,UAAU,WAAW,YAAY,OAAO;AAC7D,UAAM,SAAS,KAAK,OAAO,OAAO,aAAa,UAAU,CAAC;AAC1D,cAAU,UAAU,MAAM,IAAI,UAAU,GAAG,YAAY;AAGvD,UAAM,kBAAkB,kBAAkB,SAAS,eAAe;AAClE,UAAM,mBAAmB,kBAAkB,UAAU,eAAe;AAGpE,UAAM,uBAAuB,eAAe,KAAK,eAAe,IAAI,IAAI,eAAe;AAGvF,UAAM,cAAc,iBAAiB,KAAK,iBAAiB,IAAI;AAC/D,UAAM,kBAAkB,cAAc,eAAe;AAGrD,cAAU,QAAQ,UAAU,IAAI,WAAW,IAAI,eAAe,SAAS,SAAI,OAAO,UAAU,CAAC;AAC7F,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,gBAAU,QAAQ,aAAa,IAAI,CAAC,IAAI,WAAW,IAAI,cAAc,eAAe,eAAe;AACnG,gBAAU,QAAQ,aAAa,IAAI,CAAC,IAAI,cAAc,aAAa,CAAC,IAAI,cAAc,eAAe,gBAAgB;AAAA,IACvH;AACA,cAAU,QAAQ,aAAa,cAAc,CAAC,IAAI,WAAW,IAAI,eAAe,SAAS,SAAI,OAAO,UAAU,CAAC;AAG/G,UAAM,UAAU,cAAc,IAAI,KAAK,MAAM,aAAa,CAAC;AAC3D,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,UAAI,IAAI,MAAM,GAAG;AACf,kBAAU,QAAQ,aAAa,IAAI,CAAC,IAAI,OAAO,WAAW,UAAU;AAAA,MACtE;AAAA,IACF;AAEA,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,eAAe,WAAW,KAAK,MAAM,aAAa,CAAC,IAAI;AAC7D,YAAM,SAAS,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACvD,YAAM,YAAY,eAAe,KAAK,MAAM,SAAS,SAAS,CAAC;AAC/D,gBAAU,QAAQ,MAAM,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ;AAErE,gBAAU,iBAAiB,kBAAkB,oBAAoB;AAAA,QAC/D,SAAS;AAAA,QACT,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,WAAW,eAAe,KAAK,MAAM,QAAQ,SAAS,CAAC;AAC7D,gBAAU,QAAQ,SAAS,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACzE,WAAW,CAAC,aAAa;AACvB,YAAM,WAAW;AACjB,YAAM,SAAS,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC3E,YAAM,SAAS,UAAU,KAAK,MAAM,cAAc,CAAC;AACnD,gBAAU,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ;AAElE,YAAM,WAAW;AACjB,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC1E,gBAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ;AAAA,IACvE,WAAW,UAAU;AACnB,YAAM,MAAM,eAAe;AAC3B,YAAM,UAAU,MAAM,uCAAuC;AAC7D,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,QAAQ,UAAU,CAAC,IAAI;AACzE,YAAM,QAAQ,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACtD,gBAAU,QAAQ,KAAK,IAAI,KAAK,IAAI,MAAM,eAAe,YAAY,GAAG,OAAO;AAE/E,YAAM,aAAa,UAAU,WAAW,MAAM,OAAO;AACrD,YAAM,UAAU,WAAW,KAAK,OAAO,aAAa,WAAW,UAAU,CAAC,IAAI;AAC9E,gBAAU,QAAQ,QAAQ,CAAC,IAAI,OAAO,IAAI,UAAU,GAAG,UAAU;AAEjE,YAAM,UAAU;AAChB,YAAM,WAAW,WAAW,KAAK,OAAO,aAAa,QAAQ,UAAU,CAAC,IAAI;AAC5E,gBAAU,QAAQ,QAAQ,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACxE,OAAO;AAEL,iBAAW,YAAY,eAAe;AACpC,cAAM,KAAK,cAAc,IAAI,KAAK,MAAM,SAAS,CAAC;AAClD,cAAM,KAAK,aAAa,IAAI,KAAK,MAAM,SAAS,CAAC;AACjD,YAAI,SAAS,KAAK,KAAK,SAAS,IAAI,aAAa;AAC/C,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,SAAS,KAAK,GAAG,SAAS,IAAI;AAAA,QAC9D;AAAA,MACF;AAGA,UAAI,gBAAgB,GAAG;AACrB,iBAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,gBAAM,QAAQ,UAAU,CAAC;AACzB,gBAAM,SAAS,cAAc,IAAI,KAAK,MAAM,MAAM,CAAC;AACnD,gBAAM,SAAS,aAAa,IAAI,KAAK,MAAM,MAAM,CAAC;AAClD,gBAAM,aAAa,IAAI,UAAU,SAAS,IAAI,YAAY;AAE1D,gBAAM,aAAa,MAAM,QAAQ,MAAM,aAAa,MAAM,QAAQ,MAAM,aAAa;AACrF,oBAAU,QAAQ,MAAM,IAAI,MAAM,IAAI,UAAU,GAAG,UAAU;AAAA,QAC/D;AAGA,cAAM,cAAc,cAAc,IAAI,KAAK,MAAM,KAAK;AACtD,cAAM,cAAc,aAAa,IAAI,KAAK,MAAM,KAAK;AACrD,cAAM,eAAe,KAAK,KAAK,SAAS,SAAS,SAAS,MAAM;AAChE,cAAM,YAAY,eAAe,MAAM,eAAe,eAAe,MAAM,eAAe;AAC1F,kBAAU,QAAQ,WAAW,IAAI,WAAW,IAAI,SAAS;AAAA,MAC3D;AAGA,iBAAW,KAAK,WAAW;AACzB,cAAM,KAAK,KAAK,MAAM,cAAc,IAAI,EAAE,CAAC;AAC3C,cAAM,KAAK,KAAK,MAAM,aAAa,IAAI,EAAE,CAAC;AAC1C,YAAI,EAAE,KAAK,KAAK,EAAE,IAAI,cAAc,EAAE,KAAK,KAAK,EAAE,IAAI,aAAa;AACjE,gBAAM,QAAQ,EAAE,OAAO,IAAI,KAAK;AAChC,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,QACxD;AAAA,MACF;AAGA,iBAAW,SAAS,aAAa;AAC/B,cAAM,KAAK,KAAK,MAAM,cAAc,IAAI,MAAM,CAAC;AAC/C,cAAM,KAAK,KAAK,MAAM,aAAa,IAAI,MAAM,CAAC;AAC9C,YAAI,MAAM,KAAK,KAAK,MAAM,IAAI,aAAa;AACzC,gBAAM,QAAQ,MAAM,SAAS,KAAK,YAAY;AAC9C,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM,IAAI;AAAA,QAChE;AAAA,MACF;AAGA,UAAI,cAAc,GAAG;AACnB,cAAM,WAAW,cAAc,KAAK,UAAK,UAAU,mBAAc,GAAG,UAAU;AAC9E,cAAM,SAAS,cAAc,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC9E,cAAM,aAAa,cAAc,IAAI,IAAI,eAAe;AACxD,kBAAU,QAAQ,aAAa,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,QAAQ;AAAA,MACrE;AAGA,YAAM,gBAAgB,cAAc,IAAI;AACxC,YAAM,oBAAoB,iBAAiB,KAAK,iBAAiB,IAAI,IAAI,eAAe;AACxF,eAAS,IAAI,GAAG,IAAI,eAAe,KAAK;AACtC,cAAM,KAAK,KAAK,MAAM,OAAO,IAAI;AACjC,YAAI,MAAM,KAAK,KAAK,aAAa;AAC/B,oBAAU,QAAQ,aAAa,IAAI,EAAE,IAAI,aAAa,IAAI,iBAAiB;AAAA,QAC7E;AAAA,MACF;AAGA,YAAM,YAAY,cAAc,aAAa;AAC7C,YAAM,gBAAgB,iBAAiB,KAAK,iBAAiB,IAAI,IAAI,eAAe;AACpF,eAAS,IAAI,GAAG,IAAI,eAAe,KAAK;AACtC,cAAM,KAAK,KAAK,MAAM,GAAG,IAAI;AAC7B,YAAI,MAAM,KAAK,KAAK,aAAa;AAC/B,oBAAU,QAAQ,aAAa,IAAI,EAAE,IAAI,SAAS,IAAI,aAAa;AAAA,QACrE;AAAA,MACF;AAGA,UAAI,cAAc,KAAK,YAAY;AACjC,cAAM,WAAW,eAAe,WAAW,wBAAwB;AACnE,cAAM,WAAW,eAAe,WAAW,eAAe;AAC1D,cAAM,OAAO,cAAc,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC5E,cAAM,OAAO,aAAa,KAAK,MAAM,cAAc,CAAC;AACpD,kBAAU,QAAQ,IAAI,IAAI,IAAI,IAAI,QAAQ,GAAG,QAAQ;AAAA,MACvD;AAAA,IACF;AAGA,UAAM,OAAO,eAAe,CAAC,YAAY,CAAC,SAAS,iBAAiB;AACpE,UAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,UAAU,CAAC;AACjD,cAAU,QAAQ,UAAU,cAAc,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,IAAI;AAEhF,aAAS,MAAM,MAAM;AAAA,EACvB;AAEA,WAAS,SAAS;AAChB,QAAI,CAAC,eAAe,YAAY,OAAQ;AAGxC,QAAI,cAAc,GAAG;AACnB;AACA,UAAI,cAAc,EAAG;AAGrB,iBAAW,YAAY,eAAe;AACpC,cAAM,KAAK,SAAS,IAAI,aAAa,IAAI,OAAO;AAChD,iBAAS,KAAK,MAAM,KAAK,OAAO,IAAI,OAAO;AAC3C,iBAAS,MAAM,KAAK,OAAO,IAAI,OAAO;AAAA,MACxC;AAGA,UAAI,gBAAgB,GAAG;AACrB,wBAAgB,CAAC;AACjB,wBAAgB;AAChB,qBAAa;AAAA,MACf;AACA;AAAA,IACF;AAGA,UAAM,eAAe,KAAK,KAAK,SAAS,SAAS,SAAS,MAAM;AAChE,cAAU,KAAK,EAAE,GAAG,OAAO,GAAG,OAAO,OAAO,aAAa,CAAC;AAC1D,QAAI,UAAU,SAAS,GAAG;AACxB,gBAAU,MAAM;AAAA,IAClB;AAGA,aAAS;AACT,aAAS;AAGT,QAAI,SAAS,KAAK,SAAS,cAAc,GAAG;AAC1C,eAAS,CAAC;AACV,cAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,cAAc,GAAG,KAAK,CAAC;AAEpD,qBAAe;AACf,MAAAD,gBAAe,OAAO,SAAS,IAAI,IAAI,cAAc,GAAG,GAAG,cAAc,CAAC,QAAK,UAAK,QAAG,CAAC;AAAA,IAC1F;AAGA,QAAI,SAAS,gBAAgB,KAAK,SAAS,eAAe;AACxD,UAAI,SAAS,WAAW,SAAS,UAAU,eAAe;AAExD,iBAAS,KAAK,IAAI,MAAM;AAGxB,cAAM,UAAU,QAAQ,WAAW;AACnC,cAAM,SAAS,SAAS,OAAO,KAAK,KAAK;AACzC,cAAM,QAAQ,KAAK,IAAI,gBAAgB,KAAK,KAAK,SAAS,SAAS,SAAS,MAAM,IAAI,IAAI;AAE1F,iBAAS,KAAK,IAAI,KAAK,IAAI;AAC3B,iBAAS,KAAK,IAAI,KAAK,IAAI;AAE3B,gBAAQ,gBAAgB;AAGxB;AACA,cAAM,kBAAkB,KAAK,IAAI,YAAY,EAAE;AAC/C,yBAAiB;AAEjB,YAAI,cAAc,EAAG,eAAc,KAAK,MAAM,kBAAkB,CAAC;AACjE,QAAAA,gBAAe,gBAAgB,GAAG,OAAO,IAAI,KAAK,MAAM,kBAAkB,CAAC,GAAG,YAAY,CAAC,UAAK,UAAK,UAAK,QAAG,CAAC;AAG9G,YAAI,cAAc,KAAK,aAAa,MAAM,GAAG;AAC3C,wBAAc,gBAAgB,GAAG,QAAQ,GAAG,GAAG,UAAU,KAAK,YAAY;AAAA,QAC5E;AAAA,MACF;AAAA,IACF;AAGA,QAAI,SAAS,aAAa,gBAAgB,KAAK,SAAS,aAAa,gBAAgB,GAAG;AACtF,UAAI,SAAS,OAAO,SAAS,MAAM,eAAe;AAChD,iBAAS,CAAC,KAAK,IAAI,MAAM;AAEzB,cAAM,UAAU,QAAQ,OAAO;AAC/B,cAAM,SAAS,SAAS,OAAO,KAAK,KAAK;AACzC,cAAM,QAAQ,KAAK,IAAI,gBAAgB,KAAK,KAAK,SAAS,SAAS,SAAS,MAAM,IAAI,IAAI;AAE1F,iBAAS,CAAC,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK;AAC1C,iBAAS,KAAK,IAAI,KAAK,IAAI;AAE3B,gBAAQ,aAAa,gBAAgB;AAGrC;AACA,cAAM,kBAAkB,KAAK,IAAI,YAAY,EAAE;AAC/C,yBAAiB;AAEjB,YAAI,cAAc,EAAG,eAAc,KAAK,MAAM,kBAAkB,CAAC;AACjE,QAAAA,gBAAe,aAAa,gBAAgB,GAAG,OAAO,IAAI,KAAK,MAAM,kBAAkB,CAAC,GAAG,cAAc,CAAC,UAAK,UAAK,UAAK,QAAG,CAAC;AAG7H,YAAI,cAAc,KAAK,aAAa,MAAM,GAAG;AAC3C,wBAAc,aAAa,gBAAgB,GAAG,QAAQ,GAAG,GAAG,UAAU,KAAK,YAAY;AAAA,QACzF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,QAAQ,GAAG;AAEb;AACA,mBAAa;AACb,oBAAc;AACd,mBAAa;AACb,oBAAc;AACd,sBAAgB;AAChB,0BAAoB,MAAM;AAE1B,oBAAc,aAAa,IAAI,GAAG,cAAc,IAAI,GAAG,UAAU,YAAY;AAE7E,MAAAA,gBAAe,GAAG,OAAO,IAAI,cAAc,CAAC,UAAK,QAAK,UAAK,QAAG,CAAC;AAC/D,UAAI,WAAW,WAAW;AACxB,mBAAW;AACX,sBAAc;AACd,sBAAc;AACd,QAAAA,gBAAe,aAAa,GAAG,cAAc,GAAG,IAAI,cAAc,CAAC,UAAK,UAAK,QAAK,QAAG,CAAC;AAAA,MACxF,OAAO;AACL,kBAAU,IAAI;AAAA,MAChB;AAAA,IACF,WAAW,QAAQ,aAAa,GAAG;AAEjC;AACA,mBAAa;AACb,oBAAc;AACd,mBAAa;AACb,oBAAc;AACd,sBAAgB;AAChB,0BAAoB,OAAO;AAE3B,YAAM,aAAa,cAAc,IAAI,KAAK,UAAU,aAAa;AACjE,oBAAc,aAAa,IAAI,GAAG,cAAc,IAAI,GAAG,KAAK,UAAU,IAAI,YAAY;AAEtF,MAAAA,gBAAe,aAAa,GAAG,OAAO,IAAI,cAAc,CAAC,UAAK,UAAK,UAAK,QAAG,CAAC;AAC5E,UAAI,eAAe,WAAW;AAC5B,mBAAW;AACX,sBAAc;AACd,sBAAc;AACd,QAAAA,gBAAe,aAAa,GAAG,cAAc,GAAG,IAAI,cAAc,CAAC,UAAK,UAAK,UAAK,QAAG,CAAC;AAAA,MACxF,OAAO;AACL,kBAAU,KAAK;AAAA,MACjB;AAAA,IACF;AAGA;AACA,QAAI,mBAAmB,mBAAmB;AACxC,wBAAkB;AAGlB,YAAM,UAAU,QAAQ,SAAS;AACjC,YAAM,WAAW,MAAM,gBAAgB;AAEvC,UAAI,UAAU,WAAW,GAAG;AAC1B,cAAM,KAAK,IAAI,GAAG,MAAM,QAAQ;AAAA,MAClC,WAAW,UAAU,WAAW,GAAG;AACjC,cAAM,KAAK,IAAI,cAAc,eAAe,MAAM,QAAQ;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AAGA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,kBAAc;AACd,cAAU;AACV,aAAS;AACT,kBAAc;AAEd,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AACZ,sBAAc,cAAc;AAC5B;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,eAAe,YAAY,MAAM;AACrC,UAAI,CAAC,SAAS;AACZ,sBAAc,YAAY;AAC1B;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AACZ,oBAAY,QAAQ;AACpB;AAAA,MACF;AAEA,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS,IAAI,YAAY;AAGrC,UAAI,QAAQ,UAAU;AACpB,iBAAS,CAAC;AACV,YAAI,OAAQ,sBAAqB;AACjC;AAAA,MACF;AAGA,UAAI,QAAQ,KAAK;AACf,YAAI,UAAU,YAAY,CAAC,aAAa;AACtC,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,qBAAW,KAAK;AAChB,2BAAiB,QAAQ;AACzB;AAAA,QACF;AAAA,MACF;AAIA,UAAI,CAAC,eAAe,CAAC,QAAQ;AAC3B,sBAAc;AACd;AAAA,MACF;AAEA,UAAI,UAAU;AACZ,YAAI,QAAQ,KAAK;AACf,wBAAc;AACd,oBAAU;AACV,mBAAS;AACT,wBAAc;AAAA,QAChB;AACA;AAAA,MACF;AAGA,UAAI,QAAQ;AAEV,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AACH,uBAAS;AACT;AAAA,YACF,KAAK;AACH,4BAAc;AACd,wBAAU;AACV,uBAAS;AACT,4BAAc;AACd,uBAAS;AACT;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,yBAAW,KAAK;AAChB,+BAAiB,QAAQ;AACzB;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,gCAAkB,QAAQ;AAC1B;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,iCAAmB,QAAQ;AAC3B;AAAA,UACJ;AACA;AAAA,QACF;AAGA,YAAI,QAAQ,KAAK;AACf,wBAAc;AACd,oBAAU;AACV,mBAAS;AACT,wBAAc;AACd,mBAAS;AAAA,QACX,WAAW,QAAQ,KAAK;AACtB,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,oBAAU;AACV,4BAAkB,QAAQ;AAAA,QAC5B,WAAW,QAAQ,KAAK;AACtB,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,oBAAU;AACV,6BAAmB,QAAQ;AAAA,QAC7B;AACA;AAAA,MACF;AAEA,cAAQ,SAAS,KAAK;AAAA,QACpB,KAAK;AAAA,QACL,KAAK;AACH,cAAI,UAAU,EAAG,YAAW;AAC5B;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,cAAI,UAAU,cAAc,cAAe,YAAW;AACtD;AAAA,MACJ;AAAA,IACF,CAAC;AAED,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,oBAAc,cAAc;AAC5B,oBAAc,YAAY;AAC1B,kBAAY,QAAQ;AACpB,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;ACptBO,SAAS,cAAc,UAAsC;AAClE,QAAM,aAAa,qBAAqB;AAGxC,QAAM,QAAQ;AACd,QAAM,eAAe;AACrB,QAAM,oBAAoB;AAC1B,QAAM,iBAAiB;AACvB,QAAM,gBAAgB;AACtB,QAAM,aAAa,oBAAoB,gBAAgB;AACvD,MAAI,UAAU;AACd,MAAI,WAAW;AAGf,QAAM,WAAW,aAAa;AAC9B,QAAM,WAAW,eAAe;AAEhC,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,qBAAqB;AACzB,MAAI,QAAQ;AACZ,MAAI,YAAY;AAChB,MAAI,WAAW;AACf,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,MAAI,aAAa;AACjB,MAAI,gBAAgB;AAGpB,MAAI,aAAa;AACjB,MAAI,YAAY;AAChB,MAAI,YAAY;AAChB,QAAM,gBAAgB;AACtB,MAAI,YAAY;AAChB,MAAI,aAAa;AACjB,QAAM,iBAAiB;AAGvB,MAAI,YAAwB,CAAC;AAC7B,MAAI,YAAoB,CAAC;AACzB,MAAI,YAAwB,CAAC;AAC7B,MAAI,eAA8B,CAAC;AACnC,MAAI,aAAa;AACjB,MAAI,gBAAgB;AAGpB,MAAI,cAAc;AAClB,MAAI,cAAc;AAClB,MAAI,cAAc;AAClB,MAAI,YAAwB,CAAC;AAC7B,MAAI,cAA4B,CAAC;AACjC,MAAI,mBAAmB;AACvB,MAAI,kBAAkB;AACtB,MAAI,kBAAkB;AACtB,MAAI,qBAAqB;AAEzB,QAAM,aAA+B;AAAA,IACnC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IAEZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAEA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAEA,WAAS,aAAa,MAAc,MAAc;AAChD,cAAU,kBAAkB,MAAM,cAAc;AAAA,MAC9C,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,QAAQ;AAAA,IACV,CAAC;AACD,eAAW,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,cAAc,CAAC,CAAC;AAAA,EAC5D;AAGA,WAAS,aAAa,KAAqB;AACzC,UAAM,IAAI,OAAO,eAAe;AAEhC,UAAM,SAAS,KAAK,IAAI,GAAG,GAAG;AAC9B,WAAO,KAAK,MAAM,kBAAkB,oBAAoB,kBAAkB,MAAM;AAAA,EAClF;AAGA,WAASG,gBAAe,GAAW,GAAW,OAAe,OAAe,QAAkB,CAAC,UAAK,UAAK,UAAK,QAAG,GAAG;AAClH,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,YAAMC,SAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAIA;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAIA,SAAQ;AAAA,QAC9B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,EACF;AAGA,WAAS,cAAc,GAAW,GAAW,MAAc,QAAgB,cAAc;AACvF,gBAAY,KAAK,EAAE,GAAG,GAAG,MAAM,QAAQ,IAAI,MAAM,CAAC;AAAA,EACpD;AAEA,WAAS,WAAW;AAClB,iBAAa;AACb,gBAAY;AACZ,gBAAY;AACZ,gBAAY;AACZ,iBAAa;AACb,YAAQ;AACR,eAAW;AACX,YAAQ;AACR,YAAQ;AACR,YAAQ;AACR,iBAAa;AACb,oBAAgB;AAChB,gBAAY,CAAC;AACb,gBAAY,CAAC;AACb,gBAAY,CAAC;AACb,mBAAe,CAAC;AAChB,iBAAa;AACb,oBAAgB;AAChB,eAAW;AACX,aAAS;AACT,kBAAc;AAEd,gBAAY,CAAC;AACb,kBAAc,CAAC;AACf,uBAAmB;AACnB,sBAAkB;AAClB,sBAAkB;AAClB,yBAAqB;AACrB,kBAAc;AAGd,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,gBAAU,KAAK;AAAA,QACb,GAAG,IAAI;AAAA,QACP,MAAM,IAAI,MAAM,IAAI,SAAS;AAAA,QAC7B,QAAQ,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI;AAAA,QACxC,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC;AAAA,MACrC,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,gBAAgB;AACvB,QAAI,UAAU,KAAK,OAAK,EAAE,IAAI,eAAe,CAAC,EAAG;AAEjD,UAAM,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,KAAK;AAC7C,UAAM,QAA4B,CAAC,OAAO,WAAW,OAAO;AAC5D,UAAM,OAAO,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAC3D,UAAM,SAA6B,SAAS,UAAU,SAAU,KAAK,OAAO,IAAI,MAAM,SAAS;AAE/F,cAAU,KAAK;AAAA,MACb,GAAG,eAAe;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAGD,QAAI,KAAK,OAAO,IAAI,KAAK;AACvB,UAAI,WAAW,KAAK,MAAM,KAAK,OAAO,IAAI,KAAK;AAC/C,UAAI,aAAa,KAAM,aAAY,WAAW,KAAK;AACnD,gBAAU,KAAK;AAAA,QACb,GAAG,eAAe,IAAI,KAAK,OAAO,IAAI;AAAA,QACtC,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,gBAAgB;AACvB,UAAM,OAAO,KAAK,OAAO,IAAI,MAAM,SAAS;AAC5C,cAAU,KAAK;AAAA,MACb,GAAG,eAAe;AAAA,MAClB;AAAA,MACA,QAAQ,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI;AAAA,MACxC,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC;AAAA,IACrC,CAAC;AAAA,EACH;AAEA,WAAS,gBAAwB;AAC/B,QAAI,WAAW;AACb,YAAM,WAAW,YAAY;AAC7B,aAAO,KAAK,IAAI,WAAW,KAAK,EAAE,IAAI;AAAA,IACxC;AACA,WAAO;AAAA,EACT;AAEA,WAAS,iBAA0B;AACjC,UAAM,UAAU;AAEhB,eAAW,OAAO,WAAW;AAC3B,UAAI,IAAI,SAAS,WAAY;AAC7B,YAAM,OAAO,KAAK,IAAI,IAAI,IAAI,OAAO;AACrC,UAAI,OAAO,IAAK;AAGhB,UAAI,OAAO,OAAO,QAAQ,KAAK;AAE7B,YAAI,IAAI,WAAW,UAAU,UAAW;AACxC,YAAI,IAAI,WAAW,SAAS,cAAc,IAAI,IAAK;AAAA,MACrD;AAEA,UAAI,IAAI,WAAW,UAAU,UAAW;AACxC,UAAI,IAAI,WAAW,SAAS,cAAc,IAAI,IAAK;AAEnD,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEA,WAAS,gBAAyB;AAChC,UAAM,UAAU;AAChB,eAAW,OAAO,WAAW;AAE3B,UAAI,KAAK,IAAI,IAAI,OAAO,UAAU,MAAM,KAAK,KAAK,IAAI,IAAI,IAAI,OAAO,IAAI,GAAG;AAC1E,eAAO;AAAA,MACT;AAEA,UAAI,IAAI,SAAS,cAAc,KAAK,IAAI,IAAI,IAAI,OAAO,IAAI,GAAG;AAC5D,YAAK,IAAI,WAAW,UAAU,aAAe,IAAI,WAAW,SAAS,cAAc,IAAI,KAAM;AAC3F,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,WAAS,eAAe;AACtB,UAAM,UAAU;AAChB,UAAM,WAAmB,CAAC;AAC1B,UAAM,OAAO,SAAS;AACtB,UAAM,UAAU,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,cAAc,CAAC,CAAC,IAAI,KAAK,MAAM,aAAa,CAAC;AAE5F,eAAW,QAAQ,WAAW;AAC5B,UAAI,KAAK,SAAS,cAAc,KAAK,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK;AAChE;AACA,cAAM,SAAS,KAAK,MAAM,MAAM,IAAI,QAAQ,IAAI;AAChD,iBAAS;AAGT,0BAAkB;AAClB,cAAM,YAAY,aAAa,eAAe,CAAC;AAC/C,cAAM,WAAW,UAAU,KAAK,MAAM,YAAY,CAAC;AACnD,cAAM,QAAQ,WAAW,KAAK,OAAQ,KAAK,OAAO,OAAO,QAAS,SAAS;AAC3E,cAAM,QAAQ,UAAU,eAAe,KAAK,MAAM,KAAK,CAAC;AAExD,QAAAD,gBAAe,QAAQ,UAAU,QAAQ,SAAS,GAAG,cAAc,CAAC,UAAK,UAAK,UAAK,QAAG,CAAC;AACvF,sBAAc,OAAO,OAAO,IAAI,MAAM,IAAI,YAAY;AAAA,MACxD,OAAO;AACL,iBAAS,KAAK,IAAI;AAAA,MACpB;AAAA,IACF;AACA,gBAAY;AAAA,EACd;AAEA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,cAAU;AAGV,QAAI,mBAAmB,EAAG;AAC1B,QAAI,kBAAkB,EAAG;AACzB,QAAI,kBAAkB,EAAG;AACzB,QAAI,qBAAqB,EAAG;AAG5B,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAM,IAAI,UAAU,CAAC;AACrB,QAAE,KAAK,EAAE;AACT,QAAE,KAAK,EAAE;AACT,QAAE,MAAM;AACR,QAAE;AACF,UAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,IACxC;AAGA,aAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAM,QAAQ,YAAY,CAAC;AAC3B,YAAM,KAAK;AACX,YAAM;AACN,UAAI,MAAM,UAAU,EAAG,aAAY,OAAO,GAAG,CAAC;AAAA,IAChD;AAEA,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AAEtB,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,OAAO;AACb,YAAM,YAAY,OAAO;AACzB,YAAM,aAAa,OAAO;AAC1B,UAAIE,QAAO,aAAa,aAAa,qBAAqB,YAAY,2BAAsB;AAC5F,YAAM,OAAO,SAAS,QAAQ,OAAI,QAAQ,WAAW,IAAI,OAAI,IAAI;AACjE,YAAMC,WAAU,KAAK,MAAM,OAAO,CAAC;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAGA,WAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI;AACxG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAGA,WAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI;AAClG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAGA,WAAU,KAAK,MAAMD,MAAK,SAAS,CAAC,CAAC,CAAC,WAAW,UAAU,GAAGA,KAAI;AAC/G,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAEA,iBAAa,MAAM,IAAI;AACvB,UAAM,SAAS,cAAc,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AACrE,UAAM,aAAa,WAAW;AAC9B,UAAM,UAAU,aAAa,KAAK,MAAM,aAAa,CAAC;AAGtD,mBAAe,cAAc,KAAK;AAClC,UAAM,eAAe,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC7E,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI;AAE1D,UAAM,WAAW,KAAK,IAAI,GAAG,UAAU,CAAC;AACxC,QAAI,eAAe,MAAM,cAAc,IAAI;AACzC,gBAAU,QAAQ,QAAQ,IAAI,MAAM,YAAY,MAAM,CAAC,CAAC;AACxD,gBAAU,QAAQ,WAAW,CAAC,IAAI,SAAS,CAAC,YAAY,MAAM,CAAC,CAAC;AAAA,IAClE,OAAO;AACL,gBAAU,QAAQ,QAAQ,IAAI,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AACpE,gBAAU,QAAQ,WAAW,CAAC,IAAI,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,IAC1E;AAGA,QAAI,QAAQ,UAAU,MAAM,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,YAAY,KAAK,YAAY,MAAM,QAAQ,CAAC,CAAC;AACpG,QAAI,QAAQ,GAAG;AACb,eAAS,oBAAoB,KAAK,UAAU,UAAU;AAAA,IACxD;AACA,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,UAAU,QAAQ,IAAI,KAAK,MAAM,CAAC;AAC1E,cAAU,UAAU,MAAM,IAAI,UAAU,GAAG,KAAK;AAGhD,QAAI,gBAAgB,GAAG;AACrB,YAAM,WAAW;AACjB,YAAM,SAAS,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC;AACtD,gBAAU,UAAU,MAAM,cAAc,QAAQ;AAAA,IAClD;AAEA,UAAM,cAAc,UAAU;AAG9B,eAAW,OAAO,WAAW;AAC3B,UAAI,IAAI,IAAI,KAAK,IAAI,IAAI,aAAc;AACvC,YAAM,MAAM,eAAe,KAAK,MAAM,IAAI,CAAC;AAC3C,UAAI,MAAM,KAAK,OAAO,aAAc;AAEpC,YAAM,UAAU,UAAU;AAC1B,YAAM,YAAY,aAAa,GAAG;AAClC,YAAM,WAAW,UAAU,KAAK,MAAM,YAAY,CAAC;AACnD,YAAM,YAAY,UAAU,KAAK,MAAM,YAAY,CAAC;AAGpD,YAAM,kBAAkB,MAAM;AAC9B,YAAM,MAAM,kBAAkB,MAAM,YAAY;AAGhD,YAAM,gBAAgB;AAAA,QACpB,CAAC,UAAK,UAAK,QAAG;AAAA;AAAA,QACd,CAAC,UAAK,UAAK,QAAG;AAAA;AAAA,QACd,CAAC,UAAK,UAAK,MAAG;AAAA;AAAA,MAChB;AACA,YAAM,QAAQ,cAAc,IAAI,KAAK;AAErC,UAAI,IAAI,SAAS,QAAQ;AACvB,cAAM,OAAO,WAAW,IAAI,KAAK,MAAM,kBAAkB,CAAC;AAC1D,iBAAS,IAAI,GAAG,IAAI,IAAI,UAAU,UAAU,KAAK,SAAS,KAAK;AAC7D,gBAAM,OAAO,MAAM,KAAK,IAAI,GAAG,MAAM,SAAS,CAAC,CAAC;AAChD,oBAAU,QAAQ,UAAU,CAAC,IAAI,IAAI,IAAI,GAAG,WAAW,IAAI,GAAG,IAAI;AAAA,QACpE;AAAA,MACF,OAAO;AACL,cAAM,OAAO,YAAY,IAAI,KAAK,MAAM,kBAAkB,CAAC;AAC3D,iBAAS,IAAI,GAAG,IAAI,IAAI,UAAU,UAAU,KAAK,SAAS,KAAK;AAC7D,gBAAM,OAAO,MAAM,KAAK,IAAI,GAAG,MAAM,SAAS,CAAC,CAAC;AAChD,oBAAU,QAAQ,UAAU,CAAC,IAAI,IAAI,IAAI,GAAG,WAAW,IAAI,GAAG,IAAI;AAAA,QACpE;AAAA,MACF;AAAA,IACF;AAGA,QAAI,QAAQ,KAAK;AACf,iBAAW,UAAU,cAAc;AACjC,YAAI,OAAO,QAAQ,EAAG;AACtB,cAAM,YAAY,OAAO,OAAO,IAAI,WAAM,OAAO,OAAO,IAAI,SAAM;AAClE,kBAAU,QAAQ,OAAO,CAAC,IAAI,OAAO,CAAC,WAAW,UAAU,GAAG,SAAS;AAAA,MACzE;AAAA,IACF;AAGA,aAAS,MAAM,GAAG,MAAM,cAAc,OAAO;AAC3C,YAAM,UAAU,UAAU;AAC1B,YAAM,YAAY,aAAa,GAAG;AAClC,YAAM,WAAW,UAAU,KAAK,MAAM,YAAY,CAAC;AACnD,YAAM,YAAY,UAAU,KAAK,MAAM,YAAY,CAAC;AACpD,YAAM,kBAAkB,MAAM;AAG9B,YAAM,WAAW,kBAAkB,MAAM,SAAM,kBAAkB,MAAM,WAAM,kBAAkB,MAAM,WAAM;AAC3G,YAAM,UAAU,kBAAkB,MAAM,YAAY;AAGpD,gBAAU,QAAQ,OAAO,IAAI,QAAQ,IAAI,OAAO,WAAW,QAAQ;AACnE,gBAAU,QAAQ,OAAO,IAAI,SAAS,IAAI,OAAO,WAAW,QAAQ;AAGpE,YAAM,cAAc,kBAAkB,MAAM,MAAM,kBAAkB,MAAM,WAAM;AAChF,UAAI,mBAAmB,KAAK;AAC1B,iBAAS,IAAI,WAAW,GAAG,IAAI,WAAW,KAAK;AAE7C,gBAAM,aAAa,YAAY,YAAY;AAC3C,gBAAM,gBAAgB,KAAK,KAAK,IAAI,YAAY,SAAS,IAAI;AAC7D,cAAI,CAAC,eAAe;AAClB,sBAAU,QAAQ,OAAO,IAAI,CAAC,mBAAmB,WAAW;AAAA,UAC9D;AAAA,QACF;AAAA,MACF;AAGA,YAAM,aAAa,KAAK,MAAM,cAAc,CAAC,IAAI,OAAO;AACxD,eAAS,OAAO,GAAG,OAAO,OAAO,QAAQ;AACvC,cAAM,QAAQ,WAAW,KAAK,MAAO,OAAO,QAAS,SAAS;AAC9D,cAAM,UAAU,kBAAkB,MAAM,YAAY;AAEpD,YAAI,YAAY,GAAG;AAEjB,gBAAM,WAAW,kBAAkB,OAAO,SAAM,kBAAkB,MAAM,SAAM;AAC9E,oBAAU,QAAQ,OAAO,IAAI,KAAK,IAAI,OAAO,WAAW,QAAQ;AAAA,QAClE,OAAO;AAEL,cAAI,mBAAmB,KAAK;AAC1B,sBAAU,QAAQ,OAAO,IAAI,KAAK,mBAAmB,WAAW;AAAA,UAClE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,eAAe,KAAK,MAAM,OAAO,CAAC;AACxC,YAAM,SAAS,UAAU,KAAK,MAAM,eAAe,CAAC,IAAI;AACxD,YAAM,YAAY,eAAe,KAAK,MAAM,SAAS,SAAS,CAAC;AAC/D,gBAAU,QAAQ,MAAM,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ;AAErE,gBAAU,iBAAiB,kBAAkB,oBAAoB;AAAA,QAC/D,SAAS;AAAA,QACT,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,WAAW,eAAe,KAAK,MAAM,QAAQ,SAAS,CAAC;AAC7D,gBAAU,QAAQ,SAAS,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACzE,WAAW,CAAC,aAAa;AACvB,YAAM,WAAW;AACjB,YAAM,SAAS,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC;AACtD,YAAM,SAAS,UAAU,KAAK,MAAM,eAAe,CAAC;AACpD,gBAAU,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ;AAElE,YAAM,WAAW;AACjB,YAAM,QAAQ,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC;AACrD,gBAAU,QAAQ,cAAc,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ;AAAA,IAC5E,WAAW,UAAU;AAEnB,YAAM,aAAa,mBAAmB,KAAK,mBAAmB,IAAI,IAAI,gBAAgB;AACtF,YAAM,UAAU;AAChB,YAAM,QAAQ,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC;AACpD,YAAM,QAAQ,UAAU,KAAK,MAAM,eAAe,CAAC,IAAI;AACvD,gBAAU,QAAQ,KAAK,IAAI,KAAK,IAAI,UAAU,GAAG,OAAO;AAExD,YAAM,YAAY,eAAe,KAAK,MAAM,QAAQ,CAAC;AACrD,YAAM,YAAY,YAAY,KAAK,YAAY,KAAK;AACpD,gBAAU,QAAQ,QAAQ,CAAC,IAAI,KAAK,OAAO,OAAO,UAAU,UAAU,CAAC,CAAC,IAAI,UAAU,GAAG,SAAS;AAClG,gBAAU,QAAQ,QAAQ,CAAC,IAAI,KAAK,OAAO,OAAO,UAAU,UAAU,CAAC,CAAC,IAAI,UAAU,GAAG,SAAS;AAElG,YAAM,UAAU;AAChB,gBAAU,QAAQ,QAAQ,CAAC,IAAI,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC,CAAC,WAAW,UAAU,GAAG,OAAO;AAGrG,iBAAW,KAAK,WAAW;AACzB,cAAM,KAAK,KAAK,MAAM,aAAa,EAAE,CAAC;AACtC,cAAM,KAAK,KAAK,MAAM,UAAU,EAAE,CAAC;AACnC,YAAI,KAAK,cAAc,KAAK,aAAa,cAAc,MAAM,WAAW,KAAK,aAAa;AACxF,gBAAM,QAAQ,EAAE,OAAO,IAAI,KAAK;AAChC,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,QACxD;AAAA,MACF;AAAA,IACF,OAAO;AAEL,iBAAW,QAAQ,WAAW;AAC5B,YAAI,KAAK,IAAI,KAAK,KAAK,IAAI,aAAc;AACzC,cAAM,MAAM,eAAe,KAAK,MAAM,KAAK,CAAC;AAC5C,YAAI,MAAM,KAAK,OAAO,aAAc;AAEpC,cAAM,UAAU,UAAU;AAC1B,cAAME,aAAY,aAAa,GAAG;AAClC,cAAMC,YAAW,UAAU,KAAK,MAAMD,aAAY,CAAC;AACnD,cAAM,QAAQC,YAAW,KAAK,OAAQ,KAAK,OAAO,OAAO,QAASD,UAAS;AAC3E,cAAM,kBAAkB,MAAM;AAE9B,cAAM,WAAW,kBAAkB,MAAM,SAAM,kBAAkB,MAAM,WAAM;AAC7E,cAAM,UAAU,kBAAkB,MAAM,YAAY;AACpD,kBAAU,QAAQ,OAAO,IAAI,KAAK,IAAI,OAAO,WAAW,QAAQ;AAAA,MAClE;AAGA,iBAAW,OAAO,WAAW;AAC3B,YAAI,IAAI,IAAI,KAAK,IAAI,IAAI,eAAe,EAAG;AAC3C,cAAM,MAAM,eAAe,KAAK,MAAM,IAAI,CAAC;AAC3C,YAAI,MAAM,KAAK,OAAO,aAAc;AAEpC,cAAM,UAAU,UAAU;AAC1B,cAAMA,aAAY,aAAa,GAAG;AAClC,cAAMC,YAAW,UAAU,KAAK,MAAMD,aAAY,CAAC;AACnD,cAAM,YAAYC,YAAW,KAAK,OAAQ,IAAI,OAAO,OAAO,QAASD,UAAS;AAC9E,cAAM,kBAAkB,MAAM;AAE9B,YAAI;AACJ,YAAI;AAGJ,YAAI,kBAAkB,MAAM;AAE1B,cAAI,IAAI,SAAS,OAAO;AAAE,sBAAU;AAAK,uBAAW;AAAA,UAAY,WACvD,IAAI,SAAS,SAAS;AAAE,sBAAU;AAAK,uBAAW;AAAA,UAAY,OAClE;AAAE,sBAAU;AAAK,uBAAW;AAAA,UAAY;AAAA,QAC/C,WAAW,kBAAkB,KAAK;AAEhC,cAAI,IAAI,SAAS,OAAO;AAAE,sBAAU;AAAM,uBAAW;AAAA,UAAY,WACxD,IAAI,SAAS,SAAS;AAAE,sBAAU;AAAK,uBAAW;AAAA,UAAY,OAClE;AAAE,sBAAU;AAAM,uBAAW;AAAA,UAAY;AAAA,QAChD,WAAW,kBAAkB,MAAM;AAEjC,cAAI,IAAI,SAAS,OAAO;AAAE,sBAAU;AAAO,uBAAW;AAAA,UAAY,WACzD,IAAI,SAAS,SAAS;AAAE,sBAAU;AAAO,uBAAW;AAAA,UAAY,OACpE;AAAE,sBAAU;AAAO,uBAAW;AAAA,UAAY;AAAA,QACjD,OAAO;AAEL,cAAI,IAAI,SAAS,OAAO;AAAE,sBAAU;AAAS,uBAAW;AAAA,UAAc,WAC7D,IAAI,SAAS,SAAS;AAAE,sBAAU;AAAQ,uBAAW;AAAA,UAAc,OACvE;AAAE,sBAAU;AAAS,uBAAW;AAAA,UAAc;AAAA,QACrD;AAEA,cAAM,OAAO,YAAY,KAAK,MAAM,QAAQ,SAAS,CAAC;AACtD,cAAM,SAAS,kBAAkB,OAAO,YAAY;AACpD,kBAAU,QAAQ,OAAO,IAAI,IAAI,IAAI,MAAM,GAAG,QAAQ,GAAG,OAAO;AAGhE,YAAI,IAAI,WAAW,UAAU,kBAAkB,OAAO,MAAM,GAAG;AAC7D,gBAAM,UAAU,IAAI,SAAS,UAAU,6BAAS,IAAI,SAAS,QAAQ,mCAAU;AAC/E,oBAAU,QAAQ,UAAU,CAAC,IAAI,IAAI,IAAI,QAAQ,GAAG,OAAO;AAAA,QAC7D;AAAA,MACF;AAGA,YAAM,YAAY,eAAe;AACjC,YAAM,gBAAgB,UAAU;AAChC,YAAM,YAAY,aAAa,SAAS;AACxC,YAAM,WAAW,UAAU,KAAK,MAAM,YAAY,CAAC;AACnD,YAAM,eAAe,WAAW,KAAK,OAAQ,aAAa,OAAO,QAAS,SAAS;AAEnF,UAAI;AACJ,UAAI,cAAc;AAClB,YAAM,aAAa,cAAc;AAEjC,UAAI,WAAW;AACb,sBAAc,CAAC,sBAAO,UAAK;AAC3B,sBAAc,YAAY;AAAA,MAC5B,WAAW,WAAW;AACpB,sBAAc,CAAC,oBAAK;AACpB,sBAAc;AAAA,MAChB,OAAO;AACL,cAAM,WAAW,KAAK,MAAM,WAAW,CAAC,IAAI;AAC5C,YAAI,aAAa,EAAG,eAAc,CAAC,sBAAO,eAAK;AAAA,iBACtC,aAAa,EAAG,eAAc,CAAC,sBAAO,eAAK;AAAA,iBAC3C,aAAa,EAAG,eAAc,CAAC,sBAAO,eAAK;AAAA,YAC/C,eAAc,CAAC,sBAAO,eAAK;AAAA,MAClC;AAEA,YAAM,UAAU,eAAe,KAAK,MAAM,YAAY,CAAC,EAAE,SAAS,CAAC;AACnE,YAAM,gBAAgB,KAAK,MAAM,UAAU;AAC3C,YAAM,eAAe,gBAAgB;AAGrC,eAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;AAC3C,YAAI,gBAAgB,YAAY,SAAS,IAAI,MAAM,SAAS;AAC1D,oBAAU,QAAQ,gBAAgB,YAAY,SAAS,IAAI,EAAE,IAAI,OAAO,IAAI,WAAW,GAAG,YAAY,CAAC,CAAC;AAAA,QAC1G;AAAA,MACF;AAGA,UAAI,aAAa,KAAK;AACpB,cAAM,aAAa,KAAK,IAAI,GAAG,IAAI,KAAK,MAAM,UAAU,CAAC;AACzD,cAAM,SAAS,SAAI,OAAO,UAAU;AACpC,kBAAU,QAAQ,aAAa,IAAI,eAAe,KAAK,MAAM,aAAa,CAAC,CAAC,WAAW,UAAU,GAAG,MAAM;AAAA,MAC5G;AAGA,iBAAW,KAAK,WAAW;AACzB,cAAM,KAAK,KAAK,MAAM,aAAa,EAAE,CAAC;AACtC,cAAM,KAAK,KAAK,MAAM,UAAU,EAAE,CAAC;AACnC,YAAI,KAAK,cAAc,KAAK,aAAa,cAAc,MAAM,WAAW,KAAK,aAAa;AACxF,gBAAM,QAAQ,EAAE,OAAO,IAAI,KAAK;AAChC,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,QACxD;AAAA,MACF;AAGA,iBAAW,SAAS,aAAa;AAC/B,cAAM,KAAK,KAAK,MAAM,MAAM,CAAC;AAC7B,cAAM,KAAK,KAAK,MAAM,MAAM,CAAC;AAC7B,YAAI,MAAM,WAAW,KAAK,aAAa;AACrC,gBAAM,QAAQ,MAAM,SAAS,KAAK,YAAY;AAC9C,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM,IAAI;AAAA,QAChE;AAAA,MACF;AAAA,IACF;AAGA,UAAM,OAAO,eAAe,CAAC,YAAY,CAAC,SAAS,SAAS,SAAS,mBAAmB;AACxF,UAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,UAAU,CAAC;AACjD,cAAU,QAAQ,cAAc,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,IAAI;AAEtE,aAAS,MAAM,MAAM;AAAA,EACvB;AAEA,WAAS,SAAS;AAChB,QAAI,CAAC,eAAe,YAAY,OAAQ;AAExC,QAAI,cAAc,EAAG;AACrB,QAAI,gBAAgB,EAAG;AACvB,QAAI,aAAa,GAAG;AAClB;AACA,UAAI,eAAe,EAAG,SAAQ;AAAA,IAChC;AAEA,mBAAe,QAAQ;AAGvB,QAAI,WAAW;AACb;AACA,UAAI,aAAa,eAAe;AAC9B,oBAAY;AACZ,oBAAY;AAAA,MACd;AAAA,IACF;AAGA,QAAI,WAAW;AACb;AACA,UAAI,cAAc,gBAAgB;AAChC,oBAAY;AACZ,qBAAa;AAAA,MACf;AAAA,IACF;AAGA,UAAM,YAAY,OAAO;AACzB,gBAAY,UAAU,OAAO,SAAO;AAClC,UAAI,KAAK;AACT,aAAO,IAAI,IAAI;AAAA,IACjB,CAAC;AACD,gBAAY,UAAU,OAAO,UAAQ;AACnC,WAAK,KAAK;AACV,aAAO,KAAK,IAAI;AAAA,IAClB,CAAC;AACD,gBAAY,UAAU,OAAO,SAAO;AAClC,UAAI,KAAK,YAAY;AACrB,aAAO,IAAI,IAAI;AAAA,IACjB,CAAC;AAGD,QAAI,QAAQ,OAAO,KAAK,OAAO,IAAI,KAAK;AACtC,mBAAa,KAAK;AAAA,QAChB,GAAG,UAAU,KAAK,MAAM,KAAK,OAAO,IAAI,YAAY;AAAA,QACpD,GAAG,WAAW,KAAK,MAAM,KAAK,OAAO,IAAI,UAAU;AAAA,QACnD,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AACA,mBAAe,aAAa,OAAO,OAAK;AACtC,QAAE;AACF,aAAO,EAAE,OAAO;AAAA,IAClB,CAAC;AAGD;AACA,UAAM,YAAY,KAAK,IAAI,IAAI,KAAK,QAAQ,CAAC;AAC7C,QAAI,cAAc,WAAW;AAC3B,mBAAa;AACb,oBAAc;AAAA,IAChB;AAGA;AACA,QAAI,iBAAiB,IAAI;AACvB,sBAAgB;AAChB,oBAAc;AAAA,IAChB;AAGA,QAAI,cAAc,GAAG;AACnB;AACA,mBAAa;AACb,sBAAgB;AAChB,YAAM,iBAAiB,KAAK;AAC5B,eAAS;AAGT,YAAM,OAAO,SAAS;AACtB,YAAM,UAAU,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,cAAc,CAAC,CAAC,IAAI,KAAK,MAAM,aAAa,CAAC;AAC5F,YAAM,YAAY,aAAa,eAAe,CAAC;AAC/C,YAAM,WAAW,UAAU,KAAK,MAAM,YAAY,CAAC;AACnD,YAAM,eAAe,WAAW,KAAK,OAAQ,aAAa,OAAO,QAAS,SAAS;AACnF,MAAAJ,gBAAe,eAAe,UAAU,eAAe,GAAG,GAAG,YAAY,CAAC,UAAK,UAAK,QAAG,CAAC;AAAA,IAC1F;AAEA,iBAAa;AAEb,QAAI,eAAe,GAAG;AACpB,iBAAW;AACX,oBAAc;AACd,yBAAmB;AACnB,UAAI,QAAQ,UAAW,aAAY;AAGnC,YAAM,OAAO,SAAS;AACtB,YAAM,UAAU,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,cAAc,CAAC,CAAC,IAAI,KAAK,MAAM,aAAa,CAAC;AAC5F,YAAM,YAAY,aAAa,eAAe,CAAC;AAC/C,YAAM,WAAW,UAAU,KAAK,MAAM,YAAY,CAAC;AACnD,YAAM,eAAe,WAAW,KAAK,OAAQ,aAAa,OAAO,QAAS,SAAS;AACnF,MAAAA,gBAAe,eAAe,UAAU,eAAe,GAAG,IAAI,cAAc,CAAC,UAAK,UAAK,QAAK,UAAK,QAAG,CAAC;AACrG;AAAA,IACF;AAEA,gBAAY,OAAO;AACnB,aAAS,KAAK,MAAM,SAAS,IAAI,QAAQ,IAAI;AAC7C,YAAQ,KAAK,IAAI,GAAG,IAAI,KAAK,MAAM,WAAW,EAAE,IAAI,GAAG;AAAA,EACzD;AAGA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,aAAS;AACT,kBAAc;AAEd,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AAAE,sBAAc,cAAc;AAAG;AAAA,MAAQ;AACvD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,eAAe,YAAY,MAAM;AACrC,UAAI,CAAC,SAAS;AAAE,sBAAc,YAAY;AAAG;AAAA,MAAQ;AACrD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AAAE,oBAAY,QAAQ;AAAG;AAAA,MAAQ;AAE/C,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS,IAAI,YAAY;AAGrC,UAAI,QAAQ,UAAU;AACpB,iBAAS,CAAC;AACV,YAAI,OAAQ,sBAAqB;AACjC;AAAA,MACF;AAGA,UAAI,QAAQ,KAAK;AACf,YAAI,UAAU,YAAY,CAAC,aAAa;AACtC,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,qBAAW,KAAK;AAChB,2BAAiB,QAAQ;AACzB;AAAA,QACF;AAAA,MACF;AAIA,UAAI,CAAC,eAAe,CAAC,QAAQ;AAC3B,sBAAc;AACd;AAAA,MACF;AAEA,UAAI,UAAU;AACZ,YAAI,QAAQ,KAAK;AACf,mBAAS;AACT,wBAAc;AAAA,QAChB;AACA;AAAA,MACF;AAGA,UAAI,QAAQ;AAEV,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AACH,uBAAS;AACT;AAAA,YACF,KAAK;AACH,uBAAS;AACT,4BAAc;AACd,uBAAS;AACT;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,yBAAW,KAAK;AAChB,+BAAiB,QAAQ;AACzB;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,gCAAkB,QAAQ;AAC1B;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,iCAAmB,QAAQ;AAC3B;AAAA,UACJ;AACA;AAAA,QACF;AAGA,YAAI,QAAQ,KAAK;AACf,mBAAS;AACT,wBAAc;AACd,mBAAS;AAAA,QACX,WAAW,QAAQ,KAAK;AACtB,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,oBAAU;AACV,4BAAkB,QAAQ;AAAA,QAC5B,WAAW,QAAQ,KAAK;AACtB,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,oBAAU;AACV,6BAAmB,QAAQ;AAAA,QAC7B;AACA;AAAA,MACF;AAEA,cAAQ,SAAS,KAAK;AAAA,QACpB,KAAK;AAAA,QACL,KAAK;AACH,cAAI,aAAa,EAAG;AACpB;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,cAAI,aAAa,QAAQ,EAAG;AAC5B;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AACH,cAAI,CAAC,aAAa,CAAC,WAAW;AAC5B,wBAAY;AACZ,wBAAY;AAAA,UACd;AACA;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,cAAI,CAAC,aAAa,CAAC,WAAW;AAC5B,wBAAY;AACZ,yBAAa;AAAA,UACf;AACA;AAAA,MACJ;AAAA,IACF,CAAC;AAED,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,oBAAc,cAAc;AAC5B,oBAAc,YAAY;AAC1B,kBAAY,QAAQ;AACpB,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;AC/5BO,SAAS,aAAa,UAAqC;AAChE,QAAM,aAAa,qBAAqB;AAKxC,QAAM,WAAW;AACjB,QAAM,WAAW;AACjB,QAAM,aAAa;AACnB,QAAM,cAAc;AAGpB,QAAM,kBAAkB;AAAA,IACtB;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,EACF;AAEA,QAAM,sBAAsB;AAAA,IAC1B;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,EACF;AAEA,QAAM,iBAAiB,CAAC,KAAK,KAAK,KAAK,GAAG;AAC1C,QAAM,iBAAiB,CAAC,MAAM,SAAS,QAAQ,MAAM;AAGrD,QAAM,sBAAsB;AAC5B,QAAM,sBAAsB;AAC5B,QAAM,mBAAmB;AAKzB,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,qBAAqB;AACzB,MAAI,MAAM;AACV,MAAI,QAAQ;AACZ,MAAI,YAAY;AAGhB,MAAI,WAAW;AACf,MAAI,UAAU;AAGd,MAAI,cAAc;AAClB,MAAI,YAAwB,CAAC;AAC7B,MAAI,cAA4B,CAAC;AACjC,MAAI,cAAc;AAClB,MAAI,iBAAiB;AAGrB,MAAI,WAAuB,CAAC;AAC5B,MAAI,cAAc;AAClB,MAAI,eAAe;AACnB,MAAI,aAAa;AAIjB,MAAI,QAAmB;AACvB,MAAI,eAAe;AACnB,MAAI,aAAa;AACjB,MAAI,aAAa;AACjB,MAAI,eAAe;AACnB,MAAI,eAAe;AAGnB,MAAI,cAA+B;AACnC,MAAI,oBAAqC;AACzC,MAAI,iBAAiB;AAGrB,MAAI,gBAAgB;AACpB,MAAI,cAAc;AAClB,MAAI,cAAc;AAGlB,OAAK;AACL,OAAK;AAKL,QAAM,aAA8B;AAAA,IAClC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IACZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAKA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAMA,WAASM,gBAAe,GAAW,GAAW,OAAe,OAAe,QAAkB,CAAC,UAAU,UAAU,UAAU,QAAQ,GAAG;AACtI,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ;AAAA,QAC9B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,oBAAoB,UAAoB;AAC/C,UAAM,UAAU,aAAa;AAC7B,UAAM,UAAU,cAAc;AAC9B,UAAM,SAAS;AAEf,QAAI,IAAI;AACR,QAAI,IAAI;AAER,YAAQ,UAAU;AAAA,MAChB,KAAK;AAAG,YAAI,UAAU;AAAQ;AAAA,MAC9B,KAAK;AAAG,YAAI,UAAU,SAAS;AAAG;AAAA,MAClC,KAAK;AAAG,YAAI,UAAU;AAAQ;AAAA,MAC9B,KAAK;AAAG,YAAI,UAAU,SAAS;AAAG;AAAA,IACpC;AAEA,IAAAA,gBAAe,GAAG,GAAG,GAAG,gBAAgB,QAAQ,GAAG,CAAC,UAAU,UAAU,UAAU,QAAQ,CAAC;AAAA,EAC7F;AAEA,WAAS,cAAc,GAAW,GAAW,MAAc,QAAgB,cAAc;AACvF,gBAAY,KAAK,EAAE,GAAG,GAAG,MAAM,QAAQ,IAAI,MAAM,CAAC;AAAA,EACpD;AAEA,WAAS,aAAa,QAAgB,WAAmB;AACvD,kBAAc;AACd,qBAAiB;AAAA,EACnB;AAMA,WAAS,WAAW;AAClB,YAAQ;AACR,eAAW;AACX,UAAM;AACN,aAAS;AAGT,gBAAY,CAAC;AACb,kBAAc,CAAC;AACf,kBAAc;AAGd,eAAW,CAAC;AACZ,kBAAc;AACd,mBAAe;AACf,iBAAa;AACb,YAAQ;AACR,mBAAe;AACf,iBAAa;AACb,iBAAa;AACb,mBAAe;AACf,mBAAe;AACf,kBAAc;AACd,wBAAoB;AACpB,qBAAiB;AAEjB,oBAAgB;AAChB,kBAAc;AACd,kBAAc;AAGd,eAAW,MAAM;AACf,UAAI,WAAW,eAAe,CAAC,UAAU,CAAC,UAAU;AAClD,sBAAc;AAAA,MAChB;AAAA,IACF,GAAG,GAAI;AAAA,EACT;AAEA,WAAS,gBAAgB;AAEvB,aAAS,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,CAAa;AAGvD,YAAQ;AACR,mBAAe;AACf,iBAAa;AACb,iBAAa,KAAK,MAAM,sBAAsB,CAAC;AAE/C,oBAAgB,SAAS,YAAY;AACrC,kBAAc;AACd,kBAAc;AAAA,EAChB;AAEA,WAAS,kBAAkB,UAAoB;AAC7C,QAAI,UAAU,iBAAiB,UAAU,SAAU;AAGnD,wBAAoB;AACpB,qBAAiB;AAGjB,QAAI,aAAa,SAAS,WAAW,GAAG;AAEtC;AACA,0BAAoB,QAAQ;AAE5B,UAAI,eAAe,SAAS,QAAQ;AAElC,gBAAQ;AACR,uBAAe;AACf,iBAAS,eAAe;AAExB,cAAM,UAAU,aAAa;AAC7B,cAAM,UAAU,cAAc;AAC9B,sBAAc,UAAU,GAAG,UAAU,GAAG,IAAI,eAAe,EAAE,IAAI,YAAY;AAG7E,QAAAA,gBAAe,SAAS,SAAS,IAAI,cAAc,CAAC,UAAU,UAAU,UAAU,QAAQ,CAAC;AAE3F,wBAAgB;AAChB,sBAAc;AACd,sBAAc;AAEd,qBAAa,GAAG,CAAC;AAAA,MACnB;AAAA,IACF,OAAO;AAEL,cAAQ;AACR,qBAAe;AACf,iBAAW;AAEX,UAAI,QAAQ,WAAW;AACrB,oBAAY;AAAA,MACd;AAEA,sBAAgB;AAChB,oBAAc;AACd,oBAAc;AAEd,mBAAa,IAAI,CAAC;AAGlB,YAAM,UAAU,aAAa;AAC7B,YAAM,UAAU,cAAc;AAC9B,MAAAA,gBAAe,SAAS,SAAS,IAAI,cAAc,CAAC,UAAU,UAAU,QAAU,QAAQ,CAAC;AAAA,IAC7F;AAAA,EACF;AAEA,WAAS,SAAS;AAChB,QAAI,CAAC,eAAe,YAAY,OAAQ;AAGxC,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAM,IAAI,UAAU,CAAC;AACrB,QAAE,KAAK,EAAE;AACT,QAAE,KAAK,EAAE;AACT,QAAE,MAAM;AACR,QAAE;AACF,UAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,IACxC;AAGA,aAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAM,QAAQ,YAAY,CAAC;AAC3B,YAAM,KAAK;AACX,YAAM;AACN,UAAI,MAAM,UAAU,EAAG,aAAY,OAAO,GAAG,CAAC;AAAA,IAChD;AAGA,QAAI,iBAAiB,GAAG;AACtB;AACA,UAAI,kBAAkB,GAAG;AACvB,4BAAoB;AAAA,MACtB;AAAA,IACF;AAGA,YAAQ,OAAO;AAAA,MACb,KAAK;AACH,2BAAmB;AACnB;AAAA,MACF,KAAK;AACH,2BAAmB;AACnB;AAAA,IACJ;AAAA,EACF;AAEA,WAAS,qBAAqB;AAC5B,UAAM,gBAAgB,KAAK,MAAM,sBAAsB,UAAU;AACjE,UAAM,gBAAgB,KAAK,MAAM,sBAAsB,UAAU;AAEjE,QAAI,aAAa,GAAG;AAElB;AACA,oBAAc;AACd;AAAA,IACF;AAEA,QAAI,aAAa,GAAG;AAElB;AACA,UAAI,cAAc,GAAG;AACnB,sBAAc;AACd;AAEA,YAAI,gBAAgB,SAAS,QAAQ;AAEnC,kBAAQ;AACR,wBAAc;AACd,0BAAgB;AAChB,wBAAc;AACd,wBAAc;AAAA,QAChB,OAAO;AACL,uBAAa;AAAA,QACf;AAAA,MACF;AACA;AAAA,IACF;AAGA,QAAI,eAAe,SAAS,QAAQ;AAClC,oBAAc,SAAS,YAAY;AACnC,mBAAa;AAAA,IACf;AAAA,EACF;AAEA,WAAS,qBAAqB;AAC5B;AACA,QAAI,gBAAgB,GAAG;AAErB;AACA,oBAAc;AACd,oBAAc;AACd,oBAAc;AAAA,IAChB;AAAA,EACF;AAMA,WAAS,eAAe,QAAkB,UAAoB,OAAgB,YAAoB,WAAyB;AACzH,UAAM,UAAU,KAAK,MAAM,aAAa,CAAC;AACzC,UAAM,UAAU,KAAK,MAAM,cAAc,CAAC;AAC1C,UAAM,QAAQ,QAAQ,gBAAgB,QAAQ,IAAI,oBAAoB,QAAQ;AAG9E,UAAM,SAAS;AACf,UAAM,UAAU;AAEhB,QAAI,SAAS,aAAa;AAC1B,QAAI,SAAS,YAAY;AAGzB,YAAQ,UAAU;AAAA,MAChB,KAAK;AACH,iBAAS,aAAa,UAAU,KAAK,MAAM,SAAS,CAAC;AACrD,iBAAS,YAAY;AACrB;AAAA,MACF,KAAK;AACH,iBAAS,aAAa,UAAU;AAChC,iBAAS,YAAY,UAAU,KAAK,MAAM,UAAU,CAAC;AACrD;AAAA,MACF,KAAK;AACH,iBAAS,aAAa,UAAU,KAAK,MAAM,SAAS,CAAC;AACrD,iBAAS,YAAY,cAAc,UAAU;AAC7C;AAAA,MACF,KAAK;AACH,iBAAS,aAAa,UAAU,SAAS;AACzC,iBAAS,YAAY,UAAU,KAAK,MAAM,UAAU,CAAC;AACrD;AAAA,IACJ;AAGA,UAAM,WAAW,QAAQ,WAAW;AACpC,UAAM,YAAY,WAAW,SAAS,OAAO,MAAM,IAAI;AACvD,UAAM,eAAe,WAAW,SAAS,OAAO,MAAM,IAAI;AAE1D,WAAO,KAAK,QAAQ,MAAM,IAAI,MAAM,IAAI,KAAK,GAAG,SAAS,SAAS;AAElE,aAAS,MAAM,GAAG,MAAM,SAAS,OAAO;AACtC,YAAM,IAAI,SAAS,IAAI;AAEvB,UAAI,QAAQ,KAAK,MAAM,UAAU,CAAC,GAAG;AAEnC,cAAM,QAAQ,GAAG,eAAe,QAAQ,CAAC,KAAK,eAAe,QAAQ,CAAC;AACtE,cAAM,UAAU,KAAK,OAAO,SAAS,MAAM,UAAU,CAAC;AACtD,cAAM,UAAU,SAAS,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC;AACpD,cAAM,WAAW,SAAS,OAAO,KAAK,IAAI,GAAG,SAAS,UAAU,MAAM,MAAM,CAAC;AAC7E,eAAO,KAAK,QAAQ,CAAC,IAAI,MAAM,IAAI,KAAK,SAAS,OAAO,GAAG,QAAQ,eAAe,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,eAAe;AAAA,MACvI,OAAO;AACL,eAAO,KAAK,QAAQ,CAAC,IAAI,MAAM,IAAI,KAAK,SAAS,SAAS,OAAO,MAAM,CAAC,eAAe;AAAA,MACzF;AAAA,IACF;AAEA,WAAO,KAAK,QAAQ,SAAS,UAAU,CAAC,IAAI,MAAM,IAAI,KAAK,GAAG,YAAY,SAAS;AAAA,EACrF;AAEA,WAAS,SAAS;AAChB,UAAM,cAAwB,CAAC;AAC/B,gBAAY,KAAK,eAAe;AAGhC,QAAI,cAAc,EAAG;AAErB,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AAGtB,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,OAAO;AACb,YAAM,YAAY,OAAO;AACzB,YAAM,aAAa,OAAO;AAC1B,YAAMC,QAAO,aAAa,aAAa,qBACnC,YAAY,2BAA2B;AAC3C,YAAM,OAAO,SAAS,QAAQ,OAAS,QAAQ,WAAW,IAAI,OAAS,IAAI;AAC3E,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,kBAAY,KAAK,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI,SAAS;AACxH,kBAAY,KAAK,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI,SAAS;AAClH,kBAAY,KAAK,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAMA,MAAK,SAAS,CAAC,CAAC,CAAC,WAAW,UAAU,GAAGA,KAAI,SAAS;AAC/H,eAAS,MAAM,YAAY,KAAK,EAAE,CAAC;AACnC;AAAA,IACF;AAGA,eAAW,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,aAAa,KAAK,CAAC,CAAC;AAC9D,cAAU,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,cAAc,KAAK,CAAC,CAAC;AAG9D,QAAI,aAAa;AACjB,QAAI,YAAY;AAChB,QAAI,cAAc,GAAG;AACnB,oBAAc,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,iBAAiB,CAAC;AACnE,mBAAa,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,cAAc;AAAA,IAChE;AAGA,mBAAe,cAAc,KAAK;AAClC,UAAM,eAAe,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC7E,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI;AAE1D,QAAI,eAAe,MAAM,cAAc,IAAI;AACzC,kBAAY,KAAK,UAAU,MAAM,YAAY,MAAM,CAAC,CAAC,SAAS;AAC9D,kBAAY,KAAK,UAAU,SAAS,CAAC,YAAY,MAAM,CAAC,CAAC,SAAS;AAAA,IACpE,OAAO;AACL,kBAAY,KAAK,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC,SAAS;AAC1E,kBAAY,KAAK,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC,SAAS;AAAA,IAC5E;AAGA,UAAM,QAAQ,UAAU,YAAY,YAAY,MAAM,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,WAAW,UAAU,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC;AACjI,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,UAAU,CAAC;AACnD,gBAAY,KAAK,QAAQ,UAAU,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,KAAK,SAAS;AAG7E,gBAAY,KAAK,QAAQ,SAAS,IAAI,UAAU,IAAI,UAAU,SAAS,SAAS,OAAO,UAAU,CAAC,eAAe;AACjH,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,kBAAY,KAAK,QAAQ,YAAY,IAAI,CAAC,IAAI,UAAU,IAAI,UAAU,eAAe;AACrF,kBAAY,KAAK,QAAQ,YAAY,IAAI,CAAC,IAAI,aAAa,aAAa,CAAC,IAAI,UAAU,eAAe;AAAA,IACxG;AACA,gBAAY,KAAK,QAAQ,YAAY,cAAc,CAAC,IAAI,UAAU,IAAI,UAAU,SAAS,SAAS,OAAO,UAAU,CAAC,eAAe;AAGnI,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,eAAe,KAAK,MAAM,OAAO,CAAC;AACxC,YAAM,SAAS,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACvD,YAAM,YAAY,eAAe,KAAK,MAAM,SAAS,SAAS,CAAC;AAC/D,kBAAY,KAAK,QAAQ,MAAM,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ,SAAS;AAErF,kBAAY,KAAK,iBAAiB,kBAAkB,oBAAoB;AAAA,QACtE,SAAS;AAAA,QACT,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC,CAAC;AAEF,YAAM,UAAU;AAChB,YAAM,WAAW,eAAe,KAAK,MAAM,QAAQ,SAAS,CAAC;AAC7D,kBAAY,KAAK,QAAQ,SAAS,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO,SAAS;AAAA,IACzF,WAES,CAAC,aAAa;AACrB,YAAM,WAAW;AACjB,YAAM,SAAS,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC3E,YAAM,SAAS,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACvD,kBAAY,KAAK,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ,SAAS;AAElF,YAAM,WAAW;AACjB,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC1E,kBAAY,KAAK,QAAQ,SAAS,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ,SAAS;AAErF,YAAM,OAAO;AACb,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,KAAK,UAAU,CAAC,IAAI;AACtE,kBAAY,KAAK,QAAQ,SAAS,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,IAAI,SAAS;AAAA,IACnF,WAES,UAAU;AAEjB,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,uBAAe,aAAa,GAAe,OAAO,YAAY,SAAS;AAAA,MACzE;AAEA,YAAM,UAAU;AAChB,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,QAAQ,UAAU,CAAC,IAAI;AACzE,YAAM,QAAQ,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACtD,kBAAY,KAAK,QAAQ,KAAK,IAAI,KAAK,cAAc,OAAO,SAAS;AAErE,YAAM,YAAY,mBAAmB,eAAe,CAAC,YAAY,KAAK;AACtE,YAAM,SAAS,WAAW,KAAK,OAAO,aAAa,UAAU,UAAU,CAAC,IAAI;AAC5E,kBAAY,KAAK,QAAQ,QAAQ,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,SAAS,SAAS;AAE/E,YAAM,WAAW,SAAS,YAAY,kCAAkC,eAAe,SAAS;AAChG,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC1E,YAAM,YAAY,SAAS,YAAY,eAAe;AACtD,kBAAY,KAAK,QAAQ,QAAQ,CAAC,IAAI,KAAK,IAAI,SAAS,GAAG,QAAQ,SAAS;AAE5E,YAAM,UAAU;AAChB,YAAM,WAAW,WAAW,KAAK,OAAO,aAAa,QAAQ,UAAU,CAAC,IAAI;AAC5E,kBAAY,KAAK,QAAQ,QAAQ,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO,SAAS;AAAA,IACxF,OAEK;AAEH,YAAM,YAAY,sBAAsB,OAAO,oBAAoB;AAGnE,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,uBAAe,aAAa,GAAe,cAAc,GAAG,YAAY,SAAS;AAAA,MACnF;AAGA,YAAM,aAAa,eAAe,cAAc,KAAK,KAAK,YAAY;AACtE,YAAM,OAAO,WAAW,KAAK,OAAO,aAAa,cAAc,UAAU,CAAC,IAAI;AAC9E,YAAM,OAAO,UAAU,KAAK,MAAM,cAAc,CAAC;AACjD,kBAAY,KAAK,QAAQ,IAAI,IAAI,IAAI,IAAI,UAAU,GAAG,WAAW,GAAG,aAAa,SAAS;AAG1F,UAAI,UAAU,eAAe;AAC3B,cAAM,WAAW,IAAI,cAAc,CAAC,IAAI,SAAS,MAAM;AACvD,cAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC1E,oBAAY,KAAK,QAAQ,OAAO,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ,SAAS;AAAA,MACrF;AAGA,iBAAW,KAAK,WAAW;AACzB,cAAM,UAAU,KAAK,MAAM,aAAa,IAAI,EAAE,CAAC;AAC/C,cAAM,UAAU,KAAK,MAAM,YAAY,IAAI,EAAE,CAAC;AAC9C,YAAI,UAAU,cAAc,UAAU,aAAa,aAAa,KAC5D,UAAU,aAAa,UAAU,YAAY,cAAc,GAAG;AAChE,gBAAM,QAAQ,EAAE,OAAO,IAAI,KAAK;AAChC,sBAAY,KAAK,QAAQ,OAAO,IAAI,OAAO,IAAI,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI,SAAS;AAAA,QAClF;AAAA,MACF;AAGA,iBAAW,SAAS,aAAa;AAC/B,cAAM,UAAU,KAAK,MAAM,aAAa,IAAI,MAAM,CAAC;AACnD,cAAM,UAAU,KAAK,MAAM,YAAY,IAAI,MAAM,CAAC;AAClD,YAAI,UAAU,aAAa,UAAU,YAAY,cAAc,GAAG;AAChE,gBAAM,QAAQ,MAAM,SAAS,KAAK,YAAY;AAC9C,sBAAY,KAAK,QAAQ,OAAO,IAAI,OAAO,IAAI,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM,IAAI,SAAS;AAAA,QAC1F;AAAA,MACF;AAAA,IACF;AAGA,UAAM,OAAO,eAAe,CAAC,YAAY,CAAC,SAAS,oBAAoB,SAAS,MAAM,mBAAmB;AACzG,UAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,UAAU,CAAC;AACjD,gBAAY,KAAK,QAAQ,UAAU,cAAc,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,IAAI,SAAS;AAEhG,aAAS,MAAM,YAAY,KAAK,EAAE,CAAC;AAAA,EACrC;AAMA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,aAAS;AACT,kBAAc;AAEd,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AAAE,sBAAc,cAAc;AAAG;AAAA,MAAQ;AACvD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,eAAe,YAAY,MAAM;AACrC,UAAI,CAAC,SAAS;AAAE,sBAAc,YAAY;AAAG;AAAA,MAAQ;AACrD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AAAE,oBAAY,QAAQ;AAAG;AAAA,MAAQ;AAE/C,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS,IAAI,YAAY;AAGrC,UAAI,QAAQ,UAAU;AACpB,iBAAS,CAAC;AACV,YAAI,OAAQ,sBAAqB;AACjC;AAAA,MACF;AAGA,UAAI,QAAQ,QAAQ,UAAU,YAAY,CAAC,cAAc;AACvD,sBAAc,cAAc;AAC5B,sBAAc,YAAY;AAC1B,mBAAW,KAAK;AAChB,yBAAiB,QAAQ;AACzB;AAAA,MACF;AAGA,UAAI,CAAC,eAAe,CAAC,QAAQ;AAC3B,sBAAc;AACd,iBAAS;AACT,sBAAc;AACd;AAAA,MACF;AAGA,UAAI,UAAU;AACZ,YAAI,QAAQ,KAAK;AACf,mBAAS;AACT,wBAAc;AAAA,QAChB;AACA;AAAA,MACF;AAGA,UAAI,QAAQ;AACV,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AAAG,uBAAS;AAAO;AAAA,YACxB,KAAK;AAAG,uBAAS;AAAG,4BAAc;AAAM,uBAAS;AAAO;AAAA,YACxD,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,yBAAW,KAAK;AAChB,+BAAiB,QAAQ;AACzB;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,gCAAkB,QAAQ;AAC1B;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,iCAAmB,QAAQ;AAC3B;AAAA,UACJ;AACA;AAAA,QACF;AAGA,YAAI,QAAQ,KAAK;AAAE,mBAAS;AAAG,wBAAc;AAAM,mBAAS;AAAA,QAAO,WAC1D,QAAQ,KAAK;AAAE,wBAAc,cAAc;AAAG,wBAAc,YAAY;AAAG,oBAAU;AAAO,4BAAkB,QAAQ;AAAA,QAAG,WACzH,QAAQ,KAAK;AAAE,wBAAc,cAAc;AAAG,wBAAc,YAAY;AAAG,oBAAU;AAAO,6BAAmB,QAAQ;AAAA,QAAG;AACnI;AAAA,MACF;AAGA,UAAI,UAAU,eAAe;AAC3B,gBAAQ,SAAS,KAAK;AAAA,UACpB,KAAK;AAAA,UACL,KAAK;AACH,8BAAkB,CAAC;AACnB;AAAA,UACF,KAAK;AAAA,UACL,KAAK;AACH,8BAAkB,CAAC;AACnB;AAAA,UACF,KAAK;AAAA,UACL,KAAK;AACH,8BAAkB,CAAC;AACnB;AAAA,UACF,KAAK;AAAA,UACL,KAAK;AACH,8BAAkB,CAAC;AACnB;AAAA,QACJ;AAAA,MACF;AAAA,IACF,CAAC;AAGD,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,oBAAc,cAAc;AAC5B,oBAAc,YAAY;AAC1B,kBAAY,QAAQ;AACpB,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;ACxvBO,SAAS,aAAa,UAAqC;AAChE,QAAM,aAAa,qBAAqB;AAGxC,QAAM,WAAW;AACjB,QAAM,WAAW;AAGjB,MAAI,OAAO,SAAS;AACpB,MAAI,OAAO,SAAS;AACpB,MAAI,UAAU;AACd,MAAI,YAAY,KAAK,IAAI,OAAO,GAAG,EAAE;AACrC,MAAI,aAAa,KAAK,IAAI,OAAO,IAAI,EAAE;AACvC,MAAI,WAAW,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,YAAY,KAAK,CAAC,CAAC;AAGjE,QAAM,mBAAmB,MAAM;AAC7B,WAAO,SAAS;AAChB,WAAO,SAAS;AAChB,gBAAY,KAAK,IAAI,OAAO,GAAG,EAAE;AACjC,iBAAa,KAAK,IAAI,OAAO,IAAI,EAAE;AACnC,cAAU,kBAAkB,MAAM,aAAa,GAAG;AAAA,MAChD,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,QAAQ;AAAA,IACV,CAAC;AACD,eAAW,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,YAAY,KAAK,CAAC,CAAC;AAAA,EAC/D;AAEA,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,qBAAqB;AACzB,MAAI,QAAQ;AACZ,MAAI,YAAY;AAGhB,MAAI,QAAoC,CAAC;AACzC,MAAI,YAAuB;AAC3B,MAAI,gBAA2B;AAC/B,MAAI,OAAiC,EAAE,GAAG,GAAG,GAAG,EAAE;AAGlD,MAAI,cAAc;AAGlB,MAAI,cAAc;AAClB,MAAI,iBAAiB;AACrB,MAAI,cAAc;AAClB,MAAI,iBAAiB;AACrB,MAAI,mBAAmB;AACvB,MAAI,aAA4E;AAChF,MAAI,YAA2G,CAAC;AAChH,MAAI,aAAa;AACjB,MAAI,cAAc;AAElB,QAAM,aAA8B;AAAA,IAClC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IAEZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAGA,QAAM,cAAc;AAAA,IAClB;AAAA,MACE;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,WAAS,WAAW;AAClB,YAAQ;AAAA,MACN,EAAE,GAAG,KAAK,MAAM,YAAY,CAAC,GAAG,GAAG,KAAK,MAAM,aAAa,CAAC,EAAE;AAAA,MAC9D,EAAE,GAAG,KAAK,MAAM,YAAY,CAAC,IAAI,GAAG,GAAG,KAAK,MAAM,aAAa,CAAC,EAAE;AAAA,MAClE,EAAE,GAAG,KAAK,MAAM,YAAY,CAAC,IAAI,GAAG,GAAG,KAAK,MAAM,aAAa,CAAC,EAAE;AAAA,IACpE;AACA,gBAAY;AACZ,oBAAgB;AAChB,YAAQ;AACR,eAAW;AACX,aAAS;AAET,kBAAc;AACd,qBAAiB;AACjB,kBAAc;AACd,qBAAiB;AACjB,uBAAmB;AACnB,iBAAa;AACb,gBAAY,CAAC;AACb,iBAAa;AACb,kBAAc;AACd,cAAU;AAAA,EACZ;AAGA,WAAS,YAAY;AACnB,QAAI,WAAW;AACf,OAAG;AACD,aAAO;AAAA,QACL,GAAG,KAAK,MAAM,KAAK,OAAO,KAAK,YAAY,EAAE,IAAI;AAAA,QACjD,GAAG,KAAK,MAAM,KAAK,OAAO,KAAK,aAAa,EAAE,IAAI;AAAA,MACpD;AACA;AAAA,IACF,SAAS,MAAM,KAAK,OAAK,EAAE,MAAM,KAAK,KAAK,EAAE,MAAM,KAAK,CAAC,KAAK,WAAW;AAAA,EAC3E;AAGA,WAASC,gBAAe,GAAW,GAAW,OAAe,OAAe,QAAkB,CAAC,UAAK,UAAK,UAAK,QAAG,GAAG;AAClH,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ;AAAA;AAAA,QAC9B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF;AAGA,WAASC,mBAAkB;AACzB,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAM,IAAI,UAAU,CAAC;AACrB,QAAE,KAAK,EAAE;AACT,QAAE,KAAK,EAAE;AACT,QAAE,MAAM;AACR,QAAE;AACF,UAAI,EAAE,QAAQ,GAAG;AACf,kBAAU,OAAO,GAAG,CAAC;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAGA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,cAAU;AACV,qBAAiB;AAGjB,QAAI,cAAc,EAAG;AACrB,QAAI,cAAc,EAAG;AACrB,QAAI,iBAAiB,EAAG;AACxB,QAAI,mBAAmB,EAAG;AAC1B,QAAI,cAAc,WAAW,SAAS,GAAG;AACvC,iBAAW;AACX,iBAAW,KAAK;AAChB,UAAI,WAAW,UAAU,EAAG,cAAa;AAAA,IAC3C;AACA,IAAAA,iBAAgB;AAGhB,QAAI,iBAAiB;AACrB,QAAI,gBAAgB;AACpB,QAAI,cAAc,GAAG;AACnB,YAAM,SAAS,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,iBAAiB,CAAC;AACpE,YAAM,SAAS,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,cAAc;AAChE,uBAAiB,KAAK,IAAI,GAAG,WAAW,MAAM;AAC9C,sBAAgB,KAAK,IAAI,GAAG,UAAU,MAAM;AAAA,IAC9C;AAGA,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,OAAO;AACb,YAAM,YAAY,OAAO;AACzB,YAAM,aAAa,OAAO;AAC1B,UAAIC,QAAO;AACX,UAAI,aAAa,YAAY;AAC3B,QAAAA,QAAO;AAAA,MACT,WAAW,WAAW;AACpB,QAAAA,QAAO;AAAA,MACT,OAAO;AACL,QAAAA,QAAO;AAAA,MACT;AACA,YAAM,OAAO,SAAS,QAAQ,OAAI,QAAQ,WAAW,IAAI,OAAI,IAAI;AACjE,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI;AACxG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI;AAClG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAMA,MAAK,SAAS,CAAC,CAAC,CAAC,WAAW,UAAU,GAAGA,KAAI;AAC/G,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAGA,mBAAe,cAAc,KAAK;AAClC,UAAM,aAAa,cAAc,KAAK,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,YAAY,MAAM;AACvF,UAAM,QAAQ,YAAY,UAAU;AAEpC,UAAM,eAAe,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC7E,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI;AAC1D,UAAM,WAAW,KAAK,IAAI,GAAG,UAAU,CAAC;AAExC,cAAU,QAAQ,QAAQ,IAAI,MAAM;AACpC,QAAI,eAAe,MAAM,cAAc,IAAI;AACzC,gBAAU,WAAW,MAAM,CAAC,CAAC;AAC7B,gBAAU,QAAQ,WAAW,CAAC,IAAI,SAAS,CAAC,YAAY,MAAM,CAAC,CAAC;AAAA,IAClE,OAAO;AACL,gBAAU,GAAG,UAAU,UAAU,MAAM,CAAC,CAAC;AACzC,gBAAU,QAAQ,WAAW,CAAC,IAAI,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,IAC1E;AAGA,UAAM,YAAY,UAAU,MAAM,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC;AAC7D,UAAM,WAAW,SAAS,UAAU,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC;AAC/D,UAAM,aAAa,iBAAiB,IAAI,eAAe;AACvD,UAAM,SAAS,KAAK,IAAI,GAAG,UAAU,CAAC;AACtC,cAAU,QAAQ,MAAM,IAAI,cAAc,IAAI,UAAU,GAAG,SAAS,KAAK,QAAQ;AAGjF,UAAM,cAAc,mBAAmB,KAAK,mBAAmB,IAAI,IAAI,eAAe;AACtF,cAAU,QAAQ,aAAa,IAAI,cAAc,IAAI,WAAW,SAAI,SAAI,OAAO,SAAS,CAAC;AACzF,aAAS,IAAI,GAAG,KAAK,YAAY,KAAK;AACpC,gBAAU,QAAQ,gBAAgB,CAAC,IAAI,cAAc,IAAI,WAAW;AACpE,gBAAU,QAAQ,gBAAgB,CAAC,IAAI,iBAAiB,YAAY,CAAC,IAAI,WAAW;AAAA,IACtF;AACA,cAAU,QAAQ,gBAAgB,aAAa,CAAC,IAAI,cAAc,IAAI,WAAW,SAAI,SAAI,OAAO,SAAS,CAAC;AAE1G,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,eAAe,iBAAiB,KAAK,MAAM,YAAY,CAAC,IAAI;AAClE,YAAM,SAAS,gBAAgB,KAAK,MAAM,aAAa,CAAC,IAAI;AAC5D,YAAM,YAAY,eAAe,KAAK,MAAM,SAAS,SAAS,CAAC;AAC/D,gBAAU,QAAQ,MAAM,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ;AAGrE,gBAAU,iBAAiB,kBAAkB,oBAAoB;AAAA,QAC/D,SAAS;AAAA,QACT,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,WAAW,eAAe,KAAK,MAAM,QAAQ,SAAS,CAAC;AAC7D,gBAAU,QAAQ,SAAS,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACzE,WAAW,CAAC,aAAa;AACvB,YAAM,WAAW;AACjB,YAAM,SAAS,iBAAiB,KAAK,OAAO,YAAY,SAAS,UAAU,CAAC,IAAI;AAChF,YAAM,SAAS,gBAAgB,KAAK,MAAM,aAAa,CAAC;AACxD,gBAAU,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ;AAElE,YAAM,WAAW;AACjB,YAAM,QAAQ,iBAAiB,KAAK,OAAO,YAAY,SAAS,UAAU,CAAC,IAAI;AAC/E,gBAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ;AAAA,IACvE,WAAW,UAAU;AACnB,YAAM,UAAU;AAChB,YAAM,QAAQ,iBAAiB,KAAK,OAAO,YAAY,QAAQ,UAAU,CAAC,IAAI;AAC9E,YAAM,QAAQ,gBAAgB,KAAK,MAAM,aAAa,CAAC,IAAI;AAC3D,gBAAU,QAAQ,KAAK,IAAI,KAAK,cAAc,OAAO;AAErD,YAAM,aAAa,gBAAgB,KAAK;AACxC,YAAM,SAAS,iBAAiB,KAAK,OAAO,YAAY,WAAW,UAAU,CAAC,IAAI;AAClF,gBAAU,QAAQ,QAAQ,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,UAAU;AAEhE,YAAM,UAAU;AAChB,YAAM,WAAW,iBAAiB,KAAK,OAAO,YAAY,QAAQ,UAAU,CAAC,IAAI;AACjF,gBAAU,QAAQ,QAAQ,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACxE,OAAO;AAEL,YAAM,WAAW,cAAc,KAAK,IAAI,WAAM;AAC9C,YAAM,WAAW,iBAAiB,IAAI,eAAe;AACrD,gBAAU,QAAQ,gBAAgB,KAAK,CAAC,IAAI,iBAAiB,KAAK,IAAI,CAAC,IAAI,QAAQ,GAAG,QAAQ;AAG9F,YAAM,aAAa,iBAAiB,IAAI,eAAe;AACvD,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,cAAM,MAAM,MAAM,CAAC;AACnB,cAAM,OAAO,MAAM,IAAI,WAAM;AAC7B,cAAM,aAAa,MAAM,IAAI,YAAa,IAAI,IAAI,KAAK;AACvD,kBAAU,QAAQ,gBAAgB,IAAI,CAAC,IAAI,iBAAiB,IAAI,IAAI,CAAC,IAAI,UAAU,GAAG,UAAU,GAAG,IAAI;AAAA,MACzG;AAGA,iBAAW,KAAK,WAAW;AACzB,cAAM,KAAK,KAAK,MAAM,iBAAiB,EAAE,IAAI,CAAC;AAC9C,cAAM,KAAK,KAAK,MAAM,gBAAgB,EAAE,CAAC;AACzC,YAAI,KAAK,kBAAkB,KAAK,iBAAiB,YAAY,KACzD,KAAK,iBAAiB,KAAK,gBAAgB,aAAa,GAAG;AAC7D,gBAAM,QAAQ,EAAE,OAAO,KAAK,KAAK;AACjC,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,QACxD;AAAA,MACF;AAGA,UAAI,YAAY;AACd,cAAM,OAAO,KAAK,MAAM,iBAAiB,WAAW,IAAI,CAAC;AACzD,cAAM,OAAO,KAAK,MAAM,gBAAgB,WAAW,CAAC;AACpD,YAAI,OAAO,iBAAiB,OAAO,gBAAgB,aAAa,GAAG;AACjE,gBAAM,WAAW,WAAW,SAAS,KAAK,YAAY;AACtD,oBAAU,QAAQ,IAAI,IAAI,IAAI,IAAI,QAAQ,WAAW,WAAW,IAAI;AAAA,QACtE;AAAA,MACF;AAGA,UAAI,cAAc,GAAG;AACnB,cAAM,WAAW,cAAc,IAAI,UAAK,UAAU,oBAAe,GAAG,UAAU;AAC9E,cAAM,SAAS,iBAAiB,KAAK,OAAO,YAAY,SAAS,UAAU,CAAC,IAAI;AAChF,cAAM,aAAa,cAAc,IAAI,IAAI,eAAe;AACxD,kBAAU,QAAQ,gBAAgB,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,QAAQ;AAAA,MACxE;AAAA,IACF;AAEA,UAAM,OAAO,eAAe,CAAC,YAAY,CAAC,SAAS,iBAAiB;AACpE,cAAU,QAAQ,gBAAgB,aAAa,CAAC,IAAI,cAAc,WAAW,UAAU,GAAG,IAAI;AAE9F,aAAS,MAAM,MAAM;AAAA,EACvB;AAGA,WAAS,SAAS;AAChB,QAAI,CAAC,eAAe,YAAY,OAAQ;AAExC,gBAAY;AAEZ,UAAM,OAAO,EAAE,GAAG,MAAM,CAAC,EAAE;AAC3B,YAAQ,WAAW;AAAA,MACjB,KAAK;AAAM,aAAK;AAAK;AAAA,MACrB,KAAK;AAAQ,aAAK;AAAK;AAAA,MACvB,KAAK;AAAQ,aAAK;AAAK;AAAA,MACvB,KAAK;AAAS,aAAK;AAAK;AAAA,IAC1B;AAGA,QAAI,KAAK,KAAK,KAAK,KAAK,KAAK,aAAa,KAAK,KAAK,KAAK,KAAK,KAAK,YAAY;AAC7E,iBAAW;AACX,UAAI,QAAQ,UAAW,aAAY;AAEnC,oBAAc;AACd,uBAAiB;AACjB,yBAAmB;AAEnB,MAAAF,gBAAe,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,GAAG,IAAI,cAAc,CAAC,UAAK,UAAK,QAAK,QAAG,CAAC;AAC7E,mBAAa;AACb;AAAA,IACF;AAGA,QAAI,MAAM,KAAK,OAAK,EAAE,MAAM,KAAK,KAAK,EAAE,MAAM,KAAK,CAAC,GAAG;AACrD,iBAAW;AACX,UAAI,QAAQ,UAAW,aAAY;AAEnC,oBAAc;AACd,uBAAiB;AACjB,yBAAmB;AAEnB,MAAAA,gBAAe,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,GAAG,IAAI,cAAc,CAAC,UAAK,UAAK,QAAK,QAAG,CAAC;AAC7E,mBAAa;AACb;AAAA,IACF;AAEA,UAAM,QAAQ,IAAI;AAElB,QAAI,KAAK,MAAM,KAAK,KAAK,KAAK,MAAM,KAAK,GAAG;AAC1C,YAAM,MAAM,KAAK,IAAI;AAGrB,UAAI,MAAM,cAAc,KAAM;AAC5B;AAAA,MACF,OAAO;AACL,qBAAa;AAAA,MACf;AACA,oBAAc;AAGd,YAAM,aAAa;AACnB,YAAM,aAAa,cAAc,IAAI,KAAK,MAAM,aAAa,CAAC,IAAI;AAClE,YAAM,cAAc,aAAa;AACjC,eAAS;AAGT,oBAAc,IAAI,KAAK,IAAI,YAAY,CAAC;AACxC,uBAAiB,IAAI,KAAK,MAAM,aAAa,CAAC;AAC9C,uBAAiB;AAGjB,YAAM,YAAY,cAAc,IAAI,IAAI,WAAW,MAAM,IAAI,WAAW;AACxE,mBAAa;AAAA,QACX,GAAG,KAAK;AAAA,QACR,GAAG,KAAK;AAAA,QACR,MAAM;AAAA,QACN,QAAQ;AAAA,MACV;AAGA,YAAM,gBAAgB,IAAI,KAAK,IAAI,aAAa,GAAG,EAAE;AACrD,MAAAA,gBAAe,KAAK,GAAG,KAAK,GAAG,eAAe,cAAc,CAAC,UAAK,UAAK,UAAK,QAAG,CAAC;AAEhF,gBAAU;AAAA,IACZ,OAAO;AACL,YAAM,IAAI;AAAA,IACZ;AAAA,EACF;AAGA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,aAAS;AAET,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AACZ,sBAAc,cAAc;AAC5B;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,eAAe,YAAY,MAAM;AACrC,UAAI,CAAC,SAAS;AACZ,sBAAc,YAAY;AAC1B;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,GAAG;AAEN,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AACZ,oBAAY,QAAQ;AACpB;AAAA,MACF;AAEA,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS,IAAI,YAAY;AAGrC,UAAI,QAAQ,UAAU;AACpB,iBAAS,CAAC;AACV,YAAI,OAAQ,sBAAqB;AACjC;AAAA,MACF;AAGA,UAAI,QAAQ,KAAK;AACf,YAAI,UAAU,YAAY,CAAC,aAAa;AACtC,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,qBAAW,KAAK;AAChB,2BAAiB,QAAQ;AACzB;AAAA,QACF;AAAA,MACF;AAIA,UAAI,CAAC,eAAe,CAAC,QAAQ;AAC3B,sBAAc;AACd;AAAA,MACF;AAEA,UAAI,UAAU;AACZ,YAAI,QAAQ,KAAK;AACf,mBAAS;AACT,wBAAc;AAAA,QAChB;AACA;AAAA,MACF;AAGA,UAAI,QAAQ;AAEV,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AACH,uBAAS;AACT;AAAA,YACF,KAAK;AACH,uBAAS;AACT,4BAAc;AACd,uBAAS;AACT;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,yBAAW,KAAK;AAChB,+BAAiB,QAAQ;AACzB;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,gCAAkB,QAAQ;AAC1B;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,iCAAmB,QAAQ;AAC3B;AAAA,UACJ;AACA;AAAA,QACF;AAGA,YAAI,QAAQ,KAAK;AACf,mBAAS;AACT,wBAAc;AACd,mBAAS;AAAA,QACX,WAAW,QAAQ,KAAK;AACtB,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,oBAAU;AACV,4BAAkB,QAAQ;AAAA,QAC5B,WAAW,QAAQ,KAAK;AACtB,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,oBAAU;AACV,6BAAmB,QAAQ;AAAA,QAC7B;AACA;AAAA,MACF;AAEA,cAAQ,SAAS,KAAK;AAAA,QACpB,KAAK;AAAA,QACL,KAAK;AACH,cAAI,cAAc,OAAQ,iBAAgB;AAC1C;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,cAAI,cAAc,KAAM,iBAAgB;AACxC;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,cAAI,cAAc,QAAS,iBAAgB;AAC3C;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,cAAI,cAAc,OAAQ,iBAAgB;AAC1C;AAAA,MACJ;AAAA,IACF,CAAC;AAGD,UAAM,iBAAiB,SAAS,SAAS,MAAM;AAC7C,uBAAiB;AAAA,IACnB,CAAC;AAED,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,oBAAc,cAAc;AAC5B,oBAAc,YAAY;AAC1B,kBAAY,QAAQ;AACpB,qBAAe,QAAQ;AACvB,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;AC1hBO,SAAS,qBAAqB,UAA6C;AAChF,QAAM,aAAa,qBAAqB;AAGxC,QAAM,WAAW;AACjB,QAAM,WAAW;AAGjB,QAAM,oBAAoB,MAAM;AAC9B,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AACtB,UAAM,QAAQ,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC;AACjD,UAAM,SAAS,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC;AAClD,WAAO,EAAE,OAAO,OAAO;AAAA,EACzB;AAEA,MAAI,EAAE,OAAO,YAAY,QAAQ,YAAY,IAAI,kBAAkB;AACnE,QAAM,eAAe;AACrB,QAAM,eAAe;AACrB,QAAM,oBAAoB;AAC1B,QAAM,oBAAoB;AAE1B,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,qBAAqB;AACzB,MAAI,MAAM;AACV,MAAI,QAAQ;AACZ,MAAI,YAAY;AAChB,MAAI,QAAQ;AACZ,MAAI,QAAQ;AAGZ,MAAI,WAAW;AACf,MAAI,UAAU;AAGd,MAAI,UAAU,aAAa;AAC3B,MAAI,UAAU,cAAc;AAG5B,MAAI,WAAsB,CAAC;AAC3B,MAAI,mBAAmB;AACvB,MAAI,mBAAmB;AACvB,MAAI,mBAAmB;AACvB,MAAI,oBAAoB;AAGxB,MAAI,UAAoB,CAAC;AACzB,MAAI,sBAAsB;AAC1B,MAAI,oBAAoB;AAGxB,MAAI,aAA0B,CAAC;AAG/B,MAAI,UAAyB,CAAC;AAC9B,QAAM,eAAe;AACrB,QAAM,eAAe;AACrB,QAAM,gBAAgB;AAGtB,MAAI,cAAc;AAClB,MAAI,YAAwB,CAAC;AAC7B,MAAI,cAA4B,CAAC;AACjC,MAAI,cAAc;AAClB,MAAI,iBAAiB;AACrB,MAAI,iBAAiB;AACrB,MAAI,kBAAkB;AACtB,MAAI,kBAAkB;AACtB,MAAI,sBAAsB;AAE1B,QAAM,aAAsC;AAAA,IAC1C,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IAEZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAGA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAGA,QAAM,iBAAiB;AAAA,IACrB,CAAC,OAAO,OAAO;AAAA;AAAA,IACf,CAAC,QAAQ,MAAM;AAAA;AAAA,IACf,CAAC,OAAO,KAAK;AAAA;AAAA,EACf;AAGA,WAASG,gBAAe,GAAW,GAAW,OAAe,OAAe,QAAkB,CAAC,UAAK,UAAK,UAAK,QAAG,GAAG;AAClH,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ;AAAA,QAC9B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,EACF;AAGA,WAAS,cAAc,GAAW,GAAW,MAAc,QAAgB,cAAc;AACvF,gBAAY,KAAK,EAAE,GAAG,GAAG,MAAM,QAAQ,IAAI,MAAM,CAAC;AAAA,EACpD;AAEA,WAAS,WAAW;AAClB,cAAU,aAAa;AACvB,YAAQ,MAAM,QAAQ;AACtB,YAAQ,MAAM,QAAQ;AACtB,eAAW;AACX,UAAM;AACN,aAAS;AACT,cAAU,CAAC;AACX,iBAAa,CAAC;AACd,0BAAsB;AACtB,wBAAoB;AACpB,uBAAmB;AACnB,uBAAmB;AACnB,wBAAoB;AAEpB,gBAAY,CAAC;AACb,kBAAc,CAAC;AACf,kBAAc;AACd,qBAAiB;AACjB,qBAAiB;AACjB,sBAAkB;AAClB,sBAAkB;AAClB,0BAAsB;AAGtB,uBAAmB,KAAK,IAAI,IAAI,MAAM,QAAQ,KAAK,CAAC;AAGpD,eAAW,CAAC;AACZ,UAAM,SAAS,KAAK,OAAO,aAAa,eAAe,qBAAqB,CAAC;AAC7E,UAAM,SAAS;AAEf,aAAS,MAAM,GAAG,MAAM,cAAc,OAAO;AAC3C,eAAS,MAAM,GAAG,MAAM,cAAc,OAAO;AAC3C,iBAAS,KAAK;AAAA,UACZ,GAAG,SAAS,MAAM;AAAA,UAClB,GAAG,SAAS,MAAM;AAAA,UAClB,OAAO;AAAA,UACP,MAAM,QAAQ,IAAI,IAAI,QAAQ,IAAI,IAAI;AAAA,QACxC,CAAC;AAAA,MACH;AAAA,IACF;AAGA,cAAU,CAAC;AACX,aAAS,IAAI,GAAG,IAAI,cAAc,KAAK;AACrC,YAAM,SAAsB,CAAC;AAC7B,eAAS,IAAI,GAAG,IAAI,eAAe,KAAK;AACtC,eAAO,CAAC,IAAI,CAAC;AACb,iBAAS,IAAI,GAAG,IAAI,cAAc,KAAK;AAErC,cAAI,MAAM,MAAM,MAAM,KAAK,MAAM,eAAe,IAAI;AAClD,mBAAO,CAAC,EAAE,CAAC,IAAI;AAAA,UACjB,WAAW,MAAM,gBAAgB,KAAK,KAAK,KAAK,KAAK,GAAG;AACtD,mBAAO,CAAC,EAAE,CAAC,IAAI;AAAA,UACjB,OAAO;AACL,mBAAO,CAAC,EAAE,CAAC,IAAI;AAAA,UACjB;AAAA,QACF;AAAA,MACF;AACA,cAAQ,KAAK,MAAM;AAAA,IACrB;AAAA,EACF;AAEA,WAAS,WAAW,aAA6B;AAC/C,UAAM,gBAAgB,KAAK,MAAM,cAAc,eAAe,EAAE;AAChE,WAAO,iBAAiB,cAAc,KAAK,KAAK,MAAM,eAAe,CAAC;AAAA,EACxE;AAEA,WAAS,aAAqB;AAC5B,WAAO,cAAc;AAAA,EACvB;AAEA,WAAS,YAAY,GAAW,GAAW,UAAmB;AAC5D,YAAQ,KAAK,EAAE,GAAG,GAAG,SAAS,CAAC;AAAA,EACjC;AAEA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,cAAU;AAGV,QAAI,cAAc,EAAG;AACrB,QAAI,iBAAiB,EAAG;AACxB,QAAI,sBAAsB,EAAG;AAC7B,QAAI,kBAAkB,GAAG;AACvB;AACA,UAAI,oBAAoB,EAAG,mBAAkB;AAAA,IAC/C;AAGA,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAM,IAAI,UAAU,CAAC;AACrB,QAAE,KAAK,EAAE;AACT,QAAE,KAAK,EAAE;AACT,QAAE,MAAM;AACR,QAAE;AACF,UAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,IACxC;AAGA,aAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAM,QAAQ,YAAY,CAAC;AAC3B,YAAM,KAAK;AACX,YAAM;AACN,UAAI,MAAM,UAAU,EAAG,aAAY,OAAO,GAAG,CAAC;AAAA,IAChD;AAEA,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AAGtB,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,OAAO;AACb,YAAM,YAAY,OAAO;AACzB,YAAM,aAAa,OAAO;AAC1B,UAAIC,QAAO;AACX,UAAI,aAAa,YAAY;AAC3B,QAAAA,QAAO;AAAA,MACT,WAAW,WAAW;AACpB,QAAAA,QAAO;AAAA,MACT,OAAO;AACL,QAAAA,QAAO;AAAA,MACT;AACA,YAAM,OAAO,SAAS,QAAQ,OAAS,QAAQ,WAAW,IAAI,OAAS,IAAI;AAC3E,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI;AACxG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI;AAClG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAMA,MAAK,SAAS,CAAC,CAAC,CAAC,WAAW,UAAU,GAAGA,KAAI;AAC/G,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAGA,UAAM,UAAU,kBAAkB;AAClC,QAAI,QAAQ,UAAU,cAAc,QAAQ,WAAW,aAAa;AAElE,gBAAW,UAAU,aAAc,QAAQ;AAC3C,gBAAU,QAAQ,SAAS;AAC3B,mBAAa,QAAQ;AACrB,oBAAc,QAAQ;AAAA,IACxB;AAEA,eAAW,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,aAAa,KAAK,CAAC,CAAC;AAC9D,cAAU,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,cAAc,KAAK,CAAC,CAAC;AAG9D,QAAI,iBAAiB;AACrB,QAAI,gBAAgB;AACpB,QAAI,cAAc,GAAG;AACnB,YAAM,SAAS,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,iBAAiB,CAAC;AACpE,YAAM,SAAS,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,cAAc;AAChE,uBAAiB,KAAK,IAAI,GAAG,WAAW,MAAM;AAC9C,sBAAgB,KAAK,IAAI,GAAG,UAAU,MAAM;AAAA,IAC9C;AAGA,mBAAe,cAAc,KAAK;AAClC,UAAM,eAAe,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC7E,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI;AAE1D,cAAU,UAAU,MAAM;AAC1B,QAAI,eAAe,MAAM,cAAc,IAAI;AACzC,gBAAU,WAAW,MAAM,CAAC,CAAC;AAC7B,gBAAU,UAAU,SAAS,CAAC,YAAY,MAAM,CAAC,CAAC;AAAA,IACpD,OAAO;AACL,gBAAU,GAAG,UAAU,UAAU,MAAM,CAAC,CAAC;AACzC,gBAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,IAC5D;AAGA,UAAM,eAAe,SAAS,OAAO,KAAK;AAC1C,UAAM,QAAQ,UAAU,MAAM,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,UAAU,KAAK,KAAK,YAAY;AACzF,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,UAAU,CAAC;AACnD,cAAU,UAAU,MAAM,IAAI,UAAU,GAAG,KAAK;AAGhD,UAAM,cAAc,iBAAiB,KAAK,iBAAiB,IAAI,IAAI,eAAe;AAClF,cAAU,QAAQ,aAAa,IAAI,cAAc,IAAI,WAAW,SAAS,SAAI,OAAO,UAAU,CAAC;AAC/F,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,gBAAU,QAAQ,gBAAgB,IAAI,CAAC,IAAI,cAAc,IAAI,WAAW;AACxE,gBAAU,QAAQ,gBAAgB,IAAI,CAAC,IAAI,iBAAiB,aAAa,CAAC,IAAI,WAAW;AAAA,IAC3F;AACA,cAAU,QAAQ,gBAAgB,cAAc,CAAC,IAAI,cAAc,IAAI,WAAW,SAAS,SAAI,OAAO,UAAU,CAAC;AAEjH,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,eAAe,WAAW,KAAK,MAAM,aAAa,CAAC,IAAI;AAC7D,YAAM,SAAS,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACvD,YAAM,YAAY,eAAe,KAAK,MAAM,SAAS,SAAS,CAAC;AAC/D,gBAAU,QAAQ,MAAM,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ;AAErE,gBAAU,iBAAiB,kBAAkB,oBAAoB;AAAA,QAC/D,SAAS;AAAA,QACT,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,WAAW,eAAe,KAAK,MAAM,QAAQ,SAAS,CAAC;AAC7D,gBAAU,QAAQ,SAAS,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACzE,WAAW,CAAC,aAAa;AACvB,YAAM,WAAW;AACjB,YAAM,SAAS,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC3E,YAAM,SAAS,UAAU,KAAK,MAAM,cAAc,CAAC;AACnD,gBAAU,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ;AAElE,YAAM,WAAW;AACjB,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC1E,gBAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ;AAAA,IACvE,WAAW,UAAU;AACnB,YAAM,UAAU,MAAM,0DAA4B;AAClD,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,QAAQ,UAAU,CAAC,IAAI;AACzE,YAAM,QAAQ,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACtD,gBAAU,QAAQ,KAAK,IAAI,KAAK,IAAI,MAAM,eAAe,YAAY,GAAG,OAAO;AAE/E,YAAM,YAAY,UAAU,KAAK,WAAW,SAAS;AACrD,gBAAU,QAAQ,QAAQ,CAAC,IAAI,WAAW,KAAK,OAAO,aAAa,UAAU,UAAU,CAAC,IAAI,CAAC,IAAI,UAAU,GAAG,SAAS;AAEvH,YAAM,UAAU,MAAM,2CAAiC;AACvD,gBAAU,QAAQ,QAAQ,CAAC,IAAI,WAAW,KAAK,OAAO,aAAa,QAAQ,UAAU,CAAC,IAAI,CAAC,WAAW,UAAU,GAAG,OAAO;AAAA,IAC5H,OAAO;AAEL,YAAM,UAAU,WAAW;AAC3B,eAAS,IAAI,GAAG,IAAI,cAAc,KAAK;AACrC,cAAM,UAAU,WAAW,CAAC;AAC5B,iBAAS,IAAI,GAAG,IAAI,eAAe,KAAK;AACtC,mBAAS,IAAI,GAAG,IAAI,cAAc,KAAK;AACrC,gBAAI,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG;AACpB,oBAAM,UAAU,iBAAiB,IAAI,UAAU;AAC/C,oBAAM,UAAU,gBAAgB,IAAI,UAAU;AAC9C,wBAAU,QAAQ,OAAO,IAAI,OAAO;AAAA,YACtC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,YAAM,YAAY,KAAK,MAAM,cAAc,EAAE,IAAI;AACjD,iBAAW,WAAW,UAAU;AAC9B,YAAI,CAAC,QAAQ,MAAO;AACpB,cAAM,SAAS,eAAe,QAAQ,IAAI,EAAE,SAAS;AACrD,cAAM,UAAU,iBAAiB,IAAI,QAAQ;AAC7C,cAAM,UAAU,gBAAgB,IAAI,QAAQ;AAG5C,cAAM,SAAS,CAAC,YAAY,YAAY,UAAU;AAClD,kBAAU,QAAQ,OAAO,IAAI,OAAO,IAAI,OAAO,QAAQ,IAAI,CAAC,GAAG,MAAM;AAAA,MACvE;AAGA,iBAAW,UAAU,SAAS;AAC5B,cAAM,UAAU,iBAAiB,IAAI,KAAK,MAAM,OAAO,CAAC;AACxD,cAAM,UAAU,gBAAgB,IAAI,KAAK,MAAM,OAAO,CAAC;AACvD,YAAI,OAAO,UAAU;AACnB,oBAAU,QAAQ,OAAO,IAAI,OAAO;AAAA,QACtC,OAAO;AACL,oBAAU,QAAQ,OAAO,IAAI,OAAO;AAAA,QACtC;AAAA,MACF;AAGA,iBAAW,OAAO,YAAY;AAC5B,cAAM,UAAU,iBAAiB,IAAI,IAAI;AACzC,cAAM,UAAU,gBAAgB,IAAI,IAAI;AACxC,cAAM,WAAW,CAAC,KAAK,KAAK,QAAU,MAAQ;AAC9C,cAAM,OAAO,SAAS,KAAK,IAAI,IAAI,OAAO,SAAS,SAAS,CAAC,CAAC;AAC9D,kBAAU,QAAQ,OAAO,IAAI,OAAO,YAAY,IAAI;AAAA,MACtD;AAGA,iBAAW,KAAK,WAAW;AACzB,cAAM,UAAU,KAAK,MAAM,iBAAiB,IAAI,EAAE,CAAC;AACnD,cAAM,UAAU,KAAK,MAAM,gBAAgB,IAAI,EAAE,CAAC;AAClD,YAAI,UAAU,kBAAkB,UAAU,iBAAiB,aAAa,KACpE,UAAU,iBAAiB,UAAU,gBAAgB,cAAc,GAAG;AACxE,gBAAM,QAAQ,EAAE,OAAO,IAAI,KAAK;AAChC,oBAAU,QAAQ,OAAO,IAAI,OAAO,IAAI,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,QAClE;AAAA,MACF;AAGA,iBAAW,SAAS,aAAa;AAC/B,cAAM,UAAU,KAAK,MAAM,iBAAiB,IAAI,MAAM,CAAC;AACvD,cAAM,UAAU,KAAK,MAAM,gBAAgB,IAAI,MAAM,CAAC;AACtD,YAAI,UAAU,iBAAiB,UAAU,gBAAgB,cAAc,GAAG;AACxE,gBAAM,QAAQ,MAAM,SAAS,KAAK,YAAY;AAC9C,oBAAU,QAAQ,OAAO,IAAI,OAAO,IAAI,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM,IAAI;AAAA,QAC1E;AAAA,MACF;AAGA,UAAI,mBAAmB,GAAG;AACxB,cAAM,YAAY,mBAAmB,IAAI,UAAK,eAAe,0BAAqB,GAAG,eAAe;AACpG,cAAM,UAAU,iBAAiB,KAAK,OAAO,aAAa,UAAU,UAAU,CAAC,IAAI;AACnF,cAAM,cAAc,cAAc,IAAI,IAAI,eAAe;AACzD,kBAAU,QAAQ,gBAAgB,CAAC,IAAI,OAAO,IAAI,WAAW,GAAG,SAAS;AAAA,MAC3E;AAGA,YAAM,gBAAgB,iBAAiB,IAAI,KAAK,MAAM,OAAO,IAAI;AACjE,YAAM,gBAAgB,gBAAgB,IAAI;AAC1C,YAAM,cAAc,iBAAiB,KAAK,iBAAiB,IAAI,IAAI,eAAe;AAClF,gBAAU,QAAQ,aAAa,IAAI,aAAa,IAAI,WAAW;AAAA,IACjE;AAGA,UAAM,OAAO,eAAe,CAAC,YAAY,CAAC,SAAS,SAAS,SAAS,mBAAmB;AACxF,UAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,UAAU,CAAC;AACjD,cAAU,QAAQ,UAAU,cAAc,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,IAAI;AAEhF,aAAS,MAAM,MAAM;AAAA,EACvB;AAEA,WAAS,SAAS;AAChB,QAAI,CAAC,eAAe,YAAY,OAAQ;AAGxC,QAAI,sBAAsB,EAAG;AAC7B;AAGA,iBAAa,WAAW,OAAO,SAAO;AACpC,UAAI;AACJ,aAAO,IAAI,QAAQ;AAAA,IACrB,CAAC;AAGD;AACA,QAAI,oBAAoB,kBAAkB;AACxC,yBAAmB;AAGnB,UAAI,UAAU;AACd,iBAAW,WAAW,UAAU;AAC9B,YAAI,CAAC,QAAQ,MAAO;AACpB,cAAM,QAAQ,QAAQ,IAAI,mBAAmB;AAC7C,YAAI,SAAS,KAAK,SAAS,aAAa,GAAG;AACzC,oBAAU;AACV;AAAA,QACF;AAAA,MACF;AAEA,UAAI,SAAS;AACX,4BAAoB;AACpB,4BAAoB;AAAA,MACtB;AAGA,iBAAW,WAAW,UAAU;AAC9B,YAAI,CAAC,QAAQ,MAAO;AACpB,YAAI,oBAAoB,GAAG;AACzB,kBAAQ,KAAK;AAAA,QACf,OAAO;AACL,kBAAQ,KAAK,mBAAmB;AAAA,QAClC;AAGA,YAAI,QAAQ,KAAK,UAAU,GAAG;AAC5B,qBAAW;AACX,cAAI,QAAQ,UAAW,aAAY;AACnC;AAAA,QACF;AAAA,MACF;AACA,0BAAoB;AAAA,IACtB;AAGA,UAAM,gBAAgB,SAAS,OAAO,OAAK,EAAE,KAAK;AAClD,QAAI,cAAc,SAAS,KAAK,qBAAqB,IAAI;AACvD,0BAAoB;AAEpB,YAAM,UAAU,cAAc,KAAK,MAAM,KAAK,OAAO,IAAI,cAAc,MAAM,CAAC;AAC9E,kBAAY,QAAQ,IAAI,GAAG,QAAQ,IAAI,GAAG,KAAK;AAAA,IACjD;AAGA,cAAU,QAAQ,OAAO,YAAU;AACjC,UAAI,OAAO,UAAU;AACnB,eAAO,KAAK;AAAA,MACd,OAAO;AACL,eAAO,KAAK;AAAA,MACd;AACA,aAAO,OAAO,KAAK,KAAK,OAAO,IAAI;AAAA,IACrC,CAAC;AAGD,eAAW,UAAU,SAAS;AAC5B,UAAI,CAAC,OAAO,SAAU;AAEtB,iBAAW,WAAW,UAAU;AAC9B,YAAI,CAAC,QAAQ,MAAO;AACpB,YAAI,OAAO,KAAK,QAAQ,KAAK,OAAO,KAAK,QAAQ,IAAI,KACjD,OAAO,KAAK,QAAQ,KAAK,OAAO,KAAK,QAAQ,IAAI,GAAG;AACtD,kBAAQ,QAAQ;AAChB,iBAAO,IAAI;AACX,qBAAW,KAAK,EAAE,GAAG,QAAQ,IAAI,GAAG,GAAG,QAAQ,GAAG,OAAO,EAAE,CAAC;AAG5D;AACA,4BAAkB;AAGlB,gBAAM,aAAa,QAAQ,OAAO,KAAK;AACvC,gBAAM,cAAc,mBAAmB,IAAI,KAAK,MAAM,kBAAkB,CAAC,IAAI;AAC7E,gBAAM,aAAa,YAAY;AAC/B,mBAAS;AAGT,wBAAc,IAAI,KAAK,IAAI,iBAAiB,CAAC;AAC7C,2BAAiB,IAAI,KAAK,MAAM,kBAAkB,CAAC;AAGnD,gBAAM,gBAAgB,CAAC,cAAc,cAAc,YAAY;AAC/D,UAAAD,gBAAe,QAAQ,IAAI,GAAG,QAAQ,GAAG,IAAI,KAAK,IAAI,iBAAiB,CAAC,GAAG,cAAc,QAAQ,IAAI,GAAG,CAAC,UAAK,UAAK,UAAK,MAAG,CAAC;AAG5H,gBAAM,YAAY,mBAAmB,IAAI,IAAI,UAAU,MAAM,IAAI,UAAU;AAC3E,gBAAM,aAAa,mBAAmB,IAAI,eAAe;AACzD,wBAAc,QAAQ,IAAI,GAAG,QAAQ,IAAI,GAAG,WAAW,UAAU;AAAA,QACnE;AAAA,MACF;AAAA,IACF;AAGA,UAAM,UAAU,WAAW;AAC3B,eAAW,UAAU,SAAS;AAC5B,eAAS,IAAI,GAAG,IAAI,cAAc,KAAK;AACrC,cAAM,UAAU,WAAW,CAAC;AAC5B,cAAM,OAAO,KAAK,MAAM,OAAO,IAAI,OAAO;AAC1C,cAAM,OAAO,KAAK,MAAM,OAAO,IAAI,OAAO;AAE1C,YAAI,QAAQ,KAAK,OAAO,gBAAgB,QAAQ,KAAK,OAAO,eAAe;AACzE,cAAI,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG;AAC1B,oBAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI;AACzB,mBAAO,IAAI;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,eAAW,UAAU,SAAS;AAC5B,UAAI,OAAO,SAAU;AACrB,UAAI,OAAO,KAAK,WAAW,OAAO,KAAK,UAAU,KAC7C,OAAO,KAAK,UAAU,KAAK,OAAO,KAAK,UAAU,GAAG;AACtD,eAAO,IAAI;AACX,mBAAW,KAAK,EAAE,GAAG,KAAK,MAAM,OAAO,GAAG,GAAG,SAAS,OAAO,EAAE,CAAC;AAChE;AAGA,sBAAc;AACd,yBAAiB;AACjB,yBAAiB;AACjB,0BAAkB;AAClB,QAAAA,gBAAe,KAAK,MAAM,OAAO,GAAG,SAAS,IAAI,cAAc,CAAC,UAAK,UAAK,QAAK,QAAG,CAAC;AAEnF,YAAI,SAAS,GAAG;AACd,qBAAW;AACX,gCAAsB;AACtB,wBAAc;AACd,2BAAiB;AACjB,UAAAA,gBAAe,KAAK,MAAM,OAAO,GAAG,SAAS,IAAI,cAAc,CAAC,UAAK,UAAK,QAAK,UAAK,QAAG,CAAC;AACxF,cAAI,QAAQ,UAAW,aAAY;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AAGA,cAAU,QAAQ,OAAO,OAAK,EAAE,KAAK,CAAC;AAGtC,QAAI,cAAc,WAAW,GAAG;AAC9B,YAAM;AACN,iBAAW;AACX;AACA,UAAI,QAAQ,UAAW,aAAY;AAAA,IACrC;AAAA,EACF;AAGA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,aAAS;AACT,kBAAc;AAEd,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AACZ,sBAAc,cAAc;AAC5B;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,eAAe,YAAY,MAAM;AACrC,UAAI,CAAC,SAAS;AACZ,sBAAc,YAAY;AAC1B;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AACZ,oBAAY,QAAQ;AACpB;AAAA,MACF;AAEA,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS,IAAI,YAAY;AAGrC,UAAI,QAAQ,UAAU;AACpB,iBAAS,CAAC;AACV,YAAI,OAAQ,sBAAqB;AACjC;AAAA,MACF;AAGA,UAAI,QAAQ,KAAK;AACf,YAAI,UAAU,YAAY,CAAC,aAAa;AACtC,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,qBAAW,KAAK;AAChB,2BAAiB,QAAQ;AACzB;AAAA,QACF;AAAA,MACF;AAIA,UAAI,CAAC,eAAe,CAAC,QAAQ;AAC3B,sBAAc;AACd;AAAA,MACF;AAEA,UAAI,UAAU;AACZ,YAAI,QAAQ,KAAK;AACf,cAAI,KAAK;AAEP,qBAAS;AAAA,UACX,OAAO;AAEL,oBAAQ;AACR,qBAAS;AAAA,UACX;AACA,wBAAc;AAAA,QAChB;AACA;AAAA,MACF;AAGA,UAAI,QAAQ;AAEV,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AACH,uBAAS;AACT;AAAA,YACF,KAAK;AACH,sBAAQ;AACR,uBAAS;AACT,4BAAc;AACd,uBAAS;AACT;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,yBAAW,KAAK;AAChB,+BAAiB,QAAQ;AACzB;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,gCAAkB,QAAQ;AAC1B;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,iCAAmB,QAAQ;AAC3B;AAAA,UACJ;AACA;AAAA,QACF;AAGA,YAAI,QAAQ,KAAK;AACf,kBAAQ;AACR,mBAAS;AACT,wBAAc;AACd,mBAAS;AAAA,QACX,WAAW,QAAQ,KAAK;AACtB,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,oBAAU;AACV,4BAAkB,QAAQ;AAAA,QAC5B,WAAW,QAAQ,KAAK;AACtB,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,oBAAU;AACV,6BAAmB,QAAQ;AAAA,QAC7B;AACA;AAAA,MACF;AAEA,cAAQ,SAAS,KAAK;AAAA,QACpB,KAAK;AAAA,QACL,KAAK;AACH,cAAI,UAAU,EAAG,YAAW;AAC5B;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,cAAI,UAAU,aAAa,EAAG,YAAW;AACzC;AAAA,QACF,KAAK;AACH,cAAI,wBAAwB,GAAG;AAC7B,wBAAY,SAAS,UAAU,GAAG,IAAI;AACtC,kCAAsB;AAAA,UACxB;AACA;AAAA,MACJ;AAAA,IACF,CAAC;AAED,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,oBAAc,cAAc;AAC5B,oBAAc,YAAY;AAC1B,kBAAY,QAAQ;AACpB,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;AC1yBA,IAAM,cAAc;AAAA,EAClB,GAAG;AAAA,IACD,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;AAAA,IACb,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAAA,EACrB;AAAA,EACA,GAAG;AAAA,IACD,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAAA,EACjB;AAAA,EACA,GAAG;AAAA,IACD,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAAA,IACrB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAAA,IACvB,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAAA,IACrB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAAA,EACzB;AAAA,EACA,GAAG;AAAA,IACD,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAAA,IACrB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAAA,EACzB;AAAA,EACA,GAAG;AAAA,IACD,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAAA,IACrB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAAA,EACzB;AAAA,EACA,GAAG;AAAA,IACD,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAAA,IACrB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAAA,IACvB,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAAA,IACrB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAAA,EACzB;AAAA,EACA,GAAG;AAAA,IACD,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAAA,IACrB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAAA,IACvB,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAAA,IACrB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAAA,EACzB;AACF;AAEA,IAAM,eAAuC;AAAA,EAC3C,GAAG;AAAA;AAAA,EACH,GAAG;AAAA;AAAA,EACH,GAAG;AAAA;AAAA,EACH,GAAG;AAAA;AAAA,EACH,GAAG;AAAA;AAAA,EACH,GAAG;AAAA;AAAA,EACH,GAAG;AAAA;AACL;AAQO,SAAS,cAAc,UAAsC;AAClE,QAAM,aAAa,qBAAqB;AAGxC,QAAM,cAAc;AACpB,QAAM,eAAe;AACrB,QAAM,mBAAmB;AACzB,QAAM,mBAAmB,cAAc,IAAI;AAC3C,QAAM,cAAc,cAAc,IAAI,mBAAmB;AACzD,QAAM,UAAU;AAChB,QAAM,sBAAsB;AAG5B,QAAM,WAAW,mBAAmB;AACpC,QAAM,WAAW,eAAe;AAChC,QAAM,sBAAsB,eAAe;AAE3C,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,MAAM;AACV,MAAI,SAAS;AACb,MAAI,qBAAqB;AACzB,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,MAAI,YAAY;AAChB,MAAI,eAAyB;AAC7B,MAAI,OAAiB;AAGrB,MAAI,QAA0B,CAAC;AAG/B,MAAI,eAA0B;AAC9B,MAAI,kBAAkB;AACtB,MAAI,SAAS;AACb,MAAI,SAAS;AACb,MAAI,YAAuB;AAG3B,MAAI,cAAc;AAGlB,MAAI,cAAc;AAClB,MAAI,eAAe;AAGnB,MAAI,eAAe;AACnB,MAAI,mBAAmB;AAGvB,MAAI,cAAc;AAClB,MAAI,iBAAiB;AACrB,MAAI,YAAsB,CAAC;AAC3B,MAAI,cAAc;AAClB,MAAI,eAAe;AACnB,MAAI,cAAc;AAClB,MAAI,aAAa;AACjB,MAAI,mBAAmB;AACvB,MAAI,YAA2G,CAAC;AAEhH,QAAM,aAA+B;AAAA,IACnC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IAEZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAGA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAEA,WAAS,SAAS,SAAmB;AACnC,WAAO;AACP,YAAQ,MAAM,YAAY,EAAE,KAAK,IAAI,EAAE,IAAI,MAAM,MAAM,WAAW,EAAE,KAAK,CAAC,CAAC;AAC3E,YAAQ;AACR,YAAQ;AACR,YAAQ;AACR,mBAAe;AACf,kBAAc;AACd,eAAW;AACX,UAAM;AACN,aAAS;AACT,iBAAa;AACb,uBAAmB;AACnB,mBAAe;AACf,uBAAmB;AACnB,kBAAc;AACd,qBAAiB;AACjB,gBAAY,CAAC;AACb,kBAAc;AACd,mBAAe;AACf,kBAAc;AACd,gBAAY,CAAC;AACb,eAAW;AACX,gBAAY,YAAY;AAAA,EAC1B;AAEA,WAAS,cAAyB;AAChC,UAAM,SAAsB,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAC9D,WAAO,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,OAAO,MAAM,CAAC;AAAA,EACzD;AAEA,WAAS,aAAa;AACpB,mBAAe,aAAa,YAAY;AACxC,gBAAY,YAAY;AACxB,sBAAkB;AAClB,UAAM,QAAQ,YAAY,YAAY,EAAE,CAAC;AACzC,aAAS,KAAK,OAAO,cAAc,MAAM,CAAC,EAAE,UAAU,CAAC;AACvD,aAAS;AAET,QAAI,CAAC,gBAAgB,QAAQ,QAAQ,eAAe,GAAG;AACrD,iBAAW;AACX,UAAI,QAAQ,UAAW,aAAY;AAAA,IACrC;AAAA,EACF;AAEA,WAAS,SAAS,WAAmB,iBAA6B;AAChE,UAAM,YAAY,YAAY,YAAY;AAC1C,WAAO,UAAU,WAAW,UAAU,MAAM;AAAA,EAC9C;AAEA,WAAS,gBAAgB,GAAW,GAAW,UAA2B;AACxE,UAAM,QAAQ,YAAY,YAAY,EAAE,WAAW,YAAY,YAAY,EAAE,MAAM;AACnF,aAAS,MAAM,GAAG,MAAM,MAAM,QAAQ,OAAO;AAC3C,eAAS,MAAM,GAAG,MAAM,MAAM,GAAG,EAAE,QAAQ,OAAO;AAChD,YAAI,MAAM,GAAG,EAAE,GAAG,GAAG;AACnB,gBAAM,OAAO,IAAI;AACjB,gBAAM,OAAO,IAAI;AACjB,cAAI,OAAO,KAAK,QAAQ,eAAe,QAAQ,cAAc;AAC3D,mBAAO;AAAA,UACT;AACA,cAAI,QAAQ,KAAK,MAAM,IAAI,EAAE,IAAI,GAAG;AAClC,mBAAO;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,WAAS,YAAY;AACnB,UAAM,QAAQ,SAAS;AACvB,UAAM,QAAQ,aAAa,YAAY;AACvC,aAAS,MAAM,GAAG,MAAM,MAAM,QAAQ,OAAO;AAC3C,eAAS,MAAM,GAAG,MAAM,MAAM,GAAG,EAAE,QAAQ,OAAO;AAChD,YAAI,MAAM,GAAG,EAAE,GAAG,GAAG;AACnB,gBAAM,SAAS,SAAS;AACxB,gBAAM,SAAS,SAAS;AACxB,cAAI,UAAU,KAAK,SAAS,gBAAgB,UAAU,KAAK,SAAS,aAAa;AAC/E,kBAAM,MAAM,EAAE,MAAM,IAAI;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,eAAW;AACX,QAAI,CAAC,UAAU;AACb,iBAAW;AAAA,IACb;AAAA,EACF;AAEA,WAAS,aAAa;AAEpB,UAAM,cAAwB,CAAC;AAC/B,aAAS,MAAM,eAAe,GAAG,OAAO,GAAG,OAAO;AAChD,UAAI,MAAM,GAAG,EAAE,MAAM,UAAQ,SAAS,CAAC,GAAG;AACxC,oBAAY,KAAK,GAAG;AAAA,MACtB;AAAA,IACF;AAEA,UAAM,eAAe,YAAY;AACjC,QAAI,eAAe,GAAG;AAEpB,kBAAY,CAAC,GAAG,WAAW;AAC3B,oBAAc;AAGd,YAAM,gBAAgB,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AAC7D,YAAM,iBAAiB,CAAC,YAAY,YAAY,YAAY,YAAY,YAAY,UAAU;AAC9F,iBAAW,OAAO,aAAa;AAC7B,iBAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,cAAI,KAAK,OAAO,IAAI,KAAK;AACvB,sBAAU,KAAK;AAAA,cACb,GAAG,IAAI;AAAA,cACP,GAAG;AAAA,cACH,MAAM,cAAc,KAAK,MAAM,KAAK,OAAO,IAAI,cAAc,MAAM,CAAC;AAAA,cACpE,OAAO,eAAe,KAAK,MAAM,KAAK,OAAO,IAAI,eAAe,MAAM,CAAC;AAAA,cACvE,KAAK,KAAK,OAAO,IAAI,OAAO;AAAA,cAC5B,KAAK,KAAK,OAAO,IAAI,OAAO;AAAA,cAC5B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA,YAC1C,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAGA;AACA,YAAM,WAAW,iBAAiB;AAClC,YAAM,WAAW,YAAY,mBAAmB,MAAM,QAAQ;AAC9D,YAAM,aAAa,aAAa,KAAK,aAAa,KAAK,KAAK,QAAQ;AACpE,yBAAmB;AAGnB,uBAAiB,eAAe,KAAK,IAAI,GAAG,aAAa,CAAC;AAC1D,oBAAc,eAAe,KAAK,aAAa,IAAI,IAAI;AAGvD,UAAI,YAAY,WAAW,GAAG;AAC5B,uBAAe;AACf,sBAAc;AAAA,MAChB,WAAW,UAAU;AACnB,uBAAe;AACf,sBAAc;AAAA,MAChB,WAAW,iBAAiB,GAAG;AAC7B,uBAAe;AACf,sBAAc;AAAA,MAChB,WAAW,iBAAiB,GAAG;AAC7B,uBAAe;AACf,sBAAc;AAAA,MAChB,OAAO;AACL,uBAAe;AACf,sBAAc;AAAA,MAChB;AAEA,UAAI,aAAa,GAAG;AAClB,wBAAgB,YAAY,UAAU;AACtC,sBAAc,KAAK,IAAI,aAAa,EAAE;AAAA,MACxC;AAGA,YAAM,gBAAgB,MAAM,OAAO,SAAO,CAAC,IAAI,MAAM,UAAQ,SAAS,CAAC,CAAC;AACxE,cAAQ;AAAA,QACN,GAAG,MAAM,YAAY,EAAE,KAAK,IAAI,EAAE,IAAI,MAAM,MAAM,WAAW,EAAE,KAAK,CAAC,CAAC;AAAA,QACtE,GAAG;AAAA,MACL;AAGA,kBAAY,MAAM,KAAK,EAAE,QAAQ,aAAa,GAAG,CAAC,GAAG,MAAM,CAAC;AAE5D,YAAM,cAAc,CAAC,GAAG,KAAK,KAAK,KAAK,GAAG;AAC1C,YAAM,UAAU,YAAY,KAAK,IAAI,cAAc,YAAY,SAAS,CAAC,CAAC,KAAK,KAAK,QAAQ,aAAa;AACzG,eAAS;AACT,eAAS;AAGT,YAAM,WAAW,KAAK,MAAM,QAAQ,EAAE,IAAI;AAC1C,UAAI,WAAW,OAAO;AACpB,gBAAQ;AACR,uBAAe,KAAK,IAAI,KAAK,OAAQ,QAAQ,KAAK,GAAG;AAAA,MACvD;AAEA,UAAI,SAAS,YAAY,SAAS,qBAAqB;AACrD,cAAM;AACN,mBAAW;AACX,YAAI,QAAQ,UAAW,aAAY;AAAA,MACrC;AAAA,IACF,OAAO;AACL,mBAAa;AAAA,IACf;AAAA,EACF;AAEA,WAAS,WAAW;AAClB,QAAI,gBAAgB,SAAS,GAAG,QAAQ,eAAe,GAAG;AACxD;AAAA,IACF;AAAA,EACF;AAEA,WAAS,YAAY;AACnB,QAAI,gBAAgB,SAAS,GAAG,QAAQ,eAAe,GAAG;AACxD;AAAA,IACF;AAAA,EACF;AAEA,WAAS,WAAoB;AAC3B,QAAI,gBAAgB,QAAQ,SAAS,GAAG,eAAe,GAAG;AACxD;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEA,WAAS,WAAW;AAClB,QAAI,aAAc;AAClB,QAAI,iBAAkB;AACtB,mBAAe;AACf,uBAAmB;AAAA,EACrB;AAEA,WAAS,SAAS;AAChB,UAAM,eAAe,kBAAkB,KAAK,YAAY,YAAY,EAAE;AAEtE,QAAI,gBAAgB,QAAQ,QAAQ,WAAW,GAAG;AAChD,wBAAkB;AAClB;AAAA,IACF;AAEA,UAAM,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;AAC3B,eAAW,QAAQ,OAAO;AACxB,UAAI,gBAAgB,SAAS,MAAM,QAAQ,WAAW,GAAG;AACvD,kBAAU;AACV,0BAAkB;AAClB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,cAAU;AAEV,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AAGtB,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,OAAO;AACb,YAAM,YAAY,OAAO;AACzB,YAAM,aAAa,OAAO;AAC1B,UAAI,OAAO;AACX,UAAI,aAAa,YAAY;AAC3B,eAAO;AAAA,MACT,WAAW,WAAW;AACpB,eAAO;AAAA,MACT,OAAO;AACL,eAAO;AAAA,MACT;AACA,YAAM,OAAO,SAAS,QAAQ,OAAI,QAAQ,WAAW,IAAI,OAAI,IAAI;AACjE,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI;AACxG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI;AAClG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,UAAU,GAAG,IAAI;AAC/G,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAGA,UAAM,gBAAgB,QAAQ,cAAc;AAC5C,UAAM,YAAY,QAAQ;AAC1B,UAAM,eAAe,aAAa,OAAO;AACzC,UAAM,eAAe,gBAAgB,cAAc;AACnD,QAAI,WAAW,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,gBAAgB,CAAC,CAAC;AAChE,UAAM,YAAY,YAAa,eAAe,IAAI,IAAK;AACvD,UAAM,gBAAgB,YAAY,IAAI;AACtC,UAAM,YAAY,eAAe;AACjC,UAAM,aAAa;AACnB,UAAM,aAAa,YAAY,gBAAgB,YAAY;AAC3D,UAAM,WAAW,kBAAkB,MAAM,YAAY;AAAA,MACnD,QAAQ;AAAA,MACR,YAAY;AAAA,IACd,CAAC;AACD,QAAI,UAAU,WAAW,YAAY;AAGrC,QAAI,cAAc,GAAG;AACnB,YAAM,SAAS,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,iBAAiB,CAAC;AACpE,YAAM,SAAS,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,cAAc;AAChE,iBAAW,KAAK,IAAI,GAAG,WAAW,MAAM;AACxC,gBAAU,KAAK,IAAI,GAAG,UAAU,MAAM;AAAA,IACxC;AAGA,QAAI,WAAW;AACb,qBAAe,cAAc,KAAK;AAClC,YAAM,eAAe,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAE7E,UAAI,cAAc;AAChB,cAAM,aAAa;AACnB,cAAM,SAAS,KAAK,OAAO,OAAO,WAAW,UAAU,CAAC,IAAI;AAC5D,YAAI,eAAe,MAAM,cAAc,IAAI;AACzC,oBAAU,QAAQ,QAAQ,IAAI,MAAM,YAAY,UAAU;AAAA,QAC5D,OAAO;AACL,oBAAU,QAAQ,QAAQ,IAAI,MAAM,IAAI,UAAU,UAAU,UAAU;AAAA,QACxE;AAAA,MACF,OAAO;AACL,cAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI;AAC1D,kBAAU,QAAQ,QAAQ,IAAI,MAAM;AACpC,YAAI,eAAe,MAAM,cAAc,IAAI;AACzC,oBAAU,WAAW,MAAM,CAAC,CAAC;AAC7B,oBAAU,QAAQ,WAAW,CAAC,IAAI,SAAS,CAAC,YAAY,MAAM,CAAC,CAAC;AAAA,QAClE,OAAO;AACL,oBAAU,GAAG,UAAU,UAAU,MAAM,CAAC,CAAC;AACzC,oBAAU,QAAQ,WAAW,CAAC,IAAI,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,QAC1E;AAAA,MACF;AAAA,IACF;AAGA,cAAU,QAAQ,OAAO,IAAI,QAAQ,IAAI,UAAU,SAAI,eAAK,OAAO,WAAW,CAAC;AAC/E,aAAS,IAAI,GAAG,IAAI,cAAc,KAAK;AACrC,gBAAU,QAAQ,UAAU,IAAI,CAAC,IAAI,QAAQ,IAAI,UAAU;AAC3D,gBAAU,QAAQ,UAAU,IAAI,CAAC,IAAI,WAAW,IAAI,cAAc,CAAC,IAAI,UAAU;AAAA,IACnF;AACA,cAAU,QAAQ,UAAU,eAAe,CAAC,IAAI,QAAQ,IAAI,UAAU,SAAI,eAAK,OAAO,WAAW,CAAC;AAElG,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,eAAe,WAAW,KAAK,MAAM,cAAc,IAAI,CAAC,IAAI;AAClE,YAAM,SAAS,UAAU,KAAK,MAAM,eAAe,CAAC,IAAI;AACxD,YAAM,YAAY,eAAe,KAAK,MAAM,SAAS,SAAS,CAAC;AAC/D,gBAAU,QAAQ,MAAM,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ;AAErE,gBAAU,iBAAiB,kBAAkB,oBAAoB;AAAA,QAC/D,SAAS;AAAA,QACT,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,WAAW,eAAe,KAAK,MAAM,QAAQ,SAAS,CAAC;AAC7D,gBAAU,QAAQ,SAAS,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACzE,WAAW,CAAC,aAAa;AACvB,YAAM,WAAW;AACjB,YAAM,SAAS,WAAW,KAAK,OAAO,cAAc,IAAI,SAAS,UAAU,CAAC,IAAI;AAChF,YAAM,SAAS,UAAU,KAAK,MAAM,eAAe,CAAC;AACpD,gBAAU,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ;AAElE,YAAM,QAAQ,SAAS;AACvB,YAAM,gBAAgB,iBAAiB,aAAa,iBAAiB;AACrE,YAAM,cAAc,iBAAiB,WAAW,mBAAmB;AACnE,YAAM,aAAa,SAAS,aAAa,KAAK,WAAW;AACzD,YAAM,QAAQ,KAAK,OAAO,OAAO,WAAW,UAAU,CAAC;AACvD,gBAAU,QAAQ,KAAK,IAAI,KAAK,WAAW,UAAU,GAAG,UAAU;AAElE,YAAM,WAAW;AACjB,YAAM,QAAQ,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC;AACrD,gBAAU,QAAQ,UAAU,eAAe,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ;AAAA,IACvF,WAAW,UAAU;AACnB,YAAM,UAAU,MAAM,sCAAkB;AACxC,YAAM,QAAQ,WAAW,KAAK,OAAO,cAAc,IAAI,QAAQ,UAAU,CAAC,IAAI;AAC9E,YAAM,QAAQ,UAAU,KAAK,MAAM,eAAe,CAAC,IAAI;AACvD,YAAM,YAAY,MAAM,eAAe;AACvC,gBAAU,QAAQ,KAAK,IAAI,KAAK,IAAI,SAAS,GAAG,OAAO;AAEvD,YAAM,aAAa,UAAU,KAAK;AAClC,YAAM,SAAS,WAAW,KAAK,OAAO,cAAc,IAAI,WAAW,UAAU,CAAC,IAAI;AAClF,gBAAU,QAAQ,QAAQ,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,UAAU;AAEhE,YAAM,aAAa,UAAU,KAAK,WAAW,SAAS,WAAW,WAAW,UAAU;AACtF,YAAM,SAAS,WAAW,KAAK,OAAO,cAAc,IAAI,WAAW,UAAU,CAAC,IAAI;AAClF,gBAAU,QAAQ,QAAQ,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,UAAU;AAEhE,YAAM,UAAU;AAChB,YAAM,WAAW,WAAW,KAAK,OAAO,cAAc,IAAI,QAAQ,UAAU,CAAC,IAAI;AACjF,gBAAU,QAAQ,QAAQ,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACxE,OAAO;AAEL,eAAS,IAAI,GAAG,IAAI,cAAc,KAAK;AACrC,cAAM,aAAa,cAAc,KAAK,UAAU,SAAS,CAAC;AAC1D,iBAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,gBAAM,OAAO,MAAM,CAAC,EAAE,CAAC;AACvB,cAAI,MAAM;AACR,gBAAI,YAAY;AAEd,oBAAM,aAAa,cAAc,MAAM,IAAI,qBAAqB;AAChE,wBAAU,QAAQ,UAAU,IAAI,CAAC,IAAI,WAAW,IAAI,IAAI,CAAC,IAAI,UAAU;AAAA,YACzE,OAAO;AACL,wBAAU,QAAQ,UAAU,IAAI,CAAC,IAAI,WAAW,IAAI,IAAI,CAAC,IAAI,IAAI;AAAA,YACnE;AAAA,UACF,WAAW,YAAY;AAErB,kBAAM,aAAa,cAAc,MAAM,IAAI,qBAAqB;AAChE,sBAAU,QAAQ,UAAU,IAAI,CAAC,IAAI,WAAW,IAAI,IAAI,CAAC,IAAI,UAAU;AAAA,UACzE;AAAA,QACF;AAAA,MACF;AAGA,YAAM,QAAQ,SAAS;AACvB,YAAM,aAAa,aAAa,YAAY;AAC5C,eAAS,MAAM,GAAG,MAAM,MAAM,QAAQ,OAAO;AAC3C,iBAAS,MAAM,GAAG,MAAM,MAAM,GAAG,EAAE,QAAQ,OAAO;AAChD,cAAI,MAAM,GAAG,EAAE,GAAG,GAAG;AACnB,kBAAM,UAAU,UAAU,IAAI,SAAS;AACvC,kBAAM,UAAU,WAAW,KAAK,SAAS,OAAO;AAChD,gBAAI,SAAS,OAAO,GAAG;AACrB,wBAAU,QAAQ,OAAO,IAAI,OAAO,IAAI,UAAU;AAAA,YACpD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,UAAI,SAAS;AACb,aAAO,gBAAgB,QAAQ,SAAS,GAAG,eAAe,GAAG;AAC3D;AAAA,MACF;AACA,UAAI,WAAW,QAAQ;AACrB,iBAAS,MAAM,GAAG,MAAM,MAAM,QAAQ,OAAO;AAC3C,mBAAS,MAAM,GAAG,MAAM,MAAM,GAAG,EAAE,QAAQ,OAAO;AAChD,gBAAI,MAAM,GAAG,EAAE,GAAG,GAAG;AACnB,oBAAM,UAAU,UAAU,IAAI,SAAS;AACvC,oBAAM,UAAU,WAAW,KAAK,SAAS,OAAO;AAChD,kBAAI,SAAS,OAAO,GAAG;AACrB,0BAAU,QAAQ,OAAO,IAAI,OAAO,WAAW,UAAU;AAAA,cAC3D;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,iBAAW,KAAK,WAAW;AACzB,YAAI,EAAE,OAAO,GAAG;AACd,gBAAM,KAAK,KAAK,MAAM,WAAW,IAAI,EAAE,CAAC;AACxC,gBAAM,KAAK,KAAK,MAAM,UAAU,IAAI,EAAE,CAAC;AACvC,cAAI,KAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,KAAK,MAAM;AAC9C,sBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,UAChD;AAAA,QACF;AAAA,MACF;AAGA,UAAI,cAAc,KAAK,cAAc;AACnC,cAAM,OAAO,WAAW,KAAK,OAAO,cAAc,IAAI,aAAa,UAAU,CAAC,IAAI;AAClF,cAAM,OAAO,UAAU,KAAK,MAAM,eAAe,CAAC;AAElD,cAAM,QAAQ,cAAc,IAAI;AAChC,cAAM,WAAW,aAAa,SAAS,QAAQ,IAAK,QAAQ,eAAe,eAAiB,QAAQ,eAAe;AACnH,kBAAU,QAAQ,IAAI,IAAI,IAAI,IAAI,QAAQ,GAAG,YAAY;AAAA,MAC3D;AAAA,IACF;AAGA,QAAI,eAAe;AAEjB,YAAM,SAAS,WAAW,cAAc,IAAI;AAG5C,gBAAU,QAAQ,OAAO,IAAI,MAAM,IAAI,UAAU;AACjD,gBAAU,QAAQ,UAAU,CAAC,IAAI,MAAM,IAAI,UAAU;AACrD,gBAAU,QAAQ,UAAU,CAAC,IAAI,MAAM,IAAI,UAAU,UAAK,MAAM,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC;AAC3F,gBAAU,QAAQ,UAAU,CAAC,IAAI,MAAM,IAAI,UAAU;AACrD,gBAAU,QAAQ,UAAU,CAAC,IAAI,MAAM,IAAI,UAAU;AACrD,gBAAU,QAAQ,UAAU,CAAC,IAAI,MAAM,IAAI,UAAU,UAAK,MAAM,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC;AAC3F,gBAAU,QAAQ,UAAU,CAAC,IAAI,MAAM,IAAI,UAAU;AACrD,gBAAU,QAAQ,UAAU,CAAC,IAAI,MAAM,IAAI,UAAU;AACrD,gBAAU,QAAQ,UAAU,CAAC,IAAI,MAAM,IAAI,UAAU,UAAK,MAAM,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC;AAC3F,gBAAU,QAAQ,UAAU,CAAC,IAAI,MAAM,IAAI,UAAU;AACrD,gBAAU,QAAQ,UAAU,EAAE,IAAI,MAAM,IAAI,UAAU;AACtD,gBAAU,QAAQ,UAAU,EAAE,IAAI,MAAM,IAAI,UAAU,UAAK,UAAU,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC;AAChG,gBAAU,QAAQ,UAAU,EAAE,IAAI,MAAM,IAAI,UAAU;AAGtD,gBAAU,QAAQ,UAAU,EAAE,IAAI,MAAM,IAAI,UAAU;AACtD,gBAAU,QAAQ,UAAU,EAAE,IAAI,MAAM,IAAI,UAAU;AACtD,gBAAU,QAAQ,UAAU,EAAE,IAAI,MAAM,IAAI,UAAU;AACtD,gBAAU,QAAQ,UAAU,EAAE,IAAI,MAAM,IAAI,UAAU;AACtD,gBAAU,QAAQ,UAAU,EAAE,IAAI,MAAM,IAAI,UAAU;AACtD,gBAAU,QAAQ,UAAU,EAAE,IAAI,MAAM,IAAI,UAAU;AAEtD,UAAI,eAAe,CAAC,UAAU;AAC5B,cAAM,YAAY,YAAY,SAAS,EAAE,CAAC;AAC1C,cAAM,YAAY,aAAa,SAAS;AACxC,cAAM,UAAU,KAAK,OAAO,IAAI,UAAU,CAAC,EAAE,UAAU,CAAC;AACxD,cAAM,UAAU,KAAK,OAAO,IAAI,UAAU,UAAU,CAAC;AACrD,iBAAS,MAAM,GAAG,MAAM,UAAU,QAAQ,OAAO;AAC/C,mBAAS,MAAM,GAAG,MAAM,UAAU,GAAG,EAAE,QAAQ,OAAO;AACpD,gBAAI,UAAU,GAAG,EAAE,GAAG,GAAG;AACvB,wBAAU,QAAQ,UAAU,KAAK,UAAU,GAAG,IAAI,SAAS,KAAK,UAAU,OAAO,CAAC,IAAI,SAAS;AAAA,YACjG;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,YAAY,SAAS,WACvB,OAAO,KAAK,IAAI,GAAG,sBAAsB,KAAK,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,KAC3E;AACJ,YAAM,aAAa,SAAS,KAAK,IAAI,GAAG,KAAK,OAAO,KAAK,UAAU,UAAU,CAAC,CAAC;AAC/E,gBAAU,QAAQ,UAAU,EAAE,IAAI,UAAU,WAAW,UAAU,GAAG,SAAS;AAAA,IAC/E,OAAO;AAEL,YAAM,aAAa,SAAS,WAAW,QAAQ,KAAK,IAAI,GAAG,sBAAsB,KAAK,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,KAAK;AACxH,YAAM,WAAW,OAAO,MAAM,SAAS,EAAE,SAAS,CAAC,CAAC,QAAQ,KAAK,QAAQ,MAAM,SAAS,EAAE,SAAS,CAAC,CAAC,GAAG,UAAU;AAClH,YAAM,SAAS,WAAW,KAAK,OAAO,cAAc,IAAI,SAAS,UAAU,CAAC,IAAI;AAChF,YAAM,SAAS,UAAU;AACzB,UAAI,UAAU,GAAG;AACf,kBAAU,QAAQ,MAAM,IAAI,MAAM,IAAI,UAAU,GAAG,QAAQ;AAAA,MAC7D;AAAA,IACF;AAEA,aAAS,MAAM,MAAM;AAAA,EACvB;AAEA,WAAS,SAAS;AAChB,QAAI,CAAC,eAAe,YAAY,OAAQ;AAGxC,QAAI,cAAc;AAEhB,UAAI,QAAQ;AACZ,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAI,SAAS,GAAG;AACd,mBAAS;AACT,kBAAQ;AAAA,QACV,OAAO;AACL;AAAA,QACF;AAAA,MACF;AACA,UAAI,CAAC,OAAO;AAEV,uBAAe;AACf,kBAAU;AAAA,MACZ;AACA;AAAA,IACF;AAEA;AACA,QAAI,cAAc,WAAW,cAAc;AACzC,oBAAc;AACd,UAAI,CAAC,SAAS,GAAG;AACf,kBAAU;AAAA,MACZ;AAAA,IACF;AAGA,QAAI,cAAc,EAAG;AACrB,QAAI,cAAc,EAAG;AACrB,QAAI,cAAc,EAAG;AAGrB,eAAW,KAAK,WAAW;AACzB,UAAI,EAAE,OAAO,GAAG;AACd,UAAE,KAAK,EAAE;AACT,UAAE,KAAK,EAAE;AACT,UAAE,MAAM;AACR,UAAE;AAAA,MACJ;AAAA,IACF;AAEA,gBAAY,UAAU,OAAO,OAAK,EAAE,OAAO,CAAC;AAAA,EAC9C;AAGA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,aAAS,IAAI;AACb,kBAAc;AAEd,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AACZ,sBAAc,cAAc;AAC5B;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,OAAO;AAEV,UAAM,eAAe,YAAY,MAAM;AACrC,UAAI,CAAC,SAAS;AACZ,sBAAc,YAAY;AAC1B;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,OAAO;AAGV,UAAM,cAAc,CAAC,MAAqB;AACxC,UAAI,EAAE,QAAQ,KAAK;AACjB,2BAAmB;AAAA,MACrB;AAAA,IACF;AACA,WAAO,iBAAiB,SAAS,WAAW;AAE5C,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AACZ,oBAAY,QAAQ;AACpB,eAAO,oBAAoB,SAAS,WAAW;AAC/C;AAAA,MACF;AAEA,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS,IAAI,YAAY;AAGrC,UAAI,QAAQ,UAAU;AACpB,iBAAS,CAAC;AACV,YAAI,OAAQ,sBAAqB;AACjC;AAAA,MACF;AAGA,UAAI,QAAQ,KAAK;AACf,YAAI,UAAU,YAAY,CAAC,aAAa;AACtC,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,iBAAO,oBAAoB,SAAS,WAAW;AAC/C,qBAAW,KAAK;AAChB,2BAAiB,QAAQ;AACzB;AAAA,QACF;AAAA,MACF;AAIA,UAAI,CAAC,eAAe,CAAC,QAAQ;AAC3B,YAAI,QAAQ,eAAe,QAAQ,OAAO,QAAQ,KAAK;AACrD,yBAAe;AACf;AAAA,QACF;AACA,YAAI,QAAQ,gBAAgB,QAAQ,OAAO,QAAQ,KAAK;AACtD,yBAAe;AACf;AAAA,QACF;AACA,YAAI,QAAQ,SAAS,QAAQ,KAAK;AAChC,yBAAe,iBAAiB,aAAa,WAAW;AACxD;AAAA,QACF;AACA,iBAAS,YAAY;AACrB,sBAAc;AACd;AAAA,MACF;AAGA,UAAI,UAAU;AACZ,YAAI,QAAQ,KAAK;AACf,mBAAS,IAAI;AACb,wBAAc;AAAA,QAChB;AACA;AAAA,MACF;AAGA,UAAI,QAAQ;AAEV,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AACH,uBAAS;AACT;AAAA,YACF,KAAK;AACH,uBAAS,IAAI;AACb,4BAAc;AACd,uBAAS;AACT;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,qBAAO,oBAAoB,SAAS,WAAW;AAC/C,yBAAW,KAAK;AAChB,+BAAiB,QAAQ;AACzB;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,qBAAO,oBAAoB,SAAS,WAAW;AAC/C,wBAAU;AACV,gCAAkB,QAAQ;AAC1B;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,qBAAO,oBAAoB,SAAS,WAAW;AAC/C,wBAAU;AACV,iCAAmB,QAAQ;AAC3B;AAAA,UACJ;AACA;AAAA,QACF;AAGA,YAAI,QAAQ,KAAK;AACf,mBAAS,IAAI;AACb,wBAAc;AACd,mBAAS;AAAA,QACX,WAAW,QAAQ,KAAK;AACtB,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,iBAAO,oBAAoB,SAAS,WAAW;AAC/C,oBAAU;AACV,4BAAkB,QAAQ;AAAA,QAC5B,WAAW,QAAQ,KAAK;AACtB,wBAAc,cAAc;AAC5B,wBAAc,YAAY;AAC1B,iBAAO,oBAAoB,SAAS,WAAW;AAC/C,oBAAU;AACV,6BAAmB,QAAQ;AAAA,QAC7B;AACA;AAAA,MACF;AAGA,cAAQ,SAAS,KAAK;AAAA,QACpB,KAAK;AAAA,QACL,KAAK;AACH,mBAAS;AACT;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,oBAAU;AACV;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,cAAI,SAAS,EAAG,UAAS;AACzB;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,iBAAO;AACP;AAAA,QACF,KAAK;AACH,mBAAS;AACT;AAAA,MACJ;AAAA,IACF,CAAC;AAED,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,oBAAc,cAAc;AAC5B,oBAAc,YAAY;AAC1B,kBAAY,QAAQ;AACpB,aAAO,oBAAoB,SAAS,WAAW;AAC/C,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;ACn1BA,IAAM,eAAe;AAAA,EACnB;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AACF;AAMO,SAAS,aAAa,UAAqC;AAChE,QAAM,aAAa,qBAAqB;AAKxC,QAAM,WAAW;AACjB,QAAM,WAAW;AACjB,QAAM,sBAAsB;AAC5B,QAAM,kBAAkB;AACxB,QAAM,oBAAoB;AAG1B,MAAI,aAAa;AACjB,MAAI,cAAc;AAKlB,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,qBAAqB;AACzB,MAAI,QAAQ;AACZ,MAAI,YAAY;AAChB,MAAI,SAAS;AAGb,MAAI,WAAW;AACf,MAAI,UAAU;AAGd,MAAI,SAAS;AACb,MAAI,iBAAiB;AACrB,MAAI,aAAa;AACjB,MAAI,oBAAoB;AACxB,MAAI,oBAAoB,aAAa,CAAC;AAGtC,MAAI,QAAiB,CAAC;AAGtB,MAAI,eAAe;AACnB,MAAI,WAAW;AAGf,MAAI,cAAc;AAClB,MAAI,YAAwB,CAAC;AAC7B,MAAI,cAA4B,CAAC;AACjC,MAAI,gBAAgC,CAAC;AACrC,MAAI,cAAc;AAClB,MAAI,iBAAiB;AACrB,MAAI,cAAc;AAGlB,MAAI,aAAa;AACjB,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,MAAI,YAAY;AAChB,MAAI,YAAY;AAKhB,QAAM,aAA8B;AAAA,IAClC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IACZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAKA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAMA,WAASE,gBAAe,GAAW,GAAW,OAAe,OAAe;AAC1E,UAAM,QAAQ,CAAC,UAAK,UAAK,UAAK,QAAG;AACjC,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,YAAM,QAAQ,OAAO,KAAK,OAAO,IAAI;AACrC,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ,MAAM;AAAA;AAAA,QACpC,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,kBAAkB,GAAW,GAAW,OAAe,OAAe;AAC7E,kBAAc,KAAK;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,IAAI;AAAA,IACN,CAAC;AAAA,EACH;AAEA,WAAS,cAAc,GAAW,GAAW,MAAc,QAAgB,cAAc;AACvF,gBAAY,KAAK,EAAE,GAAG,GAAG,MAAM,QAAQ,IAAI,MAAM,CAAC;AAAA,EACpD;AAEA,WAAS,aAAa,QAAgB,WAAmB;AACvD,kBAAc;AACd,qBAAiB;AAAA,EACnB;AAMA,WAAS,WAAW;AAElB,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AACtB,iBAAa,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC;AAChD,kBAAc,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,OAAO,EAAE,CAAC;AAEjD,YAAQ;AACR,aAAS;AACT,eAAW;AACX,aAAS;AACT,mBAAe;AACf,eAAW;AAGX,wBAAoB,KAAK,IAAI,qBAAqB,KAAK,MAAM,aAAa,CAAC,CAAC;AAC5E,aAAS,KAAK,OAAO,aAAa,qBAAqB,CAAC;AACxD,qBAAiB;AACjB,iBAAa;AACb,wBAAoB,aAAa,CAAC;AAGlC,YAAQ,CAAC;AACT,UAAM,gBAAgB;AACtB,UAAM,YAAY,KAAK,OAAO,aAAa,iBAAiB,CAAC;AAC7D,UAAM,KAAK;AAAA,MACT,GAAG;AAAA,MACH,OAAO;AAAA,MACP,OAAO;AAAA,IACT,CAAC;AAGD,gBAAY,CAAC;AACb,kBAAc,CAAC;AACf,oBAAgB,CAAC;AACjB,kBAAc;AACd,kBAAc;AACd,iBAAa;AAAA,EACf;AAEA,WAAS,cAAqB;AAC5B,WAAO,MAAM,MAAM,SAAS,CAAC;AAAA,EAC/B;AAEA,WAAS,YAAY;AACnB,QAAI,cAAc,SAAU;AAE5B,iBAAa;AACb,YAAQ;AACR,YAAQ;AACR,gBAAY;AACZ,gBAAY;AAAA,EACd;AAEA,WAAS,YAAY;AACnB,UAAM,WAAW,YAAY;AAG7B,UAAM,WAAW;AACjB,UAAM,YAAY,QAAQ;AAC1B,UAAM,UAAU,SAAS;AACzB,UAAM,WAAW,SAAS,IAAI,SAAS;AAEvC,UAAM,cAAc,KAAK,IAAI,UAAU,OAAO;AAC9C,UAAM,eAAe,KAAK,IAAI,WAAW,QAAQ;AACjD,UAAM,eAAe,eAAe;AAGpC,UAAM,QAAQ,cAAc,MAAM,SAAS;AAE3C,QAAI,eAAe,iBAAiB;AAElC,iBAAW;AACX,UAAI,QAAQ,UAAW,aAAY;AACnC,UAAI,eAAe,SAAU,YAAW;AAExC,MAAAA,gBAAe,QAAQ,YAAY,GAAG,OAAO,IAAI,UAAU;AAC3D,mBAAa,IAAI,CAAC;AAClB;AAAA,IACF;AAGA,UAAM,YAAY,KAAK,IAAI,WAAW,OAAO,IAAI,qBAC/B,KAAK,IAAI,YAAY,QAAQ,IAAI;AAEnD,QAAI,SAAS;AAEb,QAAI,WAAW;AACb;AACA,YAAM,aAAa,KAAK,IAAI,eAAe,GAAG,EAAE;AAChD,gBAAU,KAAK;AAEf,oBAAc;AACd,MAAAA,gBAAe,QAAQ,YAAY,GAAG,OAAO,IAAI,UAAU;AAE3D,YAAM,YAAY,eAAe,IAAI,aAAa,YAAY,KAAK;AACnE;AAAA,QACE,KAAK,MAAM,aAAa,CAAC,IAAI,KAAK,MAAM,UAAU,SAAS,CAAC;AAAA,QAC5D,KAAK,MAAM,cAAc,CAAC;AAAA,QAC1B;AAAA,QACA,eAAe,IAAI,eAAe;AAAA,MACpC;AAEA,mBAAa,GAAG,CAAC;AAAA,IACnB,OAAO;AACL,UAAI,eAAe,SAAU,YAAW;AACxC,qBAAe;AAGf,UAAI,WAAW,SAAS;AACtB,cAAM,gBAAgB,UAAU;AAChC,0BAAkB,UAAU,OAAO,eAAe,SAAS;AAC3D,QAAAA,gBAAe,WAAW,gBAAgB,GAAG,OAAO,GAAG,SAAS;AAAA,MAClE;AACA,UAAI,YAAY,UAAU;AACxB,cAAM,gBAAgB,YAAY;AAClC,0BAAkB,UAAU,OAAO,eAAe,SAAS;AAC3D,QAAAA,gBAAe,WAAW,gBAAgB,GAAG,OAAO,GAAG,SAAS;AAAA,MAClE;AAEA,mBAAa,GAAG,CAAC;AAAA,IACnB;AAEA,aAAS;AACT;AAEA,QAAI,SAAS,IAAI;AACf,oBAAc,cAAc,eAAe,GAAG,QAAQ,GAAG,IAAI,MAAM,IAAI,UAAU;AAAA,IACnF;AAGA,UAAM,KAAK;AAAA,MACT,GAAG;AAAA,MACH,OAAO;AAAA,MACP,OAAO;AAAA,IACT,CAAC;AAGD,wBAAoB;AACpB,wBAAoB,aAAa,MAAM,SAAS,aAAa,MAAM;AAGnE,aAAS,KAAK,OAAO,aAAa,qBAAqB,CAAC;AACxD,qBAAiB,KAAK,OAAO,IAAI,MAAM,IAAI;AAG3C,iBAAa,KAAK,IAAI,KAAK,aAAa,IAAI;AAG5C,iBAAa;AAAA,EACf;AAEA,WAAS,SAAS;AAChB,QAAI,UAAU,CAAC,eAAe,SAAU;AAGxC,QAAI,CAAC,YAAY;AACf,gBAAU,iBAAiB;AAC3B,UAAI,UAAU,GAAG;AACf,iBAAS;AACT,yBAAiB;AAAA,MACnB,WAAW,SAAS,qBAAqB,YAAY;AACnD,iBAAS,aAAa;AACtB,yBAAiB;AAAA,MACnB;AAAA,IACF;AAGA,QAAI,YAAY;AACd,eAAS;AAET,UAAI,SAAS,GAAG;AACd,gBAAQ;AACR,kBAAU;AAAA,MACZ;AAAA,IACF;AAGA,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAM,IAAI,UAAU,CAAC;AACrB,QAAE,KAAK,EAAE;AACT,QAAE,KAAK,EAAE;AACT,QAAE,MAAM;AACR,QAAE;AACF,UAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,IACxC;AAGA,aAAS,IAAI,cAAc,SAAS,GAAG,KAAK,GAAG,KAAK;AAClD,YAAM,QAAQ,cAAc,CAAC;AAC7B,YAAM,KAAK,MAAM;AACjB,YAAM,MAAM;AACZ,UAAI,MAAM,IAAI,cAAc,GAAG;AAC7B,sBAAc,OAAO,GAAG,CAAC;AAAA,MAC3B;AAAA,IACF;AAGA,aAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAM,QAAQ,YAAY,CAAC;AAC3B,YAAM,KAAK;AACX,YAAM;AACN,UAAI,MAAM,UAAU,EAAG,aAAY,OAAO,GAAG,CAAC;AAAA,IAChD;AAEA,QAAI,cAAc,EAAG;AAAA,EACvB;AAMA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,cAAU;AAEV,QAAI,cAAc,EAAG;AAErB,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AAGtB,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,OAAO;AACb,YAAM,YAAY,OAAO;AACzB,YAAM,aAAa,OAAO;AAC1B,YAAMC,QAAO,aAAa,aAAa,qBACnC,YAAY,2BAAsB;AACtC,YAAM,OAAO,SAAS,QAAQ,OAAI,QAAQ,WAAW,IAAI,OAAI,IAAI;AACjE,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI;AACxG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI;AAClG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAMA,MAAK,SAAS,CAAC,CAAC,CAAC,WAAW,UAAU,GAAGA,KAAI;AAC/G,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAGA,eAAW,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,aAAa,KAAK,CAAC,CAAC;AAC9D,cAAU,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,cAAc,KAAK,CAAC,CAAC;AAG9D,QAAI,aAAa;AACjB,QAAI,YAAY;AAChB,QAAI,cAAc,GAAG;AACnB,oBAAc,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,iBAAiB,CAAC;AACnE,mBAAa,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,cAAc;AAAA,IAChE;AAGA,mBAAe,cAAc,KAAK;AAClC,UAAM,eAAe,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC7E,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI;AAE1D,QAAI,eAAe,MAAM,cAAc,IAAI;AACzC,gBAAU,UAAU,MAAM,YAAY,MAAM,CAAC,CAAC;AAC9C,gBAAU,UAAU,SAAS,CAAC,YAAY,MAAM,CAAC,CAAC;AAAA,IACpD,OAAO;AACL,gBAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAC1D,gBAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,IAC5D;AAGA,UAAM,QAAQ,WAAW,MAAM,YAAY,MAAM,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,YAAY,YAAY;AACpG,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,UAAU,CAAC;AACnD,cAAU,QAAQ,UAAU,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,KAAK;AAG7D,UAAM,cAAc,cAAc,IAAI,eAAe;AACrD,cAAU,QAAQ,SAAS,IAAI,UAAU,IAAI,WAAW,SAAI,SAAI,OAAO,UAAU,CAAC;AAClF,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,gBAAU,QAAQ,YAAY,IAAI,CAAC,IAAI,UAAU,IAAI,WAAW;AAChE,gBAAU,QAAQ,YAAY,IAAI,CAAC,IAAI,aAAa,aAAa,CAAC,IAAI,WAAW;AAAA,IACnF;AACA,cAAU,QAAQ,YAAY,cAAc,CAAC,IAAI,UAAU,IAAI,WAAW,SAAI,SAAI,OAAO,UAAU,CAAC;AAGpG,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,eAAe,KAAK,MAAM,OAAO,CAAC;AACxC,YAAM,SAAS,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACvD,YAAM,YAAY,eAAe,KAAK,MAAM,SAAS,SAAS,CAAC;AAC/D,gBAAU,QAAQ,MAAM,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ;AAErE,gBAAU,iBAAiB,kBAAkB,oBAAoB;AAAA,QAC/D,SAAS;AAAA,QACT,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,WAAW,eAAe,KAAK,MAAM,QAAQ,SAAS,CAAC;AAC7D,gBAAU,QAAQ,SAAS,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACzE,WAES,CAAC,aAAa;AACrB,YAAM,WAAW;AACjB,YAAM,SAAS,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC3E,YAAM,SAAS,UAAU,KAAK,MAAM,cAAc,CAAC;AACnD,gBAAU,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ;AAElE,YAAM,WAAW;AACjB,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC1E,gBAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ;AAErE,YAAM,QAAQ;AACd,YAAM,SAAS,WAAW,KAAK,OAAO,aAAa,MAAM,UAAU,CAAC,IAAI;AACxE,gBAAU,QAAQ,SAAS,CAAC,IAAI,MAAM,WAAW,UAAU,GAAG,KAAK;AAAA,IACrE,WAES,UAAU;AACjB,YAAM,UAAU;AAChB,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,QAAQ,UAAU,CAAC,IAAI;AACzE,YAAM,QAAQ,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACtD,gBAAU,QAAQ,KAAK,IAAI,KAAK,cAAc,OAAO;AAErD,YAAM,YAAY,WAAW,MAAM,YAAY,KAAK;AACpD,YAAM,SAAS,WAAW,KAAK,OAAO,aAAa,UAAU,UAAU,CAAC,IAAI;AAC5E,gBAAU,QAAQ,QAAQ,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,SAAS;AAE/D,YAAM,WAAW,SAAS,SAAS,iBAAiB,QAAQ;AAC5D,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC1E,gBAAU,QAAQ,QAAQ,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ;AAEpE,YAAM,UAAU;AAChB,YAAM,WAAW,WAAW,KAAK,OAAO,aAAa,QAAQ,UAAU,CAAC,IAAI;AAC5E,gBAAU,QAAQ,QAAQ,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACxE,OAEK;AAEH,YAAM,YAAY;AAIlB,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,cAAM,QAAQ,MAAM,CAAC;AAErB,cAAM,UAAU,YAAY,cAAc;AAE1C,YAAI,UAAU,aAAa,WAAW,YAAY,aAAa;AAC7D,gBAAM,WAAW,SAAI,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,KAAK,CAAC,CAAC;AAChE,gBAAM,SAAS,aAAa,IAAI,KAAK,MAAM,MAAM,CAAC;AAClD,oBAAU,QAAQ,OAAO,IAAI,MAAM,IAAI,MAAM,KAAK,GAAG,QAAQ;AAAA,QAC/D;AAAA,MACF;AAGA,YAAM,eAAe,YAAY;AAKjC,YAAM,iBAAiB,YAAY,cAAc,MAAM;AACvD,YAAM,eAAe,iBAAiB;AAGtC,UAAI,YAAY;AACd,cAAM,eAAe;AACrB,cAAM,cAAc,KAAK,MAAM,eAAe,eAAe,YAAY;AACzE,YAAI,cAAc,aAAa,eAAe,YAAY,aAAa;AACrE,gBAAM,WAAW,SAAI,OAAO,KAAK,MAAM,SAAS,CAAC;AACjD,oBAAU,QAAQ,WAAW,IAAI,aAAa,IAAI,KAAK,MAAM,KAAK,CAAC,IAAI,SAAS,GAAG,QAAQ;AAAA,QAC7F;AAAA,MACF;AAGA,UAAI,CAAC,YAAY;AACf,cAAM,WAAW,SAAI,OAAO,KAAK,MAAM,iBAAiB,CAAC;AACzD,kBAAU,QAAQ,YAAY,IAAI,aAAa,IAAI,KAAK,MAAM,MAAM,CAAC,IAAI,iBAAiB,GAAG,QAAQ;AAGrG,YAAI,iBAAiB,gBAAgB,kBAAkB,YAAY,aAAa;AAC9E,gBAAM,WAAW,SAAI,OAAO,KAAK,MAAM,iBAAiB,CAAC;AACzD,oBAAU,QAAQ,cAAc,IAAI,aAAa,IAAI,KAAK,MAAM,MAAM,CAAC,WAAW,iBAAiB,GAAG,QAAQ;AAAA,QAChH;AAAA,MACF;AAGA,iBAAW,SAAS,eAAe;AACjC,cAAM,UAAU,KAAK,MAAM,YAAY,IAAI,MAAM,CAAC;AAClD,YAAI,UAAU,aAAa,WAAW,YAAY,cAAc,GAAG;AACjE,gBAAM,WAAW,SAAI,OAAO,KAAK,MAAM,MAAM,KAAK,CAAC;AACnD,oBAAU,QAAQ,OAAO,IAAI,aAAa,IAAI,KAAK,MAAM,MAAM,CAAC,CAAC,WAAW,MAAM,KAAK,GAAG,QAAQ;AAAA,QACpG;AAAA,MACF;AAGA,iBAAW,KAAK,WAAW;AACzB,cAAM,UAAU,KAAK,MAAM,aAAa,IAAI,EAAE,CAAC;AAC/C,cAAM,UAAU,KAAK,MAAM,YAAY,IAAI,EAAE,CAAC;AAC9C,YAAI,UAAU,cAAc,UAAU,aAAa,aAAa,KAC5D,UAAU,aAAa,UAAU,YAAY,cAAc,GAAG;AAChE,gBAAM,QAAQ,EAAE,OAAO,IAAI,KAAK;AAChC,oBAAU,QAAQ,OAAO,IAAI,OAAO,IAAI,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,QAClE;AAAA,MACF;AAGA,iBAAW,SAAS,aAAa;AAC/B,cAAM,UAAU,KAAK,MAAM,aAAa,IAAI,MAAM,CAAC;AACnD,cAAM,UAAU,KAAK,MAAM,YAAY,IAAI,MAAM,CAAC;AAClD,YAAI,UAAU,aAAa,UAAU,YAAY,cAAc,GAAG;AAChE,gBAAM,QAAQ,MAAM,SAAS,KAAK,YAAY;AAC9C,oBAAU,QAAQ,OAAO,IAAI,OAAO,IAAI,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM,IAAI;AAAA,QAC1E;AAAA,MACF;AAAA,IACF;AAGA,UAAM,OAAO,eAAe,CAAC,YAAY,CAAC,SAAS,SAAS,SAAS,mBAAmB;AACxF,UAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,UAAU,CAAC;AACjD,cAAU,QAAQ,UAAU,cAAc,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,IAAI;AAEhF,aAAS,MAAM,MAAM;AAAA,EACvB;AAMA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,aAAS;AACT,kBAAc;AAEd,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AAAE,sBAAc,cAAc;AAAG;AAAA,MAAQ;AACvD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,eAAe,YAAY,MAAM;AACrC,UAAI,CAAC,SAAS;AAAE,sBAAc,YAAY;AAAG;AAAA,MAAQ;AACrD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AAAE,oBAAY,QAAQ;AAAG;AAAA,MAAQ;AAE/C,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS;AACrB,YAAM,WAAW,IAAI,YAAY;AAGjC,UAAI,QAAQ;AACV,cAAM,EAAE,cAAc,UAAU,IAAI,aAAa,oBAAoB,iBAAiB,QAAQ,KAAK,QAAQ;AAC3G,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AACA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AAAG,uBAAS;AAAO;AAAA;AAAA,YACxB,KAAK;AAAG,uBAAS;AAAG,4BAAc;AAAM,uBAAS;AAAO;AAAA;AAAA,YACxD,KAAK;AAAG,yBAAW,KAAK;AAAG,+BAAiB,QAAQ;AAAG;AAAA;AAAA,YACvD,KAAK;AAAG,yBAAW,KAAK;AAAG,gCAAkB,QAAQ;AAAG;AAAA;AAAA,YACxD,KAAK;AAAG,yBAAW,KAAK;AAAG,iCAAmB,QAAQ;AAAG;AAAA,UAC3D;AACA;AAAA,QACF;AACA;AAAA,MACF;AAGA,UAAI,UAAU;AACZ,YAAI,aAAa,KAAK;AACpB,mBAAS;AACT,wBAAc;AACd;AAAA,QACF;AACA,YAAI,aAAa,OAAO,QAAQ,UAAU;AACxC,qBAAW,KAAK;AAChB,2BAAiB,QAAQ;AACzB;AAAA,QACF;AACA;AAAA,MACF;AAGA,UAAI,QAAQ,UAAU;AACpB,iBAAS;AACT,6BAAqB;AACrB;AAAA,MACF;AAEA,UAAI,CAAC,aAAa;AAChB,YAAI,QAAQ,KAAK;AACf,wBAAc;AAAA,QAChB;AACA;AAAA,MACF;AAGA,UAAI,QAAQ,KAAK;AACf,kBAAU;AAAA,MACZ;AAAA,IACF,CAAC;AAED,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,kBAAY,QAAQ;AACpB,oBAAc,cAAc;AAC5B,oBAAc,YAAY;AAC1B,eAAS,MAAM,WAAW;AAC1B,eAAS,MAAM,aAAa;AAC5B,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;ACnpBO,SAAS,YAAY,UAAoC;AAC9D,QAAM,aAAa,qBAAqB;AAKxC,QAAM,WAAW;AACjB,QAAM,WAAW;AACjB,QAAM,aAAa;AACnB,QAAM,cAAc;AACpB,QAAM,gBAAgB;AACtB,QAAM,aAAa;AACnB,QAAM,2BAA2B;AACjC,QAAM,oBAAoB;AAC1B,QAAM,kBAAkB;AACxB,QAAM,gBAAgB;AAKtB,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,qBAAqB;AACzB,MAAI,YAAY;AAGhB,MAAI,WAAW;AACf,MAAI,UAAU;AAGd,MAAI,eAAe;AACnB,MAAI,aAAa;AACjB,MAAI,SAAS;AACb,MAAI,YAAY;AAChB,MAAI,iBAAwD;AAC5D,MAAI,kBAAkB;AAGtB,QAAM,gBAAgB;AACtB,MAAI,cAAc;AAClB,MAAI,YAAY;AAChB,MAAI,YAAY,aAAa;AAC7B,MAAI,YAAY;AAChB,MAAI,YAAY,cAAc;AAG9B,MAAI;AACJ,MAAI;AACJ,MAAI,sBAAiC;AAGrC,MAAI,cAAc;AAClB,MAAI,YAAwB,CAAC;AAC7B,MAAI,cAAc;AAClB,MAAI,iBAAiB;AACrB,MAAI,gBAAgB;AACpB,MAAI,YAAY;AAChB,MAAI,eAAsD;AAK1D,QAAM,aAA6B;AAAA,IACjC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IACZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAKA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAMA,WAASC,gBAAe,GAAW,GAAW,OAAe,OAAe,QAAkB,CAAC,UAAK,UAAK,UAAK,UAAK,QAAG,GAAG;AACvH,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ;AAAA,QAC9B,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,eAAe,GAAW,GAAW,OAAe;AAE3D,IAAAA,gBAAe,GAAG,GAAG,IAAI,OAAO,CAAC,UAAK,QAAK,UAAK,UAAK,UAAK,QAAG,CAAC;AAC9D,iBAAa,IAAI,CAAC;AAAA,EACpB;AAEA,WAAS,aAAa,QAAgB,WAAmB;AACvD,kBAAc;AACd,qBAAiB;AAAA,EACnB;AAMA,WAAS,WAAW;AAClB,mBAAe;AACf,iBAAa;AACb,aAAS;AACT,gBAAY;AACZ,eAAW;AACX,aAAS;AAGT,gBAAY,CAAC;AACb,kBAAc;AACd,oBAAgB;AAEhB,cAAU;AAAA,EACZ;AAEA,WAAS,YAAY;AAEnB,gBAAY;AACZ,gBAAY,aAAa;AACzB,gBAAY;AACZ,gBAAY,cAAc;AAC1B,kBAAc;AAGd,gBAAY,KAAK,IAAI,IAAI,cAAc,eAAe,KAAK,wBAAwB;AAGnF,aAAS;AAAA,MACP,GAAG;AAAA,MACH,GAAG,KAAK,MAAM,cAAc,CAAC;AAAA,MAC7B,WAAW;AAAA,MACX,OAAO,CAAC;AAAA,MACR,OAAO;AAAA,MACP,OAAO;AAAA,MACP,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AAGA,SAAK;AAAA,MACH,GAAG,aAAa;AAAA,MAChB,GAAG,KAAK,MAAM,cAAc,CAAC;AAAA,MAC7B,WAAW;AAAA,MACX,OAAO,CAAC;AAAA,MACR,OAAO;AAAA,MACP,OAAO;AAAA;AAAA,MACP,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AAEA,0BAAsB;AACtB,sBAAkB;AAClB,gBAAY,CAAC;AACb,oBAAgB;AAGhB,gBAAY;AACZ,QAAI,eAAgB,eAAc,cAAc;AAChD,qBAAiB,YAAY,MAAM;AACjC;AACA,UAAI,aAAa,GAAG;AAClB,YAAI,eAAgB,eAAc,cAAc;AAChD,yBAAiB;AACjB,0BAAkB;AAClB,sBAAc;AAAA,MAChB;AAAA,IACF,GAAG,GAAI;AAAA,EACT;AAEA,WAAS,gBAAgB;AACvB,QAAI,aAAc,eAAc,YAAY;AAC5C,mBAAe,YAAY,MAAM;AAC/B,UAAI,CAAC,SAAS;AACZ,YAAI,aAAc,eAAc,YAAY;AAC5C;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,SAAS;AAAA,EACd;AAEA,WAAS,eAAe;AACtB,QAAI,cAAc;AAChB,oBAAc,YAAY;AAC1B,qBAAe;AAAA,IACjB;AAAA,EACF;AAEA,WAAS,aAAa,KAAwB;AAC5C,YAAQ,KAAK;AAAA,MACX,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA,IACX;AAAA,EACF;AAEA,WAAS,UAAU,OAAmB;AACpC,QAAI,CAAC,MAAM,MAAO;AAGlB,UAAM,MAAM,KAAK,EAAE,GAAG,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;AAC3C,UAAM,YAAY,aAAa,MAAM,SAAS;AAG9C,YAAQ,MAAM,WAAW;AAAA,MACvB,KAAK;AAAM,cAAM;AAAK;AAAA,MACtB,KAAK;AAAQ,cAAM;AAAK;AAAA,MACxB,KAAK;AAAQ,cAAM;AAAK;AAAA,MACxB,KAAK;AAAS,cAAM;AAAK;AAAA,IAC3B;AAAA,EACF;AAEA,WAAS,eAAe,OAA4B;AAElD,QAAI,MAAM,KAAK,aAAa,MAAM,KAAK,aACnC,MAAM,KAAK,aAAa,MAAM,KAAK,WAAW;AAChD,aAAO;AAAA,IACT;AAGA,eAAW,OAAO,MAAM,OAAO;AAC7B,UAAI,IAAI,MAAM,MAAM,KAAK,IAAI,MAAM,MAAM,GAAG;AAC1C,eAAO;AAAA,MACT;AAAA,IACF;AAGA,UAAM,QAAQ,UAAU,SAAS,KAAK;AACtC,eAAW,OAAO,MAAM,OAAO;AAC7B,UAAI,IAAI,MAAM,MAAM,KAAK,IAAI,MAAM,MAAM,GAAG;AAC1C,eAAO;AAAA,MACT;AAAA,IACF;AAGA,QAAI,MAAM,MAAM,MAAM,KAAK,MAAM,MAAM,MAAM,GAAG;AAC9C,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,WAAW;AAClB,QAAI,CAAC,GAAG,SAAS,CAAC,OAAO,MAAO;AAGhC,UAAM,gBAA6B,CAAC;AACpC,UAAM,WAAyC;AAAA,MAC7C,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAEA,UAAM,aAA0B,CAAC,MAAM,QAAQ,QAAQ,OAAO;AAC9D,UAAM,kBAAkB,SAAS,GAAG,SAAS;AAE7C,eAAW,OAAO,YAAY;AAE5B,UAAI,QAAQ,gBAAiB;AAE7B,YAAM,QAAQ,GAAG,KAAK,QAAQ,SAAS,KAAK,QAAQ,UAAU,IAAI;AAClE,YAAM,QAAQ,GAAG,KAAK,QAAQ,OAAO,KAAK,QAAQ,SAAS,IAAI;AAG/D,UAAI,eAAe,OAAO,KAAK,GAAG;AAChC,sBAAc,KAAK,GAAG;AAAA,MACxB;AAAA,IACF;AAEA,QAAI,cAAc,WAAW,GAAG;AAE9B;AAAA,IACF;AAGA,QAAI,WAAW,cAAc,CAAC;AAC9B,QAAI,YAAY;AAEhB,eAAW,QAAQ,eAAe;AAChC,YAAM,QAAQ,GAAG,KAAK,SAAS,SAAS,KAAK,SAAS,UAAU,IAAI;AACpE,YAAM,QAAQ,GAAG,KAAK,SAAS,OAAO,KAAK,SAAS,SAAS,IAAI;AACjE,YAAM,QAAQ,iBAAiB,OAAO,OAAO,IAAI;AACjD,UAAI,QAAQ,WAAW;AACrB,oBAAY;AACZ,mBAAW;AAAA,MACb;AAAA,IACF;AAGA,QAAI,cAAc,SAAS,KAAK,KAAK,OAAO,IAAI,MAAM;AACpD,iBAAW,cAAc,KAAK,MAAM,KAAK,OAAO,IAAI,cAAc,MAAM,CAAC;AAAA,IAC3E;AAEA,OAAG,YAAY;AAAA,EACjB;AAEA,WAAS,eAAe,GAAW,GAAoB;AAErD,QAAI,KAAK,aAAa,KAAK,aAAa,KAAK,aAAa,KAAK,WAAW;AACxE,aAAO;AAAA,IACT;AAGA,eAAW,OAAO,OAAO,OAAO;AAC9B,UAAI,IAAI,MAAM,KAAK,IAAI,MAAM,EAAG,QAAO;AAAA,IACzC;AACA,eAAW,OAAO,GAAG,OAAO;AAC1B,UAAI,IAAI,MAAM,KAAK,IAAI,MAAM,EAAG,QAAO;AAAA,IACzC;AAGA,QAAI,OAAO,MAAM,KAAK,OAAO,MAAM,EAAG,QAAO;AAE7C,WAAO;AAAA,EACT;AAEA,WAAS,iBAAiB,GAAW,GAAW,WAA8B;AAC5E,QAAI,QAAQ;AAGZ,UAAM,KAAK,cAAc,SAAS,KAAK,cAAc,UAAU,IAAI;AACnE,UAAM,KAAK,cAAc,OAAO,KAAK,cAAc,SAAS,IAAI;AAGhE,aAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,YAAM,SAAS,IAAI,KAAK;AACxB,YAAM,SAAS,IAAI,KAAK;AACxB,UAAI,eAAe,QAAQ,MAAM,GAAG;AAClC,iBAAS,IAAI;AAAA,MACf,OAAO;AACL;AAAA,MACF;AAAA,IACF;AAGA,UAAM,WAAW,YAAY,aAAa;AAC1C,UAAM,WAAW,YAAY,aAAa;AAC1C,UAAM,iBAAiB,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,IAAI,IAAI,OAAO;AACnE,aAAS,iBAAiB;AAG1B,UAAM,eAAe,KAAK,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC;AACnE,QAAI,eAAe,IAAI;AACrB,gBAAU,KAAK,gBAAgB;AAAA,IACjC;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,cAAc;AACrB,QAAI,CAAC,cAAe;AAEpB;AACA,QAAI,eAAe,iBAAiB;AAClC,oBAAc;AAGd,YAAM,aAAa,YAAY,YAAY;AAC3C,YAAM,aAAa,YAAY,YAAY;AAE3C,UAAI,cAAc,YAAY;AAC5B,YAAI,YAAY;AACd,uBAAa;AACb,uBAAa;AAAA,QACf;AACA,YAAI,YAAY;AACd,uBAAa;AACb,uBAAa;AAAA,QACf;AAGA,qBAAa,GAAG,CAAC;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEA,WAAS,SAAS;AAChB,QAAI,CAAC,eAAe,YAAY,UAAU,CAAC,gBAAiB;AAG5D,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAM,IAAI,UAAU,CAAC;AACrB,QAAE,KAAK,EAAE;AACT,QAAE,KAAK,EAAE;AACT,QAAE,MAAM;AACR,QAAE;AACF,UAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,IACxC;AAGA,aAAS;AAGT,WAAO,YAAY;AAGnB,cAAU,MAAM;AAChB,cAAU,EAAE;AAGZ,UAAM,iBAAiB,eAAe,MAAM;AAC5C,UAAM,aAAa,eAAe,EAAE;AAEpC,QAAI,kBAAkB,YAAY;AAEhC,aAAO,QAAQ;AACf,SAAG,QAAQ;AACX,qBAAe,OAAO,GAAG,OAAO,GAAG,OAAO,KAAK;AAC/C,qBAAe,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK;AACnC,sBAAgB;AAChB,eAAS;AAAA,IACX,WAAW,gBAAgB;AACzB,aAAO,QAAQ;AACf,qBAAe,OAAO,GAAG,OAAO,GAAG,OAAO,KAAK;AAC/C;AACA,sBAAgB;AAChB,eAAS;AAAA,IACX,WAAW,YAAY;AACrB,SAAG,QAAQ;AACX,qBAAe,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK;AACnC;AACA,sBAAgB;AAChB,eAAS;AAAA,IACX;AAGA,gBAAY;AAAA,EACd;AAEA,WAAS,WAAW;AAClB,iBAAa;AACb,sBAAkB;AAGlB,QAAI,cAAc,eAAe;AAC/B,kBAAY;AACZ,iBAAW;AACX,sBAAgB;AAAA,IAClB,WAAW,UAAU,eAAe;AAClC,kBAAY;AACZ,iBAAW;AACX,sBAAgB;AAAA,IAClB;AAAA,EACF;AAEA,WAAS,YAAY;AACnB,QAAI,CAAC,aAAa,CAAC,UAAU;AAC3B;AACA,gBAAU;AAAA,IACZ;AAAA,EACF;AAMA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,cAAU;AAGV,QAAI,cAAc,EAAG;AAErB,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AAGtB,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,OAAO;AACb,YAAM,YAAY,OAAO;AACzB,YAAM,aAAa,OAAO;AAC1B,YAAMC,QAAO,aAAa,aAAa,qBACnC,YAAY,2BAA2B;AAC3C,YAAM,OAAO,SAAS,QAAQ,OAAS,QAAQ,WAAW,IAAI,OAAS,IAAI;AAC3E,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI;AACxG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI;AAClG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAMA,MAAK,SAAS,CAAC,CAAC,CAAC,WAAW,UAAU,GAAGA,KAAI;AAC/G,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAGA,eAAW,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,aAAa,KAAK,CAAC,CAAC;AAC9D,cAAU,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,cAAc,KAAK,CAAC,CAAC;AAG9D,QAAI,aAAa;AACjB,QAAI,YAAY;AAChB,QAAI,cAAc,GAAG;AACnB,oBAAc,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,iBAAiB,CAAC;AACnE,mBAAa,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,cAAc;AAAA,IAChE;AAGA,mBAAe,cAAc,KAAK;AAClC,UAAM,eAAe,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC7E,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI;AAE1D,QAAI,eAAe,MAAM,cAAc,IAAI;AACzC,gBAAU,UAAU,MAAM,YAAY,MAAM,CAAC,CAAC;AAC9C,gBAAU,UAAU,SAAS,CAAC,YAAY,MAAM,CAAC,CAAC;AAAA,IACpD,OAAO;AACL,gBAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAC1D,gBAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,IAC5D;AAGA,UAAM,YAAY,SAAS,YAAY;AACvC,UAAM,YAAY,QAAQ,UAAU,SAAS,MAAM,eAAe,aAAa;AAC/E,UAAM,SAAS,KAAK,OAAO,OAAO,UAAU,UAAU,CAAC;AACvD,cAAU,QAAQ,UAAU,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,SAAS,KAAK,SAAS;AAG/E,cAAU,QAAQ,SAAS,IAAI,UAAU,IAAI,UAAU,gBAAgB,SAAI,OAAO,UAAU,CAAC;AAC7F,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,gBAAU,QAAQ,YAAY,IAAI,CAAC,IAAI,UAAU,IAAI,UAAU;AAC/D,gBAAU,QAAQ,YAAY,IAAI,CAAC,IAAI,aAAa,aAAa,CAAC,IAAI,UAAU;AAAA,IAClF;AACA,cAAU,QAAQ,YAAY,cAAc,CAAC,IAAI,UAAU,IAAI,UAAU,gBAAgB,SAAI,OAAO,UAAU,CAAC;AAG/G,QAAI,kBAAkB,YAAY,KAAK,YAAY,IAAI;AAErD,YAAM,cAAc;AACpB,eAAS,IAAI,WAAW,KAAK,WAAW,KAAK;AAC3C,kBAAU,QAAQ,YAAY,IAAI,SAAS,IAAI,aAAa,IAAI,CAAC,IAAI,WAAW;AAChF,kBAAU,QAAQ,YAAY,IAAI,SAAS,IAAI,aAAa,IAAI,CAAC,IAAI,WAAW;AAAA,MAClF;AACA,eAAS,IAAI,WAAW,KAAK,WAAW,KAAK;AAC3C,kBAAU,QAAQ,YAAY,IAAI,CAAC,IAAI,aAAa,IAAI,SAAS,IAAI,WAAW;AAChF,kBAAU,QAAQ,YAAY,IAAI,CAAC,IAAI,aAAa,IAAI,SAAS,IAAI,WAAW;AAAA,MAClF;AAAA,IACF;AAGA,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,eAAe,KAAK,MAAM,OAAO,CAAC;AACxC,YAAM,SAAS,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACvD,YAAM,YAAY,eAAe,KAAK,MAAM,SAAS,SAAS,CAAC;AAC/D,gBAAU,QAAQ,MAAM,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ;AAErE,gBAAU,iBAAiB,kBAAkB,oBAAoB;AAAA,QAC/D,SAAS;AAAA,QACT,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,WAAW,eAAe,KAAK,MAAM,QAAQ,SAAS,CAAC;AAC7D,gBAAU,QAAQ,SAAS,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACzE,WAES,CAAC,aAAa;AACrB,YAAM,WAAW;AACjB,YAAM,SAAS,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC3E,YAAM,SAAS,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACvD,gBAAU,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ;AAElE,YAAM,WAAW;AACjB,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,SAAS,UAAU,CAAC,IAAI;AAC1E,gBAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,QAAQ;AAErE,YAAM,OAAO;AACb,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,KAAK,UAAU,CAAC,IAAI;AACtE,gBAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,IAAI;AAAA,IACnE,WAES,YAAY,GAAG;AAEtB,gBAAU,QAAQ,YAAY,IAAI,OAAO,CAAC,IAAI,aAAa,IAAI,OAAO,CAAC,IAAI,OAAO,KAAK,GAAG,OAAO,IAAI;AACrG,gBAAU,QAAQ,YAAY,IAAI,GAAG,CAAC,IAAI,aAAa,IAAI,GAAG,CAAC,IAAI,GAAG,KAAK,GAAG,GAAG,IAAI;AAErF,YAAM,eAAe,UAAU,SAAS;AACxC,YAAM,aAAa,WAAW,KAAK,MAAM,aAAa,CAAC;AACvD,YAAM,aAAa,UAAU,KAAK,MAAM,cAAc,CAAC;AACvD,gBAAU,QAAQ,UAAU,IAAI,UAAU,cAAc,YAAY;AAAA,IACtE,WAES,CAAC,mBAAmB,CAAC,aAAa,aAAa;AAEtD,eAAS,sBAAsB,QAAQ,YAAY,SAAS;AAG5D,YAAM,OAAO,WAAW,KAAK,OAAO,aAAa,cAAc,UAAU,CAAC,IAAI;AAC9E,YAAM,OAAO,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACrD,YAAM,WAAW,cAAc,SAAS,KAAK,IAAI,eAAe;AAChE,gBAAU,QAAQ,IAAI,IAAI,IAAI,IAAI,QAAQ,GAAG,aAAa;AAE1D,YAAM,UAAU;AAChB,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,QAAQ,UAAU,CAAC,IAAI;AACzE,gBAAU,QAAQ,OAAO,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,OAAO;AAGlE,eAAS,gBAAgB,QAAQ,YAAY,SAAS;AAAA,IACxD,WAES,UAAU;AAEjB,eAAS,sBAAsB,QAAQ,YAAY,SAAS;AAE5D,YAAM,YAAY,cAAc,gBAAgB,eAAe;AAC/D,YAAM,UAAU,cAAc,gBAC1B,mDACA;AACJ,YAAM,QAAQ,WAAW,KAAK,OAAO,aAAa,QAAQ,UAAU,CAAC,IAAI;AACzE,YAAM,QAAQ,UAAU,KAAK,MAAM,cAAc,CAAC,IAAI;AACtD,gBAAU,QAAQ,KAAK,IAAI,KAAK,IAAI,SAAS,GAAG,OAAO;AAEvD,YAAM,YAAY,cAAc,UAAU,MAAM,MAAM;AACtD,YAAM,SAAS,WAAW,KAAK,OAAO,aAAa,UAAU,UAAU,CAAC,IAAI;AAC5E,gBAAU,QAAQ,QAAQ,CAAC,IAAI,MAAM,IAAI,UAAU,GAAG,SAAS;AAE/D,YAAM,UAAU;AAChB,YAAM,WAAW,WAAW,KAAK,OAAO,aAAa,QAAQ,UAAU,CAAC,IAAI;AAC5E,gBAAU,QAAQ,QAAQ,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAGtE,eAAS,gBAAgB,QAAQ,YAAY,SAAS;AAAA,IACxD,OAEK;AAEH,iBAAW,OAAO,OAAO,OAAO;AAC9B,YAAI,IAAI,IAAI,aAAa,IAAI,IAAI,aAAa,IAAI,IAAI,aAAa,IAAI,IAAI,WAAW;AACpF,oBAAU,QAAQ,YAAY,IAAI,IAAI,CAAC,IAAI,aAAa,IAAI,IAAI,CAAC,WAAW,OAAO,KAAK;AAAA,QAC1F;AAAA,MACF;AACA,iBAAW,OAAO,GAAG,OAAO;AAC1B,YAAI,IAAI,IAAI,aAAa,IAAI,IAAI,aAAa,IAAI,IAAI,aAAa,IAAI,IAAI,WAAW;AACpF,oBAAU,QAAQ,YAAY,IAAI,IAAI,CAAC,IAAI,aAAa,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK;AAAA,QACtF;AAAA,MACF;AAGA,UAAI,OAAO,OAAO;AAChB,kBAAU,QAAQ,YAAY,IAAI,OAAO,CAAC,IAAI,aAAa,IAAI,OAAO,CAAC,WAAW,OAAO,KAAK,GAAG,OAAO,IAAI;AAAA,MAC9G;AACA,UAAI,GAAG,OAAO;AACZ,kBAAU,QAAQ,YAAY,IAAI,GAAG,CAAC,IAAI,aAAa,IAAI,GAAG,CAAC,WAAW,GAAG,KAAK,GAAG,GAAG,IAAI;AAAA,MAC9F;AAGA,eAAS,gBAAgB,QAAQ,YAAY,SAAS;AAAA,IACxD;AAGA,UAAM,OAAO,eAAe,CAAC,YAAY,CAAC,SACtC,UAAU,KAAK,OAAO,IAAI,YAAY,cAAc,GAAG,IAAI,GAAG,oBAC9D;AACJ,UAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,UAAU,CAAC;AACjD,cAAU,QAAQ,UAAU,cAAc,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,IAAI;AAEhF,aAAS,MAAM,MAAM;AAAA,EACvB;AAEA,WAAS,sBAAsB,QAAgB,YAAoB,WAA2B;AAE5F,eAAW,OAAO,OAAO,OAAO;AAC9B,gBAAU,QAAQ,YAAY,IAAI,IAAI,CAAC,IAAI,aAAa,IAAI,IAAI,CAAC,WAAW,OAAO,KAAK;AAAA,IAC1F;AACA,eAAW,OAAO,GAAG,OAAO;AAC1B,gBAAU,QAAQ,YAAY,IAAI,IAAI,CAAC,IAAI,aAAa,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK;AAAA,IACtF;AAGA,QAAI,OAAO,OAAO;AAChB,gBAAU,QAAQ,YAAY,IAAI,OAAO,CAAC,IAAI,aAAa,IAAI,OAAO,CAAC,WAAW,OAAO,KAAK,GAAG,OAAO,IAAI;AAAA,IAC9G;AACA,QAAI,GAAG,OAAO;AACZ,gBAAU,QAAQ,YAAY,IAAI,GAAG,CAAC,IAAI,aAAa,IAAI,GAAG,CAAC,WAAW,GAAG,KAAK,GAAG,GAAG,IAAI;AAAA,IAC9F;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,gBAAgB,QAAgB,YAAoB,WAA2B;AACtF,eAAW,KAAK,WAAW;AACzB,YAAM,UAAU,KAAK,MAAM,aAAa,IAAI,EAAE,CAAC;AAC/C,YAAM,UAAU,KAAK,MAAM,YAAY,IAAI,EAAE,CAAC;AAC9C,UAAI,UAAU,cAAc,UAAU,aAAa,aAAa,KAC5D,UAAU,aAAa,UAAU,YAAY,cAAc,GAAG;AAChE,cAAM,QAAQ,EAAE,OAAO,IAAI,KAAK;AAChC,kBAAU,QAAQ,OAAO,IAAI,OAAO,IAAI,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,MAClE;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAMA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,aAAS;AACT,kBAAc;AAEd,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AAAE,sBAAc,cAAc;AAAG;AAAA,MAAQ;AACvD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,mBAAmB,YAAY,MAAM;AACzC,UAAI,CAAC,SAAS;AAAE,sBAAc,gBAAgB;AAAG;AAAA,MAAQ;AAEzD,eAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,cAAM,IAAI,UAAU,CAAC;AACrB,UAAE,KAAK,EAAE;AACT,UAAE,KAAK,EAAE;AACT,UAAE,MAAM;AACR,UAAE;AACF,YAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,MACxC;AAAA,IACF,GAAG,EAAE;AAEL,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AAAE,oBAAY,QAAQ;AAAG;AAAA,MAAQ;AAE/C,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS,IAAI,YAAY;AAGrC,UAAI,QAAQ,UAAU;AACpB,iBAAS,CAAC;AACV,YAAI,QAAQ;AACV,+BAAqB;AACrB,uBAAa;AAAA,QACf,WAAW,iBAAiB;AAC1B,wBAAc;AAAA,QAChB;AACA;AAAA,MACF;AAGA,UAAI,QAAQ,QAAQ,UAAU,YAAY,CAAC,cAAc;AACvD,YAAI,eAAgB,eAAc,cAAc;AAChD,qBAAa;AACb,sBAAc,cAAc;AAC5B,sBAAc,gBAAgB;AAC9B,mBAAW,KAAK;AAChB,yBAAiB,QAAQ;AACzB;AAAA,MACF;AAGA,UAAI,CAAC,eAAe,CAAC,QAAQ;AAC3B,sBAAc;AACd,kBAAU;AACV;AAAA,MACF;AAGA,UAAI,UAAU;AACZ,YAAI,QAAQ,KAAK;AACf,mBAAS;AACT,wBAAc;AACd,oBAAU;AAAA,QACZ;AACA;AAAA,MACF;AAGA,UAAI,CAAC,mBAAmB,CAAC,aAAa,eAAe,CAAC,QAAQ;AAC5D,YAAI,QAAQ,OAAO,SAAS,QAAQ,KAAK;AACvC,oBAAU;AAAA,QACZ;AACA;AAAA,MACF;AAGA,UAAI,QAAQ;AACV,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AACH,uBAAS;AACT,kBAAI,gBAAiB,eAAc;AACnC;AAAA,YACF,KAAK;AACH,uBAAS;AACT,4BAAc;AACd,uBAAS;AACT;AAAA,YACF,KAAK;AACH,kBAAI,eAAgB,eAAc,cAAc;AAChD,2BAAa;AACb,4BAAc,cAAc;AAC5B,4BAAc,gBAAgB;AAC9B,yBAAW,KAAK;AAChB,+BAAiB,QAAQ;AACzB;AAAA,YACF,KAAK;AACH,kBAAI,eAAgB,eAAc,cAAc;AAChD,2BAAa;AACb,4BAAc,cAAc;AAC5B,4BAAc,gBAAgB;AAC9B,wBAAU;AACV,gCAAkB,QAAQ;AAC1B;AAAA,YACF,KAAK;AACH,kBAAI,eAAgB,eAAc,cAAc;AAChD,2BAAa;AACb,4BAAc,cAAc;AAC5B,4BAAc,gBAAgB;AAC9B,wBAAU;AACV,iCAAmB,QAAQ;AAC3B;AAAA,UACJ;AACA;AAAA,QACF;AAGA,YAAI,QAAQ,KAAK;AACf,mBAAS;AACT,wBAAc;AACd,mBAAS;AAAA,QACX,WAAW,QAAQ,KAAK;AACtB,cAAI,eAAgB,eAAc,cAAc;AAChD,uBAAa;AACb,wBAAc,cAAc;AAC5B,wBAAc,gBAAgB;AAC9B,oBAAU;AACV,4BAAkB,QAAQ;AAAA,QAC5B,WAAW,QAAQ,KAAK;AACtB,cAAI,eAAgB,eAAc,cAAc;AAChD,uBAAa;AACb,wBAAc,cAAc;AAC5B,wBAAc,gBAAgB;AAC9B,oBAAU;AACV,6BAAmB,QAAQ;AAAA,QAC7B;AACA;AAAA,MACF;AAGA,UAAI,mBAAmB,OAAO,OAAO;AACnC,cAAM,WAAyC;AAAA,UAC7C,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,SAAS;AAAA,QACX;AAEA,YAAI,SAA2B;AAE/B,gBAAQ,SAAS,KAAK;AAAA,UACpB,KAAK;AAAA,UACL,KAAK;AACH,qBAAS;AACT;AAAA,UACF,KAAK;AAAA,UACL,KAAK;AACH,qBAAS;AACT;AAAA,UACF,KAAK;AAAA,UACL,KAAK;AACH,qBAAS;AACT;AAAA,UACF,KAAK;AAAA,UACL,KAAK;AACH,qBAAS;AACT;AAAA,QACJ;AAGA,YAAI,UAAU,WAAW,SAAS,OAAO,SAAS,GAAG;AACnD,gCAAsB;AAAA,QACxB;AAAA,MACF;AAAA,IACF,CAAC;AAGD,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,UAAI,eAAgB,eAAc,cAAc;AAChD,mBAAa;AACb,oBAAc,cAAc;AAC5B,oBAAc,gBAAgB;AAC9B,kBAAY,QAAQ;AACpB,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;AC56BA,IAAM,aAAa;AAAA,EACjB;AAAA,EAAO;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAO;AAAA,EAAK;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAC3D;AAAA,EAAO;AAAA,EAAO;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAM;AAAA,EAAO;AAAA,EAAM;AAAA,EAAM;AAAA,EAC3D;AAAA,EAAO;AAAA,EAAO;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAC/D;AAAA,EAAM;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAO;AAAA,EAAO;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC7D;AAAA,EAAM;AAAA,EAAM;AAAA,EAAO;AAAA,EAAM;AAAA,EAAS;AAAA,EAAO;AAAA,EAAO;AAAA,EAAS;AAAA,EAAM;AACjE;AAEA,IAAM,cAAc;AAAA,EAClB;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAChE;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAChE;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAU;AAAA,EAAS;AAAA,EAAS;AAAA,EAAU;AAAA,EAAS;AAAA,EAAS;AAAA,EACjE;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAC5D;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAC5D;AAAA,EAAY;AAAA,EAAY;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAC3D;AAGA,IAAM,YAAY;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKO,SAAS,cAAc,UAA0C;AACtE,QAAM,aAAa,qBAAqB;AAGxC,QAAM,aAAa;AAGnB,QAAM,WAAW;AACjB,QAAM,WAAW;AAEjB,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,qBAAqB;AAGzB,MAAI,OAA8B;AAClC,MAAI,WAAW;AAGf,MAAI,cAAc;AAClB,MAAI,YAAY;AAChB,MAAI,YAAY;AAChB,MAAI,gBAAgB;AACpB,MAAI,eAAe;AACnB,MAAI,aAAa;AACjB,MAAI,iBAAiB;AACrB,MAAI,QAAkB,CAAC;AAGvB,MAAI,MAAM;AACV,MAAI,WAAW;AACf,MAAI,UAAU;AAGd,MAAI,UAAU;AAGd,MAAI,cAAc;AAClB,MAAI,cAAc;AAClB,MAAI,kBAAkB;AACtB,MAAI,YAAY;AAGhB,MAAI,YAAwB,CAAC;AAC7B,MAAI,cAA4B,CAAC;AACjC,MAAI,gBAAgB;AACpB,MAAI,cAAc;AAClB,MAAI,cAAc;AAClB,MAAI,aAAa;AAEjB,QAAM,aAAmC;AAAA,IACvC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IAEZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAGA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAEA,WAAS,aAAa,MAAc;AAElC,cAAU,kBAAkB,MAAM,IAAI;AAAA,MACpC,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,WAAS,eAAe;AACtB,QAAI,SAAS,aAAa;AAExB,YAAM,WAAW,CAAC,GAAG,SAAS,EAAE,KAAK,MAAM,KAAK,OAAO,IAAI,GAAG;AAC9D,oBAAc,SAAS,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG;AAAA,IAC7C,OAAO;AAEL,YAAM,WAAW,CAAC,GAAG,YAAY,GAAG,WAAW;AAC/C,cAAQ,CAAC;AACT,eAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,cAAM,KAAK,SAAS,KAAK,MAAM,KAAK,OAAO,IAAI,SAAS,MAAM,CAAC,CAAC;AAAA,MAClE;AACA,oBAAc,MAAM,KAAK,GAAG;AAAA,IAC9B;AAAA,EACF;AAEA,WAAS,WAAW;AAClB,iBAAa;AACb,gBAAY;AACZ,gBAAY;AACZ,oBAAgB;AAChB,mBAAe;AACf,iBAAa;AACb,qBAAiB;AACjB,UAAM;AACN,eAAW;AACX,eAAW;AACX,aAAS;AACT,sBAAkB;AAClB,gBAAY;AAEZ,gBAAY,CAAC;AACb,kBAAc,CAAC;AACf,oBAAgB;AAChB,kBAAc;AACd,kBAAc;AACd,iBAAa;AAAA,EACf;AAGA,WAASC,gBAAe,GAAW,GAAW,OAAe,OAAe,QAAkB,CAAC,UAAK,UAAK,UAAK,QAAG,GAAG;AAClH,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ,MAAM;AAAA,QACpC,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,EACF;AAGA,WAAS,cAAc,GAAW,GAAW,MAAc,QAAgB,cAAc;AACvF,gBAAY,KAAK,EAAE,GAAG,GAAG,MAAM,QAAQ,IAAI,MAAM,CAAC;AAAA,EACpD;AAEA,WAAS,iBAAiB;AACxB,QAAI,cAAc,EAAG;AAErB,UAAM,WAAW,KAAK,IAAI,IAAI,aAAa;AAC3C,oBAAgB,KAAK,IAAI,GAAG,WAAW,OAAO;AAI9C,UAAM,UAAU,UAAU;AAC1B,QAAI,UAAU,GAAG;AACf,YAAM,KAAK,MAAO,eAAe,IAAK,OAAO;AAAA,IAC/C;AAGA,QAAI,aAAa,GAAG;AAClB,iBAAW,KAAK,MAAO,eAAe,aAAc,GAAG;AAAA,IACzD;AAEA,QAAI,iBAAiB,GAAG;AACtB,iBAAW;AACX,kBAAY,MAAM;AAClB,UAAI,UAAW,WAAU;AACzB,wBAAkB;AAAA,IACpB;AAAA,EACF;AAEA,WAAS,WAAW,MAAc;AAChC,QAAI,YAAY,OAAQ;AAGxB,QAAI,cAAc,GAAG;AACnB,kBAAY,KAAK,IAAI;AAAA,IACvB;AAEA,UAAM,eAAe,YAAY,UAAU,MAAM;AACjD;AAGA,UAAM,OAAO,SAAS;AACtB,UAAM,eAAe,KAAK,IAAI,IAAI,OAAO,CAAC;AAC1C,UAAM,aAAa,KAAK,OAAO,OAAO,gBAAgB,CAAC;AACvD,UAAM,UAAU,aAAa,KAAK,IAAI,UAAU,QAAQ,eAAe,CAAC;AACxE,UAAM,QAAQ,UAAU;AAExB,QAAI,SAAS,cAAc;AACzB;AACA,mBAAa;AACb;AAGA,UAAI,iBAAiB,KAAK,gBAAgB,MAAM,GAAG;AAEjD,sBAAc;AACd,QAAAA,gBAAe,SAAS,OAAO,IAAI,KAAK,MAAM,gBAAgB,CAAC,GAAG,cAAc,CAAC,UAAK,UAAK,QAAG,CAAC;AAC/F,sBAAc,SAAS,QAAQ,GAAG,GAAG,aAAa,KAAK,YAAY;AAAA,MACrE,WAAW,iBAAiB,IAAI;AAE9B,YAAI,KAAK,OAAO,IAAI,KAAK;AACvB,UAAAA,gBAAe,SAAS,OAAO,GAAG,cAAc,CAAC,QAAK,UAAK,QAAG,CAAC;AAAA,QACjE;AAAA,MACF;AAGA,UAAI,SAAS,OAAO,UAAU,WAAW,YAAY,QAAQ;AAC3D;AAEA,QAAAA,gBAAe,UAAU,GAAG,OAAO,GAAG,cAAc,CAAC,UAAK,QAAK,QAAG,CAAC;AAAA,MACrE;AAGA,UAAI,UAAU,UAAU,YAAY,SAAS,IAAI;AAE/C,YAAI,SAAS,SAAS;AACpB,gBAAM,WAAW,CAAC,GAAG,YAAY,GAAG,WAAW;AAC/C,mBAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,kBAAM,KAAK,SAAS,KAAK,MAAM,KAAK,OAAO,IAAI,SAAS,MAAM,CAAC,CAAC;AAAA,UAClE;AACA,wBAAc,MAAM,KAAK,GAAG;AAAA,QAC9B;AAAA,MACF;AAAA,IACF,OAAO;AAEL,mBAAa;AACb,sBAAgB;AAChB,mBAAa;AACb,oBAAc;AAEd,MAAAA,gBAAe,SAAS,OAAO,GAAG,cAAc,CAAC,UAAK,QAAK,MAAG,CAAC;AAAA,IACjE;AAAA,EACF;AAEA,WAAS,kBAAkB;AACzB,QAAI,UAAU,SAAS,KAAK,CAAC,YAAY,CAAC,UAAU,YAAY,GAAG;AAEjE,YAAM,cAAc,UAAU,UAAU,SAAS,CAAC;AAClD,YAAM,eAAe,YAAY,UAAU,SAAS,CAAC;AACrD,UAAI,gBAAgB,cAAc;AAChC;AAAA,MACF;AACA;AACA,kBAAY,UAAU,MAAM,GAAG,EAAE;AAAA,IACnC;AAAA,EACF;AAEA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,cAAU;AAGV,QAAI,cAAc,EAAG;AACrB,QAAI,cAAc,EAAG;AACrB,QAAI,aAAa,EAAG;AAGpB,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAM,IAAI,UAAU,CAAC;AACrB,QAAE,KAAK,EAAE;AACT,QAAE,KAAK,EAAE;AACT,QAAE,MAAM;AACR,QAAE;AACF,UAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,IACxC;AAGA,aAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAM,QAAQ,YAAY,CAAC;AAC3B,YAAM,KAAK;AACX,YAAM;AACN,UAAI,MAAM,UAAU,EAAG,aAAY,OAAO,GAAG,CAAC;AAAA,IAChD;AAEA,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AAGtB,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,OAAO;AACb,YAAM,YAAY,OAAO;AACzB,YAAM,aAAa,OAAO;AAC1B,UAAIC,QAAO;AACX,UAAI,aAAa,YAAY;AAC3B,QAAAA,QAAO;AAAA,MACT,WAAW,WAAW;AACpB,QAAAA,QAAO;AAAA,MACT,OAAO;AACL,QAAAA,QAAO;AAAA,MACT;AACA,YAAM,OAAO,SAAS,QAAQ,OAAI,QAAQ,WAAW,IAAI,OAAI,IAAI;AACjE,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI;AACxG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI;AAClG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,MAAMA,MAAK,SAAS,CAAC,CAAC,CAAC,WAAW,UAAU,GAAGA,KAAI;AAC/G,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAEA,iBAAa,IAAI;AAGjB,mBAAe,cAAc,KAAK;AAClC,mBAAe,cAAc,KAAK;AAClC,UAAM,eAAe,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC7E,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI;AAE1D,UAAM,WAAW,KAAK,IAAI,GAAG,UAAU,CAAC;AACxC,cAAU,QAAQ,QAAQ,IAAI,MAAM;AACpC,QAAI,eAAe,MAAM,cAAc,IAAI;AACzC,gBAAU,WAAW,MAAM,CAAC,CAAC;AAC7B,gBAAU,QAAQ,WAAW,CAAC,IAAI,SAAS,CAAC,YAAY,MAAM,CAAC,CAAC;AAAA,IAClE,OAAO;AACL,gBAAU,GAAG,UAAU,UAAU,MAAM,CAAC,CAAC;AACzC,gBAAU,QAAQ,WAAW,CAAC,IAAI,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,IAC1E;AAEA,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,eAAe,KAAK,MAAM,OAAO,CAAC;AACxC,YAAM,SAAS,KAAK,MAAM,OAAO,CAAC,IAAI;AACtC,YAAM,YAAY,eAAe,KAAK,MAAM,SAAS,SAAS,CAAC;AAC/D,gBAAU,QAAQ,MAAM,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ;AAErE,gBAAU,iBAAiB,kBAAkB,oBAAoB;AAAA,QAC/D,SAAS;AAAA,QACT,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,WAAW,eAAe,KAAK,MAAM,QAAQ,SAAS,CAAC;AAC7D,gBAAU,QAAQ,SAAS,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACzE,WAAW,CAAC,aAAa;AAEvB,YAAM,WAAW;AACjB,YAAM,SAAS,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC;AACtD,YAAM,SAAS,KAAK,MAAM,OAAO,CAAC,IAAI;AACtC,gBAAU,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ;AAElE,YAAM,UAAU,SAAS,KAAK,YAAY,CAAC,eAAe,QAAQ;AAClE,YAAM,QAAQ,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC;AACpD,gBAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,IAAI,UAAU,GAAG,OAAO;AAE7D,YAAM,YAAY;AAClB,YAAM,SAAS,KAAK,OAAO,OAAO,UAAU,UAAU,CAAC;AACvD,gBAAU,QAAQ,SAAS,CAAC,IAAI,MAAM,WAAW,UAAU,GAAG,SAAS;AAEvE,YAAM,YAAY;AAClB,YAAM,SAAS,KAAK,OAAO,OAAO,UAAU,UAAU,CAAC;AACvD,gBAAU,QAAQ,SAAS,CAAC,IAAI,MAAM,WAAW,UAAU,GAAG,SAAS;AAGvE,UAAI,UAAU,GAAG;AACf,cAAM,UAAU,SAAS,OAAO;AAChC,cAAM,QAAQ,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC;AACpD,kBAAU,QAAQ,SAAS,CAAC,IAAI,KAAK,YAAY,OAAO;AAAA,MAC1D;AAAA,IACF,WAAW,UAAU;AAEnB,YAAM,QAAQ,UAAU;AAGxB,YAAM,WAAW,CAAC,UAAK,UAAK,UAAK,UAAK,MAAG;AACzC,YAAM,SAAS,CAAC,YAAY,YAAY,YAAY,UAAU;AAC9D,YAAM,eAAe,OAAO,KAAK,MAAM,cAAc,CAAC,IAAI,OAAO,MAAM;AAGvE,UAAI,OAAO,MAAM,kBAAkB,GAAG;AACpC,iBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,gBAAM,KAAK,KAAK,MAAM,OAAO,CAAC,IAAI,KAAK,MAAM,KAAK,IAAI,cAAc,MAAM,CAAC,IAAI,EAAE;AACjF,gBAAM,KAAK,QAAQ,KAAK,MAAM,KAAK,IAAI,cAAc,MAAM,CAAC,IAAI,CAAC;AACjE,gBAAM,UAAU,SAAS,KAAK,MAAM,KAAK,OAAO,IAAI,SAAS,MAAM,CAAC;AACpE,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,YAAY,GAAG,OAAO;AAAA,QACtD;AAAA,MACF;AAEA,YAAM,UAAU,kBAAkB,KAAK,mDAAqB;AAC5D,YAAM,eAAe,kBAAkB,KAAK,KAAK,MAAM,cAAc,CAAC,IAAI,MAAM,IAAI,eAAe,UAAU,UAAU;AACvH,YAAM,QAAQ,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC;AACpD,gBAAU,QAAQ,KAAK,IAAI,KAAK,IAAI,YAAY,GAAG,OAAO;AAG1D,YAAM,WAAW,kBAAkB,KAAK,KAAK,MAAM,cAAc,CAAC,IAAI,MAAM,IAAI,aAAa;AAC7F,YAAM,UAAU;AAAA,QACd;AAAA,QACA;AAAA,QACA;AAAA,QACA,qBAAgB,IAAI,SAAS,EAAE,SAAS,CAAC,CAAC;AAAA,QAC1C,qBAAgB,SAAS,SAAS,EAAE,SAAS,CAAC,CAAC;AAAA,QAC/C,qBAAgB,eAAe,SAAS,EAAE,SAAS,CAAC,CAAC;AAAA,QACrD,qBAAgB,aAAa,SAAS,EAAE,SAAS,CAAC,CAAC;AAAA,QACnD;AAAA,MACF;AAEA,YAAM,UAAU,QAAQ;AACxB,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,cAAM,QAAQ,KAAK,OAAO,OAAO,QAAQ,CAAC,EAAE,UAAU,CAAC;AACvD,kBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,QAAQ,GAAG,QAAQ,CAAC,CAAC;AAAA,MACjE;AAGA,UAAI,SAAS;AACb,UAAI,cAAc;AAClB,UAAI,OAAO,IAAI;AAAE,iBAAS;AAAoB,sBAAc;AAAA,MAAc,WACjE,OAAO,IAAI;AAAE,iBAAS;AAAqB,sBAAc;AAAA,MAAc,WACvE,OAAO,IAAI;AAAE,iBAAS;AAAsB,sBAAc;AAAA,MAAc,WACxE,OAAO,IAAI;AAAE,iBAAS;AAAe,sBAAc;AAAA,MAAc,OACrE;AAAE,iBAAS;AAAkB,sBAAc;AAAA,MAAc;AAG9D,UAAI,kBAAkB,KAAK,OAAO,IAAI;AACpC,cAAM,QAAQ,KAAK,MAAM,cAAc,CAAC,IAAI,MAAM;AAClD,sBAAc,QAAQ,cAAc;AAAA,MACtC;AAEA,YAAM,UAAU,KAAK,OAAO,OAAO,OAAO,UAAU,CAAC;AACrD,gBAAU,QAAQ,UAAU,QAAQ,SAAS,CAAC,IAAI,OAAO,IAAI,WAAW,GAAG,MAAM;AAGjF,UAAI,aAAa,MAAM,GAAG;AACxB,cAAM,aAAa,CAAC,UAAK,UAAK,UAAK,QAAG;AACtC,cAAM,UAAU,kBAAkB,IAC9B,GAAG,WAAW,KAAK,MAAM,cAAc,CAAC,IAAI,WAAW,MAAM,CAAC,uBAAuB,YAAY,KAAK,MAAM,cAAc,CAAC,IAAI,KAAK,WAAW,MAAM,CAAC,KACtJ;AACJ,cAAM,eAAe,kBAAkB,KAAK,KAAK,MAAM,cAAc,CAAC,IAAI,MAAM,IAAI,eAAe;AACnG,cAAM,WAAW,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC;AACvD,kBAAU,QAAQ,UAAU,QAAQ,SAAS,CAAC,IAAI,QAAQ,IAAI,YAAY,GAAG,OAAO;AAAA,MACtF;AAEA,YAAM,UAAU;AAChB,YAAM,WAAW,KAAK,OAAO,OAAO,QAAQ,UAAU,CAAC;AACvD,gBAAU,QAAQ,UAAU,QAAQ,SAAS,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IAC3F,OAAO;AAEL,YAAM,eAAe,cAAc,IAAI,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,CAAC,IAAI;AAC/E,YAAM,eAAe,cAAc,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI;AAGvE,YAAM,YAAY,iBAAiB,IAAI,aAAc,cAAc,KAAK,cAAc,IAAI,IAAI,eAAe;AAC7G,YAAM,aAAa,aAAa,KAAK,aAAa,IAAI,IAAI,eAAe;AACzE,YAAM,QAAQ,SAAS,KAAK,KAAK,aAAa,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,WAAW,IAAI,SAAS,EAAE,SAAS,CAAC,CAAC,UAAU,QAAQ;AAC7H,YAAM,SAAS,KAAK,OAAO,OAAO,MAAM,UAAU,CAAC,IAAI;AACvD,gBAAU,QAAQ,UAAU,YAAY,IAAI,MAAM,IAAI,cAAc,SAAS,GAAG,KAAK;AAGrF,YAAM,WAAW,KAAK,IAAI,IAAI,WAAW,iBAAiB,QAAQ;AAClE,YAAM,WAAW,aAAa;AAC9B,YAAM,SAAS,KAAK,MAAM,WAAW,QAAQ;AAC7C,YAAM,QAAQ,WAAW;AACzB,YAAM,cAAc,SAAI,OAAO,MAAM,IAAI,SAAI,OAAO,KAAK;AACzD,YAAM,OAAO,KAAK,OAAO,OAAO,YAAY,CAAC,IAAI;AACjD,gBAAU,QAAQ,UAAU,IAAI,YAAY,IAAI,IAAI,IAAI,SAAS,GAAG,WAAW;AAG/E,UAAI,iBAAiB,IAAI;AACvB,cAAM,YAAY,iBAAiB,KAAK,UAAK,aAAa,oBAAe,GAAG,aAAa;AACzF,cAAM,cAAc,cAAc,IAAI,IAAI,eAAe;AACzD,cAAM,UAAU,KAAK,OAAO,OAAO,UAAU,UAAU,CAAC;AACxD,kBAAU,QAAQ,UAAU,IAAI,YAAY,IAAI,OAAO,IAAI,WAAW,GAAG,SAAS;AAAA,MACpF;AAGA,YAAM,QAAQ,UAAU,IAAI;AAC5B,YAAM,eAAe,KAAK,IAAI,YAAY,OAAO,CAAC;AAClD,YAAM,aAAa,KAAK,OAAO,OAAO,gBAAgB,CAAC,IAAI;AAG3D,YAAM,WAAW,UAAU;AAC3B,YAAM,aAAa,KAAK,IAAI,GAAG,WAAW,KAAK,MAAM,eAAe,CAAC,CAAC;AACtE,YAAM,cAAc,YAAY,MAAM,YAAY,aAAa,YAAY;AAC3E,YAAM,eAAe,UAAU,MAAM,UAAU;AAG/C,gBAAU,QAAQ,KAAK,IAAI,UAAU;AACrC,eAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;AAC3C,cAAM,OAAO,YAAY,CAAC;AAC1B,cAAM,YAAY,aAAa,CAAC;AAEhC,YAAI,cAAc,QAAW;AAE3B,cAAI,MAAM,aAAa,UAAU,cAAc,IAAI;AAEjD,kBAAM,cAAc,aAAa,IAAI,eAAe;AACpD,sBAAU,UAAU,WAAW,GAAG,IAAI;AAAA,UACxC,OAAO;AACL,sBAAU,UAAU,UAAU,GAAG,IAAI;AAAA,UACvC;AAAA,QACF,WAAW,cAAc,MAAM;AAE7B,gBAAM,aAAa,iBAAiB,KAAK,eAAe;AACxD,oBAAU,GAAG,UAAU,GAAG,IAAI;AAAA,QAChC,OAAO;AAEL,gBAAM,WAAW,aAAa,KAAK,aAAa,IAAI,IAAI,kBAAkB;AAC1E,oBAAU,GAAG,QAAQ,GAAG,SAAS;AAAA,QACnC;AAAA,MACF;AAGA,iBAAW,KAAK,WAAW;AACzB,cAAM,KAAK,KAAK,MAAM,EAAE,CAAC;AACzB,cAAM,KAAK,KAAK,MAAM,EAAE,CAAC;AACzB,YAAI,KAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,KAAK,MAAM;AAC9C,gBAAM,QAAQ,EAAE,OAAO,IAAI,KAAK;AAChC,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,QACxD;AAAA,MACF;AAGA,iBAAW,SAAS,aAAa;AAC/B,cAAM,KAAK,KAAK,MAAM,MAAM,CAAC;AAC7B,cAAM,KAAK,KAAK,MAAM,MAAM,CAAC;AAC7B,YAAI,KAAK,KAAK,KAAK,MAAM;AACvB,gBAAM,QAAQ,MAAM,SAAS,KAAK,YAAY;AAC9C,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM,IAAI;AAAA,QAChE;AAAA,MACF;AAGA,YAAMA,QAAO,cAAc,IAAI,2BAA2B;AAC1D,UAAIA,OAAM;AACR,cAAMC,SAAQ,KAAK,OAAO,OAAOD,MAAK,UAAU,CAAC;AACjD,kBAAU,QAAQ,QAAQ,CAAC,IAAIC,MAAK,WAAW,UAAU,GAAGD,KAAI;AAAA,MAClE;AAAA,IACF;AAGA,UAAM,OAAO,eAAe,CAAC,YAAY,CAAC,SAAS,iBAAiB;AACpE,UAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,UAAU,CAAC;AACjD,cAAU,QAAQ,OAAO,CAAC,IAAI,KAAK,WAAW,UAAU,GAAG,IAAI;AAG/D,QAAI,kBAAkB,EAAG;AAEzB,aAAS,MAAM,MAAM;AAAA,EACvB;AAGA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,aAAS;AACT,kBAAc;AAEd,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AACZ,sBAAc,cAAc;AAC5B;AAAA,MACF;AACA,UAAI,eAAe,CAAC,YAAY,CAAC,QAAQ;AACvC,uBAAe;AAAA,MACjB;AACA,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AACZ,oBAAY,QAAQ;AACpB;AAAA,MACF;AAEA,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS;AACrB,YAAM,WAAW,IAAI,YAAY;AAGjC,UAAI,QAAQ,UAAU;AACpB,iBAAS,CAAC;AACV,YAAI,OAAQ,sBAAqB;AACjC;AAAA,MACF;AAIA,UAAI,CAAC,eAAe,CAAC,QAAQ;AAE3B,YAAI,aAAa,KAAK;AACpB,iBAAO,SAAS,UAAU,cAAc;AACxC,mBAAS;AACT;AAAA,QACF;AACA,YAAI,QAAQ,KAAK;AAAE,qBAAW;AAAI,mBAAS;AAAG;AAAA,QAAQ;AACtD,YAAI,QAAQ,KAAK;AAAE,qBAAW;AAAI,mBAAS;AAAG;AAAA,QAAQ;AACtD,YAAI,QAAQ,KAAK;AAAE,qBAAW;AAAK,mBAAS;AAAG;AAAA,QAAQ;AAGvD,YAAI,IAAI,WAAW,KAAK,QAAQ,WAAW,QAAQ,KAAK;AACtD,wBAAc;AACd,mBAAS;AAET,cAAI,IAAI,WAAW,KAAK,wBAAwB,KAAK,GAAG,GAAG;AACzD,uBAAW,GAAG;AAAA,UAChB;AAAA,QACF;AACA;AAAA,MACF;AAGA,UAAI,UAAU;AACZ,YAAI,aAAa,KAAK;AACpB,mBAAS;AACT,wBAAc;AAAA,QAChB;AACA;AAAA,MACF;AAGA,UAAI,QAAQ;AAEV,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AACH,uBAAS;AACT;AAAA,YACF,KAAK;AACH,uBAAS;AACT,4BAAc;AACd,uBAAS;AACT;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,yBAAW,KAAK;AAChB,+BAAiB,QAAQ;AACzB;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,wBAAU;AACV,gCAAkB,QAAQ;AAC1B;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,wBAAU;AACV,iCAAmB,QAAQ;AAC3B;AAAA,UACJ;AACA;AAAA,QACF;AAGA,YAAI,aAAa,KAAK;AACpB,mBAAS;AACT,wBAAc;AACd,mBAAS;AAAA,QACX,WAAW,aAAa,KAAK;AAC3B,wBAAc,cAAc;AAC5B,oBAAU;AACV,4BAAkB,QAAQ;AAAA,QAC5B,WAAW,aAAa,KAAK;AAC3B,wBAAc,cAAc;AAC5B,oBAAU;AACV,6BAAmB,QAAQ;AAAA,QAC7B;AACA;AAAA,MACF;AAGA,UAAI,QAAQ,aAAa;AACvB,wBAAgB;AAAA,MAClB,WAAW,IAAI,WAAW,GAAG;AAE3B,mBAAW,GAAG;AAAA,MAChB;AAAA,IACF,CAAC;AAED,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,oBAAc,cAAc;AAC5B,kBAAY,QAAQ;AACpB,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;ACvsBA,IAAME,SAAQ;AAAA;AAAA,EAEZ;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AACjE;AAMO,SAAS,cAAc,UAAsC;AAClE,QAAM,aAAa,qBAAqB;AAKxC,QAAM,WAAW;AACjB,QAAM,WAAW;AACjB,QAAM,cAAc;AACpB,QAAM,cAAc;AAGpB,QAAM,gBAAgB;AAAA,IACpB,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAAA,IACjD,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAAA,IAC5C,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAAA,EACpC;AAKA,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,qBAAqB;AACzB,MAAI,MAAM;AACV,MAAI,YAAY;AAGhB,MAAI,aAAa;AACjB,MAAI,UAAoB,CAAC;AACzB,MAAI,eAAe;AACnB,MAAI,eAAyC,oBAAI,IAAI;AAGrD,MAAI,QAAoB;AAAA,IACtB,aAAa;AAAA,IACb,UAAU;AAAA,IACV,eAAe;AAAA,IACf,WAAW;AAAA,IACX,mBAAmB,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,EACtC;AAGA,MAAI,OAAO,SAAS;AACpB,MAAI,OAAO,SAAS;AAGpB,MAAI,cAAc;AAClB,MAAI,YAAwB,CAAC;AAC7B,MAAI,cAA4B,CAAC;AACjC,MAAI,cAAc;AAClB,MAAI,iBAAiB;AACrB,MAAI,YAAY;AAChB,MAAI,YAAY;AAChB,MAAI,cAAc;AAClB,MAAI,cAAc;AAKlB,QAAM,aAA+B;AAAA,IACnC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IACZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAKA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAMA,WAASC,gBAAe,GAAW,GAAW,OAAe,OAAe,QAAkB,CAAC,KAAK,KAAK,KAAK,GAAG,GAAG;AAClH,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ,MAAM;AAAA,QACpC,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAASC,eAAc,GAAW,GAAW;AAC3C,UAAM,SAAS,CAAC,cAAc,cAAc,cAAc,YAAY;AACtE,UAAM,QAAQ,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,OAAO,MAAM,CAAC;AAC9D,UAAM,QAAQ,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAC3C,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK;AAClC,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ,MAAM;AAAA,QACpC,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,cAAc,GAAW,GAAW,MAAc,QAAgB,cAAc;AACvF,gBAAY,KAAK,EAAE,GAAG,GAAG,MAAM,QAAQ,IAAI,MAAM,CAAC;AAAA,EACpD;AAEA,WAAS,aAAa,QAAgB,WAAmB;AACvD,kBAAc;AACd,qBAAiB;AAAA,EACnB;AAMA,WAAS,WAAW;AAClB,iBAAaF,OAAM,KAAK,MAAM,KAAK,OAAO,IAAIA,OAAM,MAAM,CAAC;AAC3D,cAAU,CAAC;AACX,mBAAe;AACf,mBAAe,oBAAI,IAAI;AACvB,eAAW;AACX,UAAM;AACN,aAAS;AACT,gBAAY;AACZ,gBAAY;AACZ,gBAAY;AACZ,kBAAc;AAEd,gBAAY,CAAC;AACb,kBAAc,CAAC;AACf,kBAAc;AACd,kBAAc;AAAA,EAChB;AAEA,WAAS,WAAW,OAA8B;AAChD,UAAM,SAAwB,IAAI,MAAM,WAAW,EAAE,KAAK,QAAQ;AAClE,UAAM,cAAc,WAAW,MAAM,EAAE;AACvC,UAAM,aAAa,MAAM,MAAM,EAAE;AACjC,UAAM,OAAO,IAAI,MAAM,WAAW,EAAE,KAAK,KAAK;AAG9C,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,UAAI,WAAW,CAAC,MAAM,YAAY,CAAC,GAAG;AACpC,eAAO,CAAC,IAAI;AACZ,aAAK,CAAC,IAAI;AAAA,MACZ;AAAA,IACF;AAGA,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,UAAI,OAAO,CAAC,MAAM,UAAW;AAC7B,YAAM,MAAM,YAAY,UAAU,CAAC,GAAG,MAAM,MAAM,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC3E,UAAI,QAAQ,IAAI;AACd,eAAO,CAAC,IAAI;AACZ,aAAK,GAAG,IAAI;AAAA,MACd;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,mBAAmB,OAAe,QAAuB;AAChE,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,YAAM,SAAS,MAAM,CAAC;AACtB,YAAM,eAAe,aAAa,IAAI,MAAM;AAC5C,YAAM,WAAW,OAAO,CAAC;AAGzB,UAAI,CAAC,gBAAgB,iBAAiB,UAAU;AAC9C,qBAAa,IAAI,QAAQ,QAAQ;AAAA,MACnC,WAAW,iBAAiB,aAAa,aAAa,aAAa,aAAa,YAAY;AAC1F,qBAAa,IAAI,QAAQ,QAAQ;AAAA,MACnC,WAAW,iBAAiB,aAAa,aAAa,WAAW;AAC/D,qBAAa,IAAI,QAAQ,QAAQ;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAEA,WAAS,cAAc;AACrB,QAAI,aAAa,WAAW,aAAa;AACvC,mBAAa,GAAG,CAAC;AACjB,oBAAc,KAAK,MAAM,OAAO,CAAC,GAAG,GAAG,sBAAsB,YAAY;AACzE;AAAA,IACF;AAEA,UAAM,SAAS,WAAW,YAAY;AACtC,YAAQ,KAAK,YAAY;AACzB,uBAAmB,cAAc,MAAM;AAGvC,gBAAY,QAAQ,SAAS;AAC7B,gBAAY;AACZ,kBAAc;AAEd,UAAM,aAAa,OAAO,MAAM,OAAK,MAAM,SAAS;AACpD,UAAM,eAAe,OAAO,OAAO,OAAK,MAAM,SAAS,EAAE;AACzD,UAAM,eAAe,OAAO,OAAO,OAAK,MAAM,SAAS,EAAE;AAEzD,UAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,UAAM,SAAS,IAAI,QAAQ,SAAS;AAEpC,QAAI,YAAY;AACd,YAAM;AACN,iBAAW;AACX,YAAM;AACN,YAAM;AACN,YAAM;AACN,UAAI,MAAM,gBAAgB,MAAM,WAAW;AACzC,cAAM,YAAY,MAAM;AAAA,MAC1B;AACA,YAAM,kBAAkB,QAAQ,SAAS,CAAC;AAG1C,oBAAc;AACd,mBAAa,IAAI,CAAC;AAElB,YAAM,WAAW,CAAC,oBAAoB,iBAAiB,cAAc,YAAY;AACjF,oBAAc,SAAS,SAAS,GAAG,SAAS,KAAK,MAAM,KAAK,OAAO,IAAI,SAAS,MAAM,CAAC,GAAG,YAAY;AAGtG,iBAAW,MAAM;AACf,YAAI,SAAS;AACX,mBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,uBAAW,MAAM;AACf,kBAAI,WAAW,KAAK;AAClB,gBAAAE;AAAA,kBACE,KAAK,KAAK,OAAO,KAAK,OAAO;AAAA,kBAC7B,IAAI,KAAK,OAAO,IAAI;AAAA,gBACtB;AAAA,cACF;AAAA,YACF,GAAG,IAAI,GAAG;AAAA,UACZ;AAAA,QACF;AAAA,MACF,GAAG,GAAG;AAAA,IACR,WAAW,QAAQ,UAAU,aAAa;AACxC,iBAAW;AACX,YAAM;AACN,YAAM,gBAAgB;AAEtB,mBAAa,GAAG,CAAC;AACjB,oBAAc;AACd,oBAAc,SAAS,SAAS,GAAG,qBAAqB,YAAY;AACpE,MAAAD,gBAAe,SAAS,QAAQ,IAAI,cAAc,CAAC,KAAK,KAAK,KAAK,GAAG,CAAC;AAAA,IACxE,OAAO;AAEL,UAAI,eAAe,KAAK,eAAe,GAAG;AACxC,cAAM,OAAO,eAAe,IAAI,GAAG,YAAY,WAAW,GAAG,YAAY;AACzE,sBAAc,SAAS,SAAS,GAAG,MAAM,eAAe,IAAI,eAAe,YAAY;AACvF,QAAAA,gBAAe,SAAS,QAAQ,IAAI,eAAe,GAAG,eAAe,IAAI,eAAe,YAAY;AAAA,MACtG;AAAA,IACF;AAEA,mBAAe;AAAA,EACjB;AAEA,WAAS,SAAS;AAChB,QAAI,CAAC,eAAe,UAAU,UAAW;AAGzC,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAM,IAAI,UAAU,CAAC;AACrB,QAAE,KAAK,EAAE;AACT,QAAE,KAAK,EAAE;AACT,QAAE,MAAM;AACR,QAAE;AACF,UAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,IACxC;AAGA,aAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAM,QAAQ,YAAY,CAAC;AAC3B,YAAM,KAAK;AACX,YAAM;AACN,UAAI,MAAM,UAAU,EAAG,aAAY,OAAO,GAAG,CAAC;AAAA,IAChD;AAGA,QAAI,aAAa,KAAK,YAAY,aAAa;AAC7C;AACA,UAAI,eAAe,GAAG;AACpB;AACA,sBAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAMA,WAAS,eAAe,OAA4B;AAClD,YAAQ,OAAO;AAAA,MACb,KAAK;AAAW,eAAO;AAAA;AAAA,MACvB,KAAK;AAAW,eAAO;AAAA;AAAA,MACvB,KAAK;AAAU,eAAO;AAAA;AAAA,MACtB;AAAS,eAAO;AAAA,IAClB;AAAA,EACF;AAEA,WAAS,qBAAqB,OAA4B;AACxD,YAAQ,OAAO;AAAA,MACb,KAAK;AAAW,eAAO;AAAA,MACvB,KAAK;AAAW,eAAO;AAAA,MACvB,KAAK;AAAU,eAAO;AAAA,MACtB;AAAS,eAAO;AAAA,IAClB;AAAA,EACF;AAEA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,cAAU;AAGV,WAAO,SAAS;AAChB,WAAO,SAAS;AAGhB,QAAI,cAAc,EAAG;AACrB,QAAI,cAAc,EAAG;AAGrB,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,OAAO;AACb,YAAM,YAAY,OAAO;AACzB,YAAM,aAAa,OAAO;AAC1B,UAAI,OAAO,aAAa,aAAa,qBACjC,YAAY,oBAAoB;AACpC,YAAM,OAAO,SAAS,QAAQ,IAAI,QAAQ,WAAW,IAAI,IAAI,IAAI;AACjE,YAAME,WAAU,KAAK,MAAM,OAAO,CAAC;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAGA,WAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI;AACxG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAGA,WAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI;AAClG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAGA,WAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,UAAU,GAAG,IAAI;AAC/G,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAGA,QAAI,SAAS,GAAG,SAAS;AACzB,QAAI,cAAc,GAAG;AACnB,eAAS,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,iBAAiB,CAAC;AAC9D,eAAS,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,cAAc;AAAA,IAC5D;AAEA,UAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AAGnC,mBAAe,cAAc,KAAK;AAClC,UAAM,eAAe,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC7E,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI,eAAe;AAEzE,QAAI,aAAa;AACjB,QAAI,cAAc,KAAK,cAAc,IAAI,GAAG;AAC1C,mBAAa,MAAM,eAAe;AAAA,IACpC;AAEA,QAAI,eAAe,MAAM,cAAc,IAAI;AACzC,gBAAU,UAAU,KAAK,IAAI,GAAG,MAAM,CAAC,YAAY,MAAM,CAAC,CAAC;AAC3D,gBAAU,UAAU,KAAK,IAAI,GAAG,SAAS,CAAC,CAAC,YAAY,MAAM,CAAC,CAAC;AAAA,IACjE,OAAO;AACL,gBAAU,UAAU,KAAK,IAAI,GAAG,MAAM,CAAC,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AACvE,gBAAU,UAAU,KAAK,IAAI,GAAG,MAAM,CAAC,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,IACzE;AAGA,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,SAAS;AACf,YAAM,YAAY,UAAU,KAAK,MAAM,SAAS,SAAS,CAAC;AAC1D,gBAAU,QAAQ,MAAM,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ;AAErE,gBAAU,iBAAiB,kBAAkB,oBAAoB;AAAA,QAC/D;AAAA,QACA,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,WAAW,UAAU,KAAK,MAAM,QAAQ,SAAS,CAAC;AACxD,gBAAU,QAAQ,SAAS,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACzE,WAES,WAAW;AAClB,YAAM,SAAS;AACf,YAAM,WAAW;AACjB,YAAM,OAAO,UAAU,KAAK,MAAM,WAAW,CAAC;AAE9C,gBAAU,QAAQ,MAAM,IAAI,IAAI,IAAI,UAAU,IAAI,IAAI,OAAO,WAAW,CAAC,CAAC;AAC1E,gBAAU,QAAQ,SAAS,CAAC,IAAI,IAAI,IAAI,UAAU;AAClD,gBAAU,QAAQ,SAAS,CAAC,IAAI,IAAI,IAAI,UAAU,IAAI,IAAI,OAAO,WAAW,CAAC,CAAC;AAE9E,YAAM,SAAS,MAAM,cAAc,IAAI,KAAK,MAAO,MAAM,WAAW,MAAM,cAAe,GAAG,IAAI;AAEhG,gBAAU,QAAQ,SAAS,CAAC,IAAI,OAAO,CAAC,IAAI,UAAU,kBAAkB,MAAM,WAAW;AACzF,gBAAU,QAAQ,SAAS,CAAC,IAAI,OAAO,CAAC,IAAI,UAAU,kBAAkB,MAAM;AAC9E,gBAAU,QAAQ,SAAS,CAAC,IAAI,OAAO,CAAC,IAAI,UAAU,mBAAmB,MAAM,aAAa;AAC5F,gBAAU,QAAQ,SAAS,CAAC,IAAI,OAAO,CAAC,IAAI,UAAU,kBAAkB,MAAM,SAAS;AAEvF,gBAAU,QAAQ,SAAS,CAAC,IAAI,OAAO,CAAC,IAAI,UAAU;AAEtD,YAAM,UAAU,KAAK,IAAI,GAAG,MAAM,mBAAmB,CAAC;AACtD,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,cAAM,QAAQ,MAAM,kBAAkB,CAAC;AACvC,cAAM,SAAS,KAAK,MAAO,QAAQ,UAAW,EAAE;AAChD,cAAM,MAAM,IAAI,OAAO,KAAK,IAAI,QAAQ,QAAQ,IAAI,IAAI,CAAC,CAAC;AAC1D,cAAM,WAAW,MAAM,QAAQ,SAAS,KAAK,MAAM,eAAe;AAClE,kBAAU,QAAQ,SAAS,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,UAAU,GAAG,IAAI,CAAC,KAAK,QAAQ,GAAG,GAAG,WAAW,KAAK;AAAA,MACxG;AAEA,gBAAU,QAAQ,SAAS,EAAE,IAAI,IAAI,IAAI,UAAU,IAAI,IAAI,OAAO,WAAW,CAAC,CAAC;AAE/E,YAAM,OAAO;AACb,gBAAU,QAAQ,SAAS,EAAE,IAAI,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,WAAW,UAAU,GAAG,IAAI;AAAA,IACpG,WAES,CAAC,aAAa;AACrB,YAAM,WAAW;AACjB,YAAM,SAAS,KAAK,MAAM,OAAO,CAAC,IAAI;AACtC,YAAM,SAAS,UAAU,KAAK,MAAM,SAAS,SAAS,CAAC;AACvD,gBAAU,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ;AAElE,YAAM,QAAQ;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,cAAM,QAAQ,UAAU;AACxB,kBAAU,QAAQ,SAAS,IAAI,CAAC,IAAI,KAAK,IAAI,MAAM,CAAC,CAAC;AAAA,MACvD;AAEA,YAAM,WAAW;AACjB,gBAAU,QAAQ,OAAO,CAAC,IAAI,UAAU,KAAK,MAAM,SAAS,SAAS,CAAC,CAAC,WAAW,UAAU,GAAG,QAAQ;AAAA,IACzG,OAEK;AACH,YAAM,QAAQ,IAAI;AAClB,YAAM,QAAQ,UAAU,IAAI;AAG5B,eAAS,MAAM,GAAG,MAAM,aAAa,OAAO;AAC1C,cAAM,IAAI,QAAQ,MAAM;AAExB,iBAAS,MAAM,GAAG,MAAM,aAAa,OAAO;AAC1C,gBAAM,IAAI,QAAQ,MAAM;AAExB,cAAI,SAAS;AACb,cAAI,QAAqB;AACzB,cAAI,cAAc;AAElB,cAAI,MAAM,QAAQ,QAAQ;AACxB,qBAAS,QAAQ,GAAG,EAAE,GAAG;AACzB,kBAAM,SAAS,WAAW,QAAQ,GAAG,CAAC;AAGtC,gBAAI,QAAQ,aAAa,OAAO,WAAW;AACzC,sBAAQ,OAAO,GAAG;AAAA,YACpB,WAAW,QAAQ,WAAW;AAC5B,4BAAc;AAAA,YAChB,OAAO;AACL,sBAAQ,OAAO,GAAG;AAAA,YACpB;AAAA,UACF,WAAW,QAAQ,QAAQ,UAAU,MAAM,aAAa,QAAQ;AAC9D,qBAAS,aAAa,GAAG;AAAA,UAC3B;AAGA,gBAAM,YAAY,qBAAqB,KAAK;AAC5C,gBAAM,UAAU,eAAe,KAAK;AAEpC,cAAI,aAAa;AAEf,sBAAU,QAAQ,CAAC,IAAI,CAAC,IAAI,UAAU;AAAA,UACxC,WAAW,WAAW,KAAK;AACzB,sBAAU,QAAQ,CAAC,IAAI,CAAC,IAAI,SAAS,WAAW,OAAO,IAAI,MAAM,WAAW,SAAS;AAAA,UACvF,OAAO;AACL,sBAAU,QAAQ,CAAC,IAAI,CAAC,IAAI,UAAU;AAAA,UACxC;AAAA,QACF;AAAA,MACF;AAGA,YAAM,MAAM,QAAQ,cAAc,IAAI;AAEtC,eAAS,SAAS,GAAG,SAAS,cAAc,QAAQ,UAAU;AAC5D,cAAM,QAAQ,cAAc,MAAM;AAClC,cAAM,YAAY,WAAW,IAAI,IAAI,WAAW,IAAI,IAAI;AACxD,cAAM,OAAO,UAAU,KAAK,MAAM,MAAM,SAAS,IAAI,CAAC,IAAI,YAAY;AAEtE,iBAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,gBAAM,MAAM,MAAM,CAAC;AACnB,gBAAM,QAAQ,aAAa,IAAI,GAAG,KAAK;AACvC,gBAAM,WAAW,eAAe,KAAK;AAErC,oBAAU,QAAQ,MAAM,MAAM,IAAI,OAAO,IAAI,CAAC,IAAI,QAAQ,GAAG,GAAG;AAAA,QAClE;AAAA,MACF;AAGA,UAAI,UAAU;AACZ,cAAM,QAAQ,MAAM;AAEpB,YAAI,KAAK;AACP,gBAAM,SAAS;AACf,oBAAU,QAAQ,KAAK,IAAI,UAAU,KAAK,MAAM,OAAO,SAAS,CAAC,CAAC,cAAc,MAAM;AAAA,QACxF,OAAO;AACL,gBAAM,UAAU;AAChB,oBAAU,QAAQ,KAAK,IAAI,UAAU,KAAK,MAAM,QAAQ,SAAS,CAAC,CAAC,cAAc,OAAO;AACxF,gBAAM,UAAU,mBAAmB,UAAU;AAC7C,oBAAU,QAAQ,QAAQ,CAAC,IAAI,UAAU,KAAK,MAAM,QAAQ,SAAS,CAAC,CAAC,IAAI,UAAU,GAAG,OAAO;AAAA,QACjG;AAEA,cAAM,cAAc;AACpB,kBAAU,QAAQ,QAAQ,CAAC,IAAI,UAAU,KAAK,MAAM,YAAY,SAAS,CAAC,CAAC,WAAW,UAAU,GAAG,WAAW;AAAA,MAChH;AAGA,iBAAW,KAAK,WAAW;AACzB,cAAM,KAAK,KAAK,MAAM,EAAE,CAAC;AACzB,cAAM,KAAK,KAAK,MAAM,EAAE,CAAC;AACzB,YAAI,KAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,KAAK,MAAM;AAC9C,gBAAM,QAAQ,EAAE,OAAO,IAAI,KAAK;AAChC,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,QACxD;AAAA,MACF;AAGA,iBAAW,SAAS,aAAa;AAC/B,cAAM,KAAK,KAAK,MAAM,MAAM,IAAI,MAAM,KAAK,SAAS,CAAC;AACrD,cAAM,KAAK,KAAK,MAAM,MAAM,CAAC;AAC7B,YAAI,KAAK,KAAK,KAAK,QAAQ,KAAK,GAAG;AACjC,gBAAM,QAAQ,MAAM,SAAS,KAAK,YAAY;AAC9C,oBAAU,QAAQ,EAAE,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC,IAAI,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM,IAAI;AAAA,QAC7E;AAAA,MACF;AAGA,UAAI,CAAC,UAAU;AACb,cAAM,OAAO,WAAW,QAAQ,SAAS,CAAC,IAAI,WAAW;AACzD,kBAAU,QAAQ,OAAO,CAAC,IAAI,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,WAAW,UAAU,GAAG,IAAI;AAAA,MACjG;AAAA,IACF;AAGA,QAAI,cAAc,GAAG;AACnB,YAAM,aAAa,MAAM,aAAa;AACtC,YAAM,YAAY,cAAc,IAAI,IAAI,MAAM;AAC9C,eAAS,IAAI,GAAG,KAAK,MAAM,KAAK,GAAG;AACjC,kBAAU,UAAU,CAAC,IAAI,UAAU,GAAG,SAAS;AAC/C,kBAAU,QAAQ,IAAI,IAAI,CAAC,IAAI,UAAU,GAAG,SAAS;AAAA,MACvD;AAAA,IACF;AAEA,aAAS,MAAM,MAAM;AAAA,EACvB;AAMA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,aAAS;AACT,kBAAc;AAEd,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AAAE,sBAAc,cAAc;AAAG;AAAA,MAAQ;AACvD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,eAAe,YAAY,MAAM;AACrC,UAAI,CAAC,SAAS;AAAE,sBAAc,YAAY;AAAG;AAAA,MAAQ;AACrD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AAAE,oBAAY,QAAQ;AAAG;AAAA,MAAQ;AAE/C,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS;AACrB,YAAM,WAAW,IAAI,YAAY;AAGjC,UAAI,QAAQ,UAAU;AACpB,YAAI,WAAW;AACb,sBAAY;AAAA,QACd,OAAO;AACL,mBAAS,CAAC;AACV,cAAI,OAAQ,sBAAqB;AAAA,QACnC;AACA;AAAA,MACF;AAGA,UAAI,WAAW;AACb,YAAI,QAAQ,SAAS;AACnB,mBAAS;AACT,wBAAc;AACd,sBAAY;AAAA,QACd;AACA;AAAA,MACF;AAGA,UAAI,CAAC,eAAe,CAAC,QAAQ;AAC3B,sBAAc;AACd;AAAA,MACF;AAGA,UAAI,YAAY,CAAC,WAAW;AAC1B,YAAI,aAAa,KAAK;AACpB,mBAAS;AACT,wBAAc;AAAA,QAChB,WAAW,QAAQ,SAAS;AAC1B,sBAAY;AAAA,QACd;AACA;AAAA,MACF;AAGA,UAAI,QAAQ;AACV,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AAAG,uBAAS;AAAO;AAAA,YACxB,KAAK;AAAG,uBAAS;AAAG,4BAAc;AAAM,uBAAS;AAAO;AAAA,YACxD,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,yBAAW,KAAK;AAChB,+BAAiB,QAAQ;AACzB;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,gCAAkB,QAAQ;AAC1B;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,iCAAmB,QAAQ;AAC3B;AAAA,UACJ;AACA;AAAA,QACF;AAGA,YAAI,aAAa,KAAK;AAAE,mBAAS;AAAG,wBAAc;AAAM,mBAAS;AAAA,QAAO,WAC/D,aAAa,KAAK;AAAE,wBAAc,cAAc;AAAG,wBAAc,YAAY;AAAG,oBAAU;AAAO,4BAAkB,QAAQ;AAAA,QAAG,WAC9H,aAAa,KAAK;AAAE,wBAAc,cAAc;AAAG,wBAAc,YAAY;AAAG,oBAAU;AAAO,6BAAmB,QAAQ;AAAA,QAAG;AACxI;AAAA,MACF;AAGA,UAAI,QAAQ,aAAa;AACvB,uBAAe,aAAa,MAAM,GAAG,EAAE;AAAA,MACzC,WAAW,QAAQ,SAAS;AAC1B,oBAAY;AAAA,MACd,WAAW,IAAI,WAAW,KAAK,WAAW,KAAK,GAAG,KAAK,aAAa,SAAS,aAAa;AACxF,wBAAgB,IAAI,YAAY;AAEhC,QAAAF;AAAA,UACE,KAAK,MAAM,OAAO,CAAC,IAAI,IAAI,aAAa,SAAS;AAAA,UACjD,IAAI,QAAQ,SAAS;AAAA,UACrB;AAAA,UACA;AAAA,UACA,CAAC,KAAK,GAAG;AAAA,QACX;AAAA,MACF;AAAA,IACF,CAAC;AAGD,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,oBAAc,cAAc;AAC5B,oBAAc,YAAY;AAC1B,kBAAY,QAAQ;AACpB,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;AC9xBO,SAAS,cAAc,UAAoB,mBAAwF;AAExI,QAAM,UAA4B,OAAO,sBAAsB,aAC3D,EAAE,cAAc,kBAAkB,IAClC,qBAAqB,CAAC;AAC1B,QAAM,EAAE,cAAc,OAAO,IAAI;AACjC,QAAM,aAAa,qBAAqB;AACxC,QAAM,aAAaG,cAAa;AAEhC,MAAI,UAAU;AACd,MAAI,gBAAgB;AACpB,MAAI,eAAe;AAEnB,QAAM,aAAkC;AAAA,IACtC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IACZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAEA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAEA,WAAS,SAAe;AACtB,QAAI,SAAS;AACb,cAAU;AAEV,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AAGtB,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC;AACtD,cAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAC1D,cAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAG1D,UAAM,WAAW,0BAA0B,MAAM,MAAM;AACvD,cAAU,UAAU,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC,CAAC,WAAW,QAAQ;AAG/E,UAAM,WAAW;AACjB,UAAM,YAAY;AAClB,UAAM,iBAAiB,WAAW,IAAI;AACtC,UAAM,gBAAgB,QAAQ,iBAAiB;AAE/C,UAAM,aAAa;AACnB,UAAM,gBAAgB,OAAO,aAAa;AAC1C,UAAM,kBAAkB,KAAK,IAAI,GAAG,KAAK,MAAM,gBAAgB,CAAC,CAAC;AAEjE,QAAI,eAAe;AACjB,uBAAiB,QAAQ,MAAM,MAAM,UAAU,WAAW,YAAY,eAAe;AAAA,IACvF,OAAO;AACL,yBAAmB,QAAQ,MAAM,MAAM,UAAU,YAAY,eAAe;AAAA,IAC9E;AAAA,EACF;AAEA,WAAS,mBACP,YACA,MACA,MACA,UACA,YACA,iBACM;AACN,QAAI,SAAS;AACb,UAAM,OAAO,KAAK,OAAO,OAAO,YAAY,CAAC;AAC7C,UAAM,eAAe,KAAK,IAAI,iBAAiB,MAAM,MAAM;AAG3D,QAAI,gBAAgB,cAAc;AAChC,qBAAe;AAAA,IACjB,WAAW,iBAAiB,eAAe,cAAc;AACvD,qBAAe,gBAAgB,eAAe;AAAA,IAChD;AACA,mBAAe,KAAK,IAAI,GAAG,KAAK,IAAI,cAAc,MAAM,SAAS,YAAY,CAAC;AAE9E,UAAM,cAAc,eAAe;AACnC,UAAM,gBAAgB,eAAe,eAAe,MAAM;AAG1D,UAAM,qBAAqB,cAAc,kBAAkB,SAAS,OAAO,CAAC;AAC5E,UAAM,iBAAiB,WAAW,IAAI,mBAAmB;AACzD,UAAM,aAAa,KAAK,MAAM,iBAAiB,CAAC;AAChD,UAAM,cAAc,iBAAiB;AACrC,cAAU,QAAQ,UAAU,IAAI,IAAI,IAAI,UAAU,SAAS,SAAS,OAAO,UAAU,CAAC,GAAG,cAAc,aAAa,EAAE,GAAG,kBAAkB,GAAG,cAAc,aAAa,EAAE,GAAG,SAAS,OAAO,WAAW,CAAC;AAG1M,aAAS,KAAK,GAAG,KAAK,cAAc,MAAM;AACxC,YAAM,IAAI,eAAe;AACzB,YAAM,OAAO,MAAM,CAAC;AACpB,YAAM,IAAI,aAAa,IAAI,KAAK;AAChC,YAAM,aAAa,MAAM;AAEzB,gBAAU,gBAAgB,MAAM,GAAG,YAAY,GAAG,MAAM,QAAQ;AAAA,IAClE;AAGA,UAAM,UAAU,aAAa,IAAI,eAAe;AAChD,UAAM,wBAAwB,gBAAgB,kBAAkB,SAAS,OAAO,CAAC;AACjF,UAAM,oBAAoB,WAAW,IAAI,sBAAsB;AAC/D,UAAM,gBAAgB,KAAK,MAAM,oBAAoB,CAAC;AACtD,UAAM,iBAAiB,oBAAoB;AAC3C,cAAU,QAAQ,OAAO,IAAI,IAAI,IAAI,UAAU,SAAS,SAAS,OAAO,aAAa,CAAC,GAAG,gBAAgB,aAAa,EAAE,GAAG,qBAAqB,GAAG,gBAAgB,aAAa,EAAE,GAAG,SAAS,OAAO,cAAc,CAAC;AAGpN,UAAM,WAAW;AACjB,cAAU,QAAQ,OAAO,CAAC,IAAI,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC,CAAC,WAAW,QAAQ;AAEzF,aAAS,MAAM,MAAM;AAAA,EACvB;AAEA,WAAS,iBACP,YACA,MACA,MACA,UACA,WACA,YACA,iBACM;AACN,QAAI,SAAS;AAGb,UAAM,iBAAiB,KAAK,IAAI,iBAAiB,KAAK,KAAK,MAAM,SAAS,CAAC,CAAC;AAG5E,UAAM,cAAc,KAAK,MAAM,gBAAgB,CAAC;AAChD,QAAI,cAAc,cAAc;AAC9B,qBAAe;AAAA,IACjB,WAAW,eAAe,eAAe,gBAAgB;AACvD,qBAAe,cAAc,iBAAiB;AAAA,IAChD;AACA,UAAM,YAAY,KAAK,IAAI,GAAG,KAAK,KAAK,MAAM,SAAS,CAAC,IAAI,cAAc;AAC1E,mBAAe,KAAK,IAAI,GAAG,KAAK,IAAI,cAAc,SAAS,CAAC;AAE5D,UAAM,cAAc,eAAe;AACnC,UAAM,iBAAiB,eAAe,kBAAkB,IAAI,MAAM;AAGlE,UAAM,aAAa,WAAW,IAAI;AAClC,UAAM,SAAS,KAAK,OAAO,OAAO,cAAc,CAAC;AACjD,UAAM,WAAW;AACjB,UAAM,YAAY,SAAS,WAAW;AAGtC,UAAM,qBAAqB,cAAc,aAAa;AACtD,UAAM,mBAAmB,WAAW,IAAI,mBAAmB;AAC3D,UAAM,UAAU,KAAK,MAAM,mBAAmB,CAAC;AAC/C,UAAM,WAAW,mBAAmB;AAEpC,cAAU,QAAQ,UAAU,IAAI,QAAQ,IAAI,UAAU,SAAS,SAAS,OAAO,OAAO,CAAC,GAAG,cAAc,aAAa,EAAE,GAAG,kBAAkB,GAAG,cAAc,aAAa,EAAE,GAAG,SAAS,OAAO,QAAQ,CAAC;AACxM,cAAU,QAAQ,UAAU,IAAI,SAAS,IAAI,UAAU,SAAS,SAAS,OAAO,OAAO,CAAC,GAAG,cAAc,aAAa,EAAE,GAAG,kBAAkB,GAAG,cAAc,aAAa,EAAE,GAAG,SAAS,OAAO,QAAQ,CAAC;AAGzM,aAAS,MAAM,GAAG,MAAM,gBAAgB,OAAO;AAC7C,YAAM,WAAW,eAAe,OAAO;AACvC,YAAM,WAAW,UAAU;AAC3B,YAAM,IAAI,aAAa,IAAI,MAAM;AAGjC,UAAI,UAAU,MAAM,QAAQ;AAC1B,kBAAU,gBAAgB,MAAM,OAAO,GAAG,SAAS,YAAY,eAAe,GAAG,UAAU,QAAQ;AAAA,MACrG,OAAO;AAEL,kBAAU,QAAQ,CAAC,IAAI,QAAQ,IAAI,UAAU,SAAS,IAAI,OAAO,WAAW,CAAC,CAAC;AAC9E,kBAAU,QAAQ,IAAI,CAAC,IAAI,QAAQ,IAAI,UAAU,SAAS,IAAI,OAAO,WAAW,CAAC,CAAC;AAAA,MACpF;AAGA,UAAI,WAAW,MAAM,QAAQ;AAC3B,kBAAU,gBAAgB,MAAM,QAAQ,GAAG,UAAU,aAAa,eAAe,GAAG,WAAW,QAAQ;AAAA,MACzG,OAAO;AAEL,kBAAU,QAAQ,CAAC,IAAI,SAAS,IAAI,UAAU,SAAS,IAAI,OAAO,WAAW,CAAC,CAAC;AAC/E,kBAAU,QAAQ,IAAI,CAAC,IAAI,SAAS,IAAI,UAAU,SAAS,IAAI,OAAO,WAAW,CAAC,CAAC;AAAA,MACrF;AAAA,IACF;AAGA,UAAM,UAAU,aAAa,IAAI,iBAAiB;AAClD,UAAM,wBAAwB,gBAAgB,aAAa;AAC3D,UAAM,sBAAsB,WAAW,IAAI,sBAAsB;AACjE,UAAM,aAAa,KAAK,MAAM,sBAAsB,CAAC;AACrD,UAAM,cAAc,sBAAsB;AAE1C,cAAU,QAAQ,OAAO,IAAI,QAAQ,IAAI,UAAU,SAAS,SAAS,OAAO,UAAU,CAAC,GAAG,gBAAgB,aAAa,EAAE,GAAG,qBAAqB,GAAG,gBAAgB,aAAa,EAAE,GAAG,SAAS,OAAO,WAAW,CAAC;AAClN,cAAU,QAAQ,OAAO,IAAI,SAAS,IAAI,UAAU,SAAS,SAAS,OAAO,UAAU,CAAC,GAAG,gBAAgB,aAAa,EAAE,GAAG,qBAAqB,GAAG,gBAAgB,aAAa,EAAE,GAAG,SAAS,OAAO,WAAW,CAAC;AAGnN,UAAM,WAAW;AACjB,cAAU,QAAQ,OAAO,CAAC,IAAI,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC,CAAC,WAAW,QAAQ;AAEzF,aAAS,MAAM,MAAM;AAAA,EACvB;AAEA,WAAS,gBACP,MACA,OACA,YACA,GACA,MACA,UACQ;AACR,QAAI,SAAS;AACb,UAAM,eAAe,WAAW;AAEhC,UAAM,SAAS,aAAa,WAAW;AACvC,UAAM,YAAY,aAAc,aAAa,iBAAiB,cAAe;AAC7E,UAAM,WAAW,aAAa,KAAK;AACnC,UAAM,SAAS,QAAQ;AACvB,UAAM,aAAa,UAAU,IAAI,GAAG,MAAM,KAAK;AAG/C,UAAM,cAAc,GAAG,MAAM,KAAK,UAAU,KAAK,KAAK,IAAI;AAC1D,UAAM,UAAU,KAAK,IAAI,GAAG,eAAe,YAAY,MAAM;AAE7D,cAAU,QAAQ,CAAC,IAAI,IAAI,IAAI,UAAU,gBAAgB,SAAS,GAAG,QAAQ,GAAG,WAAW,GAAG,IAAI,OAAO,OAAO,CAAC,UAAU,UAAU;AAGrI,UAAM,cAAc,OAAO,KAAK,WAAW;AAC3C,UAAM,cAAc,KAAK,IAAI,GAAG,eAAe,YAAY,MAAM;AACjE,UAAM,YAAY,aAAc,aAAa,iBAAiB,cAAe;AAE7E,cAAU,QAAQ,IAAI,CAAC,IAAI,IAAI,IAAI,UAAU,gBAAgB,SAAS,GAAG,WAAW,GAAG,IAAI,OAAO,WAAW,CAAC,UAAU,UAAU;AAElI,WAAO;AAAA,EACT;AAGA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAGd,QAAI,CAAC,gBAAgB,QAAQ,GAAG;AAC9B,cAAQ,KAAK,6DAA6D;AAC1E,gBAAU;AACV;AAAA,IACF;AAEA,QAAI,cAAwD;AAE5D,QAAI;AAEF,2BAAqB,UAAU,YAAY;AAE3C,aAAO;AAEP,oBAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AAC7C,YAAI,CAAC,SAAS;AACZ,uBAAa,QAAQ;AACrB;AAAA,QACF;AAEA,YAAI;AACF,mBAAS,eAAe;AACxB,mBAAS,gBAAgB;AAEzB,gBAAM,MAAM,SAAS;AACrB,gBAAM,WAAW,IAAI,YAAY;AACjC,gBAAM,OAAO,SAAS;AACtB,gBAAM,WAAW;AACjB,gBAAM,YAAY;AAClB,gBAAM,iBAAiB,WAAW,IAAI;AACtC,gBAAM,gBAAgB,QAAQ,iBAAiB;AAG/C,cAAI,QAAQ,YAAY,aAAa,KAAK;AACxC,yBAAa,QAAQ;AACrB,uBAAW,KAAK;AAChB,gCAAoB,UAAU,iBAAiB;AAC/C,gBAAI,QAAQ;AACV,qBAAO;AAAA,YACT;AACA;AAAA,UACF;AAGA,cAAI,QAAQ,WAAW;AACrB,gBAAI,eAAe;AACjB,8BAAgB,KAAK,IAAI,GAAG,gBAAgB,CAAC;AAAA,YAC/C,OAAO;AACL,+BAAiB,gBAAgB,IAAI,MAAM,UAAU,MAAM;AAAA,YAC7D;AACA,mBAAO;AACP;AAAA,UACF;AACA,cAAI,QAAQ,aAAa;AACvB,gBAAI,eAAe;AACjB,8BAAgB,KAAK,IAAI,MAAM,SAAS,GAAG,gBAAgB,CAAC;AAAA,YAC9D,OAAO;AACL,+BAAiB,gBAAgB,KAAK,MAAM;AAAA,YAC9C;AACA,mBAAO;AACP;AAAA,UACF;AACA,cAAI,QAAQ,eAAe,eAAe;AACxC,gBAAI,gBAAgB,MAAM,GAAG;AAC3B;AAAA,YACF;AACA,mBAAO;AACP;AAAA,UACF;AACA,cAAI,QAAQ,gBAAgB,eAAe;AACzC,gBAAI,gBAAgB,MAAM,KAAK,gBAAgB,IAAI,MAAM,QAAQ;AAC/D;AAAA,YACF;AACA,mBAAO;AACP;AAAA,UACF;AAGA,gBAAMC,cAAa,OAAO,SAA+B;AACvD,yBAAa,QAAQ;AACrB,sBAAU;AAEV,gCAAoB,UAAU,mBAAmB;AAEjD,gBAAI;AACF,oBAAM,qBAAqB,UAAU,KAAK,IAAI;AAC9C,kBAAI,cAAc;AAChB,6BAAa,KAAK,EAAE;AAAA,cACtB;AAAA,YACF,SAAS,KAAK;AACZ,sBAAQ,MAAM,sCAAsC,GAAG;AAEvD,uCAAyB,UAAU,yBAAyB;AAC5D,uBAAS,MAAM,iCAAiC,GAAG;AAAA,CAAa;AAAA,YAClE;AAAA,UACF;AAGA,cAAI,QAAQ,SAAS;AACnB,YAAAA,YAAW,MAAM,aAAa,CAAC,EAAE,MAAM,SAAO;AAC5C,sBAAQ,MAAM,uCAAuC,GAAG;AAAA,YAC1D,CAAC;AACD;AAAA,UACF;AAGA,gBAAM,SAAS,SAAS,GAAG;AAC3B,cAAI,UAAU,KAAK,UAAU,MAAM,UAAU,UAAU,GAAG;AACxD,YAAAA,YAAW,MAAM,SAAS,CAAC,CAAC,EAAE,MAAM,SAAO;AACzC,sBAAQ,MAAM,uCAAuC,GAAG;AAAA,YAC1D,CAAC;AACD;AAAA,UACF;AAAA,QACF,SAAS,KAAK;AACZ,kBAAQ,MAAM,kCAAkC,GAAG;AACnD,qBAAW,KAAK;AAAA,QAClB;AAAA,MACF,CAAC;AAED,YAAM,eAAe,WAAW;AAChC,iBAAW,OAAO,MAAM;AACtB,qBAAa,QAAQ;AACrB,4BAAoB,UAAU,iBAAiB;AAC/C,qBAAa;AAAA,MACf;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,MAAM,0CAA0C,GAAG;AAC3D,+BAAyB,UAAU,uBAAuB;AAC1D,gBAAU;AAAA,IACZ;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;ACvSO,IAAM,QAAoB;AAAA;AAAA,EAE/B,EAAE,IAAI,UAAU,MAAM,UAAU,aAAa,oBAAoB,KAAK,cAAc;AAAA,EACpF,EAAE,IAAI,SAAS,MAAM,SAAS,aAAa,gBAAgB,KAAK,aAAa;AAAA,EAC7E,EAAE,IAAI,QAAQ,MAAM,QAAQ,aAAa,2BAA2B,KAAK,YAAY;AAAA,EACrF,EAAE,IAAI,UAAU,MAAM,UAAU,aAAa,iBAAiB,KAAK,cAAc;AAAA,EACjF,EAAE,IAAI,QAAQ,MAAM,QAAQ,aAAa,uBAAuB,KAAK,YAAY;AAAA,EACjF,EAAE,IAAI,UAAU,MAAM,UAAU,aAAa,kBAAkB,KAAK,cAAc;AAAA,EAClF,EAAE,IAAI,eAAe,MAAM,eAAe,aAAa,mBAAmB,KAAK,mBAAmB;AAAA,EAClG,EAAE,IAAI,WAAW,MAAM,WAAW,aAAa,kBAAkB,KAAK,eAAe;AAAA,EACrF,EAAE,IAAI,iBAAiB,MAAM,kBAAkB,aAAa,gBAAgB,KAAK,qBAAqB;AAAA,EACtG,EAAE,IAAI,SAAS,MAAM,SAAS,aAAa,iBAAiB,KAAK,aAAa;AAAA,EAC9E,EAAE,IAAI,SAAS,MAAM,SAAS,aAAa,eAAe,KAAK,aAAa;AAAA,EAC5E,EAAE,IAAI,WAAW,MAAM,WAAW,aAAa,kBAAkB,KAAK,eAAe;AAAA,EACrF,EAAE,IAAI,YAAY,MAAM,YAAY,aAAa,wBAAwB,KAAK,gBAAgB;AAAA,EAC9F,EAAE,IAAI,aAAa,MAAM,aAAa,aAAa,mBAAmB,KAAK,iBAAiB;AAAA,EAC5F,EAAE,IAAI,cAAc,MAAM,eAAe,aAAa,mBAAmB,KAAK,cAAc;AAAA,EAC5F,EAAE,IAAI,QAAQ,MAAM,QAAQ,aAAa,sBAAsB,KAAK,YAAY;AAAA,EAChF,EAAE,IAAI,SAAS,MAAM,SAAS,aAAa,mBAAmB,KAAK,aAAa;AAAA,EAChF,EAAE,IAAI,WAAW,MAAM,WAAW,aAAa,sBAAsB,KAAK,eAAe;AAC3F;;;ACxGA,IAAM,iBAAiB,oBAAI,IAA+B;AAE1D,IAAM,iBAAiB;AAAA,EACrB,iBAAiB,MAAc,SAAuB;AACpD,QAAI,CAAC,eAAe,IAAI,IAAI,EAAG,gBAAe,IAAI,MAAM,oBAAI,IAAI,CAAC;AACjE,mBAAe,IAAI,IAAI,EAAG,IAAI,OAAO;AAAA,EACvC;AAAA,EACA,oBAAoB,MAAc,SAAuB;AACvD,mBAAe,IAAI,IAAI,GAAG,OAAO,OAAO;AAAA,EAC1C;AAAA,EACA,cAAc,OAAuB;AACnC,UAAM,WAAW,eAAe,IAAI,MAAM,IAAI;AAC9C,QAAI,UAAU;AACZ,iBAAW,WAAW,UAAU;AAC9B,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAEA,IAAI,OAAO,WAAW,WAAW,aAAa;AAC5C,EAAC,WAAuC,SAAS;AACnD;AAsCA,IAAM,YAAoC;AAAA,EACxC,SAAS;AAAA,EAAI,WAAW;AAAA,EAAI,WAAW;AAAA,EAAI,YAAY;AAAA,EACvD,OAAO;AAAA,EAAI,QAAQ;AAAA,EAAI,KAAK;AAAA,EAAI,WAAW;AAAA,EAAG,KAAK;AAAA,EACnD,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EACpD,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EACpD,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EACpD,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,KAAK;AAAA,EAAI,KAAK;AAAA,EAAI,KAAK;AAAA,EAAI,KAAK;AAAA,EAAI,KAAK;AAAA,EACvD,KAAK;AAAA,EAAI,KAAK;AAAA,EAAI,KAAK;AAAA,EAAI,KAAK;AAAA,EAAI,KAAK;AAC3C;AAMA,SAAS,SAAS,MAAsB;AACtC,MAAI,SAAS,YAAY,SAAS,SAAU,QAAO;AACnD,MAAI,SAAS,YAAY,SAAS,SAAU,QAAO;AACnD,MAAI,SAAS,YAAY,SAAS,SAAU,QAAO;AACnD,MAAI,SAAS,YAAY,SAAS,SAAU,QAAO;AACnD,MAAI,SAAS,QAAQ,SAAS,KAAM,QAAO;AAC3C,MAAI,SAAS,OAAQ,QAAO;AAC5B,MAAI,SAAS,IAAK,QAAO;AACzB,MAAI,SAAS,UAAU,SAAS,KAAM,QAAO;AAC7C,MAAI,SAAS,IAAM,QAAO;AAC1B,MAAI,SAAS,IAAQ,QAAO;AAC5B,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,SAAO;AACT;AAEA,SAAS,eAAe,KAAa;AACnC,QAAM,UAAU,UAAU,GAAG,KAAK,UAAU,IAAI,YAAY,CAAC,KAAK;AAClE,SAAO;AAAA,IACL;AAAA,IACA,MAAM,IAAI,WAAW,IAAI,MAAM,IAAI,YAAY,CAAC,KAAK;AAAA,IACrD;AAAA,IACA,OAAO;AAAA,IACP,gBAAgB,MAAM;AAAA,IAAC;AAAA,IACvB,iBAAiB,MAAM;AAAA,IAAC;AAAA,IACxB,0BAA0B,MAAM;AAAA,IAAC;AAAA;AAAA,IAEjC,SAAS;AAAA,IACT,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AACF;AAGA,IAAM,WAAW,oBAAI,IAA2C;AAEhE,SAAS,qBAAmC;AAC1C,QAAM,eAA8C,CAAC;AACrD,QAAM,gBAA4C,CAAC;AACnD,QAAM,kBAAsE,CAAC;AAE7E,MAAI,QAAQ,MAAM,OAAO;AACvB,YAAQ,MAAM,WAAW,IAAI;AAAA,EAC/B;AACA,UAAQ,MAAM,OAAO;AACrB,UAAQ,MAAM,YAAY,MAAM;AAEhC,UAAQ,MAAM,GAAG,QAAQ,CAAC,SAAiB;AACzC,QAAI,SAAS,KAAQ;AACnB,cAAQ;AACR,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,MAAM,SAAS,IAAI;AACzB,UAAM,WAAW,eAAe,GAAG;AAInC,UAAM,eAAe,EAAE,GAAG,UAAU,MAAM,UAAU;AACpD,mBAAe,cAAc,YAAY;AAGzC,QAAI,SAAS,IAAI,GAAG,GAAG;AACrB,mBAAa,SAAS,IAAI,GAAG,CAAE;AAAA,IACjC;AACA,aAAS,IAAI,KAAK,WAAW,MAAM;AACjC,YAAM,aAAa,EAAE,GAAG,UAAU,MAAM,QAAQ;AAChD,qBAAe,cAAc,UAAU;AACvC,eAAS,OAAO,GAAG;AAAA,IACrB,GAAG,EAAE,CAAC;AAGN,eAAW,YAAY,CAAC,GAAG,YAAY,GAAG;AACxC,eAAS,EAAE,KAAK,SAAS,CAAC;AAAA,IAC5B;AAEA,eAAW,YAAY,CAAC,GAAG,aAAa,GAAG;AACzC,eAAS,IAAI;AAAA,IACf;AAAA,EACF,CAAC;AAED,UAAQ,OAAO,GAAG,UAAU,MAAM;AAChC,UAAM,OAAO,EAAE,MAAM,QAAQ,OAAO,WAAW,IAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG;AACnF,eAAW,YAAY,CAAC,GAAG,eAAe,GAAG;AAC3C,eAAS,IAAI;AAAA,IACf;AAAA,EACF,CAAC;AAED,WAAS,UAAU;AACjB,QAAI,QAAQ,MAAM,OAAO;AACvB,cAAQ,MAAM,WAAW,KAAK;AAAA,IAChC;AACA,YAAQ,MAAM,MAAM;AACpB,YAAQ,OAAO,MAAM,aAAa;AAClC,YAAQ,OAAO,MAAM,WAAW;AAChC,YAAQ,OAAO,MAAM,SAAS;AAAA,EAChC;AAKA,QAAM,aAAa;AACnB,QAAM,WAAW;AAEjB,QAAM,WAAyB;AAAA,IAC7B,OAAO,CAAC,SAAiB;AACvB,cAAQ,OAAO,MAAM,aAAa,OAAO,QAAQ;AAAA,IACnD;AAAA,IACA,IAAI,OAAO;AAAE,aAAO,QAAQ,OAAO,WAAW;AAAA,IAAI;AAAA,IAClD,IAAI,OAAO;AAAE,aAAO,QAAQ,OAAO,QAAQ;AAAA,IAAI;AAAA,IAC/C,SAAS,CAAC;AAAA;AAAA,IACV,OAAO,CAAC,aAAoD;AAC1D,mBAAa,KAAK,QAAQ;AAC1B,aAAO;AAAA,QACL,SAAS,MAAM;AACb,gBAAM,MAAM,aAAa,QAAQ,QAAQ;AACzC,cAAI,QAAQ,GAAI,cAAa,OAAO,KAAK,CAAC;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AAAA,IACA,QAAQ,CAAC,aAAiD;AACxD,oBAAc,KAAK,QAAQ;AAC3B,aAAO;AAAA,QACL,SAAS,MAAM;AACb,gBAAM,MAAM,cAAc,QAAQ,QAAQ;AAC1C,cAAI,QAAQ,GAAI,eAAc,OAAO,KAAK,CAAC;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAAA,IACA,UAAU,CAAC,aAAyE;AAClF,sBAAgB,KAAK,QAAQ;AAC7B,aAAO;AAAA,QACL,SAAS,MAAM;AACb,gBAAM,MAAM,gBAAgB,QAAQ,QAAQ;AAC5C,cAAI,QAAQ,GAAI,iBAAgB,OAAO,KAAK,CAAC;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,UAAQ,GAAG,QAAQ,OAAO;AAC1B,UAAQ,GAAG,UAAU,MAAM;AAAE,YAAQ;AAAG,YAAQ,KAAK,CAAC;AAAA,EAAG,CAAC;AAC1D,UAAQ,GAAG,WAAW,MAAM;AAAE,YAAQ;AAAG,YAAQ,KAAK,CAAC;AAAA,EAAG,CAAC;AAE3D,SAAO;AACT;AAMA,SAAS,gBAAgB,UAAwB;AAE/C,iBAAe,iBAAiB,YAAY,MAAM,MAAM;AACtD,eAAW,MAAM,SAAS,QAAQ,GAAG,GAAG;AAAA,EAC1C,CAAC;AACD,iBAAe,iBAAiB,YAAY,QAAQ,MAAM;AAExD,UAAM,aAAa,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AACjE,eAAW,MAAM,WAAW,UAAU,UAAU,GAAG,GAAG;AAAA,EACxD,CAAC;AACD,iBAAe,iBAAiB,YAAY,YAAY,MAAM;AAC5D,eAAW,MAAM,SAAS,QAAQ,GAAG,GAAG;AAAA,EAC1C,CAAC;AACD,iBAAe,iBAAiB,YAAY,cAAc,CAAC,UAAuB;AAChF,UAAM,SAAS,MAAM,QAAQ;AAC7B,UAAM,OAAO,MAAM,KAAK,OAAK,EAAE,OAAO,MAAM;AAC5C,QAAI,MAAM;AACR,iBAAW,MAAM,WAAW,UAAU,IAAI,GAAG,GAAG;AAAA,IAClD;AAAA,EACF,EAAkB;AACpB;AAEA,SAAS,SAAS,UAAwB;AAGxC,gBAAc,UAAiB;AAAA,IAC7B,cAAc,CAAC,WAAmB;AAChC,YAAM,OAAO,MAAM,KAAK,OAAK,EAAE,OAAO,MAAM;AAC5C,UAAI,KAAM,YAAW,UAAU,IAAI;AAAA,IACrC;AAAA,IACA,QAAQ,MAAM;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACH;AAEA,SAAS,WAAW,UAAwB,MAAgB;AAE1D,OAAK,IAAI,QAAe;AAC1B;AAMA,SAAS,OAAO;AACd,QAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AAEjC,MAAI,QAAsB;AAC1B,QAAM,WAAW,KAAK,QAAQ,SAAS;AACvC,MAAI,aAAa,MAAM,KAAK,WAAW,CAAC,GAAG;AACzC,YAAQ,KAAK,WAAW,CAAC;AACzB,SAAK,OAAO,UAAU,CAAC;AAAA,EACzB;AACA,WAAS,KAAK;AAEd,QAAM,WAAW,mBAAmB;AACpC,kBAAgB,QAAQ;AAGxB,QAAM,WAAW,KAAK,CAAC;AACvB,MAAI,UAAU;AACZ,UAAM,OAAO,MAAM,KAAK,OAAK,EAAE,OAAO,YAAY,EAAE,KAAK,YAAY,MAAM,SAAS,YAAY,CAAC;AACjG,QAAI,CAAC,MAAM;AACT,cAAQ,MAAM,iBAAiB,QAAQ,EAAE;AACzC,cAAQ,MAAM,oBAAoB,MAAM,IAAI,OAAK,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AACnE,cAAQ,KAAK,CAAC;AACd;AAAA,IACF;AACA,eAAW,UAAU,IAAI;AACzB;AAAA,EACF;AAEA,WAAS,QAAQ;AACnB;AAEA,KAAK;","names":["isLightTheme","i","spawnParticles","slide","output","hint","spawnParticles","spawnParticles","hint","popup","titleX","spawnParticles","spawnParticles","spawnSplash","lane","hint","spawnParticles","hint","spawnParticles","hint","hintX","spawnParticles","hint","centerX","spawnParticles","speed","hint","centerX","roadWidth","roadLeft","spawnParticles","hint","spawnParticles","updateParticles","hint","spawnParticles","hint","spawnParticles","hint","spawnParticles","hint","spawnParticles","hint","hintX","WORDS","spawnParticles","spawnFirework","centerX","isLightTheme","launchGame"]}
1
+ {"version":3,"sources":["../src/themes/index.ts","../src/games/utils.ts","../src/games/gameTransitions.ts","../src/games/shared/menu.ts","../src/games/2048/slideLogic.ts","../src/games/2048/index.ts","../src/games/asteroids/index.ts","../src/games/breakout/index.ts","../src/games/chopper/levels.ts","../src/games/chopper/effects.ts","../src/games/chopper/index.ts","../src/games/crack/index.ts","../src/games/frogger/index.ts","../src/games/hangman/index.ts","../src/games/minesweeper/index.ts","../src/games/pong/index.ts","../src/games/runner/index.ts","../src/games/simon/index.ts","../src/games/snake/index.ts","../src/games/spaceinvaders/index.ts","../src/games/tetris/index.ts","../src/games/tower/index.ts","../src/games/tron/index.ts","../src/games/typingtest/index.ts","../src/games/wordle/index.ts","../src/games/gamesMenu.ts","../src/games/index.ts","../src/cli.ts"],"sourcesContent":["/**\n * Terminal color themes\n *\n * Provides both CSS colors (for UI) and ANSI escape codes (for terminal).\n */\n\n/**\n * Available theme identifiers\n */\nexport type PhosphorMode =\n | 'cyan'\n | 'cyanLight'\n | 'amber'\n | 'green'\n | 'white'\n | 'hotpink'\n | 'hotpinkLight'\n | 'blood'\n | 'ice'\n | 'iceLight'\n | 'bladerunner'\n | 'bladerunnerLight'\n | 'tron'\n | 'tronLight'\n | 'daylight'\n | 'kawaii'\n | 'kawaiiLight'\n | 'oled'\n | 'solarized'\n | 'solarizedLight'\n | 'nord'\n | 'nordLight'\n | 'highcontrast'\n | 'highcontrastLight'\n | 'banana'\n | 'cream';\n\n/**\n * Theme color definition for CSS/UI usage\n */\nexport interface ThemeColors {\n /** Display name */\n name: string;\n /** Emoji icon for quick switcher / UI */\n icon: string;\n /** Primary text/accent color (hex) */\n primary: string;\n /** Secondary accent color (hex) */\n secondary: string;\n /** Subtle glow effect (rgba) */\n glow: string;\n /** Intense glow effect (rgba) */\n glowIntense: string;\n /** Background color (hex) */\n bg: string;\n /** Status bar background - slightly elevated from bg */\n statusBarBg: string;\n /** Terminal foreground color - defaults to primary if not set */\n foreground?: string;\n}\n\n/**\n * All theme definitions with CSS colors\n */\nexport const themes: Record<PhosphorMode, ThemeColors> = {\n cyan: {\n name: 'Cyberpunk',\n icon: '🔵',\n primary: '#00D9FF',\n secondary: '#FF006E',\n glow: 'rgba(0, 217, 255, 0.5)',\n glowIntense: 'rgba(0, 217, 255, 0.8)',\n bg: '#0A1628',\n statusBarBg: '#0D1E38',\n },\n cyanLight: {\n name: 'Cyberpunk Light',\n icon: '💠',\n primary: '#0099CC',\n secondary: '#CC0066',\n glow: 'rgba(0, 153, 204, 0.15)',\n glowIntense: 'rgba(0, 153, 204, 0.3)',\n bg: '#F8FAFF',\n statusBarBg: '#EEF2FA',\n foreground: '#2d3640', // Dark text for terminal readability\n },\n amber: {\n name: 'Fallout',\n icon: '🟠',\n primary: '#FFB000',\n secondary: '#FF6600',\n glow: 'rgba(255, 176, 0, 0.5)',\n glowIntense: 'rgba(255, 176, 0, 0.8)',\n bg: '#1C1408',\n statusBarBg: '#2A1E0C',\n },\n green: {\n name: 'Matrix',\n icon: '🟢',\n primary: '#39FF14',\n secondary: '#00FF00',\n glow: 'rgba(57, 255, 20, 0.5)',\n glowIntense: 'rgba(57, 255, 20, 0.8)',\n bg: '#001A00',\n statusBarBg: '#002800',\n },\n white: {\n name: 'Ghost',\n icon: '⚪',\n primary: '#FFFFFF',\n secondary: '#88CCFF',\n glow: 'rgba(255, 255, 255, 0.3)',\n glowIntense: 'rgba(255, 255, 255, 0.5)',\n bg: '#0C0C0C',\n statusBarBg: '#1A1A1A',\n },\n hotpink: {\n name: 'Synthwave',\n icon: '🩷',\n primary: '#FF6AC1',\n secondary: '#00D9FF',\n glow: 'rgba(255, 106, 193, 0.5)',\n glowIntense: 'rgba(255, 106, 193, 0.8)',\n bg: '#0F0818',\n statusBarBg: '#1A0F28',\n },\n hotpinkLight: {\n name: 'Synthwave Light',\n icon: '🌷',\n primary: '#D84A9C',\n secondary: '#0099BB',\n glow: 'rgba(216, 74, 156, 0.15)',\n glowIntense: 'rgba(216, 74, 156, 0.3)',\n bg: '#FFF8FC',\n statusBarBg: '#F5EEF2',\n foreground: '#2d3640', // Dark text for terminal readability\n },\n blood: {\n name: 'Blood',\n icon: '🔴',\n primary: '#FF3333',\n secondary: '#AA0000',\n glow: 'rgba(255, 51, 51, 0.5)',\n glowIntense: 'rgba(255, 51, 51, 0.8)',\n bg: '#1A0505',\n statusBarBg: '#280808',\n },\n ice: {\n name: 'Ice',\n icon: '🩵',\n primary: '#88FFFF',\n secondary: '#4488FF',\n glow: 'rgba(136, 255, 255, 0.4)',\n glowIntense: 'rgba(136, 255, 255, 0.7)',\n bg: '#051520',\n statusBarBg: '#082030',\n },\n iceLight: {\n name: 'Ice Light',\n icon: '🧊',\n primary: '#0077AA',\n secondary: '#2255CC',\n glow: 'rgba(0, 119, 170, 0.12)',\n glowIntense: 'rgba(0, 119, 170, 0.25)',\n bg: '#F0FAFF',\n statusBarBg: '#E5F0F8',\n foreground: '#2d3640', // Dark text for terminal readability\n },\n bladerunner: {\n name: 'Blade Runner',\n icon: '🟧',\n primary: '#FF6B35',\n secondary: '#00CED1',\n glow: 'rgba(255, 107, 53, 0.6)',\n glowIntense: 'rgba(255, 107, 53, 0.9)',\n bg: '#1F0E08',\n statusBarBg: '#2D150C',\n },\n bladerunnerLight: {\n name: 'Blade Runner Light',\n icon: '🌅',\n primary: '#CC4400',\n secondary: '#008B8B',\n glow: 'rgba(204, 68, 0, 0.15)',\n glowIntense: 'rgba(204, 68, 0, 0.3)',\n bg: '#FFFAF5',\n statusBarBg: '#F5EFEA',\n foreground: '#2d3640', // Dark text for terminal readability\n },\n tron: {\n name: 'Tron',\n icon: '🔷',\n primary: '#6FFFE9',\n secondary: '#FF6B00',\n glow: 'rgba(111, 255, 233, 0.5)',\n glowIntense: 'rgba(111, 255, 233, 0.8)',\n bg: '#020815',\n statusBarBg: '#051020',\n },\n tronLight: {\n name: 'Tron Light',\n icon: '💎',\n primary: '#008080',\n secondary: '#CC5500',\n glow: 'rgba(0, 128, 128, 0.15)',\n glowIntense: 'rgba(0, 128, 128, 0.3)',\n bg: '#F5FFFF',\n statusBarBg: '#EAF5F5',\n foreground: '#2d3640', // Dark text for terminal readability\n },\n daylight: {\n name: 'Daylight',\n icon: '☀️',\n primary: '#1a1a1a',\n secondary: '#0066CC',\n glow: 'rgba(0, 102, 204, 0.1)',\n glowIntense: 'rgba(0, 102, 204, 0.2)',\n bg: '#FAFAF8',\n statusBarBg: '#EEEEEC',\n foreground: '#1a1a1a', // Matches primary for consistent dark text\n },\n kawaii: {\n name: 'Kawaii',\n icon: '🌸',\n primary: '#FF69B4',\n secondary: '#87CEEB',\n glow: 'rgba(255, 105, 180, 0.6)',\n glowIntense: 'rgba(255, 105, 180, 0.9)',\n bg: '#1E0818',\n statusBarBg: '#2D0F25',\n },\n kawaiiLight: {\n name: 'Kawaii Light',\n icon: '🎀',\n primary: '#D4458B',\n secondary: '#7B68EE',\n glow: 'rgba(255, 105, 180, 0.2)',\n glowIntense: 'rgba(255, 105, 180, 0.4)',\n bg: '#FFF5F8',\n statusBarBg: '#F5EAEE',\n foreground: '#2d3640', // Dark text for terminal readability\n },\n oled: {\n name: 'OLED Black',\n icon: '⚫',\n primary: '#FFFFFF',\n secondary: '#00D9FF',\n glow: 'rgba(255, 255, 255, 0.3)',\n glowIntense: 'rgba(255, 255, 255, 0.5)',\n bg: '#000000',\n statusBarBg: '#0A0A0A',\n },\n solarized: {\n name: 'Solarized',\n icon: '🌊',\n primary: '#2AA198',\n secondary: '#859900',\n glow: 'rgba(42, 161, 152, 0.4)',\n glowIntense: 'rgba(42, 161, 152, 0.6)',\n bg: '#002B36',\n statusBarBg: '#073642',\n foreground: '#D4D4D4', // Light gray for better readability\n },\n solarizedLight: {\n name: 'Solarized Light',\n icon: '🏖️',\n primary: '#657B83',\n secondary: '#268BD2',\n glow: 'rgba(38, 139, 210, 0.15)',\n glowIntense: 'rgba(38, 139, 210, 0.25)',\n bg: '#FDF6E3',\n statusBarBg: '#EEE8D5',\n foreground: '#586e75', // Solarized base01 for terminal text\n },\n nord: {\n name: 'Nord',\n icon: '❄️',\n primary: '#88C0D0',\n secondary: '#81A1C1',\n glow: 'rgba(136, 192, 208, 0.3)',\n glowIntense: 'rgba(136, 192, 208, 0.5)',\n bg: '#2E3440',\n statusBarBg: '#3B4252',\n },\n nordLight: {\n name: 'Nord Light',\n icon: '🏔️',\n primary: '#2E3440',\n secondary: '#5E81AC',\n glow: 'rgba(94, 129, 172, 0.15)',\n glowIntense: 'rgba(94, 129, 172, 0.25)',\n bg: '#ECEFF4',\n statusBarBg: '#E5E9F0',\n foreground: '#2E3440', // Nord polar night for terminal text\n },\n highcontrast: {\n name: 'High Contrast',\n icon: '◐',\n primary: '#FFFFFF',\n secondary: '#FFFF00',\n glow: 'rgba(255, 255, 255, 0.1)',\n glowIntense: 'rgba(255, 255, 255, 0.2)',\n bg: '#000000',\n statusBarBg: '#111111',\n },\n highcontrastLight: {\n name: 'High Contrast Light',\n icon: '◑',\n primary: '#000000',\n secondary: '#0000CC',\n glow: 'rgba(0, 0, 0, 0.05)',\n glowIntense: 'rgba(0, 0, 0, 0.1)',\n bg: '#FFFFFF',\n statusBarBg: '#EEEEEE',\n foreground: '#000000', // Maximum contrast for terminal text\n },\n banana: {\n name: 'Banana',\n icon: '🍌',\n primary: '#FFE135',\n secondary: '#8B7500',\n glow: 'rgba(255, 225, 53, 0.5)',\n glowIntense: 'rgba(255, 225, 53, 0.8)',\n bg: '#1A1800',\n statusBarBg: '#282400',\n },\n cream: {\n name: 'Cream',\n icon: '🍦',\n primary: '#4A3C2A',\n secondary: '#C17844',\n glow: 'rgba(193, 120, 68, 0.12)',\n glowIntense: 'rgba(193, 120, 68, 0.22)',\n bg: '#EDE5D4',\n statusBarBg: '#E3DBCA',\n foreground: '#4A3C2A',\n },\n};\n\n/**\n * ANSI escape codes for terminal text coloring\n */\nconst ansiCodes: Record<PhosphorMode, string> = {\n cyan: '\\x1b[96m',\n cyanLight: '\\x1b[38;5;31m',\n amber: '\\x1b[93m',\n green: '\\x1b[92m',\n white: '\\x1b[97m',\n hotpink: '\\x1b[95m',\n hotpinkLight: '\\x1b[38;5;169m',\n blood: '\\x1b[91m',\n ice: '\\x1b[96m',\n iceLight: '\\x1b[38;5;31m',\n bladerunner: '\\x1b[38;5;208m',\n bladerunnerLight: '\\x1b[38;5;166m',\n tron: '\\x1b[96m',\n tronLight: '\\x1b[38;5;30m',\n daylight: '\\x1b[34m',\n kawaii: '\\x1b[95m',\n kawaiiLight: '\\x1b[35m',\n oled: '\\x1b[97m',\n solarized: '\\x1b[36m',\n solarizedLight: '\\x1b[38;5;66m',\n nord: '\\x1b[96m',\n nordLight: '\\x1b[38;5;59m',\n highcontrast: '\\x1b[97m',\n highcontrastLight: '\\x1b[30m',\n banana: '\\x1b[93m',\n cream: '\\x1b[38;5;130m',\n};\n\n/**\n * Light themes that need dark text\n */\nconst lightThemes: Set<PhosphorMode> = new Set([\n 'cyanLight',\n 'hotpinkLight',\n 'iceLight',\n 'bladerunnerLight',\n 'tronLight',\n 'daylight',\n 'kawaiiLight',\n 'solarizedLight',\n 'nordLight',\n 'highcontrastLight',\n 'cream',\n]);\n\n/**\n * Subtle background colors for game elements\n */\nconst subtleColors: Partial<Record<PhosphorMode, string>> = {\n cyanLight: '\\x1b[38;5;153m',\n hotpinkLight: '\\x1b[38;5;225m',\n iceLight: '\\x1b[38;5;195m',\n bladerunnerLight: '\\x1b[38;5;223m',\n tronLight: '\\x1b[38;5;159m',\n daylight: '\\x1b[38;5;252m',\n kawaiiLight: '\\x1b[38;5;218m',\n solarizedLight: '\\x1b[38;5;187m',\n nordLight: '\\x1b[38;5;255m',\n highcontrastLight: '\\x1b[38;5;250m',\n cream: '\\x1b[38;5;223m',\n oled: '\\x1b[38;5;234m',\n highcontrast: '\\x1b[38;5;238m',\n};\n\n// ============================================================================\n// API Functions\n// ============================================================================\n\n/**\n * Get theme colors by mode\n */\nexport function getTheme(mode: PhosphorMode): ThemeColors {\n return themes[mode];\n}\n\n/**\n * Get ANSI escape code for a theme\n */\nexport function getAnsiColor(mode: PhosphorMode): string {\n return ansiCodes[mode] || '\\x1b[92m';\n}\n\n/**\n * Check if a theme is light (needs dark text)\n */\nexport function isLightTheme(mode: PhosphorMode): boolean {\n return lightThemes.has(mode);\n}\n\n/**\n * Get subtle background color for game elements\n */\nexport function getSubtleColor(mode: PhosphorMode): string {\n return subtleColors[mode] || '\\x1b[38;5;236m';\n}\n\n/**\n * Get all available theme modes\n */\nexport function getThemeModes(): PhosphorMode[] {\n return Object.keys(themes) as PhosphorMode[];\n}\n\nconst VALID_THEME_MODES = new Set<string>(Object.keys(themes));\n\n/**\n * Check if a string is a valid theme mode\n */\nexport function isValidThemeMode(value: string): value is PhosphorMode {\n return VALID_THEME_MODES.has(value);\n}\n\n/**\n * ANSI reset code\n */\nexport const ANSI_RESET = '\\x1b[0m';\n\n// ============================================================================\n// xterm.js Terminal Theme\n// ============================================================================\n\n/**\n * xterm.js ITheme-compatible color set.\n * Includes the 16 ANSI colors, selection, cursor, scrollbar, and foreground/background.\n */\nexport interface ITerminalTheme {\n background: string;\n foreground: string;\n cursor: string;\n cursorAccent: string;\n selectionBackground: string;\n selectionForeground: string;\n black: string;\n red: string;\n green: string;\n yellow: string;\n blue: string;\n magenta: string;\n cyan: string;\n white: string;\n brightBlack: string;\n brightRed: string;\n brightGreen: string;\n brightYellow: string;\n brightBlue: string;\n brightMagenta: string;\n brightCyan: string;\n brightWhite: string;\n scrollbarSliderBackground: string;\n scrollbarSliderHoverBackground: string;\n scrollbarSliderActiveBackground: string;\n}\n\n/**\n * Generate a full xterm.js theme from a PhosphorMode.\n *\n * Maps theme colors to the 16 ANSI colors, selection, cursor, and scrollbar.\n * Light themes get inverted black/white and muted ANSI colors for readability.\n */\nexport function getTerminalTheme(mode: PhosphorMode): ITerminalTheme {\n const theme = themes[mode];\n const isLight = lightThemes.has(mode);\n\n const selectionBg = isLight ? '#3399FF' : theme.primary;\n const selectionFg = isLight ? '#000000' : '#000000';\n\n // For light themes, invert black/white so apps that hard-code dark backgrounds\n // (e.g. Codex using \\033[40m) remain readable on light terminal backgrounds.\n let black, white, brightBlack, brightWhite;\n\n if (isLight) {\n black = theme.bg;\n white = '#1a1a1a';\n brightBlack = '#e0e0e0';\n brightWhite = '#2a2a2a';\n } else {\n black = theme.bg;\n white = '#FFFFFF';\n brightBlack = '#636B7C';\n brightWhite = '#FFFFFF';\n }\n\n const cursorAccent = isLight\n ? (theme.foreground ?? '#1a1a1a')\n : theme.bg;\n\n return {\n background: \"rgba(0, 0, 0, 0)\",\n foreground: theme.foreground ?? theme.primary,\n cursor: theme.secondary,\n cursorAccent,\n selectionBackground: selectionBg,\n selectionForeground: selectionFg,\n black,\n red: isLight ? \"#c41a16\" : \"#FF0040\",\n green: isLight ? \"#007400\" : \"#39FF14\",\n yellow: isLight ? \"#826b00\" : \"#E5C400\",\n blue: isLight ? \"#0451a5\" : \"#7AA2F7\",\n magenta: isLight ? \"#a626a4\" : theme.secondary,\n cyan: isLight ? \"#0598bc\" : theme.primary,\n white,\n brightBlack,\n brightRed: isLight ? \"#e45649\" : \"#FF006E\",\n brightGreen: isLight ? \"#50a14f\" : \"#39FF14\",\n brightYellow: isLight ? \"#c18401\" : \"#FFD400\",\n brightBlue: isLight ? \"#4078f2\" : \"#89B4FA\",\n brightMagenta: isLight ? \"#c678dd\" : theme.secondary,\n brightCyan: isLight ? \"#0184bc\" : theme.primary,\n brightWhite,\n scrollbarSliderBackground: isLight ? 'rgba(0, 0, 0, 0.12)' : 'rgba(255, 255, 255, 0.1)',\n scrollbarSliderHoverBackground: isLight ? 'rgba(0, 0, 0, 0.2)' : 'rgba(255, 255, 255, 0.18)',\n scrollbarSliderActiveBackground: isLight ? 'rgba(0, 0, 0, 0.28)' : 'rgba(255, 255, 255, 0.25)',\n };\n}\n\n// ============================================================================\n// Light Theme Escape Sequence Transformer\n// ============================================================================\n\nfunction srgbToLinear(channel: number): number {\n const normalized = channel / 255;\n return normalized <= 0.04045\n ? normalized / 12.92\n : Math.pow((normalized + 0.055) / 1.055, 2.4);\n}\n\nfunction relativeLuminance(r: number, g: number, b: number): number {\n return 0.2126 * srgbToLinear(r) + 0.7152 * srgbToLinear(g) + 0.0722 * srgbToLinear(b);\n}\n\nfunction contrastRatio(\n fgR: number,\n fgG: number,\n fgB: number,\n bgR: number,\n bgG: number,\n bgB: number\n): number {\n const fgLum = relativeLuminance(fgR, fgG, fgB);\n const bgLum = relativeLuminance(bgR, bgG, bgB);\n const lighter = Math.max(fgLum, bgLum);\n const darker = Math.min(fgLum, bgLum);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\nfunction ensureReadableForegroundOnLightTheme(\n red: number,\n green: number,\n blue: number,\n bgR: number,\n bgG: number,\n bgB: number,\n minContrast = 4.2\n): [number, number, number] {\n if (contrastRatio(red, green, blue, bgR, bgG, bgB) >= minContrast) {\n return [red, green, blue];\n }\n\n for (let step = 1; step <= 20; step += 1) {\n const factor = 1 - step / 20;\n const nextR = Math.round(red * factor);\n const nextG = Math.round(green * factor);\n const nextB = Math.round(blue * factor);\n if (contrastRatio(nextR, nextG, nextB, bgR, bgG, bgB) >= minContrast) {\n return [nextR, nextG, nextB];\n }\n }\n\n return [30, 30, 30];\n}\n\nfunction ansi256ToRgb(colorIndex: number): [number, number, number] | null {\n if (colorIndex < 0 || colorIndex > 255) return null;\n\n // Standard + bright ANSI palette.\n const basePalette: Array<[number, number, number]> = [\n [0, 0, 0],\n [205, 49, 49],\n [13, 188, 121],\n [229, 229, 16],\n [36, 114, 200],\n [188, 63, 188],\n [17, 168, 205],\n [229, 229, 229],\n [102, 102, 102],\n [241, 76, 76],\n [35, 209, 139],\n [245, 245, 67],\n [59, 142, 234],\n [214, 112, 214],\n [41, 184, 219],\n [255, 255, 255],\n ];\n\n if (colorIndex <= 15) return basePalette[colorIndex];\n\n if (colorIndex >= 16 && colorIndex <= 231) {\n const idx = colorIndex - 16;\n const red = Math.floor(idx / 36);\n const green = Math.floor((idx % 36) / 6);\n const blue = idx % 6;\n const level = [0, 95, 135, 175, 215, 255];\n return [level[red], level[green], level[blue]];\n }\n\n const gray = 8 + (colorIndex - 232) * 10;\n return [gray, gray, gray];\n}\n\n/**\n * Transform ANSI escape sequences for light themes.\n *\n * Apps like Codex use true color (24-bit) escape sequences that bypass our\n * theme's ANSI color settings. This intercepts dark backgrounds/foregrounds\n * and inverts them so TUI apps remain readable on light backgrounds.\n *\n * @param data - Raw terminal data with ANSI escape sequences\n * @param themeBg - The theme's background color hex (e.g., \"#F5E6D3\")\n * @returns Transformed data with inverted colors for light themes\n */\nexport function transformEscapeSequencesForLightTheme(data: string, themeBg: string): string {\n const bgR = parseInt(themeBg.slice(1, 3), 16);\n const bgG = parseInt(themeBg.slice(3, 5), 16);\n const bgB = parseInt(themeBg.slice(5, 7), 16);\n // Keep a small but visible contrast band so TUI input/panel regions\n // remain distinguishable on light themes.\n const highlightDelta = 22;\n const highlightR = Math.max(bgR - highlightDelta, 0);\n const highlightG = Math.max(bgG - highlightDelta, 0);\n const highlightB = Math.max(bgB - highlightDelta, 0);\n\n const transformSgr = (sequence: string) => {\n const body = sequence.slice(2, -1);\n if (body.length === 0) return sequence;\n\n const normalized = body.replace(/:/g, ';');\n const rawParams = normalized.split(';');\n const params: number[] = [];\n\n for (const raw of rawParams) {\n if (raw === '') {\n params.push(0);\n continue;\n }\n const value = Number(raw);\n if (!Number.isFinite(value)) {\n return sequence;\n }\n params.push(value);\n }\n\n let changed = false;\n const out: number[] = [];\n\n for (let i = 0; i < params.length; i += 1) {\n const code = params[i];\n\n // 24-bit background color (48;2;R;G;B)\n if (code === 48 && params[i + 1] === 2 && i + 4 < params.length) {\n const hasColorSpace = i + 5 < params.length\n && params[i + 2] === 0\n && params[i + 3] <= 255\n && params[i + 4] <= 255\n && params[i + 5] <= 255;\n const offset = hasColorSpace ? 3 : 2;\n const red = params[i + offset];\n const green = params[i + offset + 1];\n const blue = params[i + offset + 2];\n const sum = red + green + blue;\n\n if (sum < 600) {\n // Dark and mid-range backgrounds -> theme bg (invisible)\n out.push(48, 2, bgR, bgG, bgB);\n changed = true;\n } else {\n // Preserve bright panel/input backgrounds as subtle contrast.\n out.push(48, 2, highlightR, highlightG, highlightB);\n changed = true;\n }\n i += hasColorSpace ? 5 : 4;\n continue;\n }\n\n // 8-bit background color (48;5;N)\n if (code === 48 && params[i + 1] === 5 && i + 2 < params.length) {\n const colorIndex = params[i + 2];\n if (colorIndex === 7 || colorIndex === 8 || colorIndex === 15 || (colorIndex >= 247 && colorIndex <= 255)) {\n // White/bright backgrounds often represent panel surfaces in TUIs.\n // Keep them as a subtle highlight instead of fully flattening.\n out.push(48, 2, highlightR, highlightG, highlightB);\n changed = true;\n } else if (colorIndex === 0 || colorIndex === 16 || (colorIndex >= 232 && colorIndex <= 246)) {\n // Map black and dark-to-mid grays (232-246) to theme bg.\n out.push(48, 2, bgR, bgG, bgB);\n changed = true;\n } else {\n out.push(48, 5, colorIndex);\n }\n i += 2;\n continue;\n }\n\n // 24-bit foreground color (38;2;R;G;B)\n if (code === 38 && params[i + 1] === 2 && i + 4 < params.length) {\n const hasColorSpace = i + 5 < params.length\n && params[i + 2] === 0\n && params[i + 3] <= 255\n && params[i + 4] <= 255\n && params[i + 5] <= 255;\n const offset = hasColorSpace ? 3 : 2;\n const red = params[i + offset];\n const green = params[i + offset + 1];\n const blue = params[i + offset + 2];\n const [nextR, nextG, nextB] = ensureReadableForegroundOnLightTheme(red, green, blue, bgR, bgG, bgB);\n if (nextR !== red || nextG !== green || nextB !== blue) {\n out.push(38, 2, nextR, nextG, nextB);\n changed = true;\n } else {\n out.push(38, 2, red, green, blue);\n }\n i += hasColorSpace ? 5 : 4;\n continue;\n }\n\n // 8-bit foreground color (38;5;N)\n if (code === 38 && params[i + 1] === 5 && i + 2 < params.length) {\n const colorIndex = params[i + 2];\n const rgb = ansi256ToRgb(colorIndex);\n if (!rgb) {\n out.push(38, 5, colorIndex);\n i += 2;\n continue;\n }\n const [red, green, blue] = rgb;\n const [nextR, nextG, nextB] = ensureReadableForegroundOnLightTheme(red, green, blue, bgR, bgG, bgB);\n if (nextR !== red || nextG !== green || nextB !== blue) {\n out.push(38, 2, nextR, nextG, nextB);\n changed = true;\n } else {\n out.push(38, 5, colorIndex);\n }\n i += 2;\n continue;\n }\n\n // Faint text often becomes unreadable on light backgrounds.\n if (code === 2) {\n changed = true;\n continue;\n }\n\n // Standard ANSI background black (40)\n if (code === 40) {\n out.push(48, 2, bgR, bgG, bgB);\n changed = true;\n continue;\n }\n\n // ANSI white/bright white background (47, 107)\n if (code === 47 || code === 107) {\n out.push(48, 2, highlightR, highlightG, highlightB);\n changed = true;\n continue;\n }\n\n // Bright black background (100)\n if (code === 100) {\n out.push(48, 2, highlightR, highlightG, highlightB);\n changed = true;\n continue;\n }\n\n // ANSI black foreground (30)\n if (code === 30) {\n out.push(38, 2, 60, 60, 60);\n changed = true;\n continue;\n }\n\n // Bright black foreground (90)\n if (code === 90) {\n out.push(38, 2, 100, 100, 100);\n changed = true;\n continue;\n }\n\n // ANSI white foreground (37)\n if (code === 37) {\n out.push(38, 2, 40, 40, 40);\n changed = true;\n continue;\n }\n\n // Bright white foreground (97)\n if (code === 97) {\n out.push(38, 2, 30, 30, 30);\n changed = true;\n continue;\n }\n\n // Reverse video (7) can create harsh dark pills on light themes when\n // apps rely on default background swapping. Force a subtle theme-aware bg.\n if (code === 7) {\n out.push(48, 2, highlightR, highlightG, highlightB);\n changed = true;\n continue;\n }\n\n // Inverse-off (27) should clear the background we introduced for code 7.\n if (code === 27) {\n out.push(49);\n changed = true;\n continue;\n }\n\n out.push(code);\n }\n\n if (!changed) return sequence;\n return `\\x1b[${out.join(';')}m`;\n };\n\n return data.replace(/\\x1b\\[[0-9:;]*m/g, transformSgr);\n}\n\n/**\n * Transform ANSI escape sequences for dark themes with non-black backgrounds.\n *\n * Apps like Claude Code use true-color (24-bit) escape sequences for dark\n * backgrounds (e.g. \\033[48;2;0;0;0m) which bypass the ANSI color mapping.\n * On dark themes where the bg isn't pure black, these show as jarring strips.\n * This remaps near-black and near-white backgrounds to the theme bg.\n */\nexport function transformEscapeSequencesForDarkTheme(data: string, themeBg: string): string {\n const bgR = parseInt(themeBg.slice(1, 3), 16);\n const bgG = parseInt(themeBg.slice(3, 5), 16);\n const bgB = parseInt(themeBg.slice(5, 7), 16);\n\n const transformSgr = (sequence: string) => {\n const body = sequence.slice(2, -1);\n if (body.length === 0) return sequence;\n\n const normalized = body.replace(/:/g, ';');\n const rawParams = normalized.split(';');\n const params: number[] = [];\n\n for (const raw of rawParams) {\n if (raw === '') { params.push(0); continue; }\n const value = Number(raw);\n if (!Number.isFinite(value)) return sequence;\n params.push(value);\n }\n\n let changed = false;\n const out: number[] = [];\n\n for (let i = 0; i < params.length; i += 1) {\n const code = params[i];\n\n // 24-bit background color (48;2;R;G;B) — remap near-black/near-white\n if (code === 48 && params[i + 1] === 2 && i + 4 < params.length) {\n const hasColorSpace = i + 5 < params.length\n && params[i + 2] === 0\n && params[i + 3] <= 255\n && params[i + 4] <= 255\n && params[i + 5] <= 255;\n const offset = hasColorSpace ? 3 : 2;\n const red = params[i + offset];\n const green = params[i + offset + 1];\n const blue = params[i + offset + 2];\n const sum = red + green + blue;\n\n // Near-black and near-white backgrounds are usually hard-coded TUI\n // panel fills that clash with themed dark terminals.\n if (sum < 40 || sum > 700) {\n out.push(48, 2, bgR, bgG, bgB);\n changed = true;\n } else {\n out.push(48, 2, red, green, blue);\n }\n i += hasColorSpace ? 5 : 4;\n continue;\n }\n\n // 8-bit background color (48;5;N) — remap black/near-black and white\n if (code === 48 && params[i + 1] === 5 && i + 2 < params.length) {\n const colorIndex = params[i + 2];\n if (\n colorIndex === 0\n || colorIndex === 7\n || colorIndex === 8\n || colorIndex === 15\n || colorIndex === 16\n || colorIndex === 231\n || (colorIndex >= 232 && colorIndex <= 234)\n || (colorIndex >= 250 && colorIndex <= 255)\n ) {\n out.push(48, 2, bgR, bgG, bgB);\n changed = true;\n } else {\n out.push(48, 5, colorIndex);\n }\n i += 2;\n continue;\n }\n\n // Standard ANSI white/bright white background\n if (code === 47 || code === 107) {\n out.push(48, 2, bgR, bgG, bgB);\n changed = true;\n continue;\n }\n\n out.push(code);\n }\n\n if (!changed) return sequence;\n return `\\x1b[${out.join(';')}m`;\n };\n\n return data.replace(/\\x1b\\[[0-9:;]*m/g, transformSgr);\n}\n","/**\n * Shared utilities for games\n *\n * This module provides theme-aware utilities for games.\n * The theme must be configured by the consuming application via setTheme().\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport {\n type PhosphorMode,\n getAnsiColor,\n isLightTheme as checkLightTheme,\n getSubtleColor,\n} from '../themes';\n\n// ============================================================================\n// Theme Configuration\n// ============================================================================\n\n/**\n * Current theme mode - configured by the consuming application\n */\nlet currentTheme: PhosphorMode = 'cyan';\n\n/**\n * Set the current theme mode\n * Call this from your app when the theme changes\n */\nexport function setTheme(mode: PhosphorMode): void {\n currentTheme = mode;\n}\n\n/**\n * Get the current theme mode\n */\nexport function getTheme(): PhosphorMode {\n return currentTheme;\n}\n\n// ============================================================================\n// Alternate Buffer Management\n// ============================================================================\n\n/**\n * Track which terminals are currently in alternate buffer.\n * This prevents double-entry/exit issues and provides debugging info.\n */\nconst alternateBufferState = new WeakMap<Terminal, { reason: string; enteredAt: number }>();\n\n/**\n * Check if a terminal is valid and can accept writes\n */\nexport function isTerminalValid(terminal: Terminal | null | undefined): terminal is Terminal {\n if (!terminal) return false;\n // Check if terminal has been disposed (element becomes null)\n try {\n return terminal.element !== null;\n } catch {\n return false;\n }\n}\n\n/**\n * Enter alternate screen buffer with state tracking.\n * Safe to call multiple times - will log warning but not double-enter.\n *\n * @param terminal - The xterm terminal instance\n * @param reason - Description of why we're entering (for debugging)\n * @returns true if buffer was entered, false if already in buffer or terminal invalid\n */\nexport function enterAlternateBuffer(terminal: Terminal, reason: string): boolean {\n if (!isTerminalValid(terminal)) {\n console.warn(`[AlternateBuffer] Cannot enter: terminal invalid (reason: ${reason})`);\n return false;\n }\n\n if (alternateBufferState.has(terminal)) {\n const existing = alternateBufferState.get(terminal)!;\n console.warn(`[AlternateBuffer] Already in buffer (entered by: ${existing.reason}), requested by: ${reason}`);\n return false;\n }\n\n terminal.write('\\x1b[?1049h'); // Enter alternate screen buffer\n terminal.write('\\x1b[?25l'); // Hide cursor\n terminal.write('\\x1b[2J\\x1b[H'); // Clear screen\n\n alternateBufferState.set(terminal, { reason, enteredAt: Date.now() });\n return true;\n}\n\n/**\n * Exit alternate screen buffer with state tracking.\n * Safe to call multiple times - will log warning but not double-exit.\n *\n * @param terminal - The xterm terminal instance\n * @param reason - Description of why we're exiting (for debugging)\n * @returns true if buffer was exited, false if not in buffer or terminal invalid\n */\nexport function exitAlternateBuffer(terminal: Terminal, reason: string): boolean {\n if (!isTerminalValid(terminal)) {\n console.warn(`[AlternateBuffer] Cannot exit: terminal invalid (reason: ${reason})`);\n return false;\n }\n\n if (!alternateBufferState.has(terminal)) {\n console.warn(`[AlternateBuffer] Not in alternate buffer, exit requested by: ${reason}`);\n return false;\n }\n\n terminal.write('\\x1b[?1049l'); // Exit alternate screen buffer\n terminal.write('\\x1b[?25h'); // Show cursor\n\n alternateBufferState.delete(terminal);\n return true;\n}\n\n/**\n * Check if terminal is currently in alternate buffer\n */\nexport function isInAlternateBuffer(terminal: Terminal): boolean {\n return alternateBufferState.has(terminal);\n}\n\n/**\n * Force exit alternate buffer without state check (for error recovery)\n * Use sparingly - prefer exitAlternateBuffer for normal operations\n */\nexport function forceExitAlternateBuffer(terminal: Terminal, reason: string): void {\n if (!isTerminalValid(terminal)) {\n console.warn(`[AlternateBuffer] Cannot force exit: terminal invalid (reason: ${reason})`);\n return;\n }\n\n terminal.write('\\x1b[?1049l');\n terminal.write('\\x1b[?25h');\n alternateBufferState.delete(terminal);\n console.warn(`[AlternateBuffer] Force exited (reason: ${reason})`);\n}\n\n// ============================================================================\n// Theme Color Utilities\n// ============================================================================\n\n/**\n * Get theme-appropriate ANSI color escape code\n */\nexport function getThemeColorCode(mode: PhosphorMode): string {\n return getAnsiColor(mode);\n}\n\n/**\n * Get current theme color code\n */\nexport function getCurrentThemeColor(): string {\n return getAnsiColor(currentTheme);\n}\n\n/**\n * Check if current theme is a light theme (needs dark text)\n */\nexport function isLightTheme(): boolean {\n return checkLightTheme(currentTheme);\n}\n\n/**\n * Get a subtle/muted color that blends with the terminal background\n * Useful for background elements like doors, walls, etc.\n */\nexport function getSubtleBackgroundColor(): string {\n return getSubtleColor(currentTheme);\n}\n\n// ============================================================================\n// Layout Utilities\n// ============================================================================\n\ninterface VerticalAnchorOptions {\n headerRows?: number;\n footerRows?: number;\n minTop?: number;\n}\n\n/**\n * Compute a vertically-centered top row for content while reserving header/footer space.\n */\nexport function getVerticalAnchor(\n terminalRows: number,\n contentRows: number,\n options: VerticalAnchorOptions = {}\n): number {\n const headerRows = options.headerRows ?? 0;\n const footerRows = options.footerRows ?? 0;\n const minTop = Math.max(1, options.minTop ?? 1);\n\n const availableRows = terminalRows - headerRows - footerRows;\n const centeredTop = headerRows + Math.floor((availableRows - contentRows) / 2) + 1;\n\n return Math.max(minTop, centeredTop);\n}\n\n// Re-export PhosphorMode type for convenience\nexport type { PhosphorMode } from '../themes';\n","/**\n * Game Transitions - Centralized hacker-style transition effects\n *\n * Provides cinematic transitions for game entry, exit, and switching.\n * Games don't need to know about these - they just dispatch events.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from './utils';\n\n// Transition timing constants\nconst BOOT_DURATION = 800; // ms for boot sequence\nconst EXIT_DURATION = 400; // ms for exit sequence\nconst SWITCH_DURATION = 600; // ms for game switch\n\n// Boot messages - randomized hacker-style text\nconst BOOT_MESSAGES = [\n 'INITIALIZING NEURAL INTERFACE...',\n 'LOADING HYPER PROTOCOLS...',\n 'BYPASSING SECURITY LAYER...',\n 'ESTABLISHING UPLINK...',\n 'DECRYPTING GAME MODULE...',\n 'INJECTING PAYLOAD...',\n 'COMPILING RUNTIME...',\n 'SYNCHRONIZING CORES...',\n];\n\nconst EXIT_MESSAGES = [\n 'CONNECTION TERMINATED',\n 'SIGNAL LOST',\n 'LINK SEVERED',\n 'SESSION CLOSED',\n 'UPLINK DISCONNECTED',\n];\n\nconst SWITCH_MESSAGES = [\n 'REROUTING SIGNAL...',\n 'SWITCHING CHANNELS...',\n 'REALLOCATING RESOURCES...',\n 'LOADING NEW PROTOCOL...',\n];\n\n// ASCII art for transitions\nconst LOADING_FRAMES = [\n '[ ]',\n '[= ]',\n '[== ]',\n '[=== ]',\n '[====]',\n '[ ===]',\n '[ ==]',\n '[ =]',\n];\n\nconst GLITCH_CHARS = '!@#$%^&*()_+-=[]{}|;:,.<>?/~`░▒▓█▀▄';\n\n/**\n * Generate a random glitch string\n */\nfunction glitchText(length: number): string {\n let result = '';\n for (let i = 0; i < length; i++) {\n result += GLITCH_CHARS[Math.floor(Math.random() * GLITCH_CHARS.length)];\n }\n return result;\n}\n\n/**\n * Get random message from array\n */\nfunction randomMessage(messages: string[]): string {\n return messages[Math.floor(Math.random() * messages.length)];\n}\n\n/**\n * Sleep helper\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Boot transition - plays before game starts\n */\nexport async function playBootTransition(terminal: Terminal): Promise<void> {\n const themeColor = getCurrentThemeColor();\n const cols = terminal.cols;\n\n // Enter alternate buffer for clean transition\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l'); // Hide cursor\n terminal.write('\\x1b[2J\\x1b[H'); // Clear screen\n\n const centerX = Math.floor(cols / 2);\n\n // Quick glitch burst\n for (let i = 0; i < 3; i++) {\n const glitchLine = glitchText(cols);\n const glitchY = Math.floor(Math.random() * 10) + 5;\n terminal.write(`\\x1b[${glitchY};1H\\x1b[91m${glitchLine}\\x1b[0m`);\n await sleep(30);\n terminal.write(`\\x1b[${glitchY};1H${' '.repeat(cols)}`);\n }\n\n // Boot message\n const bootMsg = randomMessage(BOOT_MESSAGES);\n const msgX = Math.max(1, centerX - Math.floor(bootMsg.length / 2));\n terminal.write(`\\x1b[8;${msgX}H${themeColor}${bootMsg}\\x1b[0m`);\n\n // Loading bar animation\n const barY = 10;\n const loadingLabel = 'LOADING: ';\n const barX = Math.max(1, centerX - Math.floor((loadingLabel.length + 8) / 2));\n\n for (let i = 0; i < LOADING_FRAMES.length; i++) {\n const frame = LOADING_FRAMES[i];\n terminal.write(`\\x1b[${barY};${barX}H\\x1b[2m${themeColor}${loadingLabel}${frame}\\x1b[0m`);\n await sleep(BOOT_DURATION / LOADING_FRAMES.length);\n }\n\n // Final flash\n terminal.write(`\\x1b[${barY};${barX}H${themeColor}\\x1b[1m${loadingLabel}[DONE]\\x1b[0m`);\n await sleep(100);\n\n // Clear for game\n terminal.write('\\x1b[2J\\x1b[H');\n\n // Exit alternate buffer - game will re-enter\n terminal.write('\\x1b[?1049l');\n terminal.write('\\x1b[?25h');\n}\n\n/**\n * Exit transition - plays when game quits back to shell\n */\nexport async function playExitTransition(terminal: Terminal): Promise<void> {\n const themeColor = getCurrentThemeColor();\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // We're already in alternate buffer from the game\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n\n // Glitch effect - corrupt the screen\n for (let i = 0; i < 5; i++) {\n const glitchY = Math.floor(Math.random() * rows) + 1;\n const glitchLine = GLITCH_CHARS.repeat(Math.floor(cols / GLITCH_CHARS.length) + 1).slice(0, cols);\n terminal.write(`\\x1b[${glitchY};1H\\x1b[91m${glitchLine}\\x1b[0m`);\n await sleep(30);\n }\n\n // Exit message\n const exitMsg = randomMessage(EXIT_MESSAGES);\n const msgX = Math.max(1, centerX - Math.floor(exitMsg.length / 2));\n\n // Flash the message\n for (let i = 0; i < 3; i++) {\n terminal.write(`\\x1b[${centerY};${msgX}H\\x1b[1;91m${exitMsg}\\x1b[0m`);\n await sleep(60);\n terminal.write(`\\x1b[${centerY};${msgX}H${' '.repeat(exitMsg.length)}`);\n await sleep(40);\n }\n terminal.write(`\\x1b[${centerY};${msgX}H\\x1b[2m${themeColor}${exitMsg}\\x1b[0m`);\n await sleep(150);\n\n // Screen wipe down effect\n for (let y = 1; y <= rows; y += 2) {\n terminal.write(`\\x1b[${y};1H${' '.repeat(cols)}`);\n if (y + 1 <= rows) {\n terminal.write(`\\x1b[${y + 1};1H${' '.repeat(cols)}`);\n }\n await sleep(EXIT_DURATION / (rows / 2));\n }\n}\n\n/**\n * Switch transition - plays when switching to a new game\n */\nexport async function playSwitchTransition(terminal: Terminal): Promise<void> {\n const themeColor = getCurrentThemeColor();\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n\n // Quick screen corruption\n for (let i = 0; i < 4; i++) {\n const y1 = Math.floor(Math.random() * rows) + 1;\n const y2 = Math.floor(Math.random() * rows) + 1;\n terminal.write(`\\x1b[${y1};1H\\x1b[96m${glitchText(cols)}\\x1b[0m`);\n terminal.write(`\\x1b[${y2};1H\\x1b[95m${glitchText(cols)}\\x1b[0m`);\n await sleep(40);\n }\n\n // Clear center for message\n for (let y = centerY - 1; y <= centerY + 1; y++) {\n terminal.write(`\\x1b[${y};1H${' '.repeat(cols)}`);\n }\n\n // Switch message with spinner\n const switchMsg = randomMessage(SWITCH_MESSAGES);\n const msgX = Math.max(1, centerX - Math.floor(switchMsg.length / 2));\n const spinnerChars = ['|', '/', '-', '\\\\'];\n\n for (let i = 0; i < 8; i++) {\n const spinner = spinnerChars[i % spinnerChars.length];\n terminal.write(`\\x1b[${centerY};${msgX - 2}H${themeColor}${spinner}\\x1b[0m`);\n terminal.write(`\\x1b[${centerY};${msgX}H\\x1b[1m${themeColor}${switchMsg}\\x1b[0m`);\n await sleep(SWITCH_DURATION / 8);\n }\n\n // Quick fade out\n terminal.write('\\x1b[2J\\x1b[H');\n await sleep(50);\n}\n\n/**\n * Quick boot - shorter version for game switching (game-to-game)\n */\nexport async function playQuickBoot(terminal: Terminal): Promise<void> {\n const themeColor = getCurrentThemeColor();\n const cols = terminal.cols;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n terminal.write('\\x1b[2J\\x1b[H');\n\n const centerX = Math.floor(cols / 2);\n\n // Just a quick loading indicator\n const msg = 'LOADING...';\n const msgX = Math.max(1, centerX - Math.floor(msg.length / 2));\n\n terminal.write(`\\x1b[8;${msgX}H${themeColor}${msg}\\x1b[0m`);\n\n // Quick bar\n for (let i = 0; i < 5; i++) {\n const bar = '='.repeat(i + 1).padEnd(5, ' ');\n terminal.write(`\\x1b[10;${msgX}H${themeColor}[${bar}]\\x1b[0m`);\n await sleep(60);\n }\n\n await sleep(50);\n terminal.write('\\x1b[2J\\x1b[H');\n terminal.write('\\x1b[?1049l');\n terminal.write('\\x1b[?25h');\n}\n\n/**\n * Select transition - plays when selecting a game from the menu\n * Shows the game name with a cool reveal effect\n */\nexport async function playSelectTransition(terminal: Terminal, gameName: string): Promise<void> {\n const themeColor = getCurrentThemeColor();\n const cols = terminal.cols;\n const rows = terminal.rows;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n\n // Clear screen with a quick flash\n terminal.write('\\x1b[2J\\x1b[H');\n terminal.write(`\\x1b[48;5;255m${' '.repeat(cols * rows)}\\x1b[0m`);\n await sleep(30);\n terminal.write('\\x1b[2J\\x1b[H');\n await sleep(50);\n\n // Draw scan lines converging to center\n for (let i = 0; i < 6; i++) {\n const offset = 6 - i;\n // Top and bottom lines moving to center\n if (centerY - offset > 0) {\n terminal.write(`\\x1b[${centerY - offset};1H${themeColor}${'─'.repeat(cols)}\\x1b[0m`);\n }\n if (centerY + offset <= rows) {\n terminal.write(`\\x1b[${centerY + offset};1H${themeColor}${'─'.repeat(cols)}\\x1b[0m`);\n }\n await sleep(30);\n // Clear previous lines\n if (i > 0) {\n const prevOffset = 7 - i;\n if (centerY - prevOffset > 0) {\n terminal.write(`\\x1b[${centerY - prevOffset};1H${' '.repeat(cols)}`);\n }\n if (centerY + prevOffset <= rows) {\n terminal.write(`\\x1b[${centerY + prevOffset};1H${' '.repeat(cols)}`);\n }\n }\n }\n\n // Clear for game name reveal\n terminal.write('\\x1b[2J\\x1b[H');\n\n // Glitch reveal of game name\n const displayName = `▶ ${gameName} ◀`;\n const nameX = Math.max(1, centerX - Math.floor(displayName.length / 2));\n\n // Glitch through random characters then reveal\n for (let frame = 0; frame < 8; frame++) {\n let revealed = '';\n for (let i = 0; i < displayName.length; i++) {\n if (frame >= 6 || Math.random() < frame / 8) {\n revealed += displayName[i];\n } else {\n revealed += GLITCH_CHARS[Math.floor(Math.random() * GLITCH_CHARS.length)];\n }\n }\n terminal.write(`\\x1b[${centerY};${nameX}H\\x1b[1m${themeColor}${revealed}\\x1b[0m`);\n await sleep(50);\n }\n\n // Final clean display with glow effect (bright)\n terminal.write(`\\x1b[${centerY};${nameX}H\\x1b[1;7m${themeColor}${displayName}\\x1b[0m`);\n await sleep(150);\n\n // Subtitle\n const loadingMsg = 'INITIALIZING...';\n const loadingX = Math.max(1, centerX - Math.floor(loadingMsg.length / 2));\n terminal.write(`\\x1b[${centerY + 2};${loadingX}H\\x1b[2m${themeColor}${loadingMsg}\\x1b[0m`);\n\n // Quick loading bar\n const barWidth = 20;\n const barX = Math.max(1, centerX - Math.floor(barWidth / 2) - 1);\n for (let i = 0; i <= barWidth; i++) {\n const filled = '█'.repeat(i);\n const empty = '░'.repeat(barWidth - i);\n terminal.write(`\\x1b[${centerY + 4};${barX}H${themeColor}[${filled}${empty}]\\x1b[0m`);\n await sleep(20);\n }\n\n await sleep(100);\n\n // Wipe out effect\n for (let i = 0; i < 3; i++) {\n terminal.write('\\x1b[2J\\x1b[H');\n await sleep(30);\n terminal.write(`\\x1b[${centerY};${nameX}H\\x1b[1m${themeColor}${displayName}\\x1b[0m`);\n await sleep(30);\n }\n\n terminal.write('\\x1b[2J\\x1b[H');\n await sleep(50);\n}\n\n// Export event types for games to dispatch\nexport const GAME_EVENTS = {\n // Game wants to quit back to shell\n QUIT: 'hypersurge:game-quit',\n // Game wants to switch to another random game\n SWITCH: 'hypersurge:random-game',\n // Game wants to show the games menu\n GAMES_MENU: 'hypersurge:games-menu',\n // Launch a specific game by id\n LAUNCH_GAME: 'hypersurge:launch-game',\n} as const;\n\n/**\n * Helper for games to dispatch quit event\n * This triggers the exit transition before returning to shell\n */\nexport function dispatchGameQuit(terminal: Terminal): void {\n window.dispatchEvent(new CustomEvent(GAME_EVENTS.QUIT, {\n detail: { terminal }\n }));\n}\n\n/**\n * Helper for games to dispatch switch event\n * This triggers the switch transition before loading new game\n */\nexport function dispatchGameSwitch(terminal: Terminal): void {\n window.dispatchEvent(new CustomEvent(GAME_EVENTS.SWITCH, {\n detail: { terminal }\n }));\n}\n\n/**\n * Helper for games to dispatch games menu event\n * This triggers the games menu to let user select a game\n */\nexport function dispatchGamesMenu(terminal: Terminal): void {\n window.dispatchEvent(new CustomEvent(GAME_EVENTS.GAMES_MENU, {\n detail: { terminal }\n }));\n}\n\n/**\n * Helper to dispatch launch game event\n * This triggers TerminalPool to launch a specific game with proper tracking\n */\nexport function dispatchLaunchGame(terminal: Terminal, gameId: string): void {\n window.dispatchEvent(new CustomEvent(GAME_EVENTS.LAUNCH_GAME, {\n detail: { terminal, gameId }\n }));\n}\n","/**\n * Shared Menu System for Easter Egg Games\n *\n * Provides consistent menu navigation (arrow keys + Enter/Space)\n * while maintaining keyboard shortcuts for quick access.\n */\n\nimport { getCurrentThemeColor } from '../utils';\n\nexport interface MenuItem {\n label: string;\n shortcut?: string; // e.g., 'ESC', 'R', 'Q'\n action: () => void;\n}\n\nexport interface MenuState {\n selection: number;\n items: MenuItem[];\n}\n\n/**\n * Create a new menu state\n */\nexport function createMenuState(items: MenuItem[]): MenuState {\n return {\n selection: 0,\n items,\n };\n}\n\n/**\n * Navigate menu selection up\n */\nexport function menuUp(state: MenuState): void {\n state.selection = (state.selection - 1 + state.items.length) % state.items.length;\n}\n\n/**\n * Navigate menu selection down\n */\nexport function menuDown(state: MenuState): void {\n state.selection = (state.selection + 1) % state.items.length;\n}\n\n/**\n * Reset menu selection to top\n */\nexport function menuReset(state: MenuState): void {\n state.selection = 0;\n}\n\n/**\n * Execute the currently selected menu item\n */\nexport function menuConfirm(state: MenuState): void {\n const item = state.items[state.selection];\n if (item) {\n item.action();\n }\n}\n\n/**\n * Handle keyboard input for menu navigation\n * Returns true if the key was handled, false otherwise\n */\nexport function handleMenuInput(\n state: MenuState,\n key: string,\n domEvent: KeyboardEvent\n): boolean {\n // Arrow navigation\n if (domEvent.key === 'ArrowUp' || key === 'w') {\n menuUp(state);\n return true;\n }\n if (domEvent.key === 'ArrowDown' || key === 's') {\n menuDown(state);\n return true;\n }\n\n // Confirm selection\n if (domEvent.key === 'Enter' || domEvent.key === ' ') {\n menuConfirm(state);\n return true;\n }\n\n // Check keyboard shortcuts\n for (let i = 0; i < state.items.length; i++) {\n const item = state.items[i];\n if (item.shortcut && key === item.shortcut.toLowerCase()) {\n item.action();\n return true;\n }\n }\n\n return false;\n}\n\nexport interface RenderMenuOptions {\n title: string;\n x: number; // Center X position\n y: number; // Starting Y position\n width?: number; // Box width (auto-calculated if not provided)\n showShortcuts?: boolean; // Show shortcuts in menu (default: true)\n blinkTitle?: boolean; // Add blink effect to title (default: true)\n}\n\n/**\n * Render a menu box with highlighted selection\n * Returns ANSI escape sequence string\n */\nexport function renderMenu(\n state: MenuState,\n options: RenderMenuOptions\n): string {\n const themeColor = getCurrentThemeColor();\n const { title, x, y, showShortcuts = true, blinkTitle = true } = options;\n\n // Calculate width based on longest item\n let maxWidth = title.length;\n for (const item of state.items) {\n let itemText = item.label;\n if (showShortcuts && item.shortcut) {\n itemText += ` [${item.shortcut}]`;\n }\n // Account for selection indicators ► ◄\n maxWidth = Math.max(maxWidth, itemText.length + 6);\n }\n // width is calculated but not used currently - kept for potential future use\n void (options.width || maxWidth + 4);\n\n let output = '';\n\n // Title with optional blink\n const titleX = x - Math.floor(title.length / 2);\n const titleStyle = blinkTitle ? '\\x1b[5m' : '';\n output += `\\x1b[${y};${titleX}H${titleStyle}${themeColor}${title}\\x1b[0m`;\n\n // Menu items\n let itemY = y + 2;\n for (let i = 0; i < state.items.length; i++) {\n const item = state.items[i];\n const isSelected = i === state.selection;\n\n let displayText = item.label;\n if (showShortcuts && item.shortcut) {\n displayText += ` [${item.shortcut}]`;\n }\n\n // Selection highlighting\n const text = isSelected ? `► ${displayText} ◄` : ` ${displayText} `;\n const style = isSelected ? '\\x1b[1;93m' : `\\x1b[2m${themeColor}`;\n\n const itemX = x - Math.floor(text.length / 2);\n output += `\\x1b[${itemY};${itemX}H${style}${text}\\x1b[0m`;\n itemY++;\n }\n\n // Navigation hint\n const hint = '↑↓ Navigate Enter Select';\n const hintX = x - Math.floor(hint.length / 2);\n output += `\\x1b[${itemY + 1};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n return output;\n}\n\n/**\n * Standard pause menu items used across most games\n */\nexport function createPauseMenuItems(callbacks: {\n onResume: () => void;\n onRestart: () => void;\n onQuit: () => void;\n onListGames?: () => void;\n onNextGame?: () => void;\n onHelp?: () => void;\n}): MenuItem[] {\n const items: MenuItem[] = [\n { label: 'RESUME', shortcut: 'ESC', action: callbacks.onResume },\n { label: 'RESTART', shortcut: 'R', action: callbacks.onRestart },\n { label: 'QUIT', shortcut: 'Q', action: callbacks.onQuit },\n ];\n\n if (callbacks.onHelp) {\n items.push({ label: 'HELP', shortcut: 'H', action: callbacks.onHelp });\n }\n\n if (callbacks.onListGames) {\n items.push({ label: 'LIST GAMES', shortcut: 'L', action: callbacks.onListGames });\n }\n\n if (callbacks.onNextGame) {\n items.push({ label: 'NEXT GAME', shortcut: 'N', action: callbacks.onNextGame });\n }\n\n return items;\n}\n\n/**\n * Standard game over menu items\n */\nexport function createGameOverMenuItems(callbacks: {\n onRestart: () => void;\n onQuit: () => void;\n onNextGame?: () => void;\n}): MenuItem[] {\n const items: MenuItem[] = [\n { label: 'RESTART', shortcut: 'R', action: callbacks.onRestart },\n { label: 'QUIT', shortcut: 'Q', action: callbacks.onQuit },\n ];\n\n if (callbacks.onNextGame) {\n items.push({ label: 'NEXT GAME', shortcut: 'N', action: callbacks.onNextGame });\n }\n\n return items;\n}\n\n/**\n * Mode selection menu (Tutorial/Play) used by games with tutorials\n */\nexport function createModeSelectMenuItems(callbacks: {\n onTutorial: () => void;\n onPlay: () => void;\n}): MenuItem[] {\n return [\n { label: 'TUTORIAL', shortcut: 'T', action: callbacks.onTutorial },\n { label: 'PLAY', shortcut: 'P', action: callbacks.onPlay },\n ];\n}\n\n// ============================================================================\n// Simple Menu Helpers (for gradual adoption)\n// These work with just indices, no callbacks needed\n// ============================================================================\n\nexport interface SimpleMenuItem {\n label: string;\n shortcut?: string;\n}\n\n/**\n * Handle menu navigation without callbacks\n * Returns new selection index\n */\nexport function navigateMenu(\n currentSelection: number,\n itemCount: number,\n key: string,\n domEvent: KeyboardEvent\n): { newSelection: number; confirmed: boolean } {\n let newSelection = currentSelection;\n let confirmed = false;\n\n if (domEvent.key === 'ArrowUp' || key === 'w') {\n newSelection = (currentSelection - 1 + itemCount) % itemCount;\n } else if (domEvent.key === 'ArrowDown' || key === 's') {\n newSelection = (currentSelection + 1) % itemCount;\n } else if (domEvent.key === 'Enter' || domEvent.key === ' ') {\n confirmed = true;\n }\n\n return { newSelection, confirmed };\n}\n\n/**\n * Check if a shortcut key was pressed\n * Returns the index of the matching item, or -1 if no match\n */\nexport function checkShortcut(\n items: SimpleMenuItem[],\n key: string\n): number {\n for (let i = 0; i < items.length; i++) {\n const shortcut = items[i].shortcut;\n if (shortcut && key === shortcut.toLowerCase()) {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * Render a simple menu (index-based, no callbacks)\n * Returns ANSI escape sequence string\n */\nexport function renderSimpleMenu(\n items: SimpleMenuItem[],\n selection: number,\n options: {\n centerX: number;\n startY: number;\n showShortcuts?: boolean;\n }\n): string {\n const themeColor = getCurrentThemeColor();\n const { centerX, startY, showShortcuts = true } = options;\n\n let output = '';\n\n items.forEach((item, i) => {\n const isSelected = i === selection;\n\n let displayText = item.label;\n if (showShortcuts && item.shortcut) {\n displayText += ` [${item.shortcut}]`;\n }\n\n const text = isSelected ? `► ${displayText} ◄` : ` ${displayText} `;\n const style = isSelected ? '\\x1b[1;93m' : `\\x1b[2m${themeColor}`;\n\n const itemX = centerX - Math.floor(text.length / 2);\n output += `\\x1b[${startY + i};${itemX}H${style}${text}\\x1b[0m`;\n });\n\n return output;\n}\n\n/**\n * Common pause menu items definition\n */\nexport const PAUSE_MENU_ITEMS: SimpleMenuItem[] = [\n { label: 'RESUME', shortcut: 'ESC' },\n { label: 'RESTART', shortcut: 'R' },\n { label: 'QUIT', shortcut: 'Q' },\n { label: 'LIST GAMES', shortcut: 'L' },\n { label: 'NEXT GAME', shortcut: 'N' },\n];\n\n/**\n * Common mode select items definition\n */\nexport const MODE_SELECT_ITEMS: SimpleMenuItem[] = [\n { label: 'TUTORIAL', shortcut: 'T' },\n { label: 'PLAY', shortcut: 'P' },\n];\n","/**\n * Pure slide/merge logic for 2048 game\n * Extracted for testability\n */\n\nexport interface SlideResult {\n result: number[];\n merged: boolean[];\n moved: boolean;\n mergeScore: number;\n}\n\n/**\n * Slide and merge a row of tiles toward index 0\n * This is the core 2048 mechanic\n *\n * @param row - Array of tile values (0 = empty)\n * @param gridSize - Size of the grid (default 4)\n * @returns SlideResult with new row, merge info, and score\n */\nexport function slide(row: number[], gridSize: number = 4): SlideResult {\n // Filter out empty cells\n const filtered = row.filter(x => x !== 0);\n const merged: boolean[] = [];\n const result: number[] = [];\n\n // Check if tiles will move just by compacting\n let moved = row.some((v, i) => v !== 0 && i >= filtered.length);\n let mergeScore = 0;\n\n // Process tiles, merging adjacent equal values\n let i = 0;\n while (i < filtered.length) {\n if (i + 1 < filtered.length && filtered[i] === filtered[i + 1]) {\n // Merge two equal tiles\n const newVal = filtered[i] * 2;\n result.push(newVal);\n merged.push(true);\n mergeScore += newVal;\n moved = true;\n i += 2;\n } else {\n // Keep single tile\n result.push(filtered[i]);\n merged.push(false);\n i++;\n }\n }\n\n // Pad with zeros\n while (result.length < gridSize) {\n result.push(0);\n merged.push(false);\n }\n\n // Final check if anything actually moved\n if (!moved) {\n moved = row.some((v, idx) => v !== result[idx]);\n }\n\n return { result, merged, moved, mergeScore };\n}\n\n/**\n * Check if any moves are possible on the grid\n *\n * @param grid - 2D array of tile values\n * @returns true if at least one move is possible\n */\nexport function canMakeMove(grid: number[][]): boolean {\n const size = grid.length;\n\n // Check for empty cells\n for (let y = 0; y < size; y++) {\n for (let x = 0; x < size; x++) {\n if (grid[y][x] === 0) return true;\n }\n }\n\n // Check for adjacent equal values\n for (let y = 0; y < size; y++) {\n for (let x = 0; x < size; x++) {\n const val = grid[y][x];\n // Check right neighbor\n if (x < size - 1 && grid[y][x + 1] === val) return true;\n // Check bottom neighbor\n if (y < size - 1 && grid[y + 1][x] === val) return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if the grid contains a 2048 (or higher) tile\n *\n * @param grid - 2D array of tile values\n * @param target - Target value (default 2048)\n * @returns true if target value exists\n */\nexport function hasReachedTarget(grid: number[][], target: number = 2048): boolean {\n for (const row of grid) {\n for (const cell of row) {\n if (cell >= target) return true;\n }\n }\n return false;\n}\n","/**\n * Hyper 2048\n *\n * Slide and merge DATA PACKETS to reach TERABYTE (2048).\n * Cyberpunk-themed with glitchy effects and theme-aware colors.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\nimport { slide as slideLogic, canMakeMove, hasReachedTarget } from './slideLogic';\n\n/**\n * 2048 Game Controller\n */\nexport interface Game2048Controller {\n stop: () => void;\n isRunning: boolean;\n}\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\ninterface UndoState {\n grid: number[][];\n score: number;\n}\n\n// ============================================================================\n// TILE COLORS AND NAMES (Cyberpunk Data Theme)\n// ============================================================================\n\nconst TILE_COLORS: Record<number, string> = {\n 2: '\\x1b[38;5;252m', // Light gray - BIT\n 4: '\\x1b[38;5;159m', // Light cyan - BYTE\n 8: '\\x1b[38;5;51m', // Cyan - WORD\n 16: '\\x1b[38;5;45m', // Blue-cyan - BLOCK\n 32: '\\x1b[38;5;39m', // Blue - SECTOR\n 64: '\\x1b[38;5;33m', // Deep blue - CLUSTER\n 128: '\\x1b[38;5;171m', // Purple - SEGMENT\n 256: '\\x1b[38;5;207m', // Magenta - PACKET\n 512: '\\x1b[38;5;213m', // Pink - FRAME\n 1024: '\\x1b[38;5;220m', // Gold - GIGABYTE\n 2048: '\\x1b[38;5;226m', // Bright gold - TERABYTE\n 4096: '\\x1b[38;5;196m', // Red - PETABYTE\n 8192: '\\x1b[38;5;201m', // Hot pink - EXABYTE\n};\n\nconst TILE_NAMES: Record<number, string> = {\n 2: 'BIT',\n 4: 'BYTE',\n 8: 'WORD',\n 16: 'BLOCK',\n 32: 'SECTOR',\n 64: 'CLUSTER',\n 128: 'SEGMENT',\n 256: 'PACKET',\n 512: 'FRAME',\n 1024: 'GIGA',\n 2048: 'TERA',\n 4096: 'PETA',\n 8192: 'EXA',\n};\n\nconst TILE_BG_COLORS: Record<number, string> = {\n 2: '\\x1b[48;5;236m',\n 4: '\\x1b[48;5;23m',\n 8: '\\x1b[48;5;24m',\n 16: '\\x1b[48;5;25m',\n 32: '\\x1b[48;5;26m',\n 64: '\\x1b[48;5;27m',\n 128: '\\x1b[48;5;53m',\n 256: '\\x1b[48;5;90m',\n 512: '\\x1b[48;5;127m',\n 1024: '\\x1b[48;5;136m',\n 2048: '\\x1b[48;5;178m',\n 4096: '\\x1b[48;5;160m',\n 8192: '\\x1b[48;5;198m',\n};\n\n// ============================================================================\n// MAIN GAME FUNCTION\n// ============================================================================\n\nexport function run2048Game(terminal: Terminal): Game2048Controller {\n const themeColor = getCurrentThemeColor();\n\n // -------------------------------------------------------------------------\n // CONSTANTS\n // -------------------------------------------------------------------------\n const MIN_COLS = 36;\n const MIN_ROWS = 16;\n const GRID_SIZE = 4;\n const TILE_WIDTH = 8;\n const TILE_HEIGHT = 3;\n const GAME_WIDTH = GRID_SIZE * TILE_WIDTH + 2;\n const GAME_HEIGHT = GRID_SIZE * TILE_HEIGHT + 2;\n const MAX_UNDOS = 3;\n\n // -------------------------------------------------------------------------\n // STATE\n // -------------------------------------------------------------------------\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let won = false;\n let continuedAfterWin = false;\n let score = 0;\n let highScore = 0;\n\n let grid: number[][] = [];\n let undoStack: UndoState[] = [];\n let undosRemaining = MAX_UNDOS;\n\n let gameLeft = 2;\n let gameTop = 4;\n\n let glitchFrame = 0;\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let shakeFrames = 0;\n let shakeIntensity = 0;\n\n // -------------------------------------------------------------------------\n // CONTROLLER\n // -------------------------------------------------------------------------\n const controller: Game2048Controller = {\n stop: () => {\n if (!running) return;\n running = false;\n },\n get isRunning() { return running; }\n };\n\n // -------------------------------------------------------------------------\n // ASCII ART TITLE\n // -------------------------------------------------------------------------\n const title = [\n '\\u2588 \\u2588 \\u2588\\u2584\\u2588 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2580\\u2588 \\u2582\\u2580\\u2580\\u2588 \\u2580\\u2580\\u2588 \\u2584 \\u2588\\u2580\\u2580 \\u2580\\u2588\\u2580',\n '\\u2588\\u2580\\u2588 \\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2588\\u2584 \\u2588\\u2580\\u2584 \\u2584\\u2580\\u2580\\u2584 \\u2580\\u2580\\u2584 \\u2588\\u2580\\u2584 \\u2588\\u2588\\u2584 \\u2588 ',\n ];\n\n // -------------------------------------------------------------------------\n // EFFECTS\n // -------------------------------------------------------------------------\n\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['\\u2726', '\\u2605', '\\u25C6', '\\u25CF']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.3 + Math.random() * 0.5;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 12 + Math.floor(Math.random() * 8),\n });\n }\n }\n\n function spawnMergeParticles(gridX: number, gridY: number, value: number) {\n const screenX = gridX * TILE_WIDTH + TILE_WIDTH / 2;\n const screenY = gridY * TILE_HEIGHT + TILE_HEIGHT / 2;\n const color = TILE_COLORS[value] || '\\x1b[97m';\n const dataChars = ['\\u2588', '\\u2593', '\\u2592', '\\u2591', '\\u25A0', '\\u25A1'];\n spawnParticles(screenX, screenY, 8, color, dataChars);\n }\n\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 20, color });\n }\n\n function triggerShake(frames: number, intensity: number) {\n shakeFrames = frames;\n shakeIntensity = intensity;\n }\n\n // -------------------------------------------------------------------------\n // GRID HELPERS\n // -------------------------------------------------------------------------\n\n function createEmptyGrid(): number[][] {\n return Array(GRID_SIZE).fill(null).map(() => Array(GRID_SIZE).fill(0));\n }\n\n function copyGrid(g: number[][]): number[][] {\n return g.map(row => [...row]);\n }\n\n function getEmptyCells(): [number, number][] {\n const empty: [number, number][] = [];\n for (let y = 0; y < GRID_SIZE; y++) {\n for (let x = 0; x < GRID_SIZE; x++) {\n if (grid[y][x] === 0) {\n empty.push([x, y]);\n }\n }\n }\n return empty;\n }\n\n function spawnTile() {\n const empty = getEmptyCells();\n if (empty.length === 0) return;\n const [x, y] = empty[Math.floor(Math.random() * empty.length)];\n grid[y][x] = Math.random() < 0.9 ? 2 : 4;\n }\n\n // Use imported canMakeMove\n function canMove(): boolean {\n return canMakeMove(grid);\n }\n\n // Use imported hasReachedTarget\n function has2048(): boolean {\n return hasReachedTarget(grid, 2048);\n }\n\n // -------------------------------------------------------------------------\n // MOVE LOGIC\n // -------------------------------------------------------------------------\n\n function saveState() {\n if (undoStack.length >= MAX_UNDOS) {\n undoStack.shift();\n }\n undoStack.push({\n grid: copyGrid(grid),\n score: score,\n });\n }\n\n function undo() {\n if (undoStack.length === 0 || undosRemaining <= 0) return false;\n const state = undoStack.pop()!;\n grid = state.grid;\n score = state.score;\n undosRemaining--;\n gameOver = false;\n won = false;\n return true;\n }\n\n // Use imported slideLogic with GRID_SIZE\n function slide(row: number[]) {\n return slideLogic(row, GRID_SIZE);\n }\n\n function move(direction: 'up' | 'down' | 'left' | 'right'): boolean {\n let totalMergeScore = 0;\n let anyMoved = false;\n\n if (direction === 'left') {\n for (let y = 0; y < GRID_SIZE; y++) {\n const { result, merged, moved, mergeScore } = slide(grid[y]);\n if (moved) anyMoved = true;\n totalMergeScore += mergeScore;\n for (let x = 0; x < GRID_SIZE; x++) {\n if (merged[x] && result[x] > 0) {\n spawnMergeParticles(x, y, result[x]);\n addScorePopup(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${result[x]}`, TILE_COLORS[result[x]]);\n }\n }\n grid[y] = result;\n }\n } else if (direction === 'right') {\n for (let y = 0; y < GRID_SIZE; y++) {\n const reversed = [...grid[y]].reverse();\n const { result, merged, moved, mergeScore } = slide(reversed);\n if (moved) anyMoved = true;\n totalMergeScore += mergeScore;\n const finalRow = result.reverse();\n const finalMerged = merged.reverse();\n for (let x = 0; x < GRID_SIZE; x++) {\n if (finalMerged[x] && finalRow[x] > 0) {\n spawnMergeParticles(x, y, finalRow[x]);\n addScorePopup(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${finalRow[x]}`, TILE_COLORS[finalRow[x]]);\n }\n }\n grid[y] = finalRow;\n }\n } else if (direction === 'up') {\n for (let x = 0; x < GRID_SIZE; x++) {\n const col = [];\n for (let y = 0; y < GRID_SIZE; y++) col.push(grid[y][x]);\n const { result, merged, moved, mergeScore } = slide(col);\n if (moved) anyMoved = true;\n totalMergeScore += mergeScore;\n for (let y = 0; y < GRID_SIZE; y++) {\n if (merged[y] && result[y] > 0) {\n spawnMergeParticles(x, y, result[y]);\n addScorePopup(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${result[y]}`, TILE_COLORS[result[y]]);\n }\n grid[y][x] = result[y];\n }\n }\n } else if (direction === 'down') {\n for (let x = 0; x < GRID_SIZE; x++) {\n const col = [];\n for (let y = 0; y < GRID_SIZE; y++) col.push(grid[y][x]);\n const reversed = col.reverse();\n const { result, merged, moved, mergeScore } = slide(reversed);\n if (moved) anyMoved = true;\n totalMergeScore += mergeScore;\n const finalCol = result.reverse();\n const finalMerged = merged.reverse();\n for (let y = 0; y < GRID_SIZE; y++) {\n if (finalMerged[y] && finalCol[y] > 0) {\n spawnMergeParticles(x, y, finalCol[y]);\n addScorePopup(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${finalCol[y]}`, TILE_COLORS[finalCol[y]]);\n }\n grid[y][x] = finalCol[y];\n }\n }\n }\n\n if (anyMoved) {\n score += totalMergeScore;\n if (totalMergeScore > 0) {\n triggerShake(4, 1);\n }\n spawnTile();\n\n if (!won && !continuedAfterWin && has2048()) {\n won = true;\n if (score > highScore) highScore = score;\n triggerShake(8, 2);\n for (let y = 0; y < GRID_SIZE; y++) {\n for (let x = 0; x < GRID_SIZE; x++) {\n if (grid[y][x] === 2048) {\n spawnMergeParticles(x, y, 2048);\n spawnMergeParticles(x, y, 2048);\n }\n }\n }\n }\n\n if (!canMove()) {\n gameOver = true;\n if (score > highScore) highScore = score;\n }\n\n return true;\n }\n\n return false;\n }\n\n // -------------------------------------------------------------------------\n // GAME LOGIC\n // -------------------------------------------------------------------------\n\n function initGame() {\n grid = createEmptyGrid();\n score = 0;\n gameOver = false;\n won = false;\n continuedAfterWin = false;\n paused = false;\n undoStack = [];\n undosRemaining = MAX_UNDOS;\n\n particles = [];\n scorePopups = [];\n shakeFrames = 0;\n\n spawnTile();\n spawnTile();\n }\n\n function update() {\n if (!gameStarted || (gameOver && !won) || paused) return;\n\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.03;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.2;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n }\n\n // -------------------------------------------------------------------------\n // RENDERING\n // -------------------------------------------------------------------------\n\n function renderTile(value: number, screenX: number, screenY: number): string {\n if (value === 0) {\n let output = '';\n const emptyChar = '\\u2591';\n for (let row = 0; row < TILE_HEIGHT; row++) {\n output += `\\x1b[${screenY + row};${screenX}H\\x1b[38;5;238m`;\n for (let col = 0; col < TILE_WIDTH; col++) {\n output += emptyChar;\n }\n output += '\\x1b[0m';\n }\n return output;\n }\n\n const color = TILE_COLORS[value] || '\\x1b[97m';\n const bgColor = TILE_BG_COLORS[value] || '\\x1b[48;5;240m';\n const name = TILE_NAMES[value] || value.toString();\n\n let output = '';\n\n output += `\\x1b[${screenY};${screenX}H${bgColor}${color}`;\n output += '\\u2584'.repeat(TILE_WIDTH);\n output += '\\x1b[0m';\n\n output += `\\x1b[${screenY + 1};${screenX}H${bgColor}${color}\\x1b[1m`;\n const displayText = name.length <= TILE_WIDTH - 2 ? name : value.toString();\n const padding = Math.floor((TILE_WIDTH - displayText.length) / 2);\n output += ' '.repeat(padding) + displayText + ' '.repeat(TILE_WIDTH - padding - displayText.length);\n output += '\\x1b[0m';\n\n output += `\\x1b[${screenY + 2};${screenX}H${bgColor}${color}`;\n output += '\\u2580'.repeat(TILE_WIDTH);\n output += '\\x1b[0m';\n\n return output;\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n if (shakeFrames > 0) shakeFrames--;\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = needWidth && needHeight ? 'Make pane larger'\n : needWidth ? 'Make pane wider ->' : 'Make pane taller v';\n const msg2 = `Need: ${MIN_COLS}x${MIN_ROWS} Have: ${cols}x${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH) / 2));\n gameTop = Math.max(4, Math.floor((rows - GAME_HEIGHT - 6) / 2));\n\n let renderLeft = gameLeft;\n let renderTop = gameTop;\n if (shakeFrames > 0) {\n renderLeft += Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n renderTop += Math.floor((Math.random() - 0.5) * shakeIntensity);\n }\n\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[1;${titleX}H\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `\\x1b[1;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n const stats = `SCORE: ${score.toString().padStart(6, '0')} HIGH: ${highScore.toString().padStart(6, '0')} UNDO: ${undosRemaining}/${MAX_UNDOS}`;\n const statsX = Math.floor((cols - stats.length) / 2);\n output += `\\x1b[${gameTop - 1};${statsX}H${themeColor}${stats}\\x1b[0m`;\n\n const borderWidth = GAME_WIDTH;\n output += `\\x1b[${renderTop};${renderLeft}H${themeColor}\\u2554${'\\u2550'.repeat(borderWidth)}\\u2557\\x1b[0m`;\n for (let y = 0; y < GAME_HEIGHT - 2; y++) {\n output += `\\x1b[${renderTop + 1 + y};${renderLeft}H${themeColor}\\u2551\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + y};${renderLeft + borderWidth + 1}H${themeColor}\\u2551\\x1b[0m`;\n }\n output += `\\x1b[${renderTop + GAME_HEIGHT - 1};${renderLeft}H${themeColor}\\u255A${'\\u2550'.repeat(borderWidth)}\\u255D\\x1b[0m`;\n\n if (paused) {\n const pauseMsg = '\\u2550\\u2550 PAUSED \\u2550\\u2550';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseY = gameTop + Math.floor(GAME_HEIGHT / 2) - 3;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = 'Up/Down select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n }\n else if (!gameStarted) {\n for (let gy = 0; gy < GRID_SIZE; gy++) {\n for (let gx = 0; gx < GRID_SIZE; gx++) {\n const tileX = renderLeft + 1 + gx * TILE_WIDTH;\n const tileY = renderTop + 1 + gy * TILE_HEIGHT;\n output += renderTile(0, tileX, tileY);\n }\n }\n\n const startMsg = '[ PRESS ANY KEY TO PLAY ]';\n const startX = Math.floor((cols - startMsg.length) / 2);\n const startY = gameTop + Math.floor(GAME_HEIGHT / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = 'Arrow Keys: SLIDE U: UNDO ESC: MENU';\n const ctrlX = Math.floor((cols - controls.length) / 2);\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n\n const goal = 'MERGE DATA PACKETS TO REACH TERABYTE (2048)';\n const goalX = Math.floor((cols - goal.length) / 2);\n output += `\\x1b[${startY + 4};${goalX}H\\x1b[2m${themeColor}${goal}\\x1b[0m`;\n }\n else if (won && !continuedAfterWin) {\n for (let gy = 0; gy < GRID_SIZE; gy++) {\n for (let gx = 0; gx < GRID_SIZE; gx++) {\n const tileX = renderLeft + 1 + gx * TILE_WIDTH;\n const tileY = renderTop + 1 + gy * TILE_HEIGHT;\n output += renderTile(grid[gy][gx], tileX, tileY);\n }\n }\n\n const winBox = [\n '\\u2554\\u2550\\u2550 TERABYTE ACHIEVED! \\u2550\\u2550\\u2557',\n '\\u2551 \\u2551',\n '\\u2551 [C] CONTINUE PLAYING \\u2551',\n '\\u2551 [R] NEW GAME \\u2551',\n '\\u2551 [Q] QUIT \\u2551',\n '\\u2551 \\u2551',\n '\\u255A\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255D',\n ];\n const boxWidth = winBox[0].length;\n const boxX = Math.floor((cols - boxWidth) / 2);\n const boxY = gameTop + Math.floor(GAME_HEIGHT / 2) - 3;\n\n for (let i = 0; i < winBox.length; i++) {\n const lineColor = i === 0 ? '\\x1b[1;92m' : themeColor;\n output += `\\x1b[${boxY + i};${boxX}H${lineColor}${winBox[i]}\\x1b[0m`;\n }\n }\n else if (gameOver) {\n for (let gy = 0; gy < GRID_SIZE; gy++) {\n for (let gx = 0; gx < GRID_SIZE; gx++) {\n const tileX = renderLeft + 1 + gx * TILE_WIDTH;\n const tileY = renderTop + 1 + gy * TILE_HEIGHT;\n output += renderTile(grid[gy][gx], tileX, tileY);\n }\n }\n\n const overMsg = '\\u2554\\u2550\\u2550 SYSTEM CRASH \\u2550\\u2550\\u2557';\n const overX = Math.floor((cols - overMsg.length) / 2);\n const overY = gameTop + Math.floor(GAME_HEIGHT / 2) - 2;\n output += `\\x1b[${overY};${overX}H\\x1b[1;91m${overMsg}\\x1b[0m`;\n\n const scoreLine = `SCORE: ${score} HIGH: ${highScore}`;\n const scoreX = Math.floor((cols - scoreLine.length) / 2);\n output += `\\x1b[${overY + 2};${scoreX}H${themeColor}${scoreLine}\\x1b[0m`;\n\n const undoHint = undosRemaining > 0 ? ' [U] UNDO' : '';\n const restart = `\\u255A [R] RESTART [Q] QUIT${undoHint} \\u255D`;\n const restartX = Math.floor((cols - restart.length) / 2);\n output += `\\x1b[${overY + 4};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n }\n else {\n for (let gy = 0; gy < GRID_SIZE; gy++) {\n for (let gx = 0; gx < GRID_SIZE; gx++) {\n const tileX = renderLeft + 1 + gx * TILE_WIDTH;\n const tileY = renderTop + 1 + gy * TILE_HEIGHT;\n output += renderTile(grid[gy][gx], tileX, tileY);\n }\n }\n\n for (const p of particles) {\n const screenX = Math.round(renderLeft + 1 + p.x);\n const screenY = Math.round(renderTop + 1 + p.y);\n if (screenX > renderLeft && screenX < renderLeft + GAME_WIDTH &&\n screenY > renderTop && screenY < renderTop + GAME_HEIGHT) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n for (const popup of scorePopups) {\n const screenX = Math.round(renderLeft + 1 + popup.x);\n const screenY = Math.round(renderTop + 1 + popup.y);\n if (screenY > renderTop && screenY < renderTop + GAME_HEIGHT) {\n const alpha = popup.frames > 12 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n }\n\n const hint = gameStarted && !gameOver && !paused && !won\n ? `Arrows: SLIDE U: UNDO(${undosRemaining}) ESC: MENU`\n : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${gameTop + GAME_HEIGHT + 1};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n // -------------------------------------------------------------------------\n // GAME LOOP\n // -------------------------------------------------------------------------\n\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) { clearInterval(gameInterval); return; }\n update();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n if (key === 'escape') {\n if (won && !continuedAfterWin) return;\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n if (key === 'q' && (paused || gameOver || !gameStarted || (won && !continuedAfterWin))) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n\n if (!gameStarted && !paused) {\n saveState();\n gameStarted = true;\n return;\n }\n\n if (won && !continuedAfterWin) {\n if (key === 'c') {\n continuedAfterWin = true;\n won = false;\n return;\n }\n if (key === 'r') {\n if (score > highScore) highScore = score;\n initGame();\n gameStarted = true;\n return;\n }\n return;\n }\n\n if (gameOver) {\n if (key === 'r') {\n if (score > highScore) highScore = score;\n initGame();\n gameStarted = true;\n } else if (key === 'u') {\n undo();\n }\n return;\n }\n\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: paused = false; break;\n case 1: initGame(); gameStarted = true; paused = false; break;\n case 2:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n if (key === 'r') { initGame(); gameStarted = true; paused = false; }\n else if (key === 'l') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGamesMenu(terminal); }\n else if (key === 'n') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGameSwitch(terminal); }\n return;\n }\n\n switch (domEvent.key) {\n case 'ArrowLeft':\n case 'a':\n saveState();\n move('left');\n break;\n case 'ArrowRight':\n case 'd':\n saveState();\n move('right');\n break;\n case 'ArrowUp':\n case 'w':\n saveState();\n move('up');\n break;\n case 'ArrowDown':\n case 's':\n saveState();\n move('down');\n break;\n case 'u':\n case 'U':\n undo();\n break;\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 50);\n\n return controller;\n}\n","/**\n * Hyper Asteroids\n *\n * Classic asteroids with ship rotation, thrust physics, and shooting.\n * Simplified visuals for terminal - single-character asteroids and ship.\n * Features screen wrapping, asteroid splitting, particle effects.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\nexport interface AsteroidsController {\n stop: () => void;\n isRunning: boolean;\n}\n\ninterface Ship {\n x: number;\n y: number;\n vx: number;\n vy: number;\n angle: number;\n thrusting: boolean;\n}\n\ninterface Bullet {\n x: number;\n y: number;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface Asteroid {\n x: number;\n y: number;\n vx: number;\n vy: number;\n size: 'large' | 'medium' | 'small';\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\nexport function runAsteroidsGame(terminal: Terminal): AsteroidsController {\n const themeColor = getCurrentThemeColor();\n\n // Lower minimum requirements\n const MIN_COLS = 35;\n const MIN_ROWS = 16;\n\n // Adaptive game dimensions\n let GAME_WIDTH = 30;\n let GAME_HEIGHT = 12;\n\n // Ship physics\n const SHIP_TURN_SPEED = 0.2;\n const SHIP_THRUST = 0.06;\n const SHIP_FRICTION = 0.98;\n const SHIP_MAX_SPEED = 0.8;\n const BULLET_SPEED = 1.2;\n const BULLET_LIFE = 30;\n const SHOOT_COOLDOWN = 10;\n\n // Asteroid speeds\n const ASTEROID_SPEEDS = { large: 0.12, medium: 0.2, small: 0.35 };\n const ASTEROID_SCORES = { large: 20, medium: 50, small: 100 };\n const ASTEROID_RADIUS = { large: 2, medium: 1.5, small: 1 };\n\n // State\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let score = 0;\n let highScore = 0;\n let lives = 3;\n let wave = 1;\n let invincibilityFrames = 0;\n let shootCooldown = 0;\n let glitchFrame = 0;\n let shakeFrames = 0;\n let shakeIntensity = 0;\n\n let gameLeft = 2;\n let gameTop = 4;\n\n let ship: Ship = { x: 0, y: 0, vx: 0, vy: 0, angle: -Math.PI / 2, thrusting: false };\n let keysDown: Set<string> = new Set();\n let bullets: Bullet[] = [];\n let asteroids: Asteroid[] = [];\n let particles: Particle[] = [];\n\n const controller: AsteroidsController = {\n stop: () => { if (running) running = false; },\n get isRunning() { return running; }\n };\n\n // Ship directions (8 directions)\n const SHIP_CHARS = ['→', '↘', '↓', '↙', '←', '↖', '↑', '↗'];\n // Asteroid characters by size\n const ASTEROID_CHARS = { large: '◉', medium: '●', small: '•' };\n\n const title = ['▄▀█ █▀ ▀█▀ █▀▀ █▀█ █▀█ █ █▀▄ █▀',\n '█▀█ ▄█ █ ██▄ █▀▄ █▄█ █ █▄▀ ▄█'];\n\n function initGame() {\n const cols = terminal.cols;\n const rows = terminal.rows;\n GAME_WIDTH = Math.min(50, Math.max(28, cols - 6));\n GAME_HEIGHT = Math.min(18, Math.max(10, rows - 8));\n\n score = 0;\n lives = 3;\n wave = 1;\n gameOver = false;\n paused = false;\n\n ship = {\n x: GAME_WIDTH / 2,\n y: GAME_HEIGHT / 2,\n vx: 0,\n vy: 0,\n angle: -Math.PI / 2,\n thrusting: false,\n };\n\n keysDown.clear();\n bullets = [];\n asteroids = [];\n particles = [];\n invincibilityFrames = 60;\n shootCooldown = 0;\n\n spawnWave();\n }\n\n function spawnWave() {\n const count = 3 + wave;\n for (let i = 0; i < count; i++) {\n let x, y;\n // Spawn away from ship\n do {\n x = Math.random() * GAME_WIDTH;\n y = Math.random() * GAME_HEIGHT;\n } while (Math.abs(x - ship.x) < 8 && Math.abs(y - ship.y) < 4);\n\n const angle = Math.random() * Math.PI * 2;\n const speed = ASTEROID_SPEEDS.large * (0.8 + Math.random() * 0.4);\n asteroids.push({\n x, y,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n size: 'large',\n });\n }\n }\n\n function wrap(value: number, max: number): number {\n if (value < 0) return max + value;\n if (value >= max) return value - max;\n return value;\n }\n\n function triggerShake(frames: number, intensity: number) {\n shakeFrames = frames;\n shakeIntensity = intensity;\n }\n\n function spawnParticles(x: number, y: number, count: number, color: string) {\n const chars = ['*', '+', '.', '·'];\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.2 + Math.random() * 0.4;\n particles.push({\n x, y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 10 + Math.floor(Math.random() * 10),\n });\n }\n }\n\n function shoot() {\n if (shootCooldown > 0) return;\n shootCooldown = SHOOT_COOLDOWN;\n\n const bulletX = ship.x + Math.cos(ship.angle) * 1.5;\n const bulletY = ship.y + Math.sin(ship.angle) * 0.75;\n\n bullets.push({\n x: bulletX,\n y: bulletY,\n vx: Math.cos(ship.angle) * BULLET_SPEED + ship.vx * 0.5,\n vy: Math.sin(ship.angle) * BULLET_SPEED * 0.5 + ship.vy * 0.5,\n life: BULLET_LIFE,\n });\n }\n\n function hitShip() {\n if (invincibilityFrames > 0) return;\n\n lives--;\n spawnParticles(ship.x, ship.y, 15, '\\x1b[91m');\n triggerShake(10, 3);\n\n if (lives <= 0) {\n gameOver = true;\n if (score > highScore) highScore = score;\n } else {\n // Reset ship position\n ship.x = GAME_WIDTH / 2;\n ship.y = GAME_HEIGHT / 2;\n ship.vx = 0;\n ship.vy = 0;\n invincibilityFrames = 90;\n }\n }\n\n function splitAsteroid(asteroid: Asteroid) {\n spawnParticles(asteroid.x, asteroid.y, 8, '\\x1b[93m');\n score += ASTEROID_SCORES[asteroid.size];\n\n if (asteroid.size === 'large') {\n for (let i = 0; i < 2; i++) {\n const angle = Math.random() * Math.PI * 2;\n asteroids.push({\n x: asteroid.x,\n y: asteroid.y,\n vx: Math.cos(angle) * ASTEROID_SPEEDS.medium,\n vy: Math.sin(angle) * ASTEROID_SPEEDS.medium * 0.5,\n size: 'medium',\n });\n }\n } else if (asteroid.size === 'medium') {\n for (let i = 0; i < 2; i++) {\n const angle = Math.random() * Math.PI * 2;\n asteroids.push({\n x: asteroid.x,\n y: asteroid.y,\n vx: Math.cos(angle) * ASTEROID_SPEEDS.small,\n vy: Math.sin(angle) * ASTEROID_SPEEDS.small * 0.5,\n size: 'small',\n });\n }\n }\n }\n\n function update() {\n if (paused || !gameStarted || gameOver) return;\n\n glitchFrame = (glitchFrame + 1) % 60;\n if (invincibilityFrames > 0) invincibilityFrames--;\n if (shootCooldown > 0) shootCooldown--;\n\n // Ship input\n if (keysDown.has('ArrowLeft') || keysDown.has('a')) ship.angle -= SHIP_TURN_SPEED;\n if (keysDown.has('ArrowRight') || keysDown.has('d')) ship.angle += SHIP_TURN_SPEED;\n\n ship.thrusting = keysDown.has('ArrowUp') || keysDown.has('w');\n if (ship.thrusting) {\n ship.vx += Math.cos(ship.angle) * SHIP_THRUST;\n ship.vy += Math.sin(ship.angle) * SHIP_THRUST * 0.5;\n }\n\n if (keysDown.has(' ')) shoot();\n\n // Physics\n ship.vx *= SHIP_FRICTION;\n ship.vy *= SHIP_FRICTION;\n\n const speed = Math.sqrt(ship.vx ** 2 + ship.vy ** 2);\n if (speed > SHIP_MAX_SPEED) {\n ship.vx = (ship.vx / speed) * SHIP_MAX_SPEED;\n ship.vy = (ship.vy / speed) * SHIP_MAX_SPEED;\n }\n\n ship.x = wrap(ship.x + ship.vx, GAME_WIDTH);\n ship.y = wrap(ship.y + ship.vy, GAME_HEIGHT);\n\n // Bullets\n for (let i = bullets.length - 1; i >= 0; i--) {\n const bullet = bullets[i];\n bullet.x = wrap(bullet.x + bullet.vx, GAME_WIDTH);\n bullet.y = wrap(bullet.y + bullet.vy, GAME_HEIGHT);\n bullet.life--;\n if (bullet.life <= 0) bullets.splice(i, 1);\n }\n\n // Asteroids\n for (let i = asteroids.length - 1; i >= 0; i--) {\n const ast = asteroids[i];\n ast.x = wrap(ast.x + ast.vx, GAME_WIDTH);\n ast.y = wrap(ast.y + ast.vy, GAME_HEIGHT);\n\n // Bullet collision\n const radius = ASTEROID_RADIUS[ast.size];\n for (let j = bullets.length - 1; j >= 0; j--) {\n const bullet = bullets[j];\n const dx = bullet.x - ast.x;\n const dy = (bullet.y - ast.y) * 2; // Account for terminal aspect\n if (dx * dx + dy * dy < radius * radius) {\n bullets.splice(j, 1);\n splitAsteroid(ast);\n asteroids.splice(i, 1);\n triggerShake(4, 1);\n break;\n }\n }\n\n // Ship collision\n if (invincibilityFrames <= 0) {\n const dx = ship.x - ast.x;\n const dy = (ship.y - ast.y) * 2;\n if (dx * dx + dy * dy < (radius + 0.5) * (radius + 0.5)) {\n hitShip();\n }\n }\n }\n\n // Particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.02;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Next wave\n if (asteroids.length === 0) {\n wave++;\n spawnWave();\n }\n }\n\n function render() {\n let output = '\\x1b[2J\\x1b[H';\n if (shakeFrames > 0) shakeFrames--;\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg = 'Terminal too small!';\n const need = `Need: ${MIN_COLS}×${MIN_ROWS} Have: ${cols}×${rows}`;\n output += `\\x1b[${Math.floor(rows/2)};${Math.max(1, Math.floor((cols-msg.length)/2))}H${themeColor}${msg}\\x1b[0m`;\n output += `\\x1b[${Math.floor(rows/2)+2};${Math.max(1, Math.floor((cols-need.length)/2))}H\\x1b[2m${need}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH - 2) / 2));\n gameTop = Math.max(4, Math.floor((rows - GAME_HEIGHT - 6) / 2));\n\n let renderLeft = gameLeft;\n let renderTop = gameTop;\n if (shakeFrames > 0) {\n renderLeft += Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n renderTop += Math.floor((Math.random() - 0.5) * shakeIntensity);\n }\n\n // Title\n const titleX = Math.floor((cols - title[0].length) / 2);\n output += `\\x1b[1;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n\n // Stats\n const stats = `SCORE: ${score.toString().padStart(5, '0')} WAVE: ${wave} ${'♥'.repeat(lives)}`;\n output += `\\x1b[${gameTop - 1};${Math.floor((cols - stats.length) / 2)}H${themeColor}${stats}\\x1b[0m`;\n\n // Border\n output += `\\x1b[${renderTop};${renderLeft}H${themeColor}╔${'═'.repeat(GAME_WIDTH)}╗\\x1b[0m`;\n for (let y = 0; y < GAME_HEIGHT; y++) {\n output += `\\x1b[${renderTop + 1 + y};${renderLeft}H${themeColor}║\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + y};${renderLeft + GAME_WIDTH + 1}H${themeColor}║\\x1b[0m`;\n }\n output += `\\x1b[${renderTop + GAME_HEIGHT + 1};${renderLeft}H${themeColor}╚${'═'.repeat(GAME_WIDTH)}╝\\x1b[0m`;\n\n // Pause menu\n if (paused) {\n const pauseY = gameTop + Math.floor(GAME_HEIGHT / 2) - 2;\n output += `\\x1b[${pauseY};${Math.floor(cols/2) - 5}H\\x1b[5m${themeColor}══ PAUSED ══\\x1b[0m`;\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: Math.floor(cols / 2),\n startY: pauseY + 2,\n showShortcuts: false,\n });\n }\n // Start screen\n else if (!gameStarted) {\n const msg = '[ PRESS SPACE TO START ]';\n output += `\\x1b[${gameTop + Math.floor(GAME_HEIGHT/2)};${gameLeft + Math.floor((GAME_WIDTH - msg.length) / 2) + 1}H\\x1b[5m${themeColor}${msg}\\x1b[0m`;\n const ctrl = '← → rotate ↑ thrust SPACE shoot';\n output += `\\x1b[${gameTop + Math.floor(GAME_HEIGHT/2) + 2};${gameLeft + Math.floor((GAME_WIDTH - ctrl.length) / 2) + 1}H\\x1b[2m${themeColor}${ctrl}\\x1b[0m`;\n }\n // Game over\n else if (gameOver) {\n const overY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n output += `\\x1b[${overY};${gameLeft + Math.floor((GAME_WIDTH - 11) / 2) + 1}H\\x1b[1;91m╔ GAME OVER ╗\\x1b[0m`;\n output += `\\x1b[${overY + 1};${gameLeft + Math.floor((GAME_WIDTH - 18) / 2) + 1}H${themeColor}SCORE: ${score} HIGH: ${highScore}\\x1b[0m`;\n output += `\\x1b[${overY + 3};${gameLeft + Math.floor((GAME_WIDTH - 20) / 2) + 1}H\\x1b[2m${themeColor}[R] RESTART [Q] QUIT\\x1b[0m`;\n }\n // Gameplay\n else {\n // Draw asteroids\n for (const ast of asteroids) {\n const sx = renderLeft + 1 + Math.floor(ast.x);\n const sy = renderTop + 1 + Math.floor(ast.y);\n if (sx > renderLeft && sx < renderLeft + GAME_WIDTH + 1 && sy > renderTop && sy < renderTop + GAME_HEIGHT + 1) {\n const color = ast.size === 'large' ? '\\x1b[93m' : ast.size === 'medium' ? '\\x1b[33m' : '\\x1b[2;33m';\n output += `\\x1b[${sy};${sx}H${color}${ASTEROID_CHARS[ast.size]}\\x1b[0m`;\n }\n }\n\n // Draw bullets\n for (const b of bullets) {\n const sx = renderLeft + 1 + Math.floor(b.x);\n const sy = renderTop + 1 + Math.floor(b.y);\n if (sx > renderLeft && sx < renderLeft + GAME_WIDTH + 1 && sy > renderTop && sy < renderTop + GAME_HEIGHT + 1) {\n output += `\\x1b[${sy};${sx}H\\x1b[1;97m•\\x1b[0m`;\n }\n }\n\n // Draw particles\n for (const p of particles) {\n const sx = renderLeft + 1 + Math.floor(p.x);\n const sy = renderTop + 1 + Math.floor(p.y);\n if (sx > renderLeft && sx < renderLeft + GAME_WIDTH + 1 && sy > renderTop && sy < renderTop + GAME_HEIGHT + 1) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${sy};${sx}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw ship\n const showShip = invincibilityFrames <= 0 || Math.floor(glitchFrame / 3) % 2 === 0;\n if (showShip) {\n const sx = renderLeft + 1 + Math.floor(ship.x);\n const sy = renderTop + 1 + Math.floor(ship.y);\n if (sx > renderLeft && sx < renderLeft + GAME_WIDTH + 1 && sy > renderTop && sy < renderTop + GAME_HEIGHT + 1) {\n // 8 directions - ensure positive index with double modulo\n const dir = ((Math.round(ship.angle / (Math.PI / 4)) % 8) + 8) % 8;\n const shipChar = SHIP_CHARS[dir];\n const shipColor = ship.thrusting ? '\\x1b[1;93m' : themeColor;\n output += `\\x1b[${sy};${sx}H${shipColor}${shipChar}\\x1b[0m`;\n\n // Thrust trail\n if (ship.thrusting) {\n const trailX = sx - Math.round(Math.cos(ship.angle) * 1.5);\n const trailY = sy - Math.round(Math.sin(ship.angle) * 0.75);\n if (trailX > renderLeft && trailX < renderLeft + GAME_WIDTH + 1 && trailY > renderTop && trailY < renderTop + GAME_HEIGHT + 1) {\n output += `\\x1b[${trailY};${trailX}H\\x1b[91m${Math.random() > 0.5 ? '~' : '*'}\\x1b[0m`;\n }\n }\n }\n }\n }\n\n // Bottom hint\n const hint = `HIGH: ${highScore} [ ESC ] MENU`;\n output += `\\x1b[${gameTop + GAME_HEIGHT + 3};${Math.floor((cols - hint.length) / 2)}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n // Game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h\\x1b[?25l');\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) { clearInterval(gameInterval); return; }\n update();\n }, 25);\n\n // Use terminal.onKey for menu/game control, track keydown for continuous input\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key;\n const keyLower = key.toLowerCase();\n\n // Track continuous input\n keysDown.add(key);\n setTimeout(() => keysDown.delete(key), 100);\n\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(pauseMenuSelection, PAUSE_MENU_ITEMS.length, key, domEvent);\n if (newSelection !== pauseMenuSelection) { pauseMenuSelection = newSelection; return; }\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: paused = false; break;\n case 1: initGame(); gameStarted = true; paused = false; break;\n case 2: controller.stop(); dispatchGameQuit(terminal); break;\n case 3: controller.stop(); dispatchGamesMenu(terminal); break;\n case 4: controller.stop(); dispatchGameSwitch(terminal); break;\n }\n return;\n }\n return;\n }\n\n if (gameOver) {\n if (keyLower === 'r') { initGame(); gameStarted = true; return; }\n if (keyLower === 'q' || key === 'Escape') { controller.stop(); dispatchGameQuit(terminal); return; }\n return;\n }\n\n if (key === 'Escape') { paused = true; pauseMenuSelection = 0; return; }\n\n if (!gameStarted && key === ' ') { gameStarted = true; return; }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n keyListener.dispose();\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n terminal.write('\\x1b[?25h\\x1b[?1049l');\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Breakout\n *\n * Classic breakout/brick breaker with cyberpunk theme.\n * Paddle at bottom, ball bounces to break bricks at top.\n * Features power-ups, particle explosions, and screen shake.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Breakout Game Controller\n */\nexport interface BreakoutController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\ninterface Brick {\n x: number;\n y: number;\n width: number;\n alive: boolean;\n type: number;\n hits: number;\n}\n\ninterface Ball {\n x: number;\n y: number;\n vx: number;\n vy: number;\n active: boolean;\n}\n\ninterface PowerUp {\n x: number;\n y: number;\n type: 'multiball' | 'wide' | 'laser' | 'slow' | 'extra';\n vy: number;\n}\n\ninterface Laser {\n x: number;\n y: number;\n}\n\n// ============================================================================\n// MAIN GAME FUNCTION\n// ============================================================================\n\nexport function runBreakoutGame(terminal: Terminal): BreakoutController {\n const themeColor = getCurrentThemeColor();\n\n const MIN_COLS = 40;\n const MIN_ROWS = 18;\n const GAME_WIDTH = 46;\n const GAME_HEIGHT = 20;\n const PADDLE_WIDTH_NORMAL = 7;\n const PADDLE_WIDTH_WIDE = 11;\n const BRICK_WIDTH = 5;\n const BRICK_HEIGHT = 1;\n const BRICK_ROWS = 5;\n const BRICK_COLS = 8;\n const BALL_SPEED = 0.4;\n const MAX_BALL_SPEED = 0.7;\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let won = false;\n let score = 0;\n let highScore = 0;\n let lives = 3;\n let level = 1;\n\n let gameLeft = 2;\n let gameTop = 4;\n\n let paddleX = GAME_WIDTH / 2;\n let paddleWidth = PADDLE_WIDTH_NORMAL;\n let paddleWidthTimer = 0;\n\n let balls: Ball[] = [];\n let bricks: Brick[] = [];\n let powerUps: PowerUp[] = [];\n let lasers: Laser[] = [];\n let laserActive = false;\n let laserTimer = 0;\n let laserCooldown = 0;\n let slowActive = false;\n let slowTimer = 0;\n\n let glitchFrame = 0;\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let shakeFrames = 0;\n let shakeIntensity = 0;\n let comboCount = 0;\n let comboTimer = 0;\n let borderFlash = 0;\n let ballAttached = true;\n\n const controller: BreakoutController = {\n stop: () => { if (!running) return; running = false; },\n get isRunning() { return running; }\n };\n\n const title = [\n '\\u2588 \\u2588 \\u2588\\u2584\\u2588 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2580\\u2588 \\u2588 \\u2580 \\u2588\\u2580\\u2588 \\u2588 \\u2588 \\u2580\\u2588\\u2580',\n '\\u2588\\u2580\\u2588 \\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2588\\u2584 \\u2588\\u2580\\u2584 \\u2588\\u2580\\u2588 \\u2588\\u2584\\u2588 \\u2588\\u2584\\u2584 \\u2588\\u2584\\u2588 \\u2588\\u2580\\u2584 \\u2588\\u2584\\u2588 \\u2588\\u2584\\u2588 \\u2588 ',\n ];\n\n const brickColors = ['\\x1b[1;91m', '\\x1b[1;93m', '\\x1b[1;92m', '\\x1b[1;96m', '\\x1b[1;95m'];\n const brickPoints = [50, 40, 30, 20, 10];\n\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['\\u2726', '\\u2605', '\\u25c6', '\\u25cf']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.2 + Math.random() * 0.4;\n particles.push({ x, y, char: chars[Math.floor(Math.random() * chars.length)], color, vx: Math.cos(angle) * speed, vy: Math.sin(angle) * speed * 0.5, life: 10 + Math.floor(Math.random() * 8) });\n }\n }\n\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 18, color });\n }\n\n function triggerShake(frames: number, intensity: number) {\n shakeFrames = frames;\n shakeIntensity = intensity;\n }\n\n function initGame() {\n score = won ? score : 0;\n lives = won ? lives : 3;\n gameOver = false;\n won = false;\n paused = false;\n paddleX = GAME_WIDTH / 2;\n paddleWidth = PADDLE_WIDTH_NORMAL;\n paddleWidthTimer = 0;\n powerUps = [];\n lasers = [];\n laserActive = false;\n laserTimer = 0;\n laserCooldown = 0;\n slowActive = false;\n slowTimer = 0;\n particles = [];\n scorePopups = [];\n shakeFrames = 0;\n comboCount = 0;\n comboTimer = 0;\n borderFlash = 0;\n ballAttached = true;\n balls = [{ x: paddleX, y: GAME_HEIGHT - 3, vx: 0, vy: 0, active: true }];\n initBricks();\n }\n\n function initBricks() {\n bricks = [];\n const startX = Math.floor((GAME_WIDTH - BRICK_COLS * BRICK_WIDTH) / 2);\n const startY = 2;\n for (let row = 0; row < BRICK_ROWS; row++) {\n for (let col = 0; col < BRICK_COLS; col++) {\n const type = row;\n const hits = level >= 3 && row === 0 ? 2 : 1;\n bricks.push({ x: startX + col * BRICK_WIDTH, y: startY + row * (BRICK_HEIGHT + 1), width: BRICK_WIDTH - 1, alive: true, type, hits });\n }\n }\n }\n\n function launchBall() {\n if (!ballAttached || balls.length === 0) return;\n ballAttached = false;\n const ball = balls[0];\n const angle = -Math.PI / 2 + (Math.random() - 0.5) * Math.PI / 2;\n const speed = BALL_SPEED + (level - 1) * 0.03;\n ball.vx = Math.cos(angle) * speed;\n ball.vy = Math.sin(angle) * speed;\n }\n\n function spawnPowerUp(x: number, y: number) {\n if (Math.random() > 0.2) return;\n const types: PowerUp['type'][] = ['multiball', 'wide', 'laser', 'slow', 'extra'];\n powerUps.push({ x, y, type: types[Math.floor(Math.random() * types.length)], vy: 0.15 });\n }\n\n function applyPowerUp(type: PowerUp['type']) {\n triggerShake(8, 2);\n borderFlash = 15;\n switch (type) {\n case 'multiball': {\n const activeBalls = balls.filter(b => b.active);\n if (activeBalls.length > 0) {\n const src = activeBalls[0];\n for (let i = 0; i < 2; i++) {\n const angle = (Math.random() - 0.5) * Math.PI;\n const speed = Math.sqrt(src.vx ** 2 + src.vy ** 2);\n balls.push({ x: src.x, y: src.y, vx: Math.cos(angle) * speed, vy: -Math.abs(Math.sin(angle) * speed), active: true });\n }\n }\n addScorePopup(paddleX, GAME_HEIGHT - 5, 'MULTI-BALL!', '\\x1b[1;96m');\n break;\n }\n case 'wide': paddleWidth = PADDLE_WIDTH_WIDE; paddleWidthTimer = 600; addScorePopup(paddleX, GAME_HEIGHT - 5, 'WIDE PADDLE!', '\\x1b[1;92m'); break;\n case 'laser': laserActive = true; laserTimer = 400; addScorePopup(paddleX, GAME_HEIGHT - 5, 'LASER!', '\\x1b[1;91m'); break;\n case 'slow': slowActive = true; slowTimer = 300; for (const b of balls) { b.vx *= 0.6; b.vy *= 0.6; } addScorePopup(paddleX, GAME_HEIGHT - 5, 'SLOW-MO!', '\\x1b[1;93m'); break;\n case 'extra': lives++; addScorePopup(paddleX, GAME_HEIGHT - 5, '+1 LIFE!', '\\x1b[1;95m'); break;\n }\n }\n\n function getPowerUpChar(type: PowerUp['type']): string { return type === 'multiball' ? 'M' : type === 'wide' ? 'W' : type === 'laser' ? 'L' : type === 'slow' ? 'S' : '+'; }\n function getPowerUpColor(type: PowerUp['type']): string { return type === 'multiball' ? '\\x1b[1;96m' : type === 'wide' ? '\\x1b[1;92m' : type === 'laser' ? '\\x1b[1;91m' : type === 'slow' ? '\\x1b[1;93m' : '\\x1b[1;95m'; }\n\n function update() {\n if (!gameStarted || gameOver || paused) return;\n const speedMult = slowActive ? 0.5 : 1;\n\n if (paddleWidthTimer > 0) { paddleWidthTimer--; if (paddleWidthTimer === 0) paddleWidth = PADDLE_WIDTH_NORMAL; }\n if (laserTimer > 0) { laserTimer--; if (laserTimer === 0) laserActive = false; }\n if (slowTimer > 0) { slowTimer--; if (slowTimer === 0) { slowActive = false; for (const b of balls) { const s = Math.sqrt(b.vx ** 2 + b.vy ** 2); if (s > 0) { const f = Math.min(BALL_SPEED, s * 1.67) / s; b.vx *= f; b.vy *= f; } } } }\n if (laserCooldown > 0) laserCooldown--;\n if (comboTimer > 0) { comboTimer--; if (comboTimer === 0) comboCount = 0; }\n\n for (let i = particles.length - 1; i >= 0; i--) { const p = particles[i]; p.x += p.vx; p.y += p.vy; p.vy += 0.02; p.life--; if (p.life <= 0) particles.splice(i, 1); }\n for (let i = scorePopups.length - 1; i >= 0; i--) { const p = scorePopups[i]; p.y -= 0.25; p.frames--; if (p.frames <= 0) scorePopups.splice(i, 1); }\n\n for (let i = powerUps.length - 1; i >= 0; i--) {\n const pu = powerUps[i];\n pu.y += pu.vy * speedMult;\n const pL = paddleX - paddleWidth / 2, pR = paddleX + paddleWidth / 2;\n if (pu.y >= GAME_HEIGHT - 2 && pu.y <= GAME_HEIGHT - 1 && pu.x >= pL && pu.x <= pR) { applyPowerUp(pu.type); powerUps.splice(i, 1); continue; }\n if (pu.y >= GAME_HEIGHT) powerUps.splice(i, 1);\n }\n\n for (let i = lasers.length - 1; i >= 0; i--) {\n const laser = lasers[i];\n laser.y -= 1;\n for (const brick of bricks) {\n if (!brick.alive) continue;\n if (laser.y >= brick.y && laser.y <= brick.y + BRICK_HEIGHT && laser.x >= brick.x && laser.x <= brick.x + brick.width) {\n brick.hits--;\n if (brick.hits <= 0) { brick.alive = false; const pts = brickPoints[brick.type] || 10; score += pts; spawnParticles(brick.x + brick.width / 2, brick.y, 6, brickColors[brick.type]); addScorePopup(brick.x + 1, brick.y - 1, `+${pts}`, brickColors[brick.type]); spawnPowerUp(brick.x + brick.width / 2, brick.y); }\n lasers.splice(i, 1);\n break;\n }\n }\n if (laser.y < 0) lasers.splice(i, 1);\n }\n\n if (ballAttached && balls.length > 0) { balls[0].x = paddleX; balls[0].y = GAME_HEIGHT - 3; }\n\n for (let i = balls.length - 1; i >= 0; i--) {\n const ball = balls[i];\n if (!ball.active || ballAttached) continue;\n ball.x += ball.vx * speedMult;\n ball.y += ball.vy * speedMult;\n\n if (ball.x <= 0) { ball.x = 0; ball.vx = Math.abs(ball.vx); spawnParticles(0, ball.y, 3, themeColor, ['\\u00b7', '\\u2022']); }\n if (ball.x >= GAME_WIDTH - 1) { ball.x = GAME_WIDTH - 1; ball.vx = -Math.abs(ball.vx); spawnParticles(GAME_WIDTH - 1, ball.y, 3, themeColor, ['\\u00b7', '\\u2022']); }\n if (ball.y <= 0) { ball.y = 0; ball.vy = Math.abs(ball.vy); spawnParticles(ball.x, 0, 3, themeColor, ['\\u00b7', '\\u2022']); }\n\n const pL = paddleX - paddleWidth / 2, pR = paddleX + paddleWidth / 2, pY = GAME_HEIGHT - 2;\n if (ball.vy > 0 && ball.y >= pY - 0.5 && ball.y <= pY + 0.5 && ball.x >= pL - 0.5 && ball.x <= pR + 0.5) {\n const hitPos = (ball.x - paddleX) / (paddleWidth / 2);\n const angle = hitPos * Math.PI / 3;\n const curSpeed = Math.sqrt(ball.vx ** 2 + ball.vy ** 2);\n const newSpeed = Math.min(MAX_BALL_SPEED, curSpeed * 1.02);\n ball.vx = Math.sin(angle) * newSpeed;\n ball.vy = -Math.cos(angle) * newSpeed;\n ball.y = pY - 1;\n spawnParticles(ball.x, pY, 4, themeColor, ['\\u2726', '\\u25cf']);\n }\n\n for (const brick of bricks) {\n if (!brick.alive) continue;\n const bL = brick.x, bR = brick.x + brick.width, bT = brick.y, bB = brick.y + BRICK_HEIGHT;\n if (ball.x >= bL - 0.5 && ball.x <= bR + 0.5 && ball.y >= bT - 0.5 && ball.y <= bB + 0.5) {\n const fromL = ball.x < bL, fromR = ball.x > bR, fromT = ball.y < bT, fromB = ball.y > bB;\n if (fromL || fromR) ball.vx = -ball.vx;\n if (fromT || fromB) ball.vy = -ball.vy;\n if (!fromL && !fromR && !fromT && !fromB) ball.vy = -ball.vy;\n brick.hits--;\n if (brick.hits <= 0) {\n brick.alive = false;\n comboCount++; comboTimer = 40;\n const basePts = brickPoints[brick.type] || 10;\n const comboBonus = comboCount > 1 ? Math.floor(comboCount * 5) : 0;\n const totalPts = basePts + comboBonus;\n score += totalPts;\n const intensity = Math.min(comboCount, 8);\n triggerShake(3 + intensity, 1 + Math.floor(intensity / 3));\n spawnParticles(brick.x + brick.width / 2, brick.y, 6 + intensity, brickColors[brick.type]);\n addScorePopup(brick.x + 1, brick.y - 1, comboCount > 1 ? `+${totalPts}!` : `+${totalPts}`, brickColors[brick.type]);\n spawnPowerUp(brick.x + brick.width / 2, brick.y);\n } else {\n spawnParticles(ball.x, ball.y, 3, '\\x1b[2m' + brickColors[brick.type], ['\\u00b7', 'x']);\n }\n break;\n }\n }\n\n if (ball.y >= GAME_HEIGHT) ball.active = false;\n }\n\n balls = balls.filter(b => b.active);\n\n if (balls.length === 0 && !ballAttached) {\n lives--;\n if (lives <= 0) { gameOver = true; if (score > highScore) highScore = score; triggerShake(20, 4); spawnParticles(paddleX, GAME_HEIGHT - 2, 15, '\\x1b[1;91m', ['\\u2717', '\\u2620', '\\u00d7', '\\u2593']); }\n else { ballAttached = true; balls = [{ x: paddleX, y: GAME_HEIGHT - 3, vx: 0, vy: 0, active: true }]; triggerShake(10, 2); }\n }\n\n const aliveBricks = bricks.filter(b => b.alive);\n if (aliveBricks.length === 0) {\n won = true; gameOver = true; level++; if (score > highScore) highScore = score; triggerShake(12, 2);\n for (let i = 0; i < 5; i++) setTimeout(() => spawnParticles(Math.random() * GAME_WIDTH, Math.random() * GAME_HEIGHT / 2, 15, brickColors[Math.floor(Math.random() * brickColors.length)], ['\\u2605', '\\u2726', '\\u25c6', '\\u25cf', '\\u2727']), i * 100);\n }\n }\n\n function render() {\n let output = '\\x1b[2J\\x1b[H';\n if (shakeFrames > 0) shakeFrames--;\n if (borderFlash > 0) borderFlash--;\n\n const cols = terminal.cols, rows = terminal.rows;\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needW = cols < MIN_COLS, needH = rows < MIN_ROWS;\n const hint = needW && needH ? 'Make pane larger' : needW ? 'Make pane wider \\u2192' : 'Make pane taller \\u2193';\n const msg2 = `Need: ${MIN_COLS}\\u00d7${MIN_ROWS} Have: ${cols}\\u00d7${rows}`;\n const cX = Math.floor(cols / 2), cY = Math.floor(rows / 2);\n output += `\\x1b[${cY - 1};${Math.max(1, cX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${cY + 1};${Math.max(1, cX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${cY + 3};${Math.max(1, cX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH - 2) / 2));\n gameTop = Math.max(4, Math.floor((rows - GAME_HEIGHT - 6) / 2));\n\n let rL = gameLeft, rT = gameTop;\n if (shakeFrames > 0) { rL += Math.floor((Math.random() - 0.5) * shakeIntensity * 2); rT += Math.floor((Math.random() - 0.5) * shakeIntensity); }\n\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOff = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOff;\n if (glitchFrame >= 55 && glitchFrame < 58) { output += `\\x1b[1;${titleX}H\\x1b[91m${title[0]}\\x1b[0m\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`; }\n else { output += `\\x1b[1;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`; }\n\n const livesDisp = '\\u2665'.repeat(Math.max(0, lives));\n const stats = `SCORE: ${score.toString().padStart(5, '0')} LVL: ${level} ${livesDisp}`;\n const statsX = Math.floor((cols - stats.length) / 2);\n output += `\\x1b[${gameTop - 1};${statsX}H${themeColor}${stats}\\x1b[0m`;\n\n let ind = '';\n if (paddleWidthTimer > 0) ind += ' [W]';\n if (laserActive) ind += ' [L]';\n if (slowActive) ind += ' [S]';\n if (ind) output += `\\x1b[${gameTop - 1};${statsX + stats.length + 1}H\\x1b[2m${themeColor}${ind}\\x1b[0m`;\n\n const bC = borderFlash > 0 && borderFlash % 4 < 2 ? '\\x1b[1;93m' : themeColor;\n output += `\\x1b[${rT};${rL}H${bC}\\u2554${'═'.repeat(GAME_WIDTH)}\\u2557\\x1b[0m`;\n for (let y = 0; y < GAME_HEIGHT; y++) { output += `\\x1b[${rT + 1 + y};${rL}H${bC}\\u2551\\x1b[0m\\x1b[${rT + 1 + y};${rL + GAME_WIDTH + 1}H${bC}\\u2551\\x1b[0m`; }\n output += `\\x1b[${rT + GAME_HEIGHT + 1};${rL}H${bC}\\u255a${'═'.repeat(GAME_WIDTH)}\\u255d\\x1b[0m`;\n\n if (paused) {\n const pauseMsg = '\\u2550\\u2550 PAUSED \\u2550\\u2550';\n const pCX = Math.floor(cols / 2), pY = gameTop + Math.floor(GAME_HEIGHT / 2) - 3;\n output += `\\x1b[${pY};${pCX - Math.floor(pauseMsg.length / 2)}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, { centerX: pCX, startY: pY + 2, showShortcuts: false });\n output += `\\x1b[${pY + 8};${pCX - 13}H\\x1b[2m${themeColor}\\u2191\\u2193 select ENTER confirm\\x1b[0m`;\n } else if (!gameStarted) {\n const startMsg = '[ PRESS SPACE TO LAUNCH ]';\n const sX = gameLeft + Math.floor((GAME_WIDTH - startMsg.length) / 2) + 1;\n const sY = gameTop + Math.floor(GAME_HEIGHT / 2) + 2;\n output += `\\x1b[${sY};${sX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n const controls = '\\u2190\\u2192 MOVE SPC FIRE/LAUNCH ESC MENU';\n output += `\\x1b[${sY + 2};${gameLeft + Math.floor((GAME_WIDTH - controls.length) / 2) + 1}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n output = renderGameObjects(output, rL, rT);\n } else if (gameOver) {\n const overMsg = won ? '\\u2554\\u2550\\u2550 LEVEL COMPLETE! \\u2550\\u2550\\u2557' : '\\u2554\\u2550\\u2550 GAME OVER \\u2550\\u2550\\u2557';\n const oX = gameLeft + Math.floor((GAME_WIDTH - overMsg.length) / 2) + 1;\n const oY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n output += `\\x1b[${oY};${oX}H${won ? '\\x1b[1;92m' : '\\x1b[1;91m'}${overMsg}\\x1b[0m`;\n const scoreLine = `SCORE: ${score} HIGH: ${highScore}`;\n output += `\\x1b[${oY + 1};${gameLeft + Math.floor((GAME_WIDTH - scoreLine.length) / 2) + 1}H${themeColor}${scoreLine}\\x1b[0m`;\n const restart = won ? '\\u255a [R] NEXT LEVEL [Q] QUIT \\u255d' : '\\u255a [R] RESTART [Q] QUIT \\u255d';\n output += `\\x1b[${oY + 2};${gameLeft + Math.floor((GAME_WIDTH - restart.length) / 2) + 1}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n output = drawEffects(output, rL, rT);\n } else {\n output = renderGameObjects(output, rL, rT);\n }\n\n const hint = gameStarted && !gameOver && !paused ? `HIGH: ${highScore} [ ESC ] MENU` : '';\n output += `\\x1b[${gameTop + GAME_HEIGHT + 3};${Math.floor((cols - hint.length) / 2)}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n }\n\n function renderGameObjects(output: string, rL: number, rT: number): string {\n for (const brick of bricks) { if (!brick.alive) continue; const sX = rL + 1 + brick.x, sY = rT + 1 + brick.y; const c = brickColors[brick.type] || themeColor; const ch = brick.hits > 1 ? '\\u2593' : '\\u2588'; output += `\\x1b[${sY};${sX}H${c}${ch.repeat(brick.width)}\\x1b[0m`; }\n for (const pu of powerUps) { const sX = Math.round(rL + 1 + pu.x), sY = Math.round(rT + 1 + pu.y); if (sY > rT && sY < rT + GAME_HEIGHT + 1) output += `\\x1b[${sY};${sX}H${getPowerUpColor(pu.type)}[${getPowerUpChar(pu.type)}]\\x1b[0m`; }\n for (const laser of lasers) { const sX = rL + 1 + Math.floor(laser.x), sY = rT + 1 + Math.floor(laser.y); if (sY > rT && sY < rT + GAME_HEIGHT + 1) output += `\\x1b[${sY};${sX}H\\x1b[1;91m\\u2502\\x1b[0m`; }\n const pSX = rL + 1 + Math.floor(paddleX - paddleWidth / 2), pSY = rT + GAME_HEIGHT - 1;\n const pCh = laserActive ? '\\u2550' : '\\u2588';\n output += `\\x1b[${pSY};${pSX}H${themeColor}${pCh.repeat(Math.ceil(paddleWidth))}\\x1b[0m`;\n if (laserActive) { output += `\\x1b[${pSY};${pSX}H\\x1b[1;91m\\u2191\\x1b[0m\\x1b[${pSY};${pSX + Math.ceil(paddleWidth) - 1}H\\x1b[1;91m\\u2191\\x1b[0m`; }\n for (const ball of balls) { if (!ball.active) continue; const sX = Math.round(rL + 1 + ball.x), sY = Math.round(rT + 1 + ball.y); if (sX > rL && sX < rL + GAME_WIDTH + 1 && sY > rT && sY < rT + GAME_HEIGHT + 1) { const spd = Math.sqrt(ball.vx ** 2 + ball.vy ** 2); output += `\\x1b[${sY};${sX}H${spd > 0.5 ? '\\x1b[1;93m' : '\\x1b[1;97m'}\\u25cf\\x1b[0m`; } }\n if (comboCount >= 3) { const comboMsg = comboCount >= 5 ? `\\u2605 ${comboCount}x COMBO! \\u2605` : `${comboCount}x COMBO!`; const comboX = rL + Math.floor((GAME_WIDTH - comboMsg.length) / 2) + 1; output += `\\x1b[${rT + GAME_HEIGHT - 3};${comboX}H${glitchFrame % 6 < 3 ? '\\x1b[1;91m' : '\\x1b[1;93m'}${comboMsg}\\x1b[0m`; }\n return drawEffects(output, rL, rT);\n }\n\n function drawEffects(output: string, rL: number, rT: number): string {\n for (const p of particles) { const sX = Math.round(rL + 1 + p.x), sY = Math.round(rT + 1 + p.y); if (sX > rL && sX < rL + GAME_WIDTH + 1 && sY > rT && sY < rT + GAME_HEIGHT + 1) output += `\\x1b[${sY};${sX}H${p.life > 5 ? '' : '\\x1b[2m'}${p.color}${p.char}\\x1b[0m`; }\n for (const popup of scorePopups) { const sX = Math.round(rL + 1 + popup.x), sY = Math.round(rT + 1 + popup.y); if (sY > rT && sY < rT + GAME_HEIGHT + 1) output += `\\x1b[${sY};${sX}H${popup.frames > 10 ? '\\x1b[1m' : '\\x1b[2m'}${popup.color}${popup.text}\\x1b[0m`; }\n return output;\n }\n\n setTimeout(() => {\n if (!running) return;\n terminal.write('\\x1b[?1049h\\x1b[?25l');\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => { if (!running) { clearInterval(renderInterval); return; } render(); }, 25);\n const gameInterval = setInterval(() => { if (!running) { clearInterval(gameInterval); return; } update(); }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n domEvent.preventDefault();\n domEvent.stopPropagation();\n const key = domEvent.key.toLowerCase();\n\n if (key === 'escape') { paused = !paused; if (paused) pauseMenuSelection = 0; return; }\n if (key === 'q' && (paused || gameOver || !gameStarted)) { clearInterval(renderInterval); clearInterval(gameInterval); controller.stop(); dispatchGameQuit(terminal); return; }\n if (!gameStarted && !paused) { if (domEvent.key === ' ') { gameStarted = true; launchBall(); } return; }\n if (gameOver) { if (key === 'r') { if (score > highScore) highScore = score; if (won) initGame(); else { level = 1; initGame(); } gameStarted = true; launchBall(); } return; }\n\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(pauseMenuSelection, PAUSE_MENU_ITEMS.length, key, domEvent);\n if (newSelection !== pauseMenuSelection) { pauseMenuSelection = newSelection; return; }\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: paused = false; break;\n case 1: level = 1; initGame(); gameStarted = true; launchBall(); paused = false; break;\n case 2: clearInterval(renderInterval); clearInterval(gameInterval); controller.stop(); dispatchGameQuit(terminal); break;\n case 3: clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGamesMenu(terminal); break;\n case 4: clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGameSwitch(terminal); break;\n }\n return;\n }\n if (key === 'r') { level = 1; initGame(); gameStarted = true; launchBall(); paused = false; }\n else if (key === 'l') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGamesMenu(terminal); }\n else if (key === 'n') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGameSwitch(terminal); }\n return;\n }\n\n const moveSpeed = 2.5;\n switch (domEvent.key) {\n case 'ArrowLeft': case 'a': paddleX = Math.max(paddleWidth / 2, paddleX - moveSpeed); break;\n case 'ArrowRight': case 'd': paddleX = Math.min(GAME_WIDTH - paddleWidth / 2, paddleX + moveSpeed); break;\n case ' ': if (ballAttached) launchBall(); else if (laserActive && laserCooldown === 0) { lasers.push({ x: paddleX - paddleWidth / 2 + 0.5, y: GAME_HEIGHT - 3 }); lasers.push({ x: paddleX + paddleWidth / 2 - 0.5, y: GAME_HEIGHT - 3 }); laserCooldown = 8; } break;\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => { clearInterval(renderInterval); clearInterval(gameInterval); keyListener.dispose(); originalStop(); };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Chopper - Level Definitions\n *\n * Each level has:\n * - name: Display name\n * - platforms: Array of {x, y, width} - huts spawn centered on each\n * - waterLevel: Y position where water starts (death zone)\n * - timeLimit: Seconds to complete all deliveries\n * - parTime: Target time for 3 stars\n *\n * Map is ~70 chars wide, ~16 rows tall\n * Y=0 is top, Y increases downward\n * Platforms need headroom above for huts (3 rows tall)\n */\n\nexport interface Platform {\n x: number;\n y: number;\n width: number;\n}\n\nexport interface Level {\n name: string;\n platforms: Platform[];\n waterLevel: number;\n timeLimit: number;\n parTime: number;\n}\n\n// Tutorial levels - progressive learning, no time pressure\nexport const TUTORIAL_LEVELS: Level[] = [\n // Tutorial 1: Flight School - just learn to fly and steer\n {\n name: 'FLIGHT SCHOOL',\n waterLevel: 17, // Very low water for safety\n platforms: [\n { x: 5, y: 14, width: 20 }, // Left platform (start here)\n { x: 45, y: 14, width: 20 }, // Right platform (fly to here)\n ],\n timeLimit: 300,\n parTime: 60,\n },\n // Tutorial 2: First Delivery - learn pickup and dropoff\n {\n name: 'FIRST DELIVERY',\n waterLevel: 17,\n platforms: [\n { x: 5, y: 14, width: 20 }, // Left platform\n { x: 45, y: 14, width: 20 }, // Right platform (same height)\n ],\n timeLimit: 300,\n parTime: 60,\n },\n // Tutorial 3: Rope Master - platforms at different heights\n {\n name: 'ROPE MASTER',\n waterLevel: 17,\n platforms: [\n { x: 5, y: 14, width: 18 }, // Low left (near water)\n { x: 45, y: 6, width: 18 }, // High right (need to raise rope!)\n ],\n timeLimit: 300,\n parTime: 60,\n },\n];\n\nexport const LEVELS: Level[] = [\n // Level 1 - Easy intro\n {\n name: 'STONE AGE TAXI',\n waterLevel: 16,\n platforms: [\n { x: 0, y: 14, width: 18 }, // Left cliff\n { x: 52, y: 14, width: 18 }, // Right cliff\n { x: 26, y: 8, width: 16 }, // Center high\n ],\n timeLimit: 60,\n parTime: 30,\n },\n\n // Level 2 - Wider gaps\n {\n name: 'CANYON RUN',\n waterLevel: 16,\n platforms: [\n { x: 0, y: 14, width: 16 }, // Bottom left\n { x: 54, y: 14, width: 16 }, // Bottom right\n { x: 26, y: 9, width: 18 }, // Center mid\n ],\n timeLimit: 75,\n parTime: 40,\n },\n\n // Level 3 - High center peak\n {\n name: 'TRIPLE PEAK',\n waterLevel: 16,\n platforms: [\n { x: 0, y: 12, width: 14 }, // Left peak\n { x: 28, y: 6, width: 14 }, // Center peak (highest)\n { x: 56, y: 12, width: 14 }, // Right peak\n ],\n timeLimit: 80,\n parTime: 45,\n },\n\n // Level 4 - Ascending platforms\n {\n name: 'THE STAIRS',\n waterLevel: 16,\n platforms: [\n { x: 0, y: 14, width: 18 }, // Ground floor\n { x: 26, y: 10, width: 16 }, // Mid level\n { x: 52, y: 6, width: 18 }, // Top level\n ],\n timeLimit: 85,\n parTime: 50,\n },\n\n // Level 5 - All same height, small islands\n {\n name: 'ISLAND HOP',\n waterLevel: 15,\n platforms: [\n { x: 5, y: 13, width: 12 }, // Left island\n { x: 29, y: 13, width: 12 }, // Center island\n { x: 53, y: 13, width: 12 }, // Right island\n ],\n timeLimit: 70,\n parTime: 40,\n },\n\n // Level 6 - Very high center tower\n {\n name: 'THE TOWER',\n waterLevel: 16,\n platforms: [\n { x: 0, y: 14, width: 20 }, // Ground left\n { x: 28, y: 5, width: 14 }, // Tower top (very high!)\n { x: 50, y: 14, width: 20 }, // Ground right\n ],\n timeLimit: 90,\n parTime: 55,\n },\n\n // Level 7 - Alternating heights\n {\n name: 'ZIGZAG',\n waterLevel: 16,\n platforms: [\n { x: 0, y: 12, width: 16 }, // High left\n { x: 27, y: 14, width: 16 }, // Low center\n { x: 54, y: 8, width: 16 }, // Higher right\n ],\n timeLimit: 85,\n parTime: 50,\n },\n\n // Level 8 - Final challenge, platforms near water\n {\n name: 'FINAL FLIGHT',\n waterLevel: 15,\n platforms: [\n { x: 2, y: 13, width: 14 }, // Left (near water!)\n { x: 28, y: 7, width: 14 }, // High center\n { x: 54, y: 13, width: 14 }, // Right (near water!)\n ],\n timeLimit: 100,\n parTime: 60,\n },\n];\n","/**\n * Hyper Chopper - Visual Effects\n *\n * Particle systems, fireworks, and celebration effects.\n */\n\nexport interface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\nexport interface Popup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\n// Maximum particles to prevent performance issues\nexport const MAX_PARTICLES = 100;\n\n// Encouraging messages for deliveries\nexport const DELIVERY_MESSAGES = [\n 'NICE!', 'AWESOME!', 'PERFECT!', 'GREAT!', 'SWEET!',\n 'BOOM!', 'YES!', 'NAILED IT!', 'SMOOTH!', 'SLICK!'\n];\n\n/**\n * Spawn particles in a burst pattern\n */\nexport function spawnParticles(\n particles: Particle[],\n x: number,\n y: number,\n count: number,\n color: string,\n chars: string[] = ['✦', '·', '○']\n): void {\n if (particles.length >= MAX_PARTICLES) return;\n\n const actualCount = Math.min(count, MAX_PARTICLES - particles.length);\n for (let i = 0; i < actualCount; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.2 + Math.random() * 0.3;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed + 0.2,\n life: 12 + Math.floor(Math.random() * 8),\n });\n }\n}\n\n/**\n * Spawn a colorful firework explosion\n */\nexport function spawnFirework(\n particles: Particle[],\n x: number,\n y: number,\n intensity: number = 1\n): void {\n const colors = ['\\x1b[1;93m', '\\x1b[1;92m', '\\x1b[1;96m', '\\x1b[1;95m', '\\x1b[1;91m', '\\x1b[1;97m'];\n const chars = ['★', '✦', '◆', '●', '✶', '✴', '◇', '♦', '•', '○'];\n\n // Central burst\n for (let i = 0; i < 12 * intensity; i++) {\n const angle = (Math.PI * 2 * i) / (12 * intensity);\n const speed = 0.4 + Math.random() * 0.4;\n const color = colors[Math.floor(Math.random() * colors.length)];\n const char = chars[Math.floor(Math.random() * chars.length)];\n particles.push({\n x, y,\n char,\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed - 0.2,\n life: 20 + Math.floor(Math.random() * 15),\n });\n }\n\n // Sparkle ring\n for (let i = 0; i < 8 * intensity; i++) {\n const angle = (Math.PI * 2 * i) / (8 * intensity) + Math.random() * 0.3;\n const dist = 1.5 + Math.random();\n particles.push({\n x: x + Math.cos(angle) * dist,\n y: y + Math.sin(angle) * dist,\n char: '✧',\n color: '\\x1b[1;97m',\n vx: Math.cos(angle) * 0.15,\n vy: Math.sin(angle) * 0.15 - 0.1,\n life: 15 + Math.floor(Math.random() * 10),\n });\n }\n}\n\n/**\n * Add a floating text popup\n */\nexport function addPopup(\n popups: Popup[],\n x: number,\n y: number,\n text: string,\n color: string = '\\x1b[1;93m'\n): void {\n popups.push({ x, y, text, frames: 25, color });\n}\n\n/**\n * Update all particles (apply physics, remove dead ones)\n */\nexport function updateParticles(particles: Particle[], gravityMult: number = 1): void {\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.02 * gravityMult;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n}\n\n/**\n * Update all popups (float up, fade out)\n */\nexport function updatePopups(popups: Popup[]): void {\n for (let i = popups.length - 1; i >= 0; i--) {\n const popup = popups[i];\n popup.y -= 0.12;\n popup.frames--;\n if (popup.frames <= 0) popups.splice(i, 1);\n }\n}\n\n/**\n * Spawn rising sparkle trail effect\n */\nexport function spawnSparkleTrail(\n particles: Particle[],\n x: number,\n y: number,\n count: number = 6,\n color: string = '\\x1b[1;93m'\n): void {\n for (let i = 0; i < count; i++) {\n particles.push({\n x: x + (Math.random() - 0.5) * 4,\n y,\n char: ['✦', '✧', '★'][Math.floor(Math.random() * 3)],\n color,\n vx: (Math.random() - 0.5) * 0.2,\n vy: -0.3 - Math.random() * 0.3,\n life: 25 + Math.floor(Math.random() * 15),\n });\n }\n}\n\n/**\n * Spawn splash effect (for water crashes)\n */\nexport function spawnSplash(\n particles: Particle[],\n x: number,\n waterY: number,\n intensity: number = 1\n): void {\n const count = Math.floor(20 * intensity);\n for (let i = 0; i < count; i++) {\n const spread = (Math.random() - 0.5) * 15 * intensity;\n particles.push({\n x: x + spread,\n y: waterY - 1,\n char: ['~', '≈', '○', '●', '◦', '∘', '█', '▓'][Math.floor(Math.random() * 8)],\n color: Math.random() > 0.3 ? '\\x1b[96m' : '\\x1b[1;97m',\n vx: spread * 0.1,\n vy: -0.5 - Math.random() * 0.8,\n life: 25 + Math.floor(Math.random() * 15),\n });\n }\n}\n\n/**\n * Get random delivery message\n */\nexport function getRandomDeliveryMessage(): string {\n return DELIVERY_MESSAGES[Math.floor(Math.random() * DELIVERY_MESSAGES.length)];\n}\n","/**\n * Hyper Chopper\n *\n * UGH!-inspired 2D physics delivery game.\n * Fly a prehistoric helicopter, pick up passengers,\n * deliver them to platforms. Don't fall in the water!\n *\n * FIXED SCREEN - no scrolling, like Pac-Man\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor, getSubtleBackgroundColor, getVerticalAnchor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { LEVELS, TUTORIAL_LEVELS, type Platform } from './levels';\nimport {\n type Particle,\n type Popup,\n spawnParticles,\n spawnFirework,\n addPopup,\n updateParticles,\n updatePopups,\n spawnSparkleTrail,\n spawnSplash,\n getRandomDeliveryMessage,\n} from './effects';\nimport {\n PAUSE_MENU_ITEMS,\n MODE_SELECT_ITEMS,\n renderSimpleMenu,\n navigateMenu,\n} from '../shared/menu';\n\n/**\n * Courier Game Controller\n */\nexport interface CourierController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// Physics constants - FLAPPY STYLE but playable! (adjusted for 40fps)\nconst GRAVITY = 0.04; // Halved for 2x frame rate\nconst FLAP_POWER = 0.35; // Halved for 2x frame rate\nconst THRUST_POWER = 0.09; // Halved for 2x frame rate\nconst MAX_VELOCITY_X = 0.35; // Halved for 2x frame rate\nconst MAX_VELOCITY_Y = 0.45; // Halved for 2x frame rate\nconst AIR_DRAG_X = 0.97; // Adjusted for 2x frame rate (sqrt of 0.94)\nconst AIR_DRAG_Y = 0.98; // Adjusted for 2x frame rate (sqrt of 0.96)\n\n// Rope mechanics - retractable! (adjusted for 40fps)\nconst ROPE_MIN_LENGTH = 1.5; // Retracted (default)\nconst ROPE_MAX_LENGTH = 5; // Extended (when SPACE held)\nconst ROPE_EXTEND_SPEED = 0.2; // Halved for 2x frame rate\nconst ROPE_RETRACT_SPEED = 0.15; // Halved for 2x frame rate\nconst ROPE_FAST_RETRACT_SPEED = 0.3; // Halved for 2x frame rate\n\n\n/**\n * Hyper Chopper Game\n */\nexport function runCourierGame(terminal: Terminal): CourierController {\n const themeColor = getCurrentThemeColor();\n\n // Minimum terminal size\n const MIN_COLS = 40;\n const MIN_ROWS = 16;\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let crashAnimation = 0; // Frames of crash animation before showing game over\n let paused = false;\n let levelComplete = false;\n\n // Menu state\n let showingModeSelect = true; // Show tutorial/play selection\n let menuSelection = 0; // 0 = Tutorial, 1 = Play\n let pauseMenuSelection = 0; // 0 = Resume, 1 = Restart, 2 = Quit, 3 = List Games, 4 = Next Game\n\n // Tutorial state\n let tutorialMode = false;\n let tutorialLevelIndex = 0; // Which tutorial level (0=flying, 1=delivery, 2=rope)\n let tutorialStep = 0; // Step within current tutorial level\n let tutorialPromptTimer = 0; // For flashing prompts\n\n // FIXED SCREEN - game world is the viewport!\n let screenWidth = 48;\n let screenHeight = 16;\n\n // Rig state\n let rigX = 10;\n let rigY = 4;\n let rigVX = 0;\n let rigVY = 0;\n let rigAngle = 0;\n\n // Passenger/payload state\n let passengerX = 0;\n let passengerY = 0;\n let passengerVX = 0;\n let passengerVY = 0;\n let hasPassenger = false;\n\n // Level state\n let currentLevel = 0;\n let timeRemaining = 60;\n let score = 0;\n let deliveriesComplete = 0;\n let totalDeliveries = 3; // Deliveries per level\n\n // Dynamic pickup/dropoff - randomly assigned each delivery\n let pickupPlatformIndex = -1;\n let dropoffPlatformIndex = -1;\n let doorAnimation = 0; // For door open/close animation\n let newPackageDelay = 0; // Delay before new package spawns (all doors inactive)\n let levelCompleteAnimation = 0; // Fun animation when level complete\n let deliveringAnimation = 0; // Animation when dropping package (before delivery completes)\n\n // Passenger pickup grace period (prevents instant water death)\n let passengerGraceFrames = 0;\n\n // Visual effects\n let particles: Particle[] = [];\n let popups: Popup[] = [];\n let screenShake = 0;\n let glitchFrame = 0;\n\n // Tutorial/grace period\n let tutorialCountdown = 0;\n let invincibleFrames = 0;\n\n // Flap state - CRITICAL FOR GAMEPLAY\n let flapCooldown = 0; // Frames until next flap (KEEP SHORT!)\n let flapAnimation = 0;\n let rotorFrame = 0;\n\n // Input state\n let inputLeft = false;\n let inputRight = false;\n let inputExtendRope = false; // SPACE held = extend rope\n let inputContractRope = false; // SHIFT held = fast retract rope\n\n // Rope state\n let currentRopeLength = ROPE_MIN_LENGTH;\n\n // Timeout tracking for cleanup\n const pendingTimeouts: ReturnType<typeof setTimeout>[] = [];\n\n // Levels imported from ./levels.ts\n const levels = LEVELS;\n\n // Interval references (set later in game loop)\n let renderInterval: ReturnType<typeof setInterval> | null = null;\n let gameInterval: ReturnType<typeof setInterval> | null = null;\n let keyListener: { dispose: () => void } | null = null;\n\n // Track if cleanup has been performed\n let cleanedUp = false;\n // Track if window listeners were added (for reliable cleanup)\n let windowListenersAdded = false;\n\n /**\n * Schedule a timeout and track it for cleanup\n */\n function scheduleTimeout(callback: () => void, delay: number): void {\n const id = setTimeout(() => {\n // Remove from tracking\n const idx = pendingTimeouts.indexOf(id);\n if (idx !== -1) pendingTimeouts.splice(idx, 1);\n // Only execute if still running\n if (running) callback();\n }, delay);\n pendingTimeouts.push(id);\n }\n\n /**\n * Clean up all game resources\n */\n function cleanup(): void {\n if (cleanedUp) return;\n cleanedUp = true;\n\n // Clear all pending timeouts\n pendingTimeouts.forEach(id => clearTimeout(id));\n pendingTimeouts.length = 0;\n\n // Clear intervals\n if (renderInterval) clearInterval(renderInterval);\n if (gameInterval) clearInterval(gameInterval);\n\n // Dispose terminal key listener\n if (keyListener) keyListener.dispose();\n\n // Remove window event listeners (only if they were added)\n if (windowListenersAdded && keyDownHandler && keyUpHandler) {\n window.removeEventListener('keydown', keyDownHandler);\n window.removeEventListener('keyup', keyUpHandler);\n windowListenersAdded = false;\n }\n\n running = false;\n }\n\n // Event handlers (defined here so cleanup can reference them)\n let keyDownHandler: (e: KeyboardEvent) => void;\n let keyUpHandler: (e: KeyboardEvent) => void;\n\n const controller: CourierController = {\n stop: () => {\n cleanup();\n },\n get isRunning() { return running; }\n };\n\n // ASCII art title\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ █▀▀ █ █ █▀█ █▀█ █▀█ █▀▀ █▀█',\n '█▀█ █ █▀▀ ██▄ █▀▄ █▄▄ █▀█ █▄█ █▀▀ █▀▀ ██▄ █▀▄',\n ];\n\n const subtitle = '~ STONE AGE TAXI SERVICE ~';\n\n /**\n * Select new random pickup and dropoff platforms for the next delivery\n */\n function selectNewRoute(): boolean {\n // Validate level index\n if (currentLevel < 0 || currentLevel >= levels.length) {\n console.error(`[Chopper] Invalid level index: ${currentLevel}`);\n return false;\n }\n\n const level = levels[currentLevel];\n const numPlatforms = level.platforms.length;\n\n // Need at least 2 platforms for pickup and dropoff\n if (numPlatforms < 2) {\n console.error(`[Chopper] Level ${currentLevel} needs at least 2 platforms`);\n return false;\n }\n\n // Pick random pickup platform\n pickupPlatformIndex = Math.floor(Math.random() * numPlatforms);\n\n // Pick random dropoff platform (different from pickup)\n do {\n dropoffPlatformIndex = Math.floor(Math.random() * numPlatforms);\n } while (dropoffPlatformIndex === pickupPlatformIndex);\n\n // Door animation - passenger appears\n doorAnimation = 30;\n\n // Spawn effect at pickup location\n const pickup = level.platforms[pickupPlatformIndex];\n spawnParticles(\n particles,\n pickup.x + Math.floor(pickup.width / 2),\n pickup.y - 1,\n 5,\n '\\x1b[92m',\n ['◇', '✦', '○']\n );\n\n return true;\n }\n\n function initGame() {\n gameOver = false;\n paused = false;\n levelComplete = false;\n score = 0;\n deliveriesComplete = 0;\n currentLevel = 0;\n tutorialMode = false;\n tutorialStep = 0;\n initLevel();\n }\n\n function initTutorial() {\n gameOver = false;\n paused = false;\n levelComplete = false;\n score = 0;\n deliveriesComplete = 0;\n tutorialMode = true;\n tutorialLevelIndex = 0; // Start at first tutorial level\n tutorialStep = 0;\n tutorialPromptTimer = 0;\n initTutorialLevel();\n }\n\n function initTutorialLevel(): boolean {\n const level = TUTORIAL_LEVELS[tutorialLevelIndex];\n if (!level) {\n console.error(`[Chopper] Invalid tutorial level: ${tutorialLevelIndex}`);\n return false;\n }\n\n // Reset tutorial step for this level\n tutorialStep = 0;\n tutorialPromptTimer = 0;\n\n // Start on left platform\n const startPlatform = level.platforms[0];\n rigX = startPlatform.x + Math.floor(startPlatform.width / 2);\n rigY = startPlatform.y - 4;\n rigVX = 0;\n rigVY = 0;\n rigAngle = 0;\n\n // No tutorial countdown in tutorial mode - we have our own prompts\n tutorialCountdown = 0;\n invincibleFrames = 200; // Extra invincibility for tutorial\n\n // Configure based on tutorial level\n if (tutorialLevelIndex === 0) {\n // FLIGHT SCHOOL - no passengers, just learn to fly\n pickupPlatformIndex = -1; // No pickup\n dropoffPlatformIndex = -1; // No dropoff\n hasPassenger = false;\n totalDeliveries = 0; // No deliveries\n } else if (tutorialLevelIndex === 1) {\n // FIRST DELIVERY - basic pickup and delivery\n pickupPlatformIndex = 0; // Left platform\n dropoffPlatformIndex = 1; // Right platform\n hasPassenger = false;\n totalDeliveries = 1;\n } else if (tutorialLevelIndex === 2) {\n // ROPE MASTER - start with passenger attached, different heights\n pickupPlatformIndex = -1; // Already have passenger\n dropoffPlatformIndex = 1; // High platform on right\n hasPassenger = true; // Start with passenger!\n totalDeliveries = 1;\n }\n\n // Reset passenger position\n passengerX = rigX;\n passengerY = rigY + ROPE_MIN_LENGTH;\n passengerVX = 0;\n passengerVY = 0;\n passengerGraceFrames = 0;\n currentRopeLength = ROPE_MIN_LENGTH;\n doorAnimation = 30;\n\n // Reset effects\n particles = [];\n popups = [];\n screenShake = 0;\n deliveringAnimation = 0;\n\n // Reset time\n timeRemaining = level.timeLimit;\n deliveriesComplete = 0;\n\n levelComplete = false;\n\n return true;\n }\n\n function initLevel(): boolean {\n // Validate level index\n if (currentLevel < 0 || currentLevel >= levels.length) {\n console.error(`[Chopper] Invalid level index: ${currentLevel}`);\n gameOver = true;\n return false;\n }\n\n const level = levels[currentLevel];\n\n // Need at least 2 platforms for pickup and dropoff\n if (level.platforms.length < 2) {\n console.error(`[Chopper] Level ${currentLevel} needs at least 2 platforms`);\n gameOver = true;\n return false;\n }\n\n // Select first random route (pickup and dropoff)\n // Do this first so we can avoid starting on pickup platform\n pickupPlatformIndex = Math.floor(Math.random() * level.platforms.length);\n do {\n dropoffPlatformIndex = Math.floor(Math.random() * level.platforms.length);\n } while (dropoffPlatformIndex === pickupPlatformIndex);\n\n // Find a start platform (not the pickup or dropoff)\n let startIndex = 0;\n for (let i = 0; i < level.platforms.length; i++) {\n if (i !== pickupPlatformIndex && i !== dropoffPlatformIndex) {\n startIndex = i;\n break;\n }\n }\n const startPlatform = level.platforms[startIndex];\n\n // Reset rig position - start ON the neutral platform\n rigX = startPlatform.x + Math.floor(startPlatform.width / 2);\n rigY = startPlatform.y - 4; // Just above platform\n rigVX = 0;\n rigVY = 0;\n rigAngle = 0;\n\n // Tutorial and safety\n tutorialCountdown = 80; // ~4 seconds (longer to read controls)\n invincibleFrames = 100; // ~5 seconds\n\n // Reset passenger and rope\n hasPassenger = false;\n passengerX = rigX;\n passengerY = rigY + ROPE_MIN_LENGTH;\n passengerVX = 0;\n passengerVY = 0;\n passengerGraceFrames = 0;\n currentRopeLength = ROPE_MIN_LENGTH;\n doorAnimation = 30; // Initial door animation\n\n // Reset effects\n particles = [];\n popups = [];\n screenShake = 0;\n deliveringAnimation = 0;\n\n // Reset time\n timeRemaining = level.timeLimit;\n deliveriesComplete = 0;\n\n levelComplete = false;\n\n return true;\n }\n\n // FLAP! - The core mechanic. Must be RESPONSIVE!\n function doFlap() {\n if (flapCooldown > 0) return;\n\n rigVY = -FLAP_POWER; // Instant upward velocity\n flapCooldown = 3; // VERY short cooldown! (~0.15s at 50ms updates)\n flapAnimation = 4;\n\n // Flap effects - subtle particles, no screen shake\n spawnParticles(particles, rigX, rigY + 2, 2, '\\x1b[93m', ['·', '∘']);\n }\n\n // Helper wrappers for effect functions (pass arrays)\n const spawn = (x: number, y: number, count: number, color: string, chars?: string[]) =>\n spawnParticles(particles, x, y, count, color, chars);\n const firework = (x: number, y: number, intensity?: number) =>\n spawnFirework(particles, x, y, intensity);\n const popup = (x: number, y: number, text: string, color?: string) =>\n addPopup(popups, x, y, text, color);\n const sparkleTrail = (x: number, y: number, count?: number, color?: string) =>\n spawnSparkleTrail(particles, x, y, count, color);\n const splash = (x: number, waterY: number, intensity?: number) =>\n spawnSplash(particles, x, waterY, intensity);\n\n function checkPlatformCollision(x: number, y: number): { platform: Platform; index: number } | null {\n const level = levels[currentLevel];\n for (let i = 0; i < level.platforms.length; i++) {\n const plat = level.platforms[i];\n // Check if position is on top of platform\n if (x >= plat.x && x < plat.x + plat.width &&\n y >= plat.y - 1 && y <= plat.y) {\n return { platform: plat, index: i };\n }\n }\n return null;\n }\n\n function checkWaterCollision(y: number): boolean {\n const level = levels[currentLevel];\n return y >= level.waterLevel;\n }\n\n function handleDelivery() {\n deliveriesComplete++;\n const timeBonus = Math.floor(timeRemaining * 2);\n const basePoints = 100;\n const points = basePoints + timeBonus;\n score += points;\n\n hasPassenger = false;\n\n // === EPIC DELIVERY CELEBRATION ===\n\n // Screen shake for impact!\n screenShake = 8;\n\n // Main firework at delivery location\n firework(passengerX, passengerY, 1.5);\n\n // Secondary bursts nearby (using tracked timeouts)\n const px = passengerX;\n const py = passengerY;\n scheduleTimeout(() => firework(px - 4, py - 2, 0.8), 50);\n scheduleTimeout(() => firework(px + 4, py - 2, 0.8), 100);\n\n // Points popup with style\n popup(passengerX - 2, passengerY - 3, `+${points}`, '\\x1b[1;93m');\n\n // Random encouraging message\n const msg = getRandomDeliveryMessage();\n popup(passengerX - Math.floor(msg.length / 2), passengerY - 5, msg, '\\x1b[1;92m');\n\n // Advance tutorial step after delivery\n if (tutorialMode) {\n if (tutorialLevelIndex === 1 && tutorialStep === 2) {\n // FIRST DELIVERY complete -> advance to level complete\n tutorialStep = 3;\n tutorialPromptTimer = 0;\n } else if (tutorialLevelIndex === 2 && tutorialStep === 3) {\n // ROPE MASTER delivery -> full tutorial complete\n tutorialStep = 4;\n tutorialPromptTimer = 0;\n }\n }\n\n // Streak indicator\n if (deliveriesComplete > 1) {\n const streakMsg = `${deliveriesComplete}x COMBO!`;\n popup(passengerX - Math.floor(streakMsg.length / 2), passengerY - 7, streakMsg, '\\x1b[1;95m');\n }\n\n // Rising sparkle trail\n sparkleTrail(passengerX, passengerY);\n\n // Check if level complete\n if (deliveriesComplete >= totalDeliveries) {\n levelComplete = true;\n levelCompleteAnimation = 80; // ~4 seconds of celebration\n screenShake = 12; // Bigger shake for level complete\n\n // MASSIVE celebration - fireworks everywhere!\n for (let i = 0; i < 8; i++) {\n const delay = i * 80;\n scheduleTimeout(() => {\n if (levelComplete) {\n const fx = 8 + Math.random() * (screenWidth - 16);\n const fy = 3 + Math.random() * (screenHeight * 0.4);\n firework(fx, fy, 1.2);\n }\n }, delay);\n }\n\n popup(screenWidth / 2 - 8, screenHeight / 2 - 2, '★ LEVEL CLEAR! ★', '\\x1b[1;92m');\n } else {\n // All doors go inactive, then new package appears\n pickupPlatformIndex = -1;\n dropoffPlatformIndex = -1;\n newPackageDelay = 40; // Slightly longer to enjoy the effects\n\n // Big \"DELIVERED\" with flair\n popup(screenWidth / 2 - 5, screenHeight / 2, '◆ DELIVERED ◆', '\\x1b[1;92m');\n }\n }\n\n function update() {\n if (!gameStarted || gameOver || paused) return;\n\n // Handle level complete celebration animation\n if (levelComplete) {\n // Continue updating particles during celebration\n updateParticles(particles);\n updatePopups(popups);\n // Spawn periodic celebration particles\n if (levelCompleteAnimation > 0) {\n levelCompleteAnimation--;\n if (levelCompleteAnimation % 8 === 0) {\n // Firework bursts at random positions\n const burstX = 5 + Math.random() * (screenWidth - 10);\n const burstY = 2 + Math.random() * (screenHeight * 0.4);\n spawn(\n burstX,\n burstY,\n 5,\n ['\\x1b[93m', '\\x1b[92m', '\\x1b[96m', '\\x1b[95m', '\\x1b[91m'][Math.floor(Math.random() * 5)],\n ['★', '✦', '◆', '●', '✶', '✴']\n );\n }\n }\n return;\n }\n\n const level = tutorialMode ? TUTORIAL_LEVELS[tutorialLevelIndex] : levels[currentLevel];\n\n // Tutorial step progression - different steps for each tutorial level\n if (tutorialMode) {\n if (tutorialLevelIndex === 0) {\n // FLIGHT SCHOOL - just learn to fly and steer\n switch (tutorialStep) {\n case 0: // Wait for player to flap and go airborne\n if (rigY < level.platforms[0].y - 6 && rigVY < 0) {\n tutorialStep = 1;\n popup(rigX, rigY - 2, 'NICE!', '\\x1b[1;93m');\n }\n break;\n case 1: // Wait for player to steer\n if (Math.abs(rigVX) > 0.3) {\n tutorialStep = 2;\n popup(rigX, rigY - 2, 'GOOD!', '\\x1b[1;93m');\n }\n break;\n case 2: // Wait for player to reach the right platform area\n if (rigX > level.platforms[1].x && rigX < level.platforms[1].x + level.platforms[1].width) {\n tutorialStep = 3;\n popup(rigX, rigY - 2, 'PERFECT!', '\\x1b[1;92m');\n }\n break;\n case 3: // Level complete - auto-advance after celebration\n tutorialPromptTimer++;\n if (tutorialPromptTimer > 80) {\n levelComplete = true;\n levelCompleteAnimation = 50;\n screenShake = 6;\n firework(screenWidth / 2, screenHeight / 2, 1.2);\n }\n break;\n }\n } else if (tutorialLevelIndex === 1) {\n // FIRST DELIVERY - learn pickup and delivery\n switch (tutorialStep) {\n case 0: // Wait for player to fly up\n if (rigY < level.platforms[0].y - 4) {\n tutorialStep = 1;\n popup(rigX, rigY - 2, 'GO!', '\\x1b[1;93m');\n }\n break;\n case 1: // Wait for pickup\n if (hasPassenger) {\n tutorialStep = 2;\n popup(rigX, rigY - 2, 'GOT IT!', '\\x1b[1;93m');\n }\n break;\n case 2: // Wait for delivery (handled in handleDelivery)\n break;\n case 3: // Level complete\n if (!levelComplete) {\n levelComplete = true;\n levelCompleteAnimation = 50;\n screenShake = 6;\n firework(screenWidth / 2, screenHeight / 2, 1.2);\n }\n break;\n }\n } else if (tutorialLevelIndex === 2) {\n // ROPE MASTER - learn rope controls with height difference\n switch (tutorialStep) {\n case 0: // Show initial info about rope (auto-advance)\n tutorialPromptTimer++;\n if (tutorialPromptTimer > 80) {\n tutorialStep = 1;\n tutorialPromptTimer = 0;\n }\n break;\n case 1: // Wait for player to use SPACE (extend rope)\n if (inputExtendRope || currentRopeLength > ROPE_MIN_LENGTH + 1) {\n tutorialStep = 2;\n popup(rigX, rigY - 2, 'GOOD!', '\\x1b[1;93m');\n }\n break;\n case 2: // Wait for player to use SHIFT (contract rope)\n if (inputContractRope) {\n tutorialStep = 3;\n popup(rigX, rigY - 2, 'NICE!', '\\x1b[1;93m');\n }\n break;\n case 3: // Wait for delivery (handled in handleDelivery)\n break;\n case 4: // Full tutorial complete!\n if (!levelComplete) {\n levelComplete = true;\n levelCompleteAnimation = 80;\n screenShake = 10;\n // Big celebration!\n firework(screenWidth / 2, screenHeight / 2, 2);\n firework(screenWidth / 3, screenHeight / 3, 1.5);\n firework(screenWidth * 2 / 3, screenHeight / 3, 1.5);\n }\n break;\n }\n }\n }\n\n // Handle crash animation countdown\n if (crashAnimation > 0) {\n crashAnimation--;\n // Keep updating particles during crash (heavier gravity for dramatic fall)\n updateParticles(particles, 1.5);\n updatePopups(popups);\n if (screenShake > 0) screenShake--;\n // When crash animation ends, show game over\n if (crashAnimation === 0) {\n gameOver = true;\n }\n return;\n }\n\n // Update timers\n if (tutorialCountdown > 0) tutorialCountdown--;\n if (invincibleFrames > 0) invincibleFrames--;\n\n // Handle delivering animation - package is on dropoff, building anticipation!\n if (deliveringAnimation > 0) {\n deliveringAnimation--;\n\n // Keep the passenger still on the platform during animation\n if (hasPassenger) {\n passengerVX *= 0.5;\n passengerVY = 0;\n }\n\n // Building anticipation effects - get more intense as we approach completion\n const progress = 1 - (deliveringAnimation / 40); // 0 to 1\n\n // Sparkle particles - more frequent as we progress\n const spawnRate = deliveringAnimation > 30 ? 10 : deliveringAnimation > 15 ? 6 : 3;\n if (deliveringAnimation % spawnRate === 0 && hasPassenger) {\n // Spiral upward effect\n const angle = (40 - deliveringAnimation) * 0.5;\n const radius = 1 + progress * 2;\n particles.push({\n x: passengerX + Math.cos(angle) * radius,\n y: passengerY - 1,\n char: ['✦', '✧', '★', '◇'][Math.floor(Math.random() * 4)],\n color: progress > 0.7 ? '\\x1b[1;92m' : '\\x1b[1;93m',\n vx: Math.cos(angle) * 0.1,\n vy: -0.2 - progress * 0.2,\n life: 12 + Math.floor(Math.random() * 8),\n });\n }\n\n // Charging glow effect at key moments\n if (deliveringAnimation === 30 && hasPassenger) {\n popup(passengerX - 4, passengerY - 3, 'CHARGING...', '\\x1b[2;93m');\n }\n if (deliveringAnimation === 15 && hasPassenger) {\n popup(passengerX - 3, passengerY - 4, 'ALMOST...', '\\x1b[1;93m');\n // Pre-burst sparkles\n for (let i = 0; i < 4; i++) {\n const a = (Math.PI * 2 * i) / 4;\n particles.push({\n x: passengerX + Math.cos(a) * 2,\n y: passengerY + Math.sin(a) * 1.5,\n char: '✧',\n color: '\\x1b[1;97m',\n vx: -Math.cos(a) * 0.15,\n vy: -Math.sin(a) * 0.15,\n life: 15,\n });\n }\n }\n\n // When animation ends, actually complete the delivery with big celebration!\n if (deliveringAnimation === 0 && hasPassenger) {\n handleDelivery();\n }\n }\n\n // New package spawn animation\n if (newPackageDelay > 0) {\n newPackageDelay--;\n if (newPackageDelay === 0) {\n // Now spawn the new package with animation\n selectNewRoute();\n popup(screenWidth / 2 - 5, screenHeight / 2, 'NEW PACKAGE!', '\\x1b[1;93m');\n }\n }\n\n // Update time (don't count during tutorial)\n if (tutorialCountdown === 0) {\n timeRemaining -= 1 / 20;\n if (timeRemaining <= 0) {\n gameOver = true;\n popup(rigX, rigY - 2, 'TIME UP!', '\\x1b[91m');\n return;\n }\n }\n\n // Update flap cooldown and animation\n if (flapCooldown > 0) flapCooldown--;\n if (flapAnimation > 0) flapAnimation--;\n rotorFrame = (rotorFrame + 1) % 6;\n\n // Update rope length - SPACE extends, SHIFT fast retracts, auto-retracts otherwise\n if (inputExtendRope && !inputContractRope) {\n currentRopeLength = Math.min(ROPE_MAX_LENGTH, currentRopeLength + ROPE_EXTEND_SPEED);\n } else if (inputContractRope) {\n currentRopeLength = Math.max(ROPE_MIN_LENGTH, currentRopeLength - ROPE_FAST_RETRACT_SPEED);\n } else {\n currentRopeLength = Math.max(ROPE_MIN_LENGTH, currentRopeLength - ROPE_RETRACT_SPEED);\n }\n\n // Apply horizontal input\n if (inputLeft) {\n rigVX -= THRUST_POWER;\n rigAngle = Math.max(-15, rigAngle - 2);\n }\n if (inputRight) {\n rigVX += THRUST_POWER;\n rigAngle = Math.min(15, rigAngle + 2);\n }\n\n // Return angle to neutral\n if (!inputLeft && !inputRight) {\n rigAngle *= 0.9;\n }\n\n // Apply gravity - always pulling down!\n rigVY += GRAVITY;\n\n // Apply drag\n rigVX *= AIR_DRAG_X;\n rigVY *= AIR_DRAG_Y;\n\n // Clamp velocity\n rigVX = Math.max(-MAX_VELOCITY_X, Math.min(MAX_VELOCITY_X, rigVX));\n rigVY = Math.max(-MAX_VELOCITY_Y, Math.min(MAX_VELOCITY_Y, rigVY));\n\n // Move rig\n rigX += rigVX;\n rigY += rigVY;\n\n // Screen bounds - clamp to edges, no wrapping\n rigX = Math.max(2, Math.min(screenWidth - 4, rigX));\n rigY = Math.max(1, rigY); // Can't go above screen\n\n // Check platform collision for rig\n const rigPlatformResult = checkPlatformCollision(rigX, rigY + 2);\n if (rigPlatformResult && rigVY > 0) {\n const { platform: rigPlatform, index: rigPlatformIndex } = rigPlatformResult;\n const impactVelocity = rigVY;\n rigY = rigPlatform.y - 3;\n rigVY = -rigVY * 0.3; // Bounce\n\n // Only shake/particles on significant impacts\n if (impactVelocity > 0.3) {\n screenShake = Math.min(5, Math.floor(impactVelocity * 4));\n spawn(rigX, rigY + 2, Math.floor(impactVelocity * 5), '\\x1b[93m', ['·', '•']);\n }\n\n // AUTO-PICKUP: If we land on current pickup platform and don't have passenger\n // Don't pickup during tutorial - give player time to lift off first!\n if (rigPlatformIndex === pickupPlatformIndex && !hasPassenger && tutorialCountdown === 0) {\n hasPassenger = true;\n passengerX = rigX;\n passengerY = rigY + 2; // Start right at rig bottom\n passengerVX = rigVX * 0.5;\n passengerVY = rigVY * 0.5; // Inherit some rig momentum\n passengerGraceFrames = 20; // Grace period before water kills\n spawn(rigX, rigY + 2, 6, themeColor, ['◇', '✦']);\n popup(rigX - 3, rigY - 1, 'GOT IT!', '\\x1b[1;93m');\n\n // Show dropoff location with popup and animation\n doorAnimation = 30;\n const dropoffPlat = level.platforms[dropoffPlatformIndex];\n const dropX = dropoffPlat.x + Math.floor(dropoffPlat.width / 2);\n const dropY = dropoffPlat.y - 5; // Above the hut\n popup(dropX - 4, dropY, 'DROP HERE!', '\\x1b[1;93m');\n spawn(dropX, dropY + 2, 4, '\\x1b[93m', ['▽', '◇', '✦']);\n }\n }\n\n // Check water collision for rig\n if (checkWaterCollision(rigY + 2)) {\n if (invincibleFrames > 0) {\n // Bounce off water during invincibility\n rigY = level.waterLevel - 4;\n rigVY = -0.4;\n screenShake = 3;\n popup(rigX, rigY, 'SPLASH!', '\\x1b[96m');\n } else {\n // CRASH - fell in water! Epic crash effect\n crashAnimation = 35; // ~1.75 seconds of crash animation\n screenShake = 15;\n // Big splash\n splash(rigX, level.waterLevel, 1.25);\n // Explosion particles\n spawn(rigX, rigY, 12, '\\x1b[91m', ['✗', '×', '▓', '░', '!', '*']);\n popup(rigX - 4, rigY - 4, '💀 SPLASH! 💀', '\\x1b[1;91m');\n return;\n }\n }\n\n // Passenger physics\n if (hasPassenger) {\n // Decrement grace period\n if (passengerGraceFrames > 0) passengerGraceFrames--;\n\n // Apply gravity to passenger\n passengerVY += GRAVITY * 1.2;\n\n // Rope constraint - uses current (dynamic) rope length\n const dx = passengerX - rigX;\n const dy = passengerY - (rigY + 2);\n const dist = Math.sqrt(dx * dx + dy * dy);\n\n // Only apply rope constraint if distance is valid (avoid division by zero)\n if (dist > 0.01 && dist > currentRopeLength) {\n const nx = dx / dist;\n const ny = dy / dist;\n const stretch = dist - currentRopeLength;\n\n // Pull passenger toward rig\n passengerVX -= nx * stretch * 0.1;\n passengerVY -= ny * stretch * 0.1;\n\n // Also affect rig (lighter effect)\n rigVX += nx * stretch * 0.03;\n rigVY += ny * stretch * 0.03;\n }\n\n // Damping\n passengerVX *= 0.95;\n passengerVY *= 0.95;\n\n // Clamp velocities to prevent runaway values\n passengerVX = Math.max(-2, Math.min(2, passengerVX));\n passengerVY = Math.max(-2, Math.min(2, passengerVY));\n\n // Move passenger\n passengerX += passengerVX;\n passengerY += passengerVY;\n\n // Screen bounds for passenger - clamp to edges\n passengerX = Math.max(1, Math.min(screenWidth - 2, passengerX));\n\n // Platform collision for passenger\n const passPlatformResult = checkPlatformCollision(passengerX, passengerY);\n if (passPlatformResult && passengerVY > 0) {\n const { platform: passPlatform, index: passPlatformIndex } = passPlatformResult;\n passengerY = passPlatform.y - 1;\n passengerVY = -passengerVY * 0.2;\n passengerVX *= 0.8;\n\n // Check if this is the current dropoff platform - start delivery animation!\n if (passPlatformIndex === dropoffPlatformIndex && Math.abs(passengerVY) < 0.3 && deliveringAnimation === 0) {\n // Start delivering animation - player sees the package land\n deliveringAnimation = 40; // ~2 seconds to watch the delivery\n spawn(passengerX, passengerY - 1, 8, '\\x1b[1;93m', ['★', '✦', '◆']);\n popup(passengerX - 4, passengerY - 3, 'DROPPING!', '\\x1b[1;93m');\n }\n }\n\n // Water collision for passenger (skip during grace period)\n if (checkWaterCollision(passengerY) && passengerGraceFrames === 0) {\n hasPassenger = false;\n crashAnimation = 35; // ~1.75 seconds of crash animation\n screenShake = 12;\n // Dramatic splash for package\n splash(passengerX, level.waterLevel, 1);\n popup(passengerX - 5, passengerY - 3, '💀 PACKAGE LOST! 💀', '\\x1b[1;91m');\n return;\n }\n }\n\n // Update particles and popups\n updateParticles(particles);\n updatePopups(popups);\n\n // Update effects\n if (screenShake > 0) screenShake--;\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg = `Need ${MIN_COLS}×${MIN_ROWS}, have ${cols}×${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY};${Math.max(1, centerX - msg.length / 2)}H${themeColor}${msg}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Adapt viewport to terminal size - wider map!\n screenWidth = Math.min(cols - 4, 70);\n screenHeight = Math.min(rows - 8, 18);\n\n const gameLeft = Math.max(2, Math.floor((cols - screenWidth - 2) / 2));\n const gameTop = getVerticalAnchor(rows, screenHeight + 2, {\n headerRows: 4,\n footerRows: 2,\n minTop: 4,\n });\n\n // Apply screen shake\n const shakeX = screenShake > 0 ? Math.floor(Math.random() * 3) - 1 : 0;\n const shakeY = screenShake > 0 ? Math.floor(Math.random() * 2) : 0;\n const displayLeft = gameLeft + shakeX;\n const displayTop = gameTop + shakeY;\n\n // Title area - show tutorial during countdown, otherwise show title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n if (gameStarted && tutorialCountdown > 0 && !paused && !gameOver && !levelComplete) {\n // Show controls in title area during tutorial\n const controls1 = '↑/W = FLAP ←/→ = STEER SPACE/SHIFT = ROPE';\n const controls2 = 'Pickup the yellow package, deliver to the ▼ marker!';\n const ctrl1X = Math.floor((cols - controls1.length) / 2);\n const ctrl2X = Math.floor((cols - controls2.length) / 2);\n const fade = tutorialCountdown < 20 ? '\\x1b[2m' : '\\x1b[1m';\n output += `\\x1b[1;${ctrl1X}H${fade}${themeColor}${controls1}\\x1b[0m`;\n output += `\\x1b[2;${ctrl2X}H${fade}${themeColor}${controls2}\\x1b[0m`;\n const countdownBar = '▓'.repeat(Math.ceil(tutorialCountdown / 10)) + '░'.repeat(8 - Math.ceil(tutorialCountdown / 10));\n const barX = Math.floor((cols - countdownBar.length) / 2);\n output += `\\x1b[3;${barX}H\\x1b[2m${themeColor}${countdownBar}\\x1b[0m`;\n } else {\n // Normal title display\n output += `\\x1b[1;${titleX}H`;\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n const subtitleX = Math.floor((cols - subtitle.length) / 2);\n output += `\\x1b[3;${subtitleX}H\\x1b[2m${themeColor}${subtitle}\\x1b[0m`;\n }\n\n // Game border\n output += `\\x1b[${displayTop};${displayLeft}H${themeColor}╔${'═'.repeat(screenWidth)}╗\\x1b[0m`;\n for (let y = 0; y < screenHeight; y++) {\n output += `\\x1b[${displayTop + 1 + y};${displayLeft}H${themeColor}║\\x1b[0m`;\n output += `\\x1b[${displayTop + 1 + y};${displayLeft + screenWidth + 1}H${themeColor}║\\x1b[0m`;\n }\n output += `\\x1b[${displayTop + screenHeight + 1};${displayLeft}H${themeColor}╚${'═'.repeat(screenWidth)}╝\\x1b[0m`;\n\n if (paused) {\n const pauseMsg = '══ PAUSED ══';\n const pauseCenterX = gameLeft + Math.floor(screenWidth / 2) + 1;\n const pauseY = gameTop + Math.floor(screenHeight / 2) - 4;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[1m${themeColor}${pauseMsg}\\x1b[0m`;\n\n // Use shared menu rendering\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted && showingModeSelect) {\n // Mode selection screen with arrow key navigation\n const modeCenterX = gameLeft + Math.floor(screenWidth / 2) + 1;\n const modeStartY = gameTop + Math.floor(screenHeight / 2) - 2;\n\n const selectMsg = 'SELECT MODE';\n const selectX = modeCenterX - Math.floor(selectMsg.length / 2);\n output += `\\x1b[${modeStartY};${selectX}H\\x1b[1m${themeColor}${selectMsg}\\x1b[0m`;\n\n // Use shared menu rendering\n output += renderSimpleMenu(MODE_SELECT_ITEMS, menuSelection, {\n centerX: modeCenterX,\n startY: modeStartY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ to select ENTER to confirm';\n const navHintX = modeCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${modeStartY + 5};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n\n const hint = 'New players: Try the tutorial first!';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${modeStartY + 7};${hintX}H\\x1b[2;3m${themeColor}${hint}\\x1b[0m`;\n } else if (!gameStarted) {\n // Legacy start screen (shouldn't be reached now)\n const startMsg = '[ PRESS ANY KEY TO START ]';\n const startX = gameLeft + Math.floor((screenWidth - startMsg.length) / 2) + 1;\n const startY = gameTop + Math.floor(screenHeight / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = '↑/W = FLAP ←/→ = STEER SPACE/SHIFT = ROPE';\n const ctrlX = Math.floor((cols - controls.length) / 2);\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n\n const hook = 'Pickup yellow packages, deliver to markers. Avoid the water!';\n const hookX = Math.floor((cols - hook.length) / 2);\n output += `\\x1b[${startY + 4};${hookX}H\\x1b[2;3m${themeColor}${hook}\\x1b[0m`;\n } else if (levelComplete) {\n const msgY = gameTop + Math.floor(screenHeight / 2) - 3;\n\n if (tutorialMode) {\n const tutLevel = TUTORIAL_LEVELS[tutorialLevelIndex];\n const isLastLesson = tutorialLevelIndex >= TUTORIAL_LEVELS.length - 1;\n\n if (isLastLesson) {\n // Final tutorial complete screen\n const completeMsg = '★ TUTORIAL COMPLETE! ★';\n const msgX = gameLeft + Math.floor((screenWidth - completeMsg.length) / 2) + 1;\n output += `\\x1b[${msgY};${msgX}H\\x1b[1;92m${completeMsg}\\x1b[0m`;\n\n const congratsMsg = 'You mastered the controls!';\n const congratsX = gameLeft + Math.floor((screenWidth - congratsMsg.length) / 2) + 1;\n output += `\\x1b[${msgY + 2};${congratsX}H${themeColor}${congratsMsg}\\x1b[0m`;\n\n const controlsMsg = '↑/W=FLAP ←/→=STEER SPACE/SHIFT=ROPE';\n const controlsX = gameLeft + Math.floor((screenWidth - controlsMsg.length) / 2) + 1;\n output += `\\x1b[${msgY + 4};${controlsX}H\\x1b[2m${themeColor}${controlsMsg}\\x1b[0m`;\n\n const nextHint = '[ SPACE ] START GAME [ Q ] QUIT';\n const nextX = gameLeft + Math.floor((screenWidth - nextHint.length) / 2) + 1;\n output += `\\x1b[${msgY + 6};${nextX}H${themeColor}${nextHint}\\x1b[0m`;\n } else {\n // Lesson complete - more lessons to go\n const completeMsg = `★ ${tutLevel.name} COMPLETE! ★`;\n const msgX = gameLeft + Math.floor((screenWidth - completeMsg.length) / 2) + 1;\n output += `\\x1b[${msgY};${msgX}H\\x1b[1;92m${completeMsg}\\x1b[0m`;\n\n const nextLevelName = TUTORIAL_LEVELS[tutorialLevelIndex + 1]?.name || 'NEXT';\n const nextLessonMsg = `Next: ${nextLevelName}`;\n const nextLessonX = gameLeft + Math.floor((screenWidth - nextLessonMsg.length) / 2) + 1;\n output += `\\x1b[${msgY + 2};${nextLessonX}H${themeColor}${nextLessonMsg}\\x1b[0m`;\n\n const progressMsg = `Lesson ${tutorialLevelIndex + 1} of ${TUTORIAL_LEVELS.length}`;\n const progressX = gameLeft + Math.floor((screenWidth - progressMsg.length) / 2) + 1;\n output += `\\x1b[${msgY + 4};${progressX}H\\x1b[2m${themeColor}${progressMsg}\\x1b[0m`;\n\n const nextHint = '[ SPACE ] NEXT LESSON [ Q ] QUIT';\n const nextX = gameLeft + Math.floor((screenWidth - nextHint.length) / 2) + 1;\n output += `\\x1b[${msgY + 6};${nextX}H${themeColor}${nextHint}\\x1b[0m`;\n }\n } else {\n // Normal level complete screen\n const level = levels[currentLevel];\n const timeBonus = timeRemaining / level.timeLimit;\n const stars = timeRemaining >= level.parTime ? 3 : timeBonus > 0.3 ? 2 : 1;\n\n const completeMsg = '★ LEVEL COMPLETE! ★';\n const msgX = gameLeft + Math.floor((screenWidth - completeMsg.length) / 2) + 1;\n output += `\\x1b[${msgY};${msgX}H\\x1b[1;92m${completeMsg}\\x1b[0m`;\n\n const scoreMsg = `SCORE: ${score}`;\n const scoreX = gameLeft + Math.floor((screenWidth - scoreMsg.length) / 2) + 1;\n output += `\\x1b[${msgY + 2};${scoreX}H${themeColor}${scoreMsg}\\x1b[0m`;\n\n const starDisplay = '★'.repeat(stars) + '☆'.repeat(3 - stars);\n const starX = gameLeft + Math.floor((screenWidth - starDisplay.length) / 2) + 1;\n output += `\\x1b[${msgY + 3};${starX}H\\x1b[1;93m${starDisplay}\\x1b[0m`;\n\n const nextHint = currentLevel < levels.length - 1 ? '[ SPACE ] NEXT [ Q ] QUIT' : '[ R ] REPLAY [ Q ] QUIT';\n const nextX = gameLeft + Math.floor((screenWidth - nextHint.length) / 2) + 1;\n output += `\\x1b[${msgY + 5};${nextX}H\\x1b[2m${themeColor}${nextHint}\\x1b[0m`;\n }\n } else if (gameOver) {\n const overMsg = '══ GAME OVER ══';\n const overX = gameLeft + Math.floor((screenWidth - overMsg.length) / 2) + 1;\n const overY = gameTop + Math.floor(screenHeight / 2) - 1;\n output += `\\x1b[${overY};${overX}H\\x1b[1;91m${overMsg}\\x1b[0m`;\n\n const scoreMsg = `SCORE: ${score}`;\n const scoreX = gameLeft + Math.floor((screenWidth - scoreMsg.length) / 2) + 1;\n output += `\\x1b[${overY + 2};${scoreX}H${themeColor}${scoreMsg}\\x1b[0m`;\n\n const restart = '[ R ] RETRY [ Q ] QUIT';\n const restartX = gameLeft + Math.floor((screenWidth - restart.length) / 2) + 1;\n output += `\\x1b[${overY + 4};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n } else {\n const level = levels[currentLevel];\n\n // Draw water - fill from waterLevel to bottom of screen\n for (let x = 0; x < screenWidth; x++) {\n // First water line - wavy surface\n const waterChar1 = (x + glitchFrame) % 4 === 0 ? '≈' : '~';\n output += `\\x1b[${displayTop + 1 + level.waterLevel};${displayLeft + 1 + x}H\\x1b[96m${waterChar1}\\x1b[0m`;\n // Fill remaining rows with darker water\n for (let wy = level.waterLevel + 1; wy < screenHeight; wy++) {\n const waterChar = (x + wy + glitchFrame) % 3 === 0 ? '≈' : '~';\n const waterColor = wy === level.waterLevel + 1 ? '\\x1b[36m' : '\\x1b[34m'; // Gets darker\n output += `\\x1b[${displayTop + 1 + wy};${displayLeft + 1 + x}H${waterColor}${waterChar}\\x1b[0m`;\n }\n }\n\n // Draw platforms with doors\n for (let platIndex = 0; platIndex < level.platforms.length; platIndex++) {\n const plat = level.platforms[platIndex];\n const isCurrentPickup = platIndex === pickupPlatformIndex;\n const isCurrentDropoff = platIndex === dropoffPlatformIndex;\n\n // Platform is always neutral brown/earth color\n const platColor = '\\x1b[38;5;94m'; // Brown/earth tone\n\n // Draw platform surface\n for (let px = 0; px < plat.width; px++) {\n const screenX = plat.x + px;\n const screenY = plat.y;\n if (screenX >= 0 && screenX < screenWidth && screenY >= 0 && screenY < screenHeight) {\n output += `\\x1b[${displayTop + 1 + screenY};${displayLeft + 1 + screenX}H${platColor}▀\\x1b[0m`;\n // Thick platform - add bottom\n if (screenY + 1 < screenHeight && screenY + 1 < level.waterLevel) {\n output += `\\x1b[${displayTop + 2 + screenY};${displayLeft + 1 + screenX}H${platColor}█\\x1b[0m`;\n }\n }\n }\n\n // Draw door/hut on each platform (5 wide, 3 tall solid block)\n const doorWidth = 5;\n const doorX = plat.x + Math.floor(plat.width / 2) - Math.floor(doorWidth / 2);\n const doorY1 = plat.y - 3; // Top row\n const doorY2 = plat.y - 2; // Middle row\n const doorY3 = plat.y - 1; // Bottom row (connects to platform)\n\n // All doors are always dim monochrome - adapts to terminal theme\n const doorColor = getSubtleBackgroundColor();\n\n // Draw 5x3 hut block (solid, always same color)\n const hutChars = '█████';\n if (doorX >= 0 && doorX + doorWidth - 1 < screenWidth && doorY1 >= 0 && doorY1 < screenHeight) {\n output += `\\x1b[${displayTop + 1 + doorY1};${displayLeft + 1 + doorX}H${doorColor}${hutChars}\\x1b[0m`;\n }\n if (doorX >= 0 && doorX + doorWidth - 1 < screenWidth && doorY2 >= 0 && doorY2 < screenHeight) {\n output += `\\x1b[${displayTop + 1 + doorY2};${displayLeft + 1 + doorX}H${doorColor}${hutChars}\\x1b[0m`;\n }\n if (doorX >= 0 && doorX + doorWidth - 1 < screenWidth && doorY3 >= 0 && doorY3 < screenHeight) {\n output += `\\x1b[${displayTop + 1 + doorY3};${displayLeft + 1 + doorX}H${doorColor}${hutChars}\\x1b[0m`;\n }\n\n // Draw yellow package on floor at pickup (the indicator!)\n if (isCurrentPickup && !hasPassenger) {\n const packageX = doorX + Math.floor(doorWidth / 2);\n const packageY = plat.y - 1; // On the platform, in front of door\n if (packageX >= 0 && packageX < screenWidth && packageY >= 0 && packageY < screenHeight) {\n const pkgChar = doorAnimation > 0 && doorAnimation % 6 < 3 ? '▪' : '█';\n output += `\\x1b[${displayTop + 1 + packageY};${displayLeft + 1 + packageX}H\\x1b[1;93m${pkgChar}\\x1b[0m`;\n }\n }\n\n // Dropoff indicator - arrow above the door pointing down\n if (isCurrentDropoff && hasPassenger) {\n const markerX = doorX + Math.floor(doorWidth / 2);\n const markerY = doorY1 - 1; // Above the door\n if (markerX >= 0 && markerX < screenWidth && markerY >= 0 && markerY < screenHeight) {\n const marker = doorAnimation > 0 && doorAnimation % 8 < 4 ? '▼' : '▽';\n output += `\\x1b[${displayTop + 1 + markerY};${displayLeft + 1 + markerX}H\\x1b[1;93m${marker}\\x1b[0m`;\n }\n }\n }\n\n // Update door animation\n if (doorAnimation > 0) doorAnimation--;\n\n // Draw rope if carrying passenger\n if (hasPassenger) {\n const dx = passengerX - rigX;\n const dy = passengerY - (rigY + 2);\n const dist = Math.sqrt(dx * dx + dy * dy);\n const steps = Math.max(2, Math.floor(dist));\n\n for (let i = 1; i < steps; i++) {\n const t = i / steps;\n const rx = Math.floor(rigX + dx * t);\n const ry = Math.floor((rigY + 2) + dy * t);\n if (rx >= 0 && rx < screenWidth && ry >= 0 && ry < screenHeight) {\n output += `\\x1b[${displayTop + 1 + ry};${displayLeft + 1 + rx}H\\x1b[2m${themeColor}│\\x1b[0m`;\n }\n }\n\n // Draw package (yellow box)\n const pScreenX = Math.floor(passengerX);\n const pScreenY = Math.floor(passengerY);\n if (pScreenX >= 0 && pScreenX < screenWidth && pScreenY >= 0 && pScreenY < screenHeight) {\n output += `\\x1b[${displayTop + 1 + pScreenY};${displayLeft + 1 + pScreenX}H\\x1b[1;93m█\\x1b[0m`;\n }\n }\n\n // Draw rig - SIMPLE BOXY HELICOPTER like UGH!\n const rigScreenX = Math.floor(rigX);\n const rigScreenY = Math.floor(rigY);\n if (rigScreenX >= 1 && rigScreenX < screenWidth - 3 && rigScreenY >= 1 && rigScreenY < screenHeight - 3) {\n // Blink if invincible\n const isBlinking = invincibleFrames > 0 && Math.floor(invincibleFrames / 4) % 2 === 0;\n const bodyColor = isBlinking ? '\\x1b[2m' + themeColor : '\\x1b[1m' + themeColor;\n\n // ROTOR - simple spinning blade, 3 chars\n const rotorFrames = ['─O─', '\\\\O/', '│O│', '/O\\\\'];\n const rotor = rotorFrames[Math.floor(rotorFrame / 1.5) % rotorFrames.length];\n output += `\\x1b[${displayTop + 1 + rigScreenY};${displayLeft + rigScreenX}H${bodyColor}${rotor}\\x1b[0m`;\n\n // BODY - simple box, 3 chars wide\n let body: string;\n if (flapAnimation > 0) {\n body = '[^]'; // Boost!\n } else if (rigAngle < -5) {\n body = '/o]'; // Tilting left\n } else if (rigAngle > 5) {\n body = '[o\\\\'; // Tilting right\n } else {\n body = '[o]'; // Centered caveman\n }\n output += `\\x1b[${displayTop + 2 + rigScreenY};${displayLeft + rigScreenX}H${bodyColor}${body}\\x1b[0m`;\n\n // SKIDS - landing gear\n output += `\\x1b[${displayTop + 3 + rigScreenY};${displayLeft + rigScreenX}H${bodyColor}└─┘\\x1b[0m`;\n }\n\n // Draw particles\n for (const p of particles) {\n const px = Math.floor(p.x);\n const py = Math.floor(p.y);\n if (px >= 0 && px < screenWidth && py >= 0 && py < screenHeight) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${displayTop + 1 + py};${displayLeft + 1 + px}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw popups\n for (const popup of popups) {\n const px = Math.floor(popup.x);\n const py = Math.floor(popup.y);\n if (px >= 0 && px < screenWidth - popup.text.length && py >= 0 && py < screenHeight) {\n const alpha = popup.frames > 15 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${displayTop + 1 + py};${displayLeft + 1 + px}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n\n // In-game tutorial prompt overlay at TOP of game area\n if (tutorialMode && !levelComplete) {\n const promptBright = Math.floor(Date.now() / 300) % 2 === 0 ? '\\x1b[1m' : '';\n let inGamePrompt = '';\n\n if (tutorialLevelIndex === 0) {\n switch (tutorialStep) {\n case 0: inGamePrompt = '▲ PRESS UP TO FLY ▲'; break;\n case 1: inGamePrompt = '◄ ► STEER LEFT/RIGHT'; break;\n case 2: inGamePrompt = '► FLY TO RIGHT PLATFORM ►'; break;\n }\n } else if (tutorialLevelIndex === 1) {\n switch (tutorialStep) {\n case 0: inGamePrompt = '▲ TAKE OFF! ▲'; break;\n case 1: inGamePrompt = '▼ LAND ON HUT TO PICKUP ▼'; break;\n case 2: inGamePrompt = '► DELIVER TO RIGHT HUT ►'; break;\n }\n } else if (tutorialLevelIndex === 2) {\n switch (tutorialStep) {\n case 0: inGamePrompt = '~ ROPE CONTROLS ~'; break;\n case 1: inGamePrompt = '[ SPACE ] = LOWER ROPE'; break;\n case 2: inGamePrompt = '[ SHIFT ] = RAISE ROPE'; break;\n case 3: inGamePrompt = '▲ DELIVER TO HIGH PLATFORM ▲'; break;\n }\n }\n\n if (inGamePrompt) {\n const promptX = displayLeft + Math.floor((screenWidth - inGamePrompt.length) / 2) + 1;\n const promptY = displayTop + 2; // Near top of game area\n // Draw a subtle background bar\n const bgBar = '─'.repeat(inGamePrompt.length + 4);\n output += `\\x1b[${promptY - 1};${promptX - 2}H\\x1b[2m${themeColor}${bgBar}\\x1b[0m`;\n output += `\\x1b[${promptY};${promptX}H${promptBright}\\x1b[1;93m${inGamePrompt}\\x1b[0m`;\n output += `\\x1b[${promptY + 1};${promptX - 2}H\\x1b[2m${themeColor}${bgBar}\\x1b[0m`;\n }\n }\n }\n\n // HUD\n if (gameStarted && !levelComplete && !gameOver && !paused) {\n const level = tutorialMode ? TUTORIAL_LEVELS[tutorialLevelIndex] : levels[currentLevel];\n const hudY = displayTop + screenHeight + 2;\n\n if (tutorialMode) {\n // Tutorial HUD - show level name and step-based prompts\n const tutorialTitle = `═══ ${level.name} (${tutorialLevelIndex + 1}/3) ═══`;\n const titleX = gameLeft + Math.floor((screenWidth - tutorialTitle.length) / 2) + 1;\n output += `\\x1b[${hudY};${titleX}H\\x1b[1;93m${tutorialTitle}\\x1b[0m`;\n\n // Tutorial step prompts with flashing effect - different for each level\n const promptBright = Math.floor(Date.now() / 300) % 2 === 0 ? '\\x1b[1m' : '\\x1b[2m';\n\n let tutorialHint = '';\n if (tutorialLevelIndex === 0) {\n // FLIGHT SCHOOL prompts\n switch (tutorialStep) {\n case 0:\n tutorialHint = '↑ Press UP or W to FLAP and fly!';\n break;\n case 1:\n tutorialHint = '← → Use arrow keys to STEER left/right';\n break;\n case 2:\n tutorialHint = '▶ Fly to the RIGHT platform!';\n break;\n case 3:\n tutorialHint = '★ GREAT! You can fly! ★';\n break;\n }\n } else if (tutorialLevelIndex === 1) {\n // FIRST DELIVERY prompts\n switch (tutorialStep) {\n case 0:\n tutorialHint = '↑ Take off and fly!';\n break;\n case 1:\n tutorialHint = '▼ Land on the LEFT hut to PICKUP package';\n break;\n case 2:\n tutorialHint = '▶ Deliver to the RIGHT hut!';\n break;\n case 3:\n tutorialHint = '★ Delivery complete! ★';\n break;\n }\n } else if (tutorialLevelIndex === 2) {\n // ROPE MASTER prompts\n switch (tutorialStep) {\n case 0:\n tutorialHint = 'You have a passenger! Learn rope controls...';\n break;\n case 1:\n tutorialHint = 'SPACE = Lower rope (hold to extend)';\n break;\n case 2:\n tutorialHint = 'SHIFT = Raise rope (hold to retract)';\n break;\n case 3:\n tutorialHint = '▶ Deliver to the HIGH platform on right!';\n break;\n case 4:\n tutorialHint = '★ TUTORIAL COMPLETE! ★';\n break;\n }\n }\n const hintX = gameLeft + Math.floor((screenWidth - tutorialHint.length) / 2) + 1;\n output += `\\x1b[${hudY + 1};${hintX}H${promptBright}${themeColor}${tutorialHint}\\x1b[0m`;\n\n // Progress indicator within level\n const maxSteps = tutorialLevelIndex === 2 ? 5 : 4;\n const progress = `Step ${Math.min(tutorialStep + 1, maxSteps)}/${maxSteps}`;\n const progressX = gameLeft + Math.floor((screenWidth - progress.length) / 2) + 1;\n output += `\\x1b[${hudY + 2};${progressX}H\\x1b[2m${themeColor}${progress}\\x1b[0m`;\n } else {\n // Normal game HUD\n // Line 1: Level name on left, Time on right\n const levelName = `LVL ${currentLevel + 1}: ${level.name}`;\n output += `\\x1b[${hudY};${gameLeft + 1}H${themeColor}${levelName}\\x1b[0m`;\n\n const timeColor = timeRemaining < 15 ? '\\x1b[91m' : timeRemaining < 30 ? '\\x1b[93m' : themeColor;\n const timeDisplay = `TIME: ${Math.ceil(timeRemaining)}s`;\n output += `\\x1b[${hudY};${gameLeft + screenWidth - timeDisplay.length + 1}H${timeColor}${timeDisplay}\\x1b[0m`;\n\n // Line 2: Deliveries centered\n const deliveryStatus = `DELIVERIES: ${deliveriesComplete}/${totalDeliveries} | SCORE: ${score}`;\n const deliveryX = gameLeft + Math.floor((screenWidth - deliveryStatus.length) / 2) + 1;\n output += `\\x1b[${hudY + 1};${deliveryX}H${themeColor}${deliveryStatus}\\x1b[0m`;\n\n // Line 3: Hint\n let hint = '';\n if (!hasPassenger) {\n hint = '▶ Land where you see the yellow package';\n } else {\n hint = '▶ Deliver to the marker (▼)';\n }\n const hintX = gameLeft + Math.floor((screenWidth - hint.length) / 2) + 1;\n output += `\\x1b[${hudY + 2};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n }\n }\n\n // Bottom hint (only when not showing game HUD)\n if (!gameStarted || paused || gameOver || levelComplete) {\n const menuHint = '[ ESC ] MENU';\n const menuX = Math.floor((cols - menuHint.length) / 2);\n output += `\\x1b[${rows - 1};${menuX}H\\x1b[2m${themeColor}${menuHint}\\x1b[0m`;\n }\n\n terminal.write(output);\n }\n\n // Start game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n renderInterval = setInterval(() => {\n if (!running) {\n clearInterval(renderInterval!);\n return;\n }\n render();\n }, 25);\n\n gameInterval = setInterval(() => {\n if (!running) {\n clearInterval(gameInterval!);\n return;\n }\n update();\n }, 25);\n\n keyDownHandler = (e: KeyboardEvent) => {\n if (!running || !gameStarted || paused || gameOver || levelComplete) return;\n\n switch (e.key) {\n case 'ArrowLeft':\n case 'a':\n inputLeft = true;\n break;\n case 'ArrowRight':\n case 'd':\n inputRight = true;\n break;\n case 'ArrowUp':\n case 'w':\n doFlap();\n break;\n case ' ':\n inputExtendRope = true;\n break;\n case 'Shift':\n inputContractRope = true;\n break;\n }\n };\n\n keyUpHandler = (e: KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowLeft':\n case 'a':\n inputLeft = false;\n break;\n case 'ArrowRight':\n case 'd':\n inputRight = false;\n break;\n case ' ':\n inputExtendRope = false;\n break;\n case 'Shift':\n inputContractRope = false;\n break;\n }\n };\n\n window.addEventListener('keydown', keyDownHandler);\n window.addEventListener('keyup', keyUpHandler);\n windowListenersAdded = true;\n\n keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener?.dispose();\n return;\n }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // ESC - toggle pause\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0; // Reset selection when opening\n return;\n }\n\n // Q to quit\n if (key === 'q') {\n if (paused || gameOver || !gameStarted || levelComplete) {\n cleanup();\n dispatchGameQuit(terminal);\n return;\n }\n }\n\n // Mode selection screen - arrow key navigation\n if (!gameStarted && showingModeSelect && !paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n menuSelection,\n MODE_SELECT_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== menuSelection) {\n menuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n showingModeSelect = false;\n if (menuSelection === 0) {\n initTutorial();\n } else {\n initGame();\n }\n gameStarted = true;\n return;\n }\n\n // Legacy shortcut keys still work\n if (key === 't') {\n showingModeSelect = false;\n initTutorial();\n gameStarted = true;\n return;\n }\n if (key === 'p') {\n showingModeSelect = false;\n initGame();\n gameStarted = true;\n return;\n }\n return;\n }\n\n // Legacy start screen (shouldn't be reached)\n if (!gameStarted && !paused) {\n showingModeSelect = false;\n initGame();\n gameStarted = true;\n return;\n }\n\n // Level complete\n if (levelComplete) {\n if (domEvent.key === ' ') {\n if (tutorialMode) {\n // Check if there are more tutorial levels\n if (tutorialLevelIndex < TUTORIAL_LEVELS.length - 1) {\n // Advance to next tutorial level\n tutorialLevelIndex++;\n initTutorialLevel();\n levelComplete = false;\n } else {\n // All tutorial levels complete - start normal game\n tutorialMode = false;\n initGame();\n levelComplete = false;\n }\n } else if (currentLevel < levels.length - 1) {\n currentLevel++;\n initLevel();\n levelComplete = false;\n }\n } else if (key === 'r') {\n if (tutorialMode) {\n initTutorial();\n } else {\n initGame();\n }\n gameStarted = true;\n }\n return;\n }\n\n // Game over\n if (gameOver) {\n if (key === 'r') {\n initLevel();\n gameStarted = true;\n gameOver = false;\n }\n return;\n }\n\n // Pause menu - arrow navigation + shortcuts\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n initLevel();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n cleanup();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n cleanup();\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n cleanup();\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (key === 'r') {\n initLevel();\n gameStarted = true;\n paused = false;\n } else if (key === 'l') {\n cleanup();\n dispatchGamesMenu(terminal);\n } else if (key === 'n') {\n cleanup();\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n // Gameplay controls - MUST handle here since terminal captures keys!\n if (domEvent.key === 'ArrowUp' || key === 'w') {\n doFlap();\n }\n // Handle left/right - apply thrust directly since onKey fires repeatedly when held\n if (domEvent.key === 'ArrowLeft' || key === 'a') {\n rigVX -= THRUST_POWER;\n rigAngle = Math.max(-15, rigAngle - 3);\n }\n if (domEvent.key === 'ArrowRight' || key === 'd') {\n rigVX += THRUST_POWER;\n rigAngle = Math.min(15, rigAngle + 3);\n }\n // SPACE extends rope - set flag (keyup handler will unset)\n if (domEvent.key === ' ') {\n inputExtendRope = true;\n }\n });\n }, 50);\n\n return controller;\n}\n","/**\n * Hyper Crack - Terminal Hacking Game\n *\n * Crack passwords to breach security layers before\n * the trace detection catches you. Wordle-style mechanics\n * with cyberpunk hacker aesthetics.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { type SimpleMenuItem, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n// Custom pause menu items with HELP option\nconst CRACK_PAUSE_MENU_ITEMS: SimpleMenuItem[] = [\n { label: 'Resume', shortcut: 'ESC' },\n { label: 'Restart', shortcut: 'R' },\n { label: 'Quit', shortcut: 'Q' },\n { label: 'Help', shortcut: 'H' },\n { label: 'List Games', shortcut: 'L' },\n { label: 'Next Game', shortcut: 'N' },\n];\n\n/**\n * Crack Game Controller\n */\nexport interface CrackController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// Word lists by difficulty (5-letter words for classic feel)\nconst PASSWORDS = [\n // Easy - common tech words\n 'ADMIN', 'LOGIN', 'GUEST', 'PROXY', 'QUERY', 'DEBUG', 'CACHE', 'STACK',\n 'PARSE', 'TOKEN', 'ROUTE', 'PATCH', 'BUILD', 'MERGE', 'CLONE', 'FETCH',\n // Medium - more obscure\n 'CRYPT', 'VAULT', 'NEXUS', 'HELIX', 'CYBER', 'GHOST', 'ROGUE', 'VENOM',\n 'CHAOS', 'RAZOR', 'BLAZE', 'STORM', 'FROST', 'SPARK', 'SURGE', 'PULSE',\n // Hard - hacker/cyber themed\n 'BREACH', 'BYPASS', 'CIPHER', 'DAEMON', 'INJECT', 'KERNEL', 'MALLOC',\n 'PHISH', 'ROOTKIT', 'SHELL', 'SPOOF', 'TROJAN', 'VECTOR', 'ZOMBIE',\n].filter(w => w.length === 5); // Ensure all 5 letters\n\n// Fake system names for immersion\nconst SYSTEM_NAMES = [\n 'NEXUS-CORP MAINFRAME',\n 'DARKNET NODE #7749',\n 'PENTAGON SUBNET',\n 'SWISS BANK VAULT',\n 'CRYPTO EXCHANGE',\n 'SATELLITE UPLINK',\n 'NEURAL NETWORK HUB',\n 'QUANTUM CLUSTER',\n];\n\nconst FAKE_IPS = [\n '192.168.13.37', '10.0.66.6', '172.16.42.0', '203.0.113.99',\n '198.51.100.23', '185.199.108.1', '140.82.114.4', '151.101.1.69',\n];\n\n// Hacker log messages\nconst LOG_MESSAGES = {\n attempt: [\n 'Attempting password injection...',\n 'Running dictionary attack...',\n 'Brute forcing hash...',\n 'Decrypting auth token...',\n 'Bypassing security layer...',\n ],\n partial: [\n 'Partial match detected!',\n 'Hash collision found...',\n 'Encryption weakening...',\n 'Security gap identified!',\n 'Pattern recognized...',\n ],\n wrong: [\n 'Access denied.',\n 'Invalid credentials.',\n 'Authentication failed.',\n 'Security block triggered.',\n 'Firewall rejected attempt.',\n ],\n success: [\n 'ACCESS GRANTED!',\n 'SECURITY BYPASSED!',\n 'LAYER BREACHED!',\n 'ENCRYPTION CRACKED!',\n 'FIREWALL DOWN!',\n ],\n detection: [\n 'INTRUSION DETECTED',\n 'TRACE COMPLETE',\n 'LOCATION COMPROMISED',\n 'SECURITY ALERTED',\n ],\n};\n\n// Particle interface for visual effects\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\n// Score popup interface for floating text\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\n/**\n * Cyberpunk Terminal Hacking Game\n */\nexport function runCrackGame(terminal: Terminal): CrackController {\n const themeColor = getCurrentThemeColor();\n\n // Minimum terminal size\n const MIN_COLS = 40;\n const MIN_ROWS = 16;\n\n let cols = terminal.cols;\n let rows = terminal.rows;\n\n const updateDimensions = () => {\n cols = terminal.cols;\n rows = terminal.rows;\n };\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let won = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let showHelp = false;\n\n // Game state\n let currentLayer = 1;\n const totalLayers = 3;\n let targetPassword = '';\n let guesses: string[] = [];\n let currentGuess = '';\n let maxGuesses = 6;\n let timeLeft = 90; // seconds\n let lastTick = Date.now();\n\n // Visual state\n let glitchFrame = 0;\n let logMessages: string[] = [];\n let systemName = '';\n let systemIP = '';\n let scanlineY = 0;\n let gameOverFrame = 0;\n let fakeCoords = { lat: 0, lng: 0 };\n\n // Juicy effect state\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let screenShake = 0;\n let shakeIntensity = 0;\n let borderFlash = 0;\n let correctFlash = 0;\n let wrongFlash = 0;\n let layerBreachFlash = 0;\n\n // Generate fake coordinates\n function generateFakeCoords(): void {\n fakeCoords = {\n lat: (Math.random() * 180 - 90).toFixed(6) as unknown as number,\n lng: (Math.random() * 360 - 180).toFixed(6) as unknown as number,\n };\n }\n\n // Spawn particles for juicy effects\n function spawnParticles(\n x: number,\n y: number,\n count: number,\n color: string,\n chars: string[] = ['█', '▓', '▒', '░', '●', '◆', '✦']\n ): void {\n for (let i = 0; i < count; i++) {\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: (Math.random() - 0.5) * 2,\n vy: (Math.random() - 0.8) * 1.5,\n life: 15 + Math.floor(Math.random() * 15),\n });\n }\n }\n\n // Add score popup for floating text feedback\n function addScorePopup(x: number, y: number, text: string, color: string): void {\n scorePopups.push({ x, y, text, frames: 30, color });\n }\n\n const controller: CrackController = {\n stop: () => {\n if (!running) return;\n running = false;\n // Note: Buffer exit is handled by TerminalPool via dispatchGameQuit\n },\n get isRunning() { return running; }\n };\n\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ █▀▀ █▀█ ▄▀█ █▀▀ █▄▀',\n '█▀█ █ █▀▀ ██▄ █▀▄ █▄▄ █▀▄ █▀█ █▄▄ █ █',\n ];\n\n function pickPassword(): string {\n return PASSWORDS[Math.floor(Math.random() * PASSWORDS.length)];\n }\n\n function pickSystem(): void {\n systemName = SYSTEM_NAMES[Math.floor(Math.random() * SYSTEM_NAMES.length)];\n systemIP = FAKE_IPS[Math.floor(Math.random() * FAKE_IPS.length)];\n }\n\n function addLog(category: keyof typeof LOG_MESSAGES): void {\n const messages = LOG_MESSAGES[category];\n const msg = messages[Math.floor(Math.random() * messages.length)];\n const timestamp = new Date().toISOString().substr(11, 8);\n logMessages.unshift(`[${timestamp}] ${msg}`);\n if (logMessages.length > 5) logMessages.pop();\n }\n\n function initGame(): void {\n currentLayer = 1;\n targetPassword = pickPassword();\n guesses = [];\n currentGuess = '';\n timeLeft = 90;\n lastTick = Date.now();\n gameOver = false;\n won = false;\n paused = false;\n logMessages = [];\n pickSystem();\n addLog('attempt');\n }\n\n function initLayer(): void {\n targetPassword = pickPassword();\n guesses = [];\n currentGuess = '';\n addLog('attempt');\n }\n\n // Check guess against target - returns array of states: 'correct', 'present', 'absent'\n function checkGuess(guess: string): ('correct' | 'present' | 'absent')[] {\n const result: ('correct' | 'present' | 'absent')[] = [];\n const targetChars = targetPassword.split('');\n const guessChars = guess.split('');\n const used = new Array(5).fill(false);\n\n // First pass: find exact matches\n for (let i = 0; i < 5; i++) {\n if (guessChars[i] === targetChars[i]) {\n result[i] = 'correct';\n used[i] = true;\n }\n }\n\n // Second pass: find present but wrong position\n for (let i = 0; i < 5; i++) {\n if (result[i]) continue;\n const idx = targetChars.findIndex((c, j) => c === guessChars[i] && !used[j]);\n if (idx !== -1) {\n result[i] = 'present';\n used[idx] = true;\n } else {\n result[i] = 'absent';\n }\n }\n\n return result;\n }\n\n function submitGuess(): void {\n if (currentGuess.length !== 5) return;\n\n const result = checkGuess(currentGuess);\n guesses.push(currentGuess);\n\n const allCorrect = result.every(r => r === 'correct');\n const correctCount = result.filter(r => r === 'correct').length;\n const presentCount = result.filter(r => r === 'present').length;\n const hasPartial = correctCount > 0 || presentCount > 0;\n\n // Calculate effect center position\n const effectX = Math.floor(cols / 2);\n const effectY = 12 + guesses.length;\n\n if (allCorrect) {\n addLog('success');\n // Big celebration for cracking the password!\n correctFlash = 12;\n borderFlash = 15;\n layerBreachFlash = 20;\n screenShake = 8;\n shakeIntensity = 3;\n\n // Massive particle explosion\n spawnParticles(effectX, effectY, 25, '\\x1b[1;32m', ['█', '▓', '✦', '★', '◆', '●']);\n spawnParticles(effectX - 5, effectY, 15, '\\x1b[1;92m', ['░', '▒', '▓']);\n spawnParticles(effectX + 5, effectY, 15, '\\x1b[1;92m', ['░', '▒', '▓']);\n\n if (currentLayer >= totalLayers) {\n won = true;\n gameOver = true;\n addScorePopup(effectX, effectY - 2, '◆ SYSTEM COMPROMISED ◆', '\\x1b[1;32m');\n // Victory explosion\n for (let i = 0; i < 5; i++) {\n setTimeout(() => {\n if (running) {\n spawnParticles(\n Math.floor(cols / 4) + Math.random() * cols / 2,\n 5 + Math.random() * 10,\n 10,\n '\\x1b[1;32m',\n ['█', '★', '◆', '●']\n );\n }\n }, i * 100);\n }\n } else {\n addScorePopup(effectX, effectY - 2, `LAYER ${currentLayer} BREACHED!`, '\\x1b[1;32m');\n currentLayer++;\n setTimeout(() => {\n if (running && !gameOver) initLayer();\n }, 1000);\n }\n } else if (guesses.length >= maxGuesses) {\n addLog('detection');\n // Dramatic failure effects\n wrongFlash = 15;\n borderFlash = 20;\n screenShake = 12;\n shakeIntensity = 4;\n gameOver = true;\n gameOverFrame = 0;\n generateFakeCoords();\n\n // Red explosion for detection\n spawnParticles(effectX, effectY, 20, '\\x1b[1;31m', ['█', '▓', '▒', '!', '@', '#']);\n addScorePopup(effectX, effectY - 2, '◆ TRACED ◆', '\\x1b[1;31m');\n } else if (hasPartial) {\n addLog('partial');\n // Encouraging feedback for partial matches\n correctFlash = 4 + correctCount * 2;\n screenShake = Math.min(correctCount + 1, 4);\n shakeIntensity = 1;\n\n // Green particles for correct, yellow for present\n if (correctCount > 0) {\n spawnParticles(effectX, effectY, 3 + correctCount * 2, '\\x1b[1;32m', ['█', '●', '◆']);\n addScorePopup(effectX, effectY - 1, `${correctCount} EXACT!`, '\\x1b[1;32m');\n }\n if (presentCount > 0) {\n spawnParticles(effectX + 3, effectY, 2 + presentCount, '\\x1b[1;33m', ['░', '▒', '●']);\n if (correctCount === 0) {\n addScorePopup(effectX, effectY - 1, `${presentCount} CLOSE`, '\\x1b[1;33m');\n }\n }\n } else {\n addLog('wrong');\n // Miss feedback - shake and red flash\n wrongFlash = 6;\n screenShake = 3;\n shakeIntensity = 2;\n\n // Small red particles\n spawnParticles(effectX, effectY, 5, '\\x1b[31m', ['░', '▒', '×', '·']);\n addScorePopup(effectX, effectY - 1, 'DENIED', '\\x1b[2;31m');\n }\n\n currentGuess = '';\n }\n\n function render(): void {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const msg2 = `Need: ${MIN_COLS}x${MIN_ROWS} Have: ${cols}x${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 2};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Calculate screen shake offset\n let shakeOffsetX = 0;\n let shakeOffsetY = 0;\n if (screenShake > 0) {\n shakeOffsetX = Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n shakeOffsetY = Math.floor((Math.random() - 0.5) * shakeIntensity);\n screenShake--;\n }\n\n // Decrement effect timers\n if (borderFlash > 0) borderFlash--;\n if (correctFlash > 0) correctFlash--;\n if (wrongFlash > 0) wrongFlash--;\n if (layerBreachFlash > 0) layerBreachFlash--;\n\n // Update particles\n particles = particles.filter(p => {\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.03; // gravity\n p.life--;\n return p.life > 0;\n });\n\n // Update score popups\n scorePopups = scorePopups.filter(sp => {\n sp.y -= 0.15; // float upward\n sp.frames--;\n return sp.frames > 0;\n });\n\n glitchFrame = (glitchFrame + 1) % 60;\n scanlineY = (scanlineY + 1) % rows;\n\n // Title (with shake offset)\n const titleX = Math.floor((cols - title[0].length) / 2) + shakeOffsetX;\n const titleY = 1 + shakeOffsetY;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n\n // Title color based on effects\n let titleColor = themeColor;\n if (layerBreachFlash > 0 && layerBreachFlash % 4 < 2) {\n titleColor = '\\x1b[1;32m'; // Green flash on layer breach\n } else if (wrongFlash > 0 && wrongFlash % 4 < 2) {\n titleColor = '\\x1b[1;31m'; // Red flash on wrong\n } else if (correctFlash > 0 && correctFlash % 3 < 2) {\n titleColor = '\\x1b[1;92m'; // Bright green on correct\n }\n\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[${Math.max(1, titleY)};${Math.max(1, titleX + glitchOffset)}H\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[${Math.max(1, titleY + 1)};${Math.max(1, titleX + glitchOffset + 1)}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `\\x1b[${Math.max(1, titleY)};${Math.max(1, titleX)}H${titleColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[${Math.max(1, titleY + 1)};${Math.max(1, titleX)}H${titleColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n if (paused) {\n // Pause menu\n const pauseY = 8;\n const pauseMsg = '══ PAUSED ══';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(CRACK_PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 10};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted) {\n // Start screen\n const startY = 5;\n\n // Fake target system info\n output += `\\x1b[${startY};3H${themeColor}TARGET SYSTEM:\\x1b[0m`;\n output += `\\x1b[${startY + 1};3H\\x1b[2m${themeColor}├─ ${systemName || 'CLASSIFIED'}\\x1b[0m`;\n output += `\\x1b[${startY + 2};3H\\x1b[2m${themeColor}└─ IP: ${systemIP || '???.???.???.???'}\\x1b[0m`;\n\n // Mission briefing\n const missionY = startY + 5;\n output += `\\x1b[${missionY};3H${themeColor}MISSION:\\x1b[0m`;\n output += `\\x1b[${missionY + 1};3H\\x1b[2m${themeColor}Crack ${totalLayers} security layers before trace detection.\\x1b[0m`;\n output += `\\x1b[${missionY + 2};3H\\x1b[2m${themeColor}Each password is 5 characters.\\x1b[0m`;\n output += `\\x1b[${missionY + 3};3H\\x1b[2m${themeColor}You have ${maxGuesses} attempts per layer.\\x1b[0m`;\n\n // Color legend\n const legendY = missionY + 6;\n output += `\\x1b[${legendY};3H${themeColor}FEEDBACK:\\x1b[0m`;\n output += `\\x1b[${legendY + 1};3H\\x1b[1;32m█\\x1b[0m\\x1b[2m = Correct position\\x1b[0m`;\n output += `\\x1b[${legendY + 2};3H\\x1b[1;33m█\\x1b[0m\\x1b[2m = Wrong position\\x1b[0m`;\n output += `\\x1b[${legendY + 3};3H\\x1b[2m█ = Not in password\\x1b[0m`;\n\n // Start prompt\n const startMsg = '[ PRESS ENTER TO BEGIN BREACH ]';\n const startX = Math.floor((cols - startMsg.length) / 2);\n output += `\\x1b[${rows - 4};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = 'ESC: Menu';\n output += `\\x1b[${rows - 2};3H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n } else if (gameOver) {\n // Game over screen - more dramatic!\n const overY = 4;\n\n if (won) {\n // SUCCESS - Hacker victory screen\n const accessGranted = '╔═══════════════════════════════════╗';\n const accessMsg = '║ ██ ACCESS GRANTED ██ ║';\n const accessBottom = '╚═══════════════════════════════════╝';\n const boxX = Math.floor((cols - accessGranted.length) / 2);\n\n output += `\\x1b[${overY};${boxX}H\\x1b[1;32m${accessGranted}\\x1b[0m`;\n output += `\\x1b[${overY + 1};${boxX}H\\x1b[1;32m${accessMsg}\\x1b[0m`;\n output += `\\x1b[${overY + 2};${boxX}H\\x1b[1;32m${accessBottom}\\x1b[0m`;\n\n output += `\\x1b[${overY + 4};${boxX}H${themeColor}Target: ${systemName}\\x1b[0m`;\n output += `\\x1b[${overY + 5};${boxX}H${themeColor}Status: \\x1b[32mFULLY COMPROMISED\\x1b[0m`;\n output += `\\x1b[${overY + 6};${boxX}H${themeColor}Time remaining: \\x1b[33m${timeLeft}s\\x1b[0m`;\n output += `\\x1b[${overY + 7};${boxX}H${themeColor}Layers breached: \\x1b[32m${totalLayers}/${totalLayers}\\x1b[0m`;\n\n // Download animation\n const dlProgress = Math.min(gameOverFrame * 5, 100);\n const dlBar = '█'.repeat(Math.floor(dlProgress / 5)) + '░'.repeat(20 - Math.floor(dlProgress / 5));\n output += `\\x1b[${overY + 9};${boxX}H\\x1b[32mDownloading data... [${dlBar}] ${dlProgress}%\\x1b[0m`;\n\n if (dlProgress >= 100) {\n output += `\\x1b[${overY + 11};${boxX}H\\x1b[1;32m✓ 847 FILES EXTRACTED\\x1b[0m`;\n output += `\\x1b[${overY + 12};${boxX}H\\x1b[1;32m✓ LOGS WIPED\\x1b[0m`;\n output += `\\x1b[${overY + 13};${boxX}H\\x1b[1;32m✓ BACKDOOR INSTALLED\\x1b[0m`;\n }\n } else {\n // FAILURE - Dramatic busted screen\n const warningGlitch = gameOverFrame % 8 < 4;\n const glitchChar = warningGlitch ? '▓' : '░';\n\n // Flashing warning banner\n const warningColor = gameOverFrame % 6 < 3 ? '\\x1b[1;31m' : '\\x1b[41;97m';\n const warningBanner = `${glitchChar}${glitchChar} INTRUSION DETECTED ${glitchChar}${glitchChar}`;\n output += `\\x1b[${overY};${Math.floor((cols - warningBanner.length) / 2)}H${warningColor}${warningBanner}\\x1b[0m`;\n\n // Connection terminated box\n const termBox = [\n '┌─────────────────────────────────────┐',\n '│ ▄▀▀▀▄ CONNECTION TERMINATED ▄▀▀▀▄│',\n '├─────────────────────────────────────┤',\n ];\n const boxX = Math.floor((cols - termBox[0].length) / 2);\n\n for (let i = 0; i < termBox.length; i++) {\n output += `\\x1b[${overY + 2 + i};${boxX}H\\x1b[31m${termBox[i]}\\x1b[0m`;\n }\n\n // Trace info with fake coordinates\n output += `\\x1b[${overY + 5};${boxX}H\\x1b[31m│\\x1b[0m TRACE STATUS: \\x1b[1;31mCOMPLETE\\x1b[0m`;\n output += `\\x1b[${overY + 6};${boxX}H\\x1b[31m│\\x1b[0m YOUR COORDS: \\x1b[33m${fakeCoords.lat}, ${fakeCoords.lng}\\x1b[0m`;\n output += `\\x1b[${overY + 7};${boxX}H\\x1b[31m│\\x1b[0m ISP: \\x1b[33mIDENTIFIED\\x1b[0m`;\n output += `\\x1b[${overY + 8};${boxX}H\\x1b[31m│\\x1b[0m AUTHORITIES: \\x1b[5;31mDISPATCHED\\x1b[0m`;\n output += `\\x1b[${overY + 9};${boxX}H\\x1b[31m└─────────────────────────────────────┘\\x1b[0m`;\n\n // Stats\n output += `\\x1b[${overY + 11};${boxX}H\\x1b[2m${themeColor}Layers cracked: ${currentLayer - 1}/${totalLayers}\\x1b[0m`;\n output += `\\x1b[${overY + 12};${boxX}H\\x1b[2m${themeColor}Password was: \\x1b[33m${targetPassword}\\x1b[0m`;\n\n // Glitch effect - random characters at edges\n if (gameOverFrame % 4 === 0) {\n const glitchChars = '!@#$%^&*░▒▓█';\n for (let i = 0; i < 3; i++) {\n const gx = Math.floor(Math.random() * cols);\n const gy = Math.floor(Math.random() * rows);\n const gc = glitchChars[Math.floor(Math.random() * glitchChars.length)];\n output += `\\x1b[${gy};${gx}H\\x1b[31m${gc}\\x1b[0m`;\n }\n }\n }\n\n const restartMsg = '[ R ] RESTART [ Q ] QUIT [ N ] NEXT GAME';\n output += `\\x1b[${rows - 3};${Math.floor((cols - restartMsg.length) / 2)}H\\x1b[2m${themeColor}${restartMsg}\\x1b[0m`;\n } else if (showHelp) {\n // Help overlay\n const helpY = 5;\n const helpBox = [\n '╔══════════════════════════════════════╗',\n '║ HYPER CRACK HELP ║',\n '╠══════════════════════════════════════╣',\n '║ Crack passwords before trace timer ║',\n '║ runs out. Breach all 3 layers! ║',\n '╠══════════════════════════════════════╣',\n '║ ■ GREEN = Correct position ║',\n '║ ■ YELLOW = Wrong position ║',\n '║ ■ DIM = Not in password ║',\n '╠══════════════════════════════════════╣',\n '║ CONTROLS: ║',\n '║ A-Z = Type letters ║',\n '║ ENTER = Submit guess ║',\n '║ BKSP = Delete letter ║',\n '║ ESC = Pause menu ║',\n '╚══════════════════════════════════════╝',\n ];\n const helpX = Math.floor((cols - helpBox[0].length) / 2);\n for (let i = 0; i < helpBox.length; i++) {\n output += `\\x1b[${helpY + i};${helpX}H${themeColor}${helpBox[i]}\\x1b[0m`;\n }\n output += `\\x1b[${helpY + helpBox.length + 1};${helpX + 8}H\\x1b[2m[ Press ESC to close ]\\x1b[0m`;\n } else {\n // Main game screen\n const gameY = 4;\n\n // System info header\n output += `\\x1b[${gameY};2H${themeColor}┌─ TARGET: ${systemName} ─┐\\x1b[0m`;\n output += `\\x1b[${gameY + 1};2H${themeColor}│\\x1b[0m IP: ${systemIP}`;\n output += `\\x1b[${gameY + 2};2H${themeColor}│\\x1b[0m LAYER: \\x1b[1m${currentLayer}/${totalLayers}\\x1b[0m`;\n\n // Trace timer - more urgent as time decreases\n const timerColor = timeLeft <= 10 ? '\\x1b[1;31m' : timeLeft <= 30 ? '\\x1b[33m' : themeColor;\n const timerBlink = timeLeft <= 10 ? '\\x1b[5m' : '';\n output += `\\x1b[${gameY + 3};2H${themeColor}│\\x1b[0m TRACE: ${timerBlink}${timerColor}${timeLeft}s\\x1b[0m`;\n output += `\\x1b[${gameY + 4};2H${themeColor}└${'─'.repeat(30)}┘\\x1b[0m`;\n\n // Password display area\n const pwdY = gameY + 6;\n output += `\\x1b[${pwdY};2H${themeColor}PASSWORD CRACK:\\x1b[0m`;\n\n // Previous guesses\n for (let i = 0; i < guesses.length; i++) {\n const guess = guesses[i];\n const result = checkGuess(guess);\n let guessDisplay = '';\n for (let j = 0; j < 5; j++) {\n const char = guess[j];\n if (result[j] === 'correct') {\n guessDisplay += `\\x1b[1;32m${char}\\x1b[0m `;\n } else if (result[j] === 'present') {\n guessDisplay += `\\x1b[1;33m${char}\\x1b[0m `;\n } else {\n guessDisplay += `\\x1b[2m${char}\\x1b[0m `;\n }\n }\n output += `\\x1b[${pwdY + 1 + i};4H${guessDisplay}`;\n }\n\n // Current guess input\n const inputY = pwdY + 1 + guesses.length;\n let inputDisplay = '';\n for (let i = 0; i < 5; i++) {\n if (i < currentGuess.length) {\n inputDisplay += `${themeColor}\\x1b[1m${currentGuess[i]}\\x1b[0m `;\n } else if (i === currentGuess.length) {\n // Blinking cursor\n const cursorChar = glitchFrame % 20 < 10 ? '█' : '_';\n inputDisplay += `${themeColor}${cursorChar}\\x1b[0m `;\n } else {\n inputDisplay += `\\x1b[2m_\\x1b[0m `;\n }\n }\n output += `\\x1b[${inputY};4H${inputDisplay}`;\n\n // Remaining attempts\n const attemptsLeft = maxGuesses - guesses.length;\n output += `\\x1b[${inputY + 2};4H\\x1b[2mAttempts: ${attemptsLeft}/${maxGuesses}\\x1b[0m`;\n\n // System log area (right side)\n const logX = 40;\n const logY = gameY;\n output += `\\x1b[${logY};${logX}H${themeColor}┌─ SYSTEM LOG ─┐\\x1b[0m`;\n for (let i = 0; i < 5; i++) {\n const logMsg = logMessages[i] || '';\n const truncated = logMsg.substring(0, cols - logX - 4);\n output += `\\x1b[${logY + 1 + i};${logX}H${themeColor}│\\x1b[0m\\x1b[2m ${truncated}\\x1b[0m`;\n }\n output += `\\x1b[${logY + 6};${logX}H${themeColor}└${'─'.repeat(16)}┘\\x1b[0m`;\n\n // Help\n output += `\\x1b[${rows - 2};2H\\x1b[2m${themeColor}Type 5 letters, ENTER to submit | ESC: Menu\\x1b[0m`;\n }\n\n // Render particles\n for (const p of particles) {\n const px = Math.round(p.x) + shakeOffsetX;\n const py = Math.round(p.y) + shakeOffsetY;\n if (px >= 1 && px < cols && py >= 1 && py < rows) {\n const fade = p.life > 10 ? '' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${p.color}${fade}${p.char}\\x1b[0m`;\n }\n }\n\n // Render score popups\n for (const sp of scorePopups) {\n const px = Math.round(sp.x - sp.text.length / 2) + shakeOffsetX;\n const py = Math.round(sp.y) + shakeOffsetY;\n if (py >= 1 && py < rows && px >= 1) {\n const fade = sp.frames > 15 ? '' : sp.frames > 8 ? '\\x1b[2m' : '\\x1b[2m';\n output += `\\x1b[${py};${Math.max(1, px)}H${sp.color}${fade}${sp.text}\\x1b[0m`;\n }\n }\n\n // Border flash effect\n if (borderFlash > 0) {\n const flashColor = wrongFlash > 0 ? '\\x1b[31m' : '\\x1b[32m';\n const flashChar = borderFlash % 4 < 2 ? '█' : '▓';\n // Top and bottom borders\n for (let x = 1; x <= cols; x += 3) {\n if (Math.random() > 0.5) {\n output += `\\x1b[1;${x}H${flashColor}${flashChar}\\x1b[0m`;\n output += `\\x1b[${rows};${x}H${flashColor}${flashChar}\\x1b[0m`;\n }\n }\n // Left and right borders\n for (let y = 1; y <= rows; y += 2) {\n if (Math.random() > 0.5) {\n output += `\\x1b[${y};1H${flashColor}${flashChar}\\x1b[0m`;\n output += `\\x1b[${y};${cols}H${flashColor}${flashChar}\\x1b[0m`;\n }\n }\n }\n\n terminal.write(output);\n }\n\n function update(): void {\n if (!gameStarted || gameOver || paused) return;\n\n // Update timer\n const now = Date.now();\n if (now - lastTick >= 1000) {\n timeLeft--;\n lastTick = now;\n\n // Low time warning effects\n if (timeLeft <= 10 && timeLeft > 0) {\n screenShake = 2;\n shakeIntensity = 1;\n borderFlash = 3;\n wrongFlash = 3;\n // Spawn warning particles around edges\n if (timeLeft % 2 === 0) {\n spawnParticles(Math.random() * cols, 2, 3, '\\x1b[1;31m', ['!', '▓', '░']);\n }\n }\n\n if (timeLeft <= 0) {\n addLog('detection');\n gameOver = true;\n gameOverFrame = 0;\n generateFakeCoords();\n // Big explosion for trace complete\n screenShake = 15;\n shakeIntensity = 5;\n wrongFlash = 20;\n borderFlash = 25;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n spawnParticles(centerX, centerY, 30, '\\x1b[1;31m', ['█', '▓', '▒', '!', '@', '#', '×']);\n addScorePopup(centerX, centerY - 3, '◆◆ TRACE COMPLETE ◆◆', '\\x1b[1;31m');\n }\n }\n\n // Increment game over animation frame\n if (gameOver) {\n gameOverFrame++;\n }\n }\n\n // Start game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n pickSystem();\n initGame();\n gameStarted = false; // Show start screen first\n\n const renderInterval = setInterval(() => {\n if (!running) {\n clearInterval(renderInterval);\n return;\n }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) {\n clearInterval(gameInterval);\n return;\n }\n update();\n }, 100);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener.dispose();\n return;\n }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key;\n const keyLower = key.toLowerCase();\n\n // ESC - toggle pause or close help\n if (key === 'Escape') {\n if (showHelp) {\n showHelp = false;\n } else {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n }\n return;\n }\n\n // Start screen\n if (!gameStarted && !paused) {\n if (key === 'Enter') {\n gameStarted = true;\n initGame();\n }\n return;\n }\n\n // Game over\n if (gameOver) {\n if (keyLower === 'r') {\n initGame();\n gameStarted = true;\n } else if (keyLower === 'q') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n } else if (keyLower === 'n') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n // Pause menu\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n CRACK_PAUSE_MENU_ITEMS.length,\n keyLower,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n initGame();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // Help\n showHelp = true;\n paused = false;\n break;\n case 4: // List Games\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 5: // Next Game\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (keyLower === 'r') {\n initGame();\n gameStarted = true;\n paused = false;\n } else if (keyLower === 'l') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (keyLower === 'n') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n } else if (keyLower === 'h') {\n showHelp = true;\n paused = false;\n }\n return;\n }\n\n // Help screen - ESC closes it (handled above)\n if (showHelp) {\n return;\n }\n\n // Gameplay input\n if (key === 'Backspace') {\n currentGuess = currentGuess.slice(0, -1);\n } else if (key === 'Enter') {\n submitGuess();\n } else if (key.length === 1 && /[a-zA-Z]/.test(key) && currentGuess.length < 5) {\n currentGuess += key.toUpperCase();\n // Subtle typing feedback\n const inputX = 4 + currentGuess.length * 2;\n const inputY = 12 + guesses.length;\n spawnParticles(inputX, inputY, 1, themeColor, ['·', '●']);\n // Tiny shake on last letter\n if (currentGuess.length === 5) {\n screenShake = 2;\n shakeIntensity = 1;\n borderFlash = 2;\n }\n }\n });\n\n const resizeListener = terminal.onResize(() => {\n updateDimensions();\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n resizeListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Frogger\n *\n * Guide your frog across dangerous roads and rivers!\n * - Avoid cars and trucks on the road\n * - Hop on logs and turtles to cross the water\n * - Reach all 5 lily pads to advance\n *\n * Features:\n * - Progressive difficulty (starts easy)\n * - Visual frog character with animation\n * - Better themed obstacles\n * - Lower terminal requirements\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\nexport interface FroggerController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface Vehicle {\n x: number;\n width: number;\n sprite: string;\n color: string;\n}\n\ninterface Log {\n x: number;\n width: number;\n sprite: string;\n isTurtle: boolean;\n submergeTimer?: number;\n}\n\ninterface Lane {\n type: 'road' | 'water' | 'safe' | 'goal';\n speed: number;\n vehicles?: Vehicle[];\n logs?: Log[];\n}\n\n// ============================================================================\n// MAIN GAME FUNCTION\n// ============================================================================\n\nexport function runFroggerGame(terminal: Terminal): FroggerController {\n const themeColor = getCurrentThemeColor();\n\n // -------------------------------------------------------------------------\n // CONSTANTS\n // -------------------------------------------------------------------------\n const MIN_COLS = 40;\n const MIN_ROWS = 16;\n const LILY_PAD_COUNT = 5;\n const TIME_LIMIT = 45;\n const MOVE_COOLDOWN = 100;\n\n // -------------------------------------------------------------------------\n // STATE\n // -------------------------------------------------------------------------\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let score = 0;\n let highScore = 0;\n let level = 1;\n let lives = 3;\n\n // Computed dimensions\n let GAME_WIDTH = 40;\n let GAME_HEIGHT = 13;\n let gameLeft = 2;\n let gameTop = 4;\n\n // Lane layout (from bottom to top)\n const SAFE_START = 0; // Starting safe zone\n const ROAD_START = 1; // Road lanes start\n const ROAD_END = 4; // Road lanes end\n const MEDIAN = 5; // Middle safe zone\n const WATER_START = 6; // Water lanes start\n const WATER_END = 9; // Water lanes end\n const GOAL_ROW = 10; // Lily pad row\n\n let timeRemaining = TIME_LIMIT;\n let lastTimeUpdate = Date.now();\n\n let playerX = 0;\n let playerY = 0;\n let playerOnLog = false;\n let lastMoveTime = 0;\n let furthestY = 0;\n let hopFrame = 0;\n\n let lilyPads: boolean[] = [false, false, false, false, false];\n let lilyPadX: number[] = [];\n let lanes: Lane[] = [];\n\n let particles: Particle[] = [];\n let shakeFrames = 0;\n let deathFlash = 0;\n let winFlash = 0;\n\n // Frog sprites (facing up)\n const FROG_IDLE = '◎';\n const FROG_HOP = '^';\n const FROG_ON_LOG = '●';\n\n // Vehicle sprites\n const CAR_LEFT = '<≡>';\n const CAR_RIGHT = '<≡>';\n const TRUCK = '⊏══⊐';\n const MOTORCYCLE = '○>';\n\n // Water sprites\n const LOG_CHAR = '═';\n const TURTLE = '◗◖';\n\n // -------------------------------------------------------------------------\n // CONTROLLER\n // -------------------------------------------------------------------------\n const controller: FroggerController = {\n stop: () => {\n if (!running) return;\n running = false;\n },\n get isRunning() { return running; }\n };\n\n // -------------------------------------------------------------------------\n // ASCII ART\n // -------------------------------------------------------------------------\n const title = [\n '█▀▀ █▀█ █▀█ █▀▀ █▀▀ █▀▀ █▀█',\n '█▀ █▀▄ █▄█ █▄█ █▄█ ██▄ █▀▄',\n ];\n\n // -------------------------------------------------------------------------\n // EFFECTS\n // -------------------------------------------------------------------------\n\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[]) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.1 + Math.random() * 0.15; // Halved for 2x frame rate\n particles.push({\n x, y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 16 + Math.floor(Math.random() * 12), // Doubled for 2x frame rate\n });\n }\n }\n\n function spawnSplash(x: number, y: number) {\n spawnParticles(x, y, 8, '\\x1b[96m', ['~', '∼', '≈', '○']);\n }\n\n function spawnCrash(x: number, y: number) {\n spawnParticles(x, y, 10, '\\x1b[91m', ['*', 'x', '×', '#']);\n }\n\n function spawnSuccess(x: number, y: number) {\n spawnParticles(x, y, 12, '\\x1b[92m', ['*', '+', '♦', '◇']);\n }\n\n // -------------------------------------------------------------------------\n // GAME SETUP\n // -------------------------------------------------------------------------\n\n function calculateLilyPads() {\n lilyPadX = [];\n const padSpacing = Math.floor(GAME_WIDTH / (LILY_PAD_COUNT + 1));\n for (let i = 0; i < LILY_PAD_COUNT; i++) {\n lilyPadX.push(padSpacing * (i + 1) - 1);\n }\n }\n\n function generateLanes() {\n lanes = [];\n\n // Difficulty scaling\n const speedMult = 0.6 + level * 0.15;\n const vehicleCountBase = Math.min(level + 1, 4);\n\n for (let row = 0; row <= GOAL_ROW; row++) {\n if (row === SAFE_START || row === MEDIAN) {\n lanes.push({ type: 'safe', speed: 0 });\n } else if (row >= ROAD_START && row <= ROAD_END) {\n // Road lanes\n const direction = row % 2 === 0 ? 1 : -1;\n const speed = (0.075 + Math.random() * 0.075) * direction * speedMult; // Halved for 2x frame rate\n const lane: Lane = { type: 'road', speed, vehicles: [] };\n\n const vehicleCount = vehicleCountBase - Math.floor(Math.random() * 2);\n const spacing = GAME_WIDTH / vehicleCount;\n\n for (let v = 0; v < vehicleCount; v++) {\n const rand = Math.random();\n let sprite: string, width: number, color: string;\n\n if (rand < 0.2 && level >= 2) {\n // Motorcycle (fast, small)\n sprite = MOTORCYCLE;\n width = 2;\n color = '\\x1b[93m';\n } else if (rand < 0.5) {\n // Truck (slow, big)\n sprite = TRUCK;\n width = 5;\n color = '\\x1b[33m';\n } else {\n // Car\n sprite = direction > 0 ? CAR_RIGHT : CAR_LEFT;\n width = 3;\n color = '\\x1b[91m';\n }\n\n lane.vehicles!.push({\n x: v * spacing + Math.random() * (spacing / 3),\n width,\n sprite,\n color,\n });\n }\n lanes.push(lane);\n } else if (row >= WATER_START && row <= WATER_END) {\n // Water lanes\n const direction = row % 2 === 0 ? 1 : -1;\n const speed = (0.04 + Math.random() * 0.05) * direction * speedMult; // Halved for 2x frame rate\n const lane: Lane = { type: 'water', speed, logs: [] };\n\n const logCount = 2 + Math.floor(Math.random() * 2);\n const spacing = GAME_WIDTH / logCount;\n\n for (let l = 0; l < logCount; l++) {\n const isTurtle = Math.random() < 0.3 && level >= 2;\n const width = isTurtle ? 4 : 4 + Math.floor(Math.random() * 3);\n\n lane.logs!.push({\n x: l * spacing + Math.random() * (spacing / 3),\n width,\n sprite: isTurtle ? TURTLE.repeat(2) : LOG_CHAR.repeat(width),\n isTurtle,\n submergeTimer: isTurtle ? Math.random() * 200 : undefined,\n });\n }\n lanes.push(lane);\n } else if (row === GOAL_ROW) {\n lanes.push({ type: 'goal', speed: 0 });\n } else {\n lanes.push({ type: 'safe', speed: 0 });\n }\n }\n }\n\n function initGame() {\n score = 0;\n level = 1;\n lives = 3;\n gameOver = false;\n paused = false;\n lilyPads = [false, false, false, false, false];\n timeRemaining = TIME_LIMIT;\n lastTimeUpdate = Date.now();\n furthestY = GAME_HEIGHT - 1;\n\n particles = [];\n shakeFrames = 0;\n deathFlash = 0;\n winFlash = 0;\n\n calculateLilyPads();\n generateLanes();\n resetPlayer();\n }\n\n function resetPlayer() {\n playerX = Math.floor(GAME_WIDTH / 2);\n playerY = GAME_HEIGHT - 1;\n playerOnLog = false;\n furthestY = GAME_HEIGHT - 1;\n timeRemaining = TIME_LIMIT;\n lastTimeUpdate = Date.now();\n hopFrame = 0;\n }\n\n function advanceLevel() {\n level++;\n lilyPads = [false, false, false, false, false];\n timeRemaining = TIME_LIMIT;\n lastTimeUpdate = Date.now();\n\n const bonus = level * 500 + Math.floor(timeRemaining) * 5;\n score += bonus;\n if (score > highScore) highScore = score;\n\n winFlash = 25;\n for (let i = 0; i < 3; i++) {\n spawnSuccess(Math.random() * GAME_WIDTH, Math.random() * GAME_HEIGHT);\n }\n\n generateLanes();\n resetPlayer();\n }\n\n function die() {\n lives--;\n spawnCrash(playerX, playerY);\n shakeFrames = 12;\n deathFlash = 15;\n\n if (lives <= 0) {\n gameOver = true;\n if (score > highScore) highScore = score;\n } else {\n resetPlayer();\n }\n }\n\n // -------------------------------------------------------------------------\n // COLLISION\n // -------------------------------------------------------------------------\n\n function getLaneAt(y: number): Lane | null {\n const row = GAME_HEIGHT - 1 - y;\n if (row < 0 || row >= lanes.length) return null;\n return lanes[row];\n }\n\n function checkVehicleCollision(): boolean {\n const lane = getLaneAt(playerY);\n if (!lane || lane.type !== 'road' || !lane.vehicles) return false;\n\n for (const v of lane.vehicles) {\n const vLeft = v.x;\n const vRight = v.x + v.width;\n if (playerX >= vLeft && playerX < vRight) {\n return true;\n }\n // Handle wrap\n if (vLeft < 0 && playerX >= GAME_WIDTH + vLeft) return true;\n if (vRight > GAME_WIDTH && playerX < vRight - GAME_WIDTH) return true;\n }\n return false;\n }\n\n function checkWaterSafety(): { safe: boolean; speed: number } {\n const lane = getLaneAt(playerY);\n if (!lane || lane.type !== 'water' || !lane.logs) {\n return { safe: false, speed: 0 };\n }\n\n for (const log of lane.logs) {\n // Skip submerged turtles\n if (log.isTurtle && log.submergeTimer !== undefined && log.submergeTimer < 30) {\n continue;\n }\n\n const logLeft = log.x;\n const logRight = log.x + log.width;\n\n if (playerX >= logLeft && playerX < logRight) {\n return { safe: true, speed: lane.speed };\n }\n // Handle wrap\n if (logLeft < 0 && playerX >= GAME_WIDTH + logLeft) {\n return { safe: true, speed: lane.speed };\n }\n if (logRight > GAME_WIDTH && playerX < logRight - GAME_WIDTH) {\n return { safe: true, speed: lane.speed };\n }\n }\n\n return { safe: false, speed: 0 };\n }\n\n function checkGoal() {\n const row = GAME_HEIGHT - 1 - playerY;\n if (row !== GOAL_ROW) return;\n\n for (let i = 0; i < LILY_PAD_COUNT; i++) {\n const padX = lilyPadX[i];\n // Lily pad visual is \"(○)\" at padX, padX+1, padX+2\n // Center collision on the middle character (padX+1) with ±2 tolerance\n const padCenter = padX + 1;\n if (Math.abs(playerX - padCenter) <= 2) {\n if (!lilyPads[i]) {\n lilyPads[i] = true;\n const bonus = 100 + timeRemaining * 5;\n score += bonus;\n spawnSuccess(padCenter, playerY); // Spawn particles at pad center\n\n if (lilyPads.every(p => p)) {\n advanceLevel();\n return;\n }\n resetPlayer();\n return;\n } else {\n // Already filled - die\n die();\n return;\n }\n }\n }\n // Missed lily pad - die (fell into water)\n spawnSplash(playerX, playerY);\n die();\n }\n\n // -------------------------------------------------------------------------\n // UPDATE\n // -------------------------------------------------------------------------\n\n function update() {\n if (!gameStarted || gameOver || paused) return;\n\n // Timer\n const now = Date.now();\n if (now - lastTimeUpdate >= 1000) {\n timeRemaining--;\n lastTimeUpdate = now;\n if (timeRemaining <= 0) {\n die();\n return;\n }\n }\n\n // Particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.015;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update flash counters\n if (shakeFrames > 0) shakeFrames--;\n if (deathFlash > 0) deathFlash--;\n if (winFlash > 0) winFlash--;\n\n // Hop animation\n if (hopFrame > 0) hopFrame--;\n\n // Move vehicles and logs\n for (const lane of lanes) {\n if (lane.type === 'road' && lane.vehicles) {\n for (const v of lane.vehicles) {\n v.x += lane.speed;\n if (v.x > GAME_WIDTH) v.x = -v.width;\n if (v.x + v.width < 0) v.x = GAME_WIDTH;\n }\n } else if (lane.type === 'water' && lane.logs) {\n for (const log of lane.logs) {\n log.x += lane.speed;\n if (log.x > GAME_WIDTH) log.x = -log.width;\n if (log.x + log.width < 0) log.x = GAME_WIDTH;\n\n // Turtle submerge cycle\n if (log.isTurtle && log.submergeTimer !== undefined) {\n log.submergeTimer--;\n if (log.submergeTimer <= 0) {\n log.submergeTimer = 150 + Math.random() * 100;\n }\n }\n }\n }\n }\n\n // Check water safety and move with log\n const lane = getLaneAt(playerY);\n if (lane && lane.type === 'water') {\n const waterCheck = checkWaterSafety();\n if (waterCheck.safe) {\n playerOnLog = true;\n playerX += waterCheck.speed;\n // Boundary check\n if (playerX < 0 || playerX >= GAME_WIDTH) {\n spawnSplash(playerX, playerY);\n die();\n return;\n }\n } else {\n // In water without log\n spawnSplash(playerX, playerY);\n die();\n return;\n }\n } else {\n playerOnLog = false;\n }\n\n // Check vehicle collision\n if (checkVehicleCollision()) {\n die();\n return;\n }\n\n // Check goal\n checkGoal();\n }\n\n // -------------------------------------------------------------------------\n // PLAYER MOVEMENT\n // -------------------------------------------------------------------------\n\n function movePlayer(dx: number, dy: number) {\n const now = Date.now();\n if (now - lastMoveTime < MOVE_COOLDOWN) return;\n lastMoveTime = now;\n\n const newX = playerX + dx;\n const newY = playerY + dy;\n\n if (newX < 0 || newX >= GAME_WIDTH) return;\n if (newY < 0 || newY >= GAME_HEIGHT) return;\n\n playerX = newX;\n playerY = newY;\n hopFrame = 4;\n\n // Score for forward progress\n if (dy < 0 && playerY < furthestY) {\n score += 10;\n furthestY = playerY;\n }\n\n // Immediate collision check\n const lane = getLaneAt(playerY);\n\n if (lane && lane.type === 'road') {\n if (checkVehicleCollision()) {\n die();\n return;\n }\n }\n\n if (lane && lane.type === 'water') {\n const waterCheck = checkWaterSafety();\n if (!waterCheck.safe) {\n spawnSplash(playerX, playerY);\n die();\n return;\n }\n playerOnLog = true;\n }\n\n checkGoal();\n }\n\n // -------------------------------------------------------------------------\n // RENDERING\n // -------------------------------------------------------------------------\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const msg2 = `Need: ${MIN_COLS}×${MIN_ROWS} Have: ${cols}×${rows}`;\n const hint = cols < MIN_COLS && rows < MIN_ROWS ? 'Make pane larger'\n : cols < MIN_COLS ? 'Make pane wider →' : 'Make pane taller ↓';\n const cx = Math.floor(cols / 2);\n const cy = Math.floor(rows / 2);\n output += `\\x1b[${cy - 1};${Math.max(1, cx - msg1.length / 2)}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${cy + 1};${Math.max(1, cx - msg2.length / 2)}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${cy + 3};${Math.max(1, cx - hint.length / 2)}H${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Adaptive dimensions\n GAME_WIDTH = Math.min(cols - 4, 50);\n GAME_HEIGHT = Math.min(rows - 8, 15);\n gameLeft = Math.floor((cols - GAME_WIDTH - 2) / 2);\n gameTop = Math.floor((rows - GAME_HEIGHT - 6) / 2) + 2;\n\n // Recalculate lily pads if needed\n if (lilyPadX.length === 0) {\n calculateLilyPads();\n }\n\n // Apply shake\n let renderLeft = gameLeft;\n let renderTop = gameTop;\n if (shakeFrames > 0) {\n renderLeft += Math.floor((Math.random() - 0.5) * 4);\n renderTop += Math.floor((Math.random() - 0.5) * 2);\n }\n\n // Title\n const titleX = Math.floor((cols - title[0].length) / 2);\n output += `\\x1b[1;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n\n // Stats\n const hearts = '♥'.repeat(lives);\n const timerColor = timeRemaining <= 10 ? '\\x1b[91m' : '\\x1b[97m';\n const stats = `SCORE: ${score.toString().padStart(5, '0')} LVL: ${level} TIME: ${timerColor}${timeRemaining.toString().padStart(2, '0')}\\x1b[0m \\x1b[91m${hearts}\\x1b[0m`;\n const statsX = Math.floor((cols - 45) / 2);\n output += `\\x1b[${gameTop - 1};${statsX}H${stats}`;\n\n // Border\n let borderColor = themeColor;\n if (deathFlash > 0 && deathFlash % 4 < 2) borderColor = '\\x1b[91m';\n if (winFlash > 0 && winFlash % 4 < 2) borderColor = '\\x1b[92m';\n\n output += `\\x1b[${renderTop};${renderLeft}H${borderColor}╔${'═'.repeat(GAME_WIDTH)}╗\\x1b[0m`;\n for (let y = 0; y < GAME_HEIGHT; y++) {\n output += `\\x1b[${renderTop + 1 + y};${renderLeft}H${borderColor}║\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + y};${renderLeft + GAME_WIDTH + 1}H${borderColor}║\\x1b[0m`;\n }\n output += `\\x1b[${renderTop + GAME_HEIGHT + 1};${renderLeft}H${borderColor}╚${'═'.repeat(GAME_WIDTH)}╝\\x1b[0m`;\n\n // PAUSE MENU\n if (paused) {\n const pauseMsg = '══ PAUSED ══';\n const cx = Math.floor(cols / 2);\n const pauseY = gameTop + Math.floor(GAME_HEIGHT / 2) - 2;\n output += `\\x1b[${pauseY};${cx - pauseMsg.length / 2}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: cx,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n }\n // START SCREEN\n else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO PLAY ]';\n const startX = gameLeft + Math.floor((GAME_WIDTH - startMsg.length) / 2) + 1;\n const startY = gameTop + Math.floor(GAME_HEIGHT / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = '← → ↑ ↓ Move ESC Menu';\n const ctrlX = gameLeft + Math.floor((GAME_WIDTH - controls.length) / 2) + 1;\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${controls}\\x1b[0m`;\n\n const desc = 'Cross roads and rivers to reach the lily pads!';\n const descX = gameLeft + Math.floor((GAME_WIDTH - desc.length) / 2) + 1;\n output += `\\x1b[${startY + 4};${descX}H\\x1b[2m${desc}\\x1b[0m`;\n }\n // GAME OVER\n else if (gameOver) {\n const overMsg = '╔══ GAME OVER ══╗';\n const overX = gameLeft + Math.floor((GAME_WIDTH - overMsg.length) / 2) + 1;\n const overY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n output += `\\x1b[${overY};${overX}H\\x1b[1;91m${overMsg}\\x1b[0m`;\n\n const scoreLine = `SCORE: ${score} HIGH: ${highScore}`;\n const scoreX = gameLeft + Math.floor((GAME_WIDTH - scoreLine.length) / 2) + 1;\n output += `\\x1b[${overY + 1};${scoreX}H${themeColor}${scoreLine}\\x1b[0m`;\n\n const restart = '╚ [R] RETRY [Q] QUIT ╝';\n const restartX = gameLeft + Math.floor((GAME_WIDTH - restart.length) / 2) + 1;\n output += `\\x1b[${overY + 2};${restartX}H\\x1b[2m${restart}\\x1b[0m`;\n }\n // GAMEPLAY\n else {\n // Draw lanes\n for (let y = 0; y < GAME_HEIGHT; y++) {\n const row = GAME_HEIGHT - 1 - y;\n if (row < 0 || row >= lanes.length) continue;\n\n const lane = lanes[row];\n const screenY = renderTop + 1 + y;\n\n // Background\n let bgColor = '\\x1b[48;5;22m'; // Green grass\n let bgChar = ' ';\n\n if (lane.type === 'road') {\n bgColor = '\\x1b[48;5;236m'; // Dark gray road\n bgChar = ' ';\n } else if (lane.type === 'water') {\n bgColor = '\\x1b[48;5;17m'; // Dark blue water\n bgChar = '~';\n } else if (lane.type === 'goal') {\n bgColor = '\\x1b[48;5;22m'; // Green\n bgChar = ' ';\n }\n\n output += `\\x1b[${screenY};${renderLeft + 1}H${bgColor}\\x1b[34m${bgChar.repeat(GAME_WIDTH)}\\x1b[0m`;\n\n // Draw lily pads in goal row\n if (lane.type === 'goal') {\n for (let i = 0; i < LILY_PAD_COUNT; i++) {\n const padX = lilyPadX[i];\n if (padX >= 0 && padX < GAME_WIDTH - 2) {\n const screenX = renderLeft + 1 + padX;\n if (lilyPads[i]) {\n output += `\\x1b[${screenY};${screenX}H\\x1b[92m[◎]\\x1b[0m`;\n } else {\n output += `\\x1b[${screenY};${screenX}H\\x1b[32m(○)\\x1b[0m`;\n }\n }\n }\n }\n\n // Draw vehicles\n if (lane.type === 'road' && lane.vehicles) {\n for (const v of lane.vehicles) {\n const vx = Math.floor(v.x);\n if (vx >= 0 && vx + v.width <= GAME_WIDTH) {\n output += `\\x1b[${screenY};${renderLeft + 1 + vx}H${v.color}${v.sprite}\\x1b[0m`;\n } else if (vx < 0) {\n // Wrap from left\n const visible = v.sprite.slice(-vx);\n if (visible.length > 0) {\n output += `\\x1b[${screenY};${renderLeft + 1}H${v.color}${visible}\\x1b[0m`;\n }\n } else if (vx < GAME_WIDTH) {\n // Partial from right\n const visible = v.sprite.slice(0, GAME_WIDTH - vx);\n output += `\\x1b[${screenY};${renderLeft + 1 + vx}H${v.color}${visible}\\x1b[0m`;\n }\n }\n }\n\n // Draw logs/turtles\n if (lane.type === 'water' && lane.logs) {\n for (const log of lane.logs) {\n // Skip submerged turtles\n const isSubmerged = log.isTurtle && log.submergeTimer !== undefined && log.submergeTimer < 30;\n\n const lx = Math.floor(log.x);\n const logColor = isSubmerged ? '\\x1b[34m' : (log.isTurtle ? '\\x1b[92m' : '\\x1b[33m');\n const displaySprite = isSubmerged ? '∼'.repeat(log.width) : log.sprite;\n\n if (lx >= 0 && lx + log.width <= GAME_WIDTH) {\n output += `\\x1b[${screenY};${renderLeft + 1 + lx}H${logColor}${displaySprite.slice(0, log.width)}\\x1b[0m`;\n } else if (lx < 0) {\n const visible = displaySprite.slice(-lx, log.width);\n if (visible.length > 0) {\n output += `\\x1b[${screenY};${renderLeft + 1}H${logColor}${visible}\\x1b[0m`;\n }\n } else if (lx < GAME_WIDTH) {\n const visible = displaySprite.slice(0, GAME_WIDTH - lx);\n output += `\\x1b[${screenY};${renderLeft + 1 + lx}H${logColor}${visible}\\x1b[0m`;\n }\n }\n }\n }\n\n // Draw frog\n const frogScreenX = renderLeft + 1 + Math.floor(playerX);\n const frogScreenY = renderTop + 1 + playerY;\n let frogChar = FROG_IDLE;\n if (hopFrame > 0) frogChar = FROG_HOP;\n else if (playerOnLog) frogChar = FROG_ON_LOG;\n\n const frogColor = deathFlash > 0 ? '\\x1b[91m' : '\\x1b[1;92m';\n output += `\\x1b[${frogScreenY};${frogScreenX}H${frogColor}${frogChar}\\x1b[0m`;\n\n // Draw particles\n for (const p of particles) {\n const sx = Math.round(renderLeft + 1 + p.x);\n const sy = Math.round(renderTop + 1 + p.y);\n if (sx > renderLeft && sx < renderLeft + GAME_WIDTH + 1 &&\n sy > renderTop && sy < renderTop + GAME_HEIGHT + 1) {\n output += `\\x1b[${sy};${sx}H${p.color}${p.char}\\x1b[0m`;\n }\n }\n }\n\n // Bottom hint\n const hint = gameStarted && !gameOver && !paused ? `HIGH: ${highScore} [ ESC ] MENU` : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${gameTop + GAME_HEIGHT + 3};${hintX}H\\x1b[2m${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n // -------------------------------------------------------------------------\n // GAME LOOP\n // -------------------------------------------------------------------------\n\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) { clearInterval(gameInterval); return; }\n update();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n if (key === 'q' && (paused || gameOver || !gameStarted)) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n\n if (!gameStarted && !paused) {\n gameStarted = true;\n return;\n }\n\n if (gameOver) {\n if (key === 'r') {\n if (score > highScore) highScore = score;\n initGame();\n gameStarted = true;\n }\n return;\n }\n\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: paused = false; break;\n case 1: initGame(); gameStarted = true; paused = false; break;\n case 2:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n if (key === 'r') { initGame(); gameStarted = true; paused = false; }\n else if (key === 'l') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGamesMenu(terminal); }\n else if (key === 'n') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGameSwitch(terminal); }\n return;\n }\n\n // Movement\n switch (domEvent.key) {\n case 'ArrowLeft':\n case 'a':\n movePlayer(-1, 0);\n break;\n case 'ArrowRight':\n case 'd':\n movePlayer(1, 0);\n break;\n case 'ArrowUp':\n case 'w':\n movePlayer(0, -1);\n break;\n case 'ArrowDown':\n case 's':\n movePlayer(0, 1);\n break;\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Hangman\n *\n * Cyberpunk-themed word guessing game with glitchy effects,\n * neon visuals, and theme-aware colors.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor, getVerticalAnchor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Hangman Game Controller\n */\nexport interface HangmanController {\n stop: () => void;\n isRunning: boolean;\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\n// Word list - cyberpunk/tech themed\nconst WORDS = [\n 'TERMINAL', 'HACKER', 'MATRIX', 'CYBER', 'NEURAL', 'QUANTUM',\n 'BINARY', 'PROTOCOL', 'NETWORK', 'ENCRYPT', 'DECRYPT', 'SYSTEM',\n 'CIRCUIT', 'DAEMON', 'KERNEL', 'BUFFER', 'MEMORY', 'PROCESS',\n 'SCRIPT', 'MODULE', 'VECTOR', 'SYNTAX', 'COMPILE', 'RUNTIME',\n 'CURSOR', 'PROMPT', 'SHELL', 'STREAM', 'SIGNAL', 'THREAD',\n 'SOCKET', 'SERVER', 'CLIENT', 'PACKET', 'ROUTER', 'FIREWALL',\n 'PROXY', 'TOKEN', 'CIPHER', 'BREACH', 'SPLICE', 'INJECT',\n 'PATCH', 'DEBUG', 'TRACE', 'STACK', 'HEAP', 'CACHE',\n 'NEXUS', 'PULSE', 'GHOST', 'SHADOW', 'BLADE', 'CHROME',\n 'NEON', 'SYNTH', 'GRID', 'SURGE', 'FLUX', 'STORM',\n];\n\n// ASCII art hangman stages\nconst HANGMAN_STAGES = [\n // 0 mistakes\n [\n ' ┌───────┐ ',\n ' │ │ ',\n ' │ ',\n ' │ ',\n ' │ ',\n ' │ ',\n '══╧════════ ',\n ],\n // 1 mistake - head\n [\n ' ┌───────┐ ',\n ' │ │ ',\n ' │ ◯ ',\n ' │ ',\n ' │ ',\n ' │ ',\n '══╧════════ ',\n ],\n // 2 mistakes - body\n [\n ' ┌───────┐ ',\n ' │ │ ',\n ' │ ◯ ',\n ' │ │ ',\n ' │ ',\n ' │ ',\n '══╧════════ ',\n ],\n // 3 mistakes - left arm\n [\n ' ┌───────┐ ',\n ' │ │ ',\n ' │ ◯ ',\n ' │ ╱│ ',\n ' │ ',\n ' │ ',\n '══╧════════ ',\n ],\n // 4 mistakes - right arm\n [\n ' ┌───────┐ ',\n ' │ │ ',\n ' │ ◯ ',\n ' │ ╱│╲ ',\n ' │ ',\n ' │ ',\n '══╧════════ ',\n ],\n // 5 mistakes - left leg\n [\n ' ┌───────┐ ',\n ' │ │ ',\n ' │ ◯ ',\n ' │ ╱│╲ ',\n ' │ ╱ ',\n ' │ ',\n '══╧════════ ',\n ],\n // 6 mistakes - dead\n [\n ' ┌───────┐ ',\n ' │ │ ',\n ' │ ◯ ',\n ' │ ╱│╲ ',\n ' │ ╱ ╲ ',\n ' │ ',\n '══╧════════ ',\n ],\n];\n\n/**\n * Cyberpunk Hangman Game\n */\nexport function runHangmanGame(terminal: Terminal): HangmanController {\n const themeColor = getCurrentThemeColor();\n\n // Game dimensions\n const GAME_WIDTH = 40;\n\n // Minimum terminal size (compact - just needs to fit the content)\n const MIN_COLS = 32;\n const MIN_ROWS = 16;\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let won = false;\n let score = 0;\n let streak = 0;\n let highStreak = 0;\n\n // Game state\n let currentWord = '';\n let guessedLetters: Set<string> = new Set();\n let wrongGuesses = 0;\n const MAX_WRONG = 6;\n\n // Game area positioning\n let gameLeft = 2;\n let gameTop = 4;\n\n // Visual effects\n let glitchFrame = 0;\n let flashWrong = 0;\n let flashRight = 0;\n let winAnimation = 0;\n let loseAnimation = 0;\n let screenShake = 0;\n\n // Juicy effects\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let correctStreak = 0;\n let borderFlash = 0;\n\n const controller: HangmanController = {\n stop: () => {\n if (!running) return;\n running = false;\n // Note: Buffer exit is handled by TerminalPool via dispatchGameQuit\n },\n get isRunning() { return running; }\n };\n\n // ASCII art title\n const title = [\n '█ █ ▄▀█ █▄ █ █▀▀ █▄ ▄█ ▄▀█ █▄ █',\n '█▀█ █▀█ █ ▀█ █▄█ █ ▀ █ █▀█ █ ▀█',\n ];\n\n function updateLayout(rows: number) {\n // Core content: gallows, word, wrong letters, and status rows.\n gameTop = getVerticalAnchor(rows, 16, {\n headerRows: 3,\n footerRows: 2,\n minTop: 4,\n });\n }\n\n function initGame() {\n // Pick a random word\n currentWord = WORDS[Math.floor(Math.random() * WORDS.length)];\n guessedLetters = new Set();\n wrongGuesses = 0;\n gameOver = false;\n won = false;\n paused = false;\n flashWrong = 0;\n flashRight = 0;\n // Reset juicy effects\n particles = [];\n scorePopups = [];\n correctStreak = 0;\n borderFlash = 0;\n screenShake = 0;\n winAnimation = 0;\n loseAnimation = 0;\n }\n\n // Spawn particles at position\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['✦', '★', '◆', '●']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.3 + Math.random() * 0.5;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5 - 0.2,\n life: 15 + Math.floor(Math.random() * 10),\n });\n }\n }\n\n // Add score popup\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 22, color });\n }\n\n function getDisplayWord(): string {\n return currentWord\n .split('')\n .map(letter => guessedLetters.has(letter) ? letter : '_')\n .join(' ');\n }\n\n function getUsedLetters(): string {\n const wrong = [...guessedLetters].filter(l => !currentWord.includes(l)).sort().join(' ');\n return wrong || '-';\n }\n\n function checkWin(): boolean {\n return currentWord.split('').every(letter => guessedLetters.has(letter));\n }\n\n function guessLetter(letter: string) {\n if (gameOver || paused || guessedLetters.has(letter)) return;\n\n guessedLetters.add(letter);\n\n if (currentWord.includes(letter)) {\n // Correct guess\n flashRight = 8;\n borderFlash = 8;\n correctStreak++;\n const letterCount = currentWord.split(letter).length - 1;\n const points = 10 * letterCount;\n score += points;\n\n // Effects based on streak and letter count\n const effectIntensity = Math.min(correctStreak + letterCount, 8);\n screenShake = 2 + Math.floor(effectIntensity / 2);\n\n // Spawn particles at word display area (we'll use center screen)\n const centerX = Math.floor(terminal.cols / 2);\n const wordY = gameTop + 9;\n spawnParticles(centerX, wordY, 4 + effectIntensity, '\\x1b[1;92m', ['✦', '★', '◆', '●']);\n\n // Score popup\n const popupText = letterCount > 1 ? `+${points}!` : `+${points}`;\n const popupColor = correctStreak >= 3 ? '\\x1b[1;93m' : '\\x1b[1;92m';\n addScorePopup(centerX - 2, wordY - 2, popupText, popupColor);\n\n // Streak message\n if (correctStreak >= 3) {\n addScorePopup(centerX - 4, wordY - 4, `${correctStreak}x STREAK!`, '\\x1b[1;96m');\n }\n\n if (checkWin()) {\n won = true;\n gameOver = true;\n streak++;\n if (streak > highStreak) highStreak = streak;\n const bonus = Math.max(0, (MAX_WRONG - wrongGuesses)) * 20;\n score += bonus;\n winAnimation = 30;\n screenShake = 8;\n // Big win explosion\n spawnParticles(centerX, wordY, 15, '\\x1b[1;93m', ['★', '✦', '♦', '◆', '●']);\n if (bonus > 0) {\n addScorePopup(centerX - 3, wordY + 2, `+${bonus} BONUS!`, '\\x1b[1;93m');\n }\n }\n } else {\n // Wrong guess\n flashWrong = 8;\n wrongGuesses++;\n correctStreak = 0; // Reset correct streak on wrong\n\n // Shake and particles\n screenShake = 4 + wrongGuesses;\n\n // Spawn red particles at hangman\n const hangmanX = gameLeft + 6;\n const hangmanY = gameTop + 4;\n spawnParticles(hangmanX, hangmanY, 5, '\\x1b[1;91m', ['✗', '×', '·', '○']);\n\n if (wrongGuesses >= MAX_WRONG) {\n gameOver = true;\n streak = 0;\n loseAnimation = 40;\n screenShake = 20;\n // Death explosion\n spawnParticles(hangmanX, hangmanY, 12, '\\x1b[1;91m', ['✗', '☠', '×', '▒', '░']);\n addScorePopup(hangmanX - 3, hangmanY - 2, 'FAILED!', '\\x1b[1;91m');\n }\n }\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Update effect timers\n if (borderFlash > 0) borderFlash--;\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.03;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.15;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = '';\n if (needWidth && needHeight) {\n hint = 'Make pane larger';\n } else if (needWidth) {\n hint = 'Make pane wider →';\n } else {\n hint = 'Make pane taller ↓';\n }\n const msg2 = `Need: ${MIN_COLS}×${MIN_ROWS} Have: ${cols}×${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n updateLayout(rows);\n\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH) / 2));\n\n // Glitchy title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n const titleTop = Math.max(1, gameTop - 2);\n output += `\\x1b[${titleTop};${titleX}H`;\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n if (paused) {\n const pauseMsg = '══ PAUSED ══';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseY = Math.floor(rows / 2) - 3;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted) {\n // Show start screen\n const startMsg = '[ PRESS ANY KEY TO START ]';\n const startX = Math.floor((cols - startMsg.length) / 2);\n const startY = Math.floor(rows / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = 'A-Z GUESS ESC MENU';\n const ctrlX = Math.floor((cols - controls.length) / 2);\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n } else {\n // Apply screen shake offset\n const shakeOffsetX = screenShake > 0 ? Math.floor((Math.random() - 0.5) * Math.min(screenShake, 3)) : 0;\n const shakeOffsetY = screenShake > 0 ? Math.floor((Math.random() - 0.5) * Math.min(screenShake / 2, 1)) : 0;\n const renderLeft = gameLeft + shakeOffsetX;\n const renderTop = gameTop + shakeOffsetY;\n\n // Stats bar\n const statsColor = borderFlash > 0 && borderFlash % 4 < 2 ? '\\x1b[1;92m' : themeColor;\n const stats = `SCORE: ${score.toString().padStart(4, '0')} STREAK: ${streak} BEST: ${highStreak}`;\n const statsX = Math.floor((cols - stats.length) / 2) + shakeOffsetX;\n output += `\\x1b[${gameTop - 1};${statsX}H${statsColor}${stats}\\x1b[0m`;\n\n // Draw hangman with shake\n const hangmanStage = HANGMAN_STAGES[Math.min(wrongGuesses, MAX_WRONG)];\n const hangmanColor = flashWrong > 0 && flashWrong % 4 < 2 ? '\\x1b[1;91m' : themeColor;\n for (let i = 0; i < hangmanStage.length; i++) {\n output += `\\x1b[${renderTop + 1 + i};${renderLeft}H${hangmanColor}${hangmanStage[i]}\\x1b[0m`;\n }\n\n // Draw word display with shake\n const displayWord = getDisplayWord();\n const wordX = Math.floor((cols - displayWord.length) / 2) + shakeOffsetX;\n const wordY = renderTop + 9;\n const wordColor = flashRight > 0 && flashRight % 4 < 2 ? '\\x1b[1;92m' : themeColor;\n output += `\\x1b[${wordY};${wordX}H${wordColor}\\x1b[1m${displayWord}\\x1b[0m`;\n\n // Draw wrong letters\n const wrongLabel = 'WRONG: ';\n const wrongLetters = getUsedLetters();\n const wrongX = Math.floor((cols - (wrongLabel.length + wrongLetters.length)) / 2) + shakeOffsetX;\n const wrongY = wordY + 2;\n output += `\\x1b[${wrongY};${wrongX}H\\x1b[2m${themeColor}${wrongLabel}\\x1b[91m${wrongLetters}\\x1b[0m`;\n\n // Draw remaining guesses\n const remaining = `GUESSES LEFT: ${MAX_WRONG - wrongGuesses}`;\n const remainingX = Math.floor((cols - remaining.length) / 2) + shakeOffsetX;\n output += `\\x1b[${wrongY + 2};${remainingX}H\\x1b[2m${themeColor}${remaining}\\x1b[0m`;\n\n // Draw particles\n for (const p of particles) {\n const px = Math.round(p.x);\n const py = Math.round(p.y);\n if (px > 0 && px < cols && py > 0 && py < rows) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const px = Math.round(popup.x);\n const py = Math.round(popup.y);\n if (py > 0 && py < rows) {\n const alpha = popup.frames > 14 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n\n // Draw correct streak message\n if (correctStreak >= 3 && !gameOver) {\n const streakMsg = correctStreak >= 5 ? `★ ${correctStreak}x STREAK! ★` : `${correctStreak}x STREAK!`;\n const streakX = Math.floor((cols - streakMsg.length) / 2);\n const streakColor = glitchFrame % 6 < 3 ? '\\x1b[1;93m' : '\\x1b[1;96m';\n output += `\\x1b[${gameTop};${streakX}H${streakColor}${streakMsg}\\x1b[0m`;\n }\n\n if (gameOver) {\n const overY = gameTop + 15;\n\n if (won) {\n // Win animation - sparkles and color cycling\n const sparkles = ['✦', '✧', '★', '☆', '·'];\n const colors = ['\\x1b[92m', '\\x1b[96m', '\\x1b[93m', '\\x1b[95m'];\n const sparkleColor = colors[Math.floor(glitchFrame / 5) % colors.length];\n\n // Add sparkles around the message\n if (winAnimation > 0) {\n for (let i = 0; i < 6; i++) {\n const sx = Math.floor(cols / 2) + Math.floor(Math.cos(glitchFrame * 0.3 + i) * 15);\n const sy = overY - 2 + Math.floor(Math.sin(glitchFrame * 0.2 + i) * 2);\n const sparkle = sparkles[Math.floor(Math.random() * sparkles.length)];\n output += `\\x1b[${sy};${sx}H${sparkleColor}${sparkle}\\x1b[0m`;\n }\n }\n\n const overMsg = winAnimation > 20 ? '★ DECODED! ★' : '✦ DECODED! ✦';\n const msgColor = winAnimation > 0 && Math.floor(glitchFrame / 3) % 2 === 0 ? '\\x1b[1;93m' : '\\x1b[1;92m';\n const overX = Math.floor((cols - overMsg.length) / 2);\n output += `\\x1b[${overY};${overX}H${msgColor}${overMsg}\\x1b[0m`;\n } else {\n // Lose animation - glitch and shake\n const shakeX = screenShake > 0 ? Math.floor(Math.random() * 3) - 1 : 0;\n\n // Glitchy \"TERMINATED\" with random corruption\n let overMsg = '══ TERMINATED ══';\n if (loseAnimation > 20) {\n // Corrupt some characters\n const glitchChars = ['█', '▓', '░', '╳', '┼', '╬'];\n overMsg = overMsg.split('').map(c =>\n Math.random() < 0.2 ? glitchChars[Math.floor(Math.random() * glitchChars.length)] : c\n ).join('');\n }\n\n const loseColor = loseAnimation > 0 && Math.floor(glitchFrame / 2) % 2 === 0 ? '\\x1b[91m' : '\\x1b[1;31m';\n const overX = Math.floor((cols - overMsg.length) / 2) + shakeX;\n output += `\\x1b[${overY};${overX}H${loseColor}${overMsg}\\x1b[0m`;\n\n const wordReveal = `WORD: ${currentWord}`;\n const revealX = Math.floor((cols - wordReveal.length) / 2) + shakeX;\n output += `\\x1b[${overY + 1};${revealX}H${themeColor}${wordReveal}\\x1b[0m`;\n }\n\n const restart = '[ R ] NEW WORD [ ESC ] QUIT';\n const restartX = Math.floor((cols - restart.length) / 2);\n output += `\\x1b[${overY + 3};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n }\n }\n\n // Hint at bottom\n const hint = gameStarted && !gameOver && !paused ? '[ ESC ] MENU' : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${rows - 1};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n // Update flash effects\n if (flashWrong > 0) flashWrong--;\n if (flashRight > 0) flashRight--;\n if (winAnimation > 0) winAnimation--;\n if (loseAnimation > 0) loseAnimation--;\n if (screenShake > 0) screenShake--;\n\n terminal.write(output);\n }\n\n // Start game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) {\n clearInterval(renderInterval);\n return;\n }\n render();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener.dispose();\n return;\n }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // Handle ESC key - toggle pause (works on start screen too)\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Start screen - any key (except ESC handled above) starts the game\n // Skip if paused (ESC menu open on start screen)\n if (!gameStarted && !paused) {\n gameStarted = true;\n return;\n }\n\n // Game over - R to restart\n if (gameOver) {\n if (key === 'r') {\n initGame();\n gameStarted = true;\n }\n return;\n }\n\n // Pause menu actions\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n initGame();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n clearInterval(renderInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n clearInterval(renderInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n clearInterval(renderInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (key === 'r') {\n initGame();\n gameStarted = true;\n paused = false;\n } else if (key === 'l') {\n clearInterval(renderInterval);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (key === 'n') {\n clearInterval(renderInterval);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n // Handle letter guesses (only A-Z)\n if (/^[a-z]$/.test(key)) {\n guessLetter(key.toUpperCase());\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 50);\n\n return controller;\n}\n","/**\n * Hyper Minesweeper\n *\n * Cyberpunk minesweeper - \"defuse the malware grid\".\n * Navigate the grid, flag malware, reveal safe sectors.\n * Theme-aware with glitchy effects and particle systems.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Minesweeper Game Controller\n */\nexport interface MinesweeperController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface Cell {\n isMine: boolean;\n isRevealed: boolean;\n isFlagged: boolean;\n adjacentMines: number;\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\ninterface Difficulty {\n name: string;\n width: number;\n height: number;\n mines: number;\n minCols: number;\n minRows: number;\n}\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nconst DIFFICULTIES: Difficulty[] = [\n { name: 'EASY', width: 9, height: 9, mines: 10, minCols: 32, minRows: 16 },\n { name: 'MEDIUM', width: 16, height: 16, mines: 40, minCols: 44, minRows: 20 },\n { name: 'HARD', width: 20, height: 16, mines: 60, minCols: 54, minRows: 20 },\n];\n\n// Cell display characters\nconst CELL_HIDDEN = '[]';\nconst CELL_FLAG = '<>';\nconst CELL_MINE = '@@';\nconst CELL_EMPTY = ' ';\n\n// Number colors (1-8)\nconst NUMBER_COLORS = [\n '', // 0 - not used\n '\\x1b[96m', // 1 - cyan\n '\\x1b[92m', // 2 - green\n '\\x1b[91m', // 3 - red\n '\\x1b[94m', // 4 - blue\n '\\x1b[95m', // 5 - magenta\n '\\x1b[36m', // 6 - dark cyan\n '\\x1b[97m', // 7 - white\n '\\x1b[90m', // 8 - gray\n];\n\n// ============================================================================\n// MAIN GAME FUNCTION\n// ============================================================================\n\nexport function runMinesweeperGame(terminal: Terminal): MinesweeperController {\n const themeColor = getCurrentThemeColor();\n\n // -------------------------------------------------------------------------\n // STATE\n // -------------------------------------------------------------------------\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let won = false;\n let firstClick = true;\n\n // Difficulty\n let difficultyIndex = 0;\n let difficulty = DIFFICULTIES[difficultyIndex];\n let selectingDifficulty = true;\n let difficultySelection = 0;\n\n // Grid\n let grid: Cell[][] = [];\n let cursorX = 0;\n let cursorY = 0;\n\n // Stats\n let flagsPlaced = 0;\n let cellsRevealed = 0;\n let startTime = 0;\n let elapsedTime = 0;\n\n // Visual effects\n let glitchFrame = 0;\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let shakeFrames = 0;\n let shakeIntensity = 0;\n let scanLineY = -1;\n let scanLineFrames = 0;\n\n // Positioning\n let gameLeft = 2;\n let gameTop = 4;\n\n // -------------------------------------------------------------------------\n // CONTROLLER\n // -------------------------------------------------------------------------\n const controller: MinesweeperController = {\n stop: () => {\n if (!running) return;\n running = false;\n },\n get isRunning() { return running; }\n };\n\n // -------------------------------------------------------------------------\n // ASCII ART TITLE\n // -------------------------------------------------------------------------\n const title = [\n '█▄ ▄█ █ █▄ █ █▀▀ █▀▀ █ █ █ █▀▀ █▀▀ █▀█ █▀▀ █▀█',\n '█ ▀ █ █ █ ▀█ ██▄ ▄▄█ ▀▄▀▄▀ ██▄ ██▄ █▀▀ ██▄ █▀▄',\n ];\n\n // -------------------------------------------------------------------------\n // EFFECTS\n // -------------------------------------------------------------------------\n\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['*', '+', '.', 'o']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.2 + Math.random() * 0.4;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 10 + Math.floor(Math.random() * 8),\n });\n }\n }\n\n function spawnExplosion(x: number, y: number) {\n // Big explosion for mine hit\n const colors = ['\\x1b[1;91m', '\\x1b[1;93m', '\\x1b[1;97m'];\n const chars = ['*', '#', '@', '%', '!', 'X'];\n for (let i = 0; i < 20; i++) {\n const angle = (Math.PI * 2 * i) / 20 + Math.random() * 0.3;\n const speed = 0.3 + Math.random() * 0.5;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color: colors[Math.floor(Math.random() * colors.length)],\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5 - 0.2,\n life: 15 + Math.floor(Math.random() * 10),\n });\n }\n }\n\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 20, color });\n }\n\n function triggerShake(frames: number, intensity: number) {\n shakeFrames = frames;\n shakeIntensity = intensity;\n }\n\n // -------------------------------------------------------------------------\n // GRID GENERATION\n // -------------------------------------------------------------------------\n\n function createEmptyGrid(): Cell[][] {\n const newGrid: Cell[][] = [];\n for (let y = 0; y < difficulty.height; y++) {\n const row: Cell[] = [];\n for (let x = 0; x < difficulty.width; x++) {\n row.push({\n isMine: false,\n isRevealed: false,\n isFlagged: false,\n adjacentMines: 0,\n });\n }\n newGrid.push(row);\n }\n return newGrid;\n }\n\n function placeMines(safeX: number, safeY: number) {\n // Place mines avoiding the first clicked cell and its neighbors\n let minesPlaced = 0;\n while (minesPlaced < difficulty.mines) {\n const x = Math.floor(Math.random() * difficulty.width);\n const y = Math.floor(Math.random() * difficulty.height);\n\n // Skip if already a mine\n if (grid[y][x].isMine) continue;\n\n // Skip if within safe zone (3x3 around first click)\n if (Math.abs(x - safeX) <= 1 && Math.abs(y - safeY) <= 1) continue;\n\n grid[y][x].isMine = true;\n minesPlaced++;\n }\n\n // Calculate adjacent mine counts\n for (let y = 0; y < difficulty.height; y++) {\n for (let x = 0; x < difficulty.width; x++) {\n if (!grid[y][x].isMine) {\n grid[y][x].adjacentMines = countAdjacentMines(x, y);\n }\n }\n }\n }\n\n function countAdjacentMines(x: number, y: number): number {\n let count = 0;\n for (let dy = -1; dy <= 1; dy++) {\n for (let dx = -1; dx <= 1; dx++) {\n if (dx === 0 && dy === 0) continue;\n const nx = x + dx;\n const ny = y + dy;\n if (nx >= 0 && nx < difficulty.width && ny >= 0 && ny < difficulty.height) {\n if (grid[ny][nx].isMine) count++;\n }\n }\n }\n return count;\n }\n\n // -------------------------------------------------------------------------\n // GAME LOGIC\n // -------------------------------------------------------------------------\n\n function initGame() {\n difficulty = DIFFICULTIES[difficultyIndex];\n grid = createEmptyGrid();\n cursorX = Math.floor(difficulty.width / 2);\n cursorY = Math.floor(difficulty.height / 2);\n flagsPlaced = 0;\n cellsRevealed = 0;\n startTime = 0;\n elapsedTime = 0;\n gameOver = false;\n won = false;\n paused = false;\n firstClick = true;\n\n // Reset effects\n particles = [];\n scorePopups = [];\n shakeFrames = 0;\n scanLineY = -1;\n scanLineFrames = 0;\n }\n\n function revealCell(x: number, y: number, isChain = false) {\n if (x < 0 || x >= difficulty.width || y < 0 || y >= difficulty.height) return;\n const cell = grid[y][x];\n if (cell.isRevealed || cell.isFlagged) return;\n\n // First click - place mines avoiding this cell\n if (firstClick) {\n placeMines(x, y);\n firstClick = false;\n startTime = Date.now();\n\n // Start scan line effect\n scanLineY = 0;\n scanLineFrames = 40;\n }\n\n cell.isRevealed = true;\n cellsRevealed++;\n\n // Hit a mine!\n if (cell.isMine) {\n gameOver = true;\n won = false;\n triggerShake(25, 4);\n spawnExplosion(x * 2 + 1, y);\n addScorePopup(x * 2, y - 1, 'MALWARE!', '\\x1b[1;91m');\n revealAllMines();\n return;\n }\n\n // Spawn reveal particles\n if (!isChain) {\n spawnParticles(x * 2 + 1, y, 4, themeColor, ['.', '*', '+']);\n }\n\n // If empty cell, flood fill reveal\n if (cell.adjacentMines === 0) {\n for (let dy = -1; dy <= 1; dy++) {\n for (let dx = -1; dx <= 1; dx++) {\n if (dx !== 0 || dy !== 0) {\n // Add small delay for cascade effect\n setTimeout(() => {\n if (running && !gameOver) {\n revealCell(x + dx, y + dy, true);\n }\n }, 20);\n }\n }\n }\n }\n\n checkWin();\n }\n\n function toggleFlag(x: number, y: number) {\n const cell = grid[y][x];\n if (cell.isRevealed) return;\n\n cell.isFlagged = !cell.isFlagged;\n if (cell.isFlagged) {\n flagsPlaced++;\n spawnParticles(x * 2 + 1, y, 3, '\\x1b[1;93m', ['!', '^', '*']);\n } else {\n flagsPlaced--;\n }\n }\n\n function revealAllMines() {\n for (let y = 0; y < difficulty.height; y++) {\n for (let x = 0; x < difficulty.width; x++) {\n if (grid[y][x].isMine) {\n grid[y][x].isRevealed = true;\n }\n }\n }\n }\n\n function checkWin() {\n // Win if all non-mine cells are revealed\n const totalNonMines = difficulty.width * difficulty.height - difficulty.mines;\n if (cellsRevealed >= totalNonMines) {\n gameOver = true;\n won = true;\n triggerShake(10, 2);\n\n // Victory particles\n for (let i = 0; i < 5; i++) {\n const x = Math.floor(Math.random() * difficulty.width);\n const y = Math.floor(Math.random() * difficulty.height);\n spawnParticles(x * 2 + 1, y, 6, '\\x1b[1;92m', ['*', '+', '#']);\n }\n addScorePopup(difficulty.width, difficulty.height / 2, 'GRID SECURE!', '\\x1b[1;92m');\n }\n }\n\n function update() {\n if (!gameStarted || gameOver || paused || selectingDifficulty) return;\n\n // Update timer\n if (startTime > 0 && !gameOver) {\n elapsedTime = Math.floor((Date.now() - startTime) / 1000);\n }\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.03;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.2;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n // Update scan line\n if (scanLineFrames > 0) {\n scanLineFrames--;\n scanLineY = Math.floor((40 - scanLineFrames) / 40 * difficulty.height);\n if (scanLineFrames <= 0) {\n scanLineY = -1;\n }\n }\n }\n\n // -------------------------------------------------------------------------\n // RENDERING\n // -------------------------------------------------------------------------\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Effect timers\n if (shakeFrames > 0) shakeFrames--;\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n const currentDifficulty = DIFFICULTIES[selectingDifficulty ? difficultySelection : difficultyIndex];\n const minCols = currentDifficulty.minCols;\n const minRows = currentDifficulty.minRows;\n\n // Check minimum terminal size\n if (cols < minCols || rows < minRows) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < minCols;\n const needHeight = rows < minRows;\n let hint = needWidth && needHeight ? 'Make pane larger'\n : needWidth ? 'Make pane wider' : 'Make pane taller';\n const msg2 = `Need: ${minCols}x${minRows} Have: ${cols}x${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Calculate game area dimensions\n const gridWidth = difficulty.width * 2 + 2;\n const gridHeight = difficulty.height + 2;\n\n // Center game area\n gameLeft = Math.max(2, Math.floor((cols - gridWidth) / 2));\n gameTop = Math.max(4, Math.floor((rows - gridHeight - 6) / 2) + 3);\n\n // Apply screen shake\n let renderLeft = gameLeft;\n let renderTop = gameTop;\n if (shakeFrames > 0) {\n renderLeft += Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n renderTop += Math.floor((Math.random() - 0.5) * shakeIntensity);\n }\n\n // Glitch title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[1;${titleX}H\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `\\x1b[1;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n // DIFFICULTY SELECTION SCREEN\n if (selectingDifficulty) {\n const selectY = Math.floor(rows / 2) - 3;\n const selectMsg = '[ SELECT DIFFICULTY ]';\n const selectX = Math.floor((cols - selectMsg.length) / 2);\n output += `\\x1b[${selectY};${selectX}H${themeColor}\\x1b[1m${selectMsg}\\x1b[0m`;\n\n for (let i = 0; i < DIFFICULTIES.length; i++) {\n const d = DIFFICULTIES[i];\n const isSelected = i === difficultySelection;\n const label = `${d.name} (${d.width}x${d.height}, ${d.mines} malware)`;\n const labelX = Math.floor((cols - label.length - 4) / 2);\n const style = isSelected ? '\\x1b[1;93m' : `\\x1b[2m${themeColor}`;\n const prefix = isSelected ? ' >' : ' ';\n const suffix = isSelected ? '< ' : ' ';\n output += `\\x1b[${selectY + 2 + i};${labelX}H${style}${prefix}${label}${suffix}\\x1b[0m`;\n }\n\n const hint = 'Arrow keys to select, ENTER to confirm';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${selectY + 6};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n return;\n }\n\n // Stats bar\n const minesLeft = difficulty.mines - flagsPlaced;\n const timeStr = formatTime(elapsedTime);\n const stats = `MALWARE: ${minesLeft.toString().padStart(3, ' ')} TIME: ${timeStr} [${difficulty.name}]`;\n const statsX = Math.floor((cols - stats.length) / 2);\n output += `\\x1b[${renderTop - 1};${statsX}H${themeColor}${stats}\\x1b[0m`;\n\n // Grid border\n const borderColor = gameOver && !won ? '\\x1b[1;91m' : themeColor;\n output += `\\x1b[${renderTop};${renderLeft}H${borderColor}+${'-'.repeat(difficulty.width * 2)}+\\x1b[0m`;\n for (let y = 0; y < difficulty.height; y++) {\n output += `\\x1b[${renderTop + 1 + y};${renderLeft}H${borderColor}|\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + y};${renderLeft + difficulty.width * 2 + 1}H${borderColor}|\\x1b[0m`;\n }\n output += `\\x1b[${renderTop + difficulty.height + 1};${renderLeft}H${borderColor}+${'-'.repeat(difficulty.width * 2)}+\\x1b[0m`;\n\n // PAUSE MENU\n if (paused) {\n const pauseMsg = '== PAUSED ==';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseY = Math.floor(rows / 2) - 3;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = 'Arrow keys select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n }\n // START SCREEN\n else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO SCAN ]';\n const startX = Math.floor((cols - startMsg.length) / 2);\n const startY = Math.floor(rows / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = 'ARROWS move SPACE reveal F flag ESC menu';\n const ctrlX = Math.floor((cols - controls.length) / 2);\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n\n // Draw empty grid preview\n for (let y = 0; y < difficulty.height; y++) {\n for (let x = 0; x < difficulty.width; x++) {\n const cellX = renderLeft + 1 + x * 2;\n const cellY = renderTop + 1 + y;\n output += `\\x1b[${cellY};${cellX}H\\x1b[2m${themeColor}${CELL_HIDDEN}\\x1b[0m`;\n }\n }\n }\n // GAME OVER\n else if (gameOver) {\n // Draw the final grid state\n output += renderGrid(renderLeft, renderTop, false);\n\n const overMsg = won ? '== GRID SECURED ==' : '== MALWARE BREACH ==';\n const overX = Math.floor((cols - overMsg.length) / 2);\n const overY = Math.floor(rows / 2) - 1;\n output += `\\x1b[${overY};${overX}H${won ? '\\x1b[1;92m' : '\\x1b[1;91m'}${overMsg}\\x1b[0m`;\n\n const timeMsg = `Time: ${formatTime(elapsedTime)}`;\n const timeX = Math.floor((cols - timeMsg.length) / 2);\n output += `\\x1b[${overY + 1};${timeX}H${themeColor}${timeMsg}\\x1b[0m`;\n\n const restart = '[ R ] RESTART [ D ] DIFFICULTY [ Q ] QUIT';\n const restartX = Math.floor((cols - restart.length) / 2);\n output += `\\x1b[${overY + 3};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n }\n // GAMEPLAY\n else {\n output += renderGrid(renderLeft, renderTop, true);\n\n // Draw scan line effect\n if (scanLineY >= 0 && scanLineY < difficulty.height) {\n const scanX = renderLeft + 1;\n const scanY = renderTop + 1 + scanLineY;\n output += `\\x1b[${scanY};${scanX}H\\x1b[7m${themeColor}${' '.repeat(difficulty.width * 2)}\\x1b[0m`;\n }\n\n // Draw particles\n for (const p of particles) {\n const screenX = Math.round(renderLeft + 1 + p.x);\n const screenY = Math.round(renderTop + 1 + p.y);\n if (screenX > renderLeft && screenX < renderLeft + difficulty.width * 2 + 1 &&\n screenY > renderTop && screenY < renderTop + difficulty.height + 1) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const screenX = Math.round(renderLeft + 1 + popup.x);\n const screenY = Math.round(renderTop + 1 + popup.y);\n if (screenY > renderTop && screenY < renderTop + difficulty.height + 1) {\n const alpha = popup.frames > 10 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n }\n\n // Bottom hint\n const hint = gameStarted && !gameOver && !paused\n ? `Revealed: ${cellsRevealed}/${difficulty.width * difficulty.height - difficulty.mines} [ ESC ] MENU`\n : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${renderTop + difficulty.height + 3};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n function renderGrid(renderLeft: number, renderTop: number, showCursor: boolean): string {\n let output = '';\n\n for (let y = 0; y < difficulty.height; y++) {\n for (let x = 0; x < difficulty.width; x++) {\n const cell = grid[y][x];\n const cellX = renderLeft + 1 + x * 2;\n const cellY = renderTop + 1 + y;\n const isCursor = showCursor && x === cursorX && y === cursorY;\n\n let cellChar = '';\n let cellColor = '';\n\n if (cell.isRevealed) {\n if (cell.isMine) {\n cellChar = CELL_MINE;\n cellColor = '\\x1b[1;91m';\n } else if (cell.adjacentMines > 0) {\n cellChar = ` ${cell.adjacentMines}`;\n cellColor = NUMBER_COLORS[cell.adjacentMines] || themeColor;\n } else {\n cellChar = CELL_EMPTY;\n cellColor = '\\x1b[2m';\n }\n } else if (cell.isFlagged) {\n cellChar = CELL_FLAG;\n cellColor = '\\x1b[1;93m';\n } else {\n cellChar = CELL_HIDDEN;\n cellColor = `\\x1b[2m${themeColor}`;\n }\n\n if (isCursor) {\n // Cursor highlight - invert colors\n output += `\\x1b[${cellY};${cellX}H\\x1b[7m${cellColor}${cellChar}\\x1b[0m`;\n } else {\n output += `\\x1b[${cellY};${cellX}H${cellColor}${cellChar}\\x1b[0m`;\n }\n }\n }\n\n return output;\n }\n\n function formatTime(seconds: number): string {\n const mins = Math.floor(seconds / 60);\n const secs = seconds % 60;\n return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;\n }\n\n // -------------------------------------------------------------------------\n // GAME LOOP\n // -------------------------------------------------------------------------\n\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n selectingDifficulty = true;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) { clearInterval(gameInterval); return; }\n update();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // ESC toggles pause (not in difficulty select)\n if (key === 'escape' && !selectingDifficulty) {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Q to quit from pause/game over/start screen\n if (key === 'q' && (paused || gameOver || !gameStarted)) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n\n // Difficulty selection\n if (selectingDifficulty) {\n if (domEvent.key === 'ArrowUp') {\n difficultySelection = (difficultySelection - 1 + DIFFICULTIES.length) % DIFFICULTIES.length;\n } else if (domEvent.key === 'ArrowDown') {\n difficultySelection = (difficultySelection + 1) % DIFFICULTIES.length;\n } else if (domEvent.key === 'Enter' || domEvent.key === ' ') {\n difficultyIndex = difficultySelection;\n selectingDifficulty = false;\n initGame();\n } else if (key === 'q') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n }\n return;\n }\n\n // Start screen - any key starts\n if (!gameStarted && !paused) {\n gameStarted = true;\n return;\n }\n\n // Game over\n if (gameOver) {\n if (key === 'r') {\n initGame();\n gameStarted = true;\n } else if (key === 'd') {\n selectingDifficulty = true;\n difficultySelection = difficultyIndex;\n }\n return;\n }\n\n // Pause menu navigation\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: paused = false; break;\n case 1: initGame(); gameStarted = true; paused = false; break;\n case 2:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcuts\n if (key === 'r') { initGame(); gameStarted = true; paused = false; }\n else if (key === 'l') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGamesMenu(terminal); }\n else if (key === 'n') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGameSwitch(terminal); }\n return;\n }\n\n // GAMEPLAY INPUT\n switch (domEvent.key) {\n case 'ArrowLeft':\n case 'a':\n cursorX = Math.max(0, cursorX - 1);\n break;\n case 'ArrowRight':\n case 'd':\n cursorX = Math.min(difficulty.width - 1, cursorX + 1);\n break;\n case 'ArrowUp':\n case 'w':\n cursorY = Math.max(0, cursorY - 1);\n break;\n case 'ArrowDown':\n case 's':\n cursorY = Math.min(difficulty.height - 1, cursorY + 1);\n break;\n case ' ':\n case 'Enter':\n // Reveal cell\n if (!grid[cursorY][cursorX].isFlagged) {\n revealCell(cursorX, cursorY);\n }\n break;\n case 'f':\n case 'F':\n // Toggle flag\n toggleFlag(cursorX, cursorY);\n break;\n }\n });\n\n // Clean up on stop\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Pong\n *\n * Cyberpunk-themed Pong game with glitchy effects,\n * neon visuals, and theme-aware colors.\n * Single player vs AI.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Pong Game Controller\n */\nexport interface PongController {\n stop: () => void;\n isRunning: boolean;\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\n/**\n * Cyberpunk Pong Game\n */\nexport function runPongGame(terminal: Terminal): PongController {\n const themeColor = getCurrentThemeColor();\n\n // Minimum terminal size (reduced for better compatibility)\n const MIN_COLS = 40;\n const MIN_ROWS = 16;\n\n // Game dimensions - adaptive based on terminal size\n // Width: 40-60, Height: 14-20\n const getGameDimensions = () => {\n const cols = terminal.cols;\n const rows = terminal.rows;\n const width = Math.min(60, Math.max(40, cols - 6));\n const height = Math.min(20, Math.max(14, rows - 6));\n return { width, height };\n };\n\n let { width: GAME_WIDTH, height: GAME_HEIGHT } = getGameDimensions();\n const PADDLE_HEIGHT = Math.max(3, Math.min(4, Math.floor(GAME_HEIGHT / 5)));\n const PADDLE_OFFSET = 2;\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n\n // Game area positioning\n let gameLeft = 2;\n let gameTop = 4;\n\n // Scores\n let playerScore = 0;\n let aiScore = 0;\n const WIN_SCORE = 7;\n\n // Paddle positions (y coordinate of top of paddle)\n let playerY = Math.floor((GAME_HEIGHT - PADDLE_HEIGHT) / 2);\n let aiY = Math.floor((GAME_HEIGHT - PADDLE_HEIGHT) / 2);\n\n // Ball state\n let ballX = GAME_WIDTH / 2;\n let ballY = GAME_HEIGHT / 2;\n let ballVX = 0.4;\n let ballVY = 0.3;\n const BALL_SPEED = 0.5;\n const MAX_BALL_SPEED = 0.9;\n\n // AI difficulty (reaction delay)\n let aiReactionTimer = 0;\n const AI_REACTION_DELAY = 3;\n const AI_SPEED = 0.4;\n\n // Visual effects\n let glitchFrame = 0;\n let scoreFlash = 0;\n let ballTrail: { x: number; y: number; speed: number }[] = [];\n\n // Score celebration effects\n let scoreFreeze = 0; // Pause frames after scoring\n let lastScorer: 'player' | 'ai' | null = null;\n let screenShake = 0;\n let goalExplosion: { x: number; y: number; char: string; color: string }[] = [];\n let goalFlashSide: 'left' | 'right' | null = null;\n\n // Juicy effects\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let paddleHitFlash = 0;\n let rallyCount = 0;\n let wallHitFlash = 0;\n\n const controller: PongController = {\n stop: () => {\n if (!running) return;\n running = false;\n // Note: Buffer exit is handled by TerminalPool via dispatchGameQuit\n },\n get isRunning() { return running; }\n };\n\n // ASCII art title\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ █▀█ █▀█ █▄ █ █▀▀',\n '█▀█ █ █▀▀ ██▄ █▀▄ █▀▀ █▄█ █ ▀█ █▄█',\n ];\n\n function initGame() {\n playerY = Math.floor((GAME_HEIGHT - PADDLE_HEIGHT) / 2);\n aiY = Math.floor((GAME_HEIGHT - PADDLE_HEIGHT) / 2);\n resetBall(true);\n gameOver = false;\n paused = false;\n scoreFlash = 0;\n ballTrail = [];\n scoreFreeze = 0;\n lastScorer = null;\n screenShake = 0;\n goalExplosion = [];\n goalFlashSide = null;\n // Reset juicy effects\n particles = [];\n scorePopups = [];\n paddleHitFlash = 0;\n rallyCount = 0;\n wallHitFlash = 0;\n }\n\n // Spawn particles at position\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['✦', '★', '◆', '●']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.2 + Math.random() * 0.4;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 12 + Math.floor(Math.random() * 8),\n });\n }\n }\n\n // Add score popup\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 20, color });\n }\n\n function createGoalExplosion(side: 'left' | 'right') {\n const x = side === 'left' ? 1 : GAME_WIDTH - 2;\n const chars = ['*', '+', '\\u00d7', '\\u25cf', '\\u2022', '\\u2605'];\n const colors = ['\\x1b[93m', '\\x1b[91m', '\\x1b[95m', '\\x1b[96m', '\\x1b[97m'];\n\n goalExplosion = [];\n for (let i = 0; i < 12; i++) {\n goalExplosion.push({\n x: x + (Math.random() - 0.5) * 6,\n y: Math.floor(GAME_HEIGHT / 2) + (Math.random() - 0.5) * GAME_HEIGHT * 0.8,\n char: chars[Math.floor(Math.random() * chars.length)],\n color: colors[Math.floor(Math.random() * colors.length)],\n });\n }\n }\n\n function resetBall(towardsPlayer: boolean) {\n ballX = GAME_WIDTH / 2;\n ballY = GAME_HEIGHT / 2;\n\n // Random angle between -45 and 45 degrees\n const angle = (Math.random() - 0.5) * Math.PI / 2;\n const direction = towardsPlayer ? -1 : 1;\n\n ballVX = Math.cos(angle) * BALL_SPEED * direction;\n ballVY = Math.sin(angle) * BALL_SPEED;\n ballTrail = [];\n rallyCount = 0;\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Update effect timers\n if (paddleHitFlash > 0) paddleHitFlash--;\n if (wallHitFlash > 0) wallHitFlash--;\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.02;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.2;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = '';\n if (needWidth && needHeight) {\n hint = 'Make pane larger';\n } else if (needWidth) {\n hint = 'Make pane wider \\u2192';\n } else {\n hint = 'Make pane taller \\u2193';\n }\n const msg2 = `Need: ${MIN_COLS}\\u00d7${MIN_ROWS} Have: ${cols}\\u00d7${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Update game dimensions on resize\n const newDims = getGameDimensions();\n if (newDims.width !== GAME_WIDTH || newDims.height !== GAME_HEIGHT) {\n // Scale positions to new dimensions\n ballX = (ballX / GAME_WIDTH) * newDims.width;\n ballY = (ballY / GAME_HEIGHT) * newDims.height;\n playerY = Math.min(playerY, newDims.height - PADDLE_HEIGHT);\n aiY = Math.min(aiY, newDims.height - PADDLE_HEIGHT);\n GAME_WIDTH = newDims.width;\n GAME_HEIGHT = newDims.height;\n }\n\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH - 2) / 2));\n gameTop = Math.max(3, Math.floor((rows - GAME_HEIGHT - 4) / 2));\n\n // Apply screen shake\n const shakeOffsetX = screenShake > 0 ? Math.floor(Math.random() * 3) - 1 : 0;\n const shakeOffsetY = screenShake > 0 ? Math.floor(Math.random() * 2) : 0;\n const displayLeft = gameLeft + shakeOffsetX;\n const displayTop = gameTop + shakeOffsetY;\n\n // Glitchy title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n output += `\\x1b[1;${titleX}H`;\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n // Score display with flash effect\n const scoreColor = scoreFlash > 0 ? '\\x1b[1;93m' : themeColor;\n if (scoreFlash > 0) scoreFlash--;\n const scoreDisplay = `YOU [ ${playerScore} ] - [ ${aiScore} ] CPU`;\n const scoreX = Math.floor((cols - scoreDisplay.length) / 2);\n output += `\\x1b[4;${scoreX}H${scoreColor}${scoreDisplay}\\x1b[0m`;\n\n // Goal flash colors\n const leftBorderColor = goalFlashSide === 'left' ? '\\x1b[1;91m' : themeColor;\n const rightBorderColor = goalFlashSide === 'right' ? '\\x1b[1;92m' : themeColor;\n\n // Wall hit flash for top/bottom borders\n const topBottomBorderColor = wallHitFlash > 0 && wallHitFlash % 4 < 2 ? '\\x1b[1;93m' : themeColor;\n\n // Paddle hit flash for all borders\n const borderFlash = paddleHitFlash > 0 && paddleHitFlash % 4 < 2;\n const mainBorderColor = borderFlash ? '\\x1b[1;96m' : topBottomBorderColor;\n\n // Game border\n output += `\\x1b[${displayTop};${displayLeft}H${mainBorderColor}\\u2554${'═'.repeat(GAME_WIDTH)}\\u2557\\x1b[0m`;\n for (let y = 0; y < GAME_HEIGHT; y++) {\n output += `\\x1b[${displayTop + 1 + y};${displayLeft}H${borderFlash ? '\\x1b[1;96m' : leftBorderColor}\\u2551\\x1b[0m`;\n output += `\\x1b[${displayTop + 1 + y};${displayLeft + GAME_WIDTH + 1}H${borderFlash ? '\\x1b[1;96m' : rightBorderColor}\\u2551\\x1b[0m`;\n }\n output += `\\x1b[${displayTop + GAME_HEIGHT + 1};${displayLeft}H${mainBorderColor}\\u255a${'═'.repeat(GAME_WIDTH)}\\u255d\\x1b[0m`;\n\n // Center line (dashed)\n const centerX = displayLeft + 1 + Math.floor(GAME_WIDTH / 2);\n for (let y = 0; y < GAME_HEIGHT; y++) {\n if (y % 2 === 0) {\n output += `\\x1b[${displayTop + 1 + y};${centerX}H\\x1b[2m${themeColor}\\u2502\\x1b[0m`;\n }\n }\n\n if (paused) {\n const pauseMsg = '\\u2550\\u2550 PAUSED \\u2550\\u2550';\n const pauseCenterX = gameLeft + Math.floor(GAME_WIDTH / 2) + 1;\n const pauseY = gameTop + Math.floor(GAME_HEIGHT / 2) - 3;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO START ]';\n const startX = gameLeft + Math.floor((GAME_WIDTH - startMsg.length) / 2) + 1;\n const startY = gameTop + Math.floor(GAME_HEIGHT / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = '\\u2191\\u2193 MOVE ESC MENU FIRST TO 7 WINS';\n const ctrlX = gameLeft + Math.floor((GAME_WIDTH - controls.length) / 2) + 1;\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n } else if (gameOver) {\n const won = playerScore >= WIN_SCORE;\n const overMsg = won ? '\\u2550\\u2550 YOU WIN! \\u2550\\u2550' : '\\u2550\\u2550 CPU WINS \\u2550\\u2550';\n const overX = gameLeft + Math.floor((GAME_WIDTH - overMsg.length) / 2) + 1;\n const overY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n output += `\\x1b[${overY};${overX}H${won ? '\\x1b[1;92m' : '\\x1b[1;91m'}${overMsg}\\x1b[0m`;\n\n const finalScore = `FINAL: ${playerScore} - ${aiScore}`;\n const scoreX2 = gameLeft + Math.floor((GAME_WIDTH - finalScore.length) / 2) + 1;\n output += `\\x1b[${overY + 2};${scoreX2}H${themeColor}${finalScore}\\x1b[0m`;\n\n const restart = '[ R ] REMATCH [ Q ] QUIT';\n const restartX = gameLeft + Math.floor((GAME_WIDTH - restart.length) / 2) + 1;\n output += `\\x1b[${overY + 4};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n } else {\n // Draw goal explosion particles\n for (const particle of goalExplosion) {\n const px = displayLeft + 1 + Math.floor(particle.x);\n const py = displayTop + 1 + Math.floor(particle.y);\n if (particle.y >= 0 && particle.y < GAME_HEIGHT) {\n output += `\\x1b[${py};${px}H${particle.color}${particle.char}\\x1b[0m`;\n }\n }\n\n // Draw ball trail (only if not in score freeze)\n if (scoreFreeze === 0) {\n for (let i = 0; i < ballTrail.length; i++) {\n const trail = ballTrail[i];\n const trailX = displayLeft + 1 + Math.floor(trail.x);\n const trailY = displayTop + 1 + Math.floor(trail.y);\n const brightness = i < ballTrail.length / 2 ? '\\x1b[2m' : '';\n // Color based on speed\n const trailColor = trail.speed > 0.7 ? '\\x1b[91m' : trail.speed > 0.5 ? '\\x1b[93m' : themeColor;\n output += `\\x1b[${trailY};${trailX}H${brightness}${trailColor}\\u00b7\\x1b[0m`;\n }\n\n // Draw ball with color based on speed\n const ballScreenX = displayLeft + 1 + Math.floor(ballX);\n const ballScreenY = displayTop + 1 + Math.floor(ballY);\n const currentSpeed = Math.sqrt(ballVX * ballVX + ballVY * ballVY);\n const ballColor = currentSpeed > 0.7 ? '\\x1b[1;91m' : currentSpeed > 0.5 ? '\\x1b[1;93m' : '\\x1b[1;97m';\n output += `\\x1b[${ballScreenY};${ballScreenX}H${ballColor}\\u25cf\\x1b[0m`;\n }\n\n // Draw particles\n for (const p of particles) {\n const px = Math.round(displayLeft + 1 + p.x);\n const py = Math.round(displayTop + 1 + p.y);\n if (p.x >= 0 && p.x < GAME_WIDTH && p.y >= 0 && p.y < GAME_HEIGHT) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const px = Math.round(displayLeft + 1 + popup.x);\n const py = Math.round(displayTop + 1 + popup.y);\n if (popup.y >= 0 && popup.y < GAME_HEIGHT) {\n const alpha = popup.frames > 12 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n\n // Draw rally counter\n if (rallyCount >= 3) {\n const rallyMsg = rallyCount >= 10 ? `★ ${rallyCount} RALLY! ★` : `${rallyCount} RALLY!`;\n const rallyX = displayLeft + Math.floor((GAME_WIDTH - rallyMsg.length) / 2) + 1;\n const rallyColor = glitchFrame % 6 < 3 ? '\\x1b[1;93m' : '\\x1b[1;96m';\n output += `\\x1b[${displayTop + 2};${rallyX}H${rallyColor}${rallyMsg}\\x1b[0m`;\n }\n\n // Draw player paddle (left side) with hit flash\n const playerPaddleX = displayLeft + 1 + PADDLE_OFFSET;\n const playerPaddleColor = paddleHitFlash > 0 && paddleHitFlash % 4 < 2 ? '\\x1b[1;97m' : themeColor;\n for (let i = 0; i < PADDLE_HEIGHT; i++) {\n const py = Math.floor(playerY) + i;\n if (py >= 0 && py < GAME_HEIGHT) {\n output += `\\x1b[${displayTop + 1 + py};${playerPaddleX}H${playerPaddleColor}\\u2588\\x1b[0m`;\n }\n }\n\n // Draw AI paddle (right side) with hit flash\n const aiPaddleX = displayLeft + GAME_WIDTH - PADDLE_OFFSET;\n const aiPaddleColor = paddleHitFlash > 0 && paddleHitFlash % 4 < 2 ? '\\x1b[1;97m' : '\\x1b[91m';\n for (let i = 0; i < PADDLE_HEIGHT; i++) {\n const ay = Math.floor(aiY) + i;\n if (ay >= 0 && ay < GAME_HEIGHT) {\n output += `\\x1b[${displayTop + 1 + ay};${aiPaddleX}H${aiPaddleColor}\\u2588\\x1b[0m`;\n }\n }\n\n // Draw score message during freeze\n if (scoreFreeze > 0 && lastScorer) {\n const scoreMsg = lastScorer === 'player' ? '\\u2605 GOAL! \\u2605' : '\\u2716 MISS! \\u2716';\n const msgColor = lastScorer === 'player' ? '\\x1b[1;92m' : '\\x1b[1;91m';\n const msgX = displayLeft + Math.floor((GAME_WIDTH - scoreMsg.length) / 2) + 1;\n const msgY = displayTop + Math.floor(GAME_HEIGHT / 2);\n output += `\\x1b[${msgY};${msgX}H${msgColor}${scoreMsg}\\x1b[0m`;\n }\n }\n\n // Hint\n const hint = gameStarted && !gameOver && !paused ? '[ ESC ] MENU' : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${gameTop + GAME_HEIGHT + 3};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n function update() {\n if (!gameStarted || gameOver || paused) return;\n\n // Handle score freeze (pause after scoring)\n if (scoreFreeze > 0) {\n scoreFreeze--;\n if (screenShake > 0) screenShake--;\n\n // Animate explosion particles outward\n for (const particle of goalExplosion) {\n const dx = particle.x < GAME_WIDTH / 2 ? -0.5 : 0.5;\n particle.x += dx + (Math.random() - 0.5) * 0.3;\n particle.y += (Math.random() - 0.5) * 0.5;\n }\n\n // Clear effects when freeze ends\n if (scoreFreeze === 0) {\n goalExplosion = [];\n goalFlashSide = null;\n lastScorer = null;\n }\n return;\n }\n\n // Update ball trail with speed\n const currentSpeed = Math.sqrt(ballVX * ballVX + ballVY * ballVY);\n ballTrail.push({ x: ballX, y: ballY, speed: currentSpeed });\n if (ballTrail.length > 6) {\n ballTrail.shift();\n }\n\n // Move ball\n ballX += ballVX;\n ballY += ballVY;\n\n // Ball collision with top/bottom walls\n if (ballY <= 0 || ballY >= GAME_HEIGHT - 1) {\n ballVY = -ballVY;\n ballY = Math.max(0, Math.min(GAME_HEIGHT - 1, ballY));\n // Wall hit effects (subtle - no screen shake)\n wallHitFlash = 6;\n spawnParticles(ballX, ballY <= 0 ? 1 : GAME_HEIGHT - 2, 4, '\\x1b[1;93m', ['·', '•', '○']);\n }\n\n // Ball collision with player paddle\n if (ballX <= PADDLE_OFFSET + 1 && ballX >= PADDLE_OFFSET) {\n if (ballY >= playerY && ballY <= playerY + PADDLE_HEIGHT) {\n // Bounce off paddle\n ballVX = Math.abs(ballVX);\n\n // Adjust angle based on where ball hit paddle\n const hitPos = (ballY - playerY) / PADDLE_HEIGHT; // 0 to 1\n const angle = (hitPos - 0.5) * Math.PI / 3; // -30 to +30 degrees\n const speed = Math.min(MAX_BALL_SPEED, Math.sqrt(ballVX * ballVX + ballVY * ballVY) * 1.05);\n\n ballVX = Math.cos(angle) * speed;\n ballVY = Math.sin(angle) * speed;\n\n ballX = PADDLE_OFFSET + 2;\n\n // Rally and effects\n rallyCount++;\n const effectIntensity = Math.min(rallyCount, 10);\n paddleHitFlash = 8;\n // Only shake on high rallies (5+)\n if (rallyCount >= 5) screenShake = Math.floor(effectIntensity / 4);\n spawnParticles(PADDLE_OFFSET + 2, ballY, 4 + Math.floor(effectIntensity / 2), themeColor, ['✦', '★', '◆', '●']);\n\n // Rally popup\n if (rallyCount >= 3 && rallyCount % 3 === 0) {\n addScorePopup(PADDLE_OFFSET + 4, ballY - 1, `${rallyCount}!`, '\\x1b[1;96m');\n }\n }\n }\n\n // Ball collision with AI paddle\n if (ballX >= GAME_WIDTH - PADDLE_OFFSET - 2 && ballX <= GAME_WIDTH - PADDLE_OFFSET - 1) {\n if (ballY >= aiY && ballY <= aiY + PADDLE_HEIGHT) {\n ballVX = -Math.abs(ballVX);\n\n const hitPos = (ballY - aiY) / PADDLE_HEIGHT;\n const angle = (hitPos - 0.5) * Math.PI / 3;\n const speed = Math.min(MAX_BALL_SPEED, Math.sqrt(ballVX * ballVX + ballVY * ballVY) * 1.05);\n\n ballVX = -Math.abs(Math.cos(angle) * speed);\n ballVY = Math.sin(angle) * speed;\n\n ballX = GAME_WIDTH - PADDLE_OFFSET - 3;\n\n // Rally and effects (AI hit)\n rallyCount++;\n const effectIntensity = Math.min(rallyCount, 10);\n paddleHitFlash = 8;\n // Only shake on high rallies (5+)\n if (rallyCount >= 5) screenShake = Math.floor(effectIntensity / 4);\n spawnParticles(GAME_WIDTH - PADDLE_OFFSET - 2, ballY, 4 + Math.floor(effectIntensity / 2), '\\x1b[1;91m', ['✦', '★', '◆', '●']);\n\n // Rally popup\n if (rallyCount >= 3 && rallyCount % 3 === 0) {\n addScorePopup(GAME_WIDTH - PADDLE_OFFSET - 6, ballY - 1, `${rallyCount}!`, '\\x1b[1;91m');\n }\n }\n }\n\n // Scoring\n if (ballX < 0) {\n // AI scores\n aiScore++;\n scoreFlash = 15;\n scoreFreeze = 30; // Pause for celebration\n lastScorer = 'ai';\n screenShake = 8;\n goalFlashSide = 'left';\n createGoalExplosion('left');\n // Score popup\n addScorePopup(GAME_WIDTH / 2 - 3, GAME_HEIGHT / 2 - 2, 'CPU +1', '\\x1b[1;91m');\n // More particles on goal\n spawnParticles(2, ballY, 10, '\\x1b[1;91m', ['✗', '×', '▒', '░']);\n if (aiScore >= WIN_SCORE) {\n gameOver = true;\n scoreFreeze = 0; // Skip freeze on game end\n screenShake = 15;\n spawnParticles(GAME_WIDTH / 2, GAME_HEIGHT / 2, 20, '\\x1b[1;91m', ['✗', '☠', '×', '▓']);\n } else {\n resetBall(true);\n }\n } else if (ballX > GAME_WIDTH - 1) {\n // Player scores\n playerScore++;\n scoreFlash = 15;\n scoreFreeze = 30; // Pause for celebration\n lastScorer = 'player';\n screenShake = 8;\n goalFlashSide = 'right';\n createGoalExplosion('right');\n // Score popup with rally bonus display\n const rallyBonus = rallyCount >= 5 ? ` (${rallyCount} rally!)` : '';\n addScorePopup(GAME_WIDTH / 2 - 2, GAME_HEIGHT / 2 - 2, `+1${rallyBonus}`, '\\x1b[1;92m');\n // More particles on goal\n spawnParticles(GAME_WIDTH - 3, ballY, 10, '\\x1b[1;92m', ['✦', '★', '◆', '●']);\n if (playerScore >= WIN_SCORE) {\n gameOver = true;\n scoreFreeze = 0; // Skip freeze on game end\n screenShake = 15;\n spawnParticles(GAME_WIDTH / 2, GAME_HEIGHT / 2, 20, '\\x1b[1;93m', ['★', '✦', '♦', '◆']);\n } else {\n resetBall(false);\n }\n }\n\n // AI movement\n aiReactionTimer++;\n if (aiReactionTimer >= AI_REACTION_DELAY) {\n aiReactionTimer = 0;\n\n // AI tracks the ball with some prediction\n const targetY = ballY + ballVY * 5; // Predict where ball will be\n const aiCenter = aiY + PADDLE_HEIGHT / 2;\n\n if (targetY < aiCenter - 1) {\n aiY = Math.max(0, aiY - AI_SPEED);\n } else if (targetY > aiCenter + 1) {\n aiY = Math.min(GAME_HEIGHT - PADDLE_HEIGHT, aiY + AI_SPEED);\n }\n }\n }\n\n // Start game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n playerScore = 0;\n aiScore = 0;\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) {\n clearInterval(renderInterval);\n return;\n }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) {\n clearInterval(gameInterval);\n return;\n }\n update();\n }, 30); // Faster update for smoother ball movement\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener.dispose();\n return;\n }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // Handle ESC key - toggle pause (works on start screen too)\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Q to quit (from start screen, pause, or game over)\n if (key === 'q') {\n if (paused || gameOver || !gameStarted) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n }\n\n // Start screen - any key (except ESC/Q handled above) starts the game\n // Skip if paused (ESC menu open on start screen)\n if (!gameStarted && !paused) {\n gameStarted = true;\n return;\n }\n\n if (gameOver) {\n if (key === 'r') {\n playerScore = 0;\n aiScore = 0;\n initGame();\n gameStarted = true;\n }\n return;\n }\n\n // Pause menu actions\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n playerScore = 0;\n aiScore = 0;\n initGame();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (key === 'r') {\n playerScore = 0;\n aiScore = 0;\n initGame();\n gameStarted = true;\n paused = false;\n } else if (key === 'l') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (key === 'n') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n switch (domEvent.key) {\n case 'ArrowUp':\n case 'w':\n if (playerY > 0) playerY -= 1.5;\n break;\n case 'ArrowDown':\n case 's':\n if (playerY < GAME_HEIGHT - PADDLE_HEIGHT) playerY += 1.5;\n break;\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Runner\n *\n * Cyberpunk endless runner game - dodge obstacles,\n * collect power-ups, and survive as long as you can.\n * Subway Surfers-style vertical perspective with cyberpunk aesthetics.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor, getVerticalAnchor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Runner Game Controller\n */\nexport interface RunnerController {\n stop: () => void;\n isRunning: boolean;\n}\n\ninterface Obstacle {\n y: number; // Distance from player (higher = further away)\n lane: number; // 0, 1, 2\n type: 'car' | 'barrier' | 'drone';\n height: 'low' | 'high';\n}\n\ninterface Coin {\n y: number;\n lane: number;\n}\n\ninterface Building {\n y: number;\n side: 'left' | 'right';\n height: number; // 1-3\n style: number; // 0-2\n}\n\ninterface SpeedStreak {\n y: number;\n x: number;\n life: number;\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\n/**\n * Cyberpunk Endless Runner - Vertical perspective\n */\nexport function runRunnerGame(terminal: Terminal): RunnerController {\n const themeColor = getCurrentThemeColor();\n\n // Game dimensions\n const LANES = 3;\n const TRACK_HEIGHT = 14;\n const ROAD_WIDTH_BOTTOM = 24; // Road width at bottom (near player)\n const ROAD_WIDTH_TOP = 6; // Road width at top (horizon)\n const SCENERY_WIDTH = 8; // Space for buildings on each side\n const GAME_WIDTH = ROAD_WIDTH_BOTTOM + SCENERY_WIDTH * 2;\n let gameTop = 5;\n let gameLeft = 4;\n\n // Minimum terminal size\n const MIN_COLS = GAME_WIDTH + 2;\n const MIN_ROWS = TRACK_HEIGHT + 8;\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let score = 0;\n let highScore = 0;\n let distance = 0;\n let speed = 1;\n let coins = 0;\n let combo = 0;\n let comboTimer = 0;\n let nearMissFlash = 0;\n\n // Player state\n let playerLane = 1;\n let isJumping = false;\n let jumpFrame = 0;\n const JUMP_DURATION = 12;\n let isSliding = false;\n let slideFrame = 0;\n const SLIDE_DURATION = 10;\n\n // Game objects\n let obstacles: Obstacle[] = [];\n let coinItems: Coin[] = [];\n let buildings: Building[] = [];\n let speedStreaks: SpeedStreak[] = [];\n let spawnTimer = 0;\n let buildingTimer = 0;\n\n // Visual effects\n let glitchFrame = 0;\n let screenShake = 0;\n let trackOffset = 0;\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let crashFlashFrames = 0;\n let coinFlashFrames = 0;\n let jumpFlashFrames = 0;\n let landingShakeFrames = 0;\n\n const controller: RunnerController = {\n stop: () => {\n if (!running) return;\n running = false;\n // Note: Buffer exit is handled by TerminalPool via dispatchGameQuit\n },\n get isRunning() { return running; }\n };\n\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ █▀█ █ █ █▄ █ █▄ █ █▀▀ █▀█',\n '█▀█ █ █▀▀ ██▄ █▀▄ █▀▄ █▄█ █ ▀█ █ ▀█ ██▄ █▀▄',\n ];\n\n function updateLayout(rows: number, cols: number) {\n gameTop = getVerticalAnchor(rows, TRACK_HEIGHT, {\n headerRows: 4,\n footerRows: 2,\n minTop: 5,\n });\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH) / 2));\n }\n\n // Calculate road width at a given row (0 = top/far, TRACK_HEIGHT-1 = bottom/near)\n function getRoadWidth(row: number): number {\n const t = row / (TRACK_HEIGHT - 1); // 0 to 1\n // Exponential interpolation for perspective\n const factor = Math.pow(t, 0.6);\n return Math.floor(ROAD_WIDTH_TOP + (ROAD_WIDTH_BOTTOM - ROAD_WIDTH_TOP) * factor);\n }\n\n // Spawn particles at position\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['✦', '★', '◆', '●']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.3 + Math.random() * 0.5;\n particles.push({\n x: x,\n y: y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color: color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 12 + Math.floor(Math.random() * 8),\n });\n }\n }\n\n // Add score popup\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 20, color });\n }\n\n function initGame() {\n playerLane = 1;\n isJumping = false;\n isSliding = false;\n jumpFrame = 0;\n slideFrame = 0;\n score = 0;\n distance = 0;\n speed = 1;\n coins = 0;\n combo = 0;\n comboTimer = 0;\n nearMissFlash = 0;\n obstacles = [];\n coinItems = [];\n buildings = [];\n speedStreaks = [];\n spawnTimer = 0;\n buildingTimer = 0;\n gameOver = false;\n paused = false;\n trackOffset = 0;\n // Reset effects\n particles = [];\n scorePopups = [];\n crashFlashFrames = 0;\n coinFlashFrames = 0;\n jumpFlashFrames = 0;\n landingShakeFrames = 0;\n screenShake = 0;\n\n // Spawn initial buildings\n for (let i = 0; i < 8; i++) {\n buildings.push({\n y: i * 2,\n side: i % 2 === 0 ? 'left' : 'right',\n height: Math.floor(Math.random() * 3) + 1,\n style: Math.floor(Math.random() * 3),\n });\n }\n }\n\n function spawnObstacle() {\n if (obstacles.some(o => o.y > TRACK_HEIGHT - 2)) return;\n\n const lane = Math.floor(Math.random() * LANES);\n const types: Obstacle['type'][] = ['car', 'barrier', 'drone'];\n const type = types[Math.floor(Math.random() * types.length)];\n const height: Obstacle['height'] = type === 'drone' ? 'high' : (Math.random() > 0.6 ? 'high' : 'low');\n\n obstacles.push({\n y: TRACK_HEIGHT + 2,\n lane,\n type,\n height,\n });\n\n // Spawn coin in different lane\n if (Math.random() > 0.4) {\n let coinLane = Math.floor(Math.random() * LANES);\n if (coinLane === lane) coinLane = (coinLane + 1) % LANES;\n coinItems.push({\n y: TRACK_HEIGHT + 3 + Math.random() * 2,\n lane: coinLane,\n });\n }\n }\n\n function spawnBuilding() {\n const side = Math.random() > 0.5 ? 'left' : 'right';\n buildings.push({\n y: TRACK_HEIGHT + 2,\n side,\n height: Math.floor(Math.random() * 3) + 1,\n style: Math.floor(Math.random() * 3),\n });\n }\n\n function getJumpHeight(): number {\n if (isJumping) {\n const progress = jumpFrame / JUMP_DURATION;\n return Math.sin(progress * Math.PI) * 2.5;\n }\n return 0;\n }\n\n function checkCollision(): boolean {\n const playerY = 2;\n\n for (const obs of obstacles) {\n if (obs.lane !== playerLane) continue;\n const dist = Math.abs(obs.y - playerY);\n if (dist > 1.5) continue;\n\n // Near miss detection (close but not collision)\n if (dist > 0.8 && dist <= 1.5) {\n // Check if we're actually dodging\n if (obs.height === 'high' && isSliding) continue;\n if (obs.height === 'low' && getJumpHeight() > 0.5) continue;\n }\n\n if (obs.height === 'high' && isSliding) continue;\n if (obs.height === 'low' && getJumpHeight() > 0.5) continue;\n\n return true;\n }\n return false;\n }\n\n function checkNearMiss(): boolean {\n const playerY = 2;\n for (const obs of obstacles) {\n // Check adjacent lanes for near miss\n if (Math.abs(obs.lane - playerLane) === 1 && Math.abs(obs.y - playerY) < 1) {\n return true;\n }\n // Check same lane with jump/slide dodge\n if (obs.lane === playerLane && Math.abs(obs.y - playerY) < 1) {\n if ((obs.height === 'high' && isSliding) || (obs.height === 'low' && getJumpHeight() > 0.5)) {\n return true;\n }\n }\n }\n return false;\n }\n\n function collectCoins() {\n const playerY = 2;\n const newCoins: Coin[] = [];\n const cols = terminal.cols;\n const centerX = Math.max(2, Math.floor((cols - GAME_WIDTH) / 2)) + Math.floor(GAME_WIDTH / 2);\n\n for (const coin of coinItems) {\n if (coin.lane === playerLane && Math.abs(coin.y - playerY) < 1.5) {\n coins++;\n const points = Math.floor(50 * (1 + combo * 0.5));\n score += points;\n\n // Coin collection effects\n coinFlashFrames = 6;\n const roadWidth = getRoadWidth(TRACK_HEIGHT - 1);\n const roadLeft = centerX - Math.floor(roadWidth / 2);\n const coinX = roadLeft + Math.floor(((coin.lane + 0.5) / LANES) * roadWidth);\n const coinY = gameTop + TRACK_HEIGHT - Math.floor(coin.y);\n\n spawnParticles(coinX - gameLeft, coinY - gameTop, 6, '\\x1b[1;93m', ['◆', '★', '●', '♦']);\n addScorePopup(coinX, coinY, `+${points}`, '\\x1b[1;93m');\n } else {\n newCoins.push(coin);\n }\n }\n coinItems = newCoins;\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Update effect timers\n if (crashFlashFrames > 0) crashFlashFrames--;\n if (coinFlashFrames > 0) coinFlashFrames--;\n if (jumpFlashFrames > 0) jumpFlashFrames--;\n if (landingShakeFrames > 0) landingShakeFrames--;\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.03;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.3;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = needWidth && needHeight ? 'Make pane larger' : needWidth ? 'Make pane wider →' : 'Make pane taller ↓';\n const msg2 = `Need: ${MIN_COLS}×${MIN_ROWS} Have: ${cols}×${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n updateLayout(rows, cols);\n const shakeX = screenShake > 0 ? Math.floor(Math.random() * 3) - 1 : 0;\n const actualLeft = gameLeft + shakeX;\n const centerX = actualLeft + Math.floor(GAME_WIDTH / 2);\n\n // Title with glitch effect\n glitchFrame = (glitchFrame + 1) % 80;\n const glitchOffset = glitchFrame >= 75 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n const titleTop = Math.max(1, gameTop - 3);\n if (glitchFrame >= 75 && glitchFrame < 78) {\n output += `\\x1b[${titleTop};${titleX}H\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `\\x1b[${titleTop};${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n // Stats bar with combo indicator\n let stats = `SCORE: ${score.toString().padStart(5, '0')} COINS: ${coins} SPEED: ${speed.toFixed(1)}x`;\n if (combo > 0) {\n stats += ` \\x1b[93mCOMBO x${combo}\\x1b[0m${themeColor}`;\n }\n const statsX = Math.floor((cols - stats.length + (combo > 0 ? 15 : 0)) / 2);\n output += `\\x1b[4;${statsX}H${themeColor}${stats}\\x1b[0m`;\n\n // Near miss flash\n if (nearMissFlash > 0) {\n const flashMsg = '★ NEAR MISS! ★';\n const flashX = Math.floor((cols - flashMsg.length) / 2);\n output += `\\x1b[3;${flashX}H\\x1b[1;93m${flashMsg}\\x1b[0m`;\n }\n\n const trackBottom = gameTop + TRACK_HEIGHT;\n\n // Draw buildings on the sides (background layer)\n for (const bld of buildings) {\n if (bld.y < 0 || bld.y > TRACK_HEIGHT) continue;\n const row = TRACK_HEIGHT - Math.floor(bld.y);\n if (row < 0 || row >= TRACK_HEIGHT) continue;\n\n const screenY = gameTop + row;\n const roadWidth = getRoadWidth(row);\n const roadLeft = centerX - Math.floor(roadWidth / 2);\n const roadRight = centerX + Math.floor(roadWidth / 2);\n\n // Building appearance based on distance and style\n const normalizedDepth = row / TRACK_HEIGHT;\n const dim = normalizedDepth < 0.5 ? '\\x1b[2m' : '';\n\n // Different building styles\n const buildingChars = [\n ['█', '▓', '░'], // Solid building\n ['▐', '│', '░'], // Slim building\n ['◰', '◱', '·'], // Tech building\n ];\n const chars = buildingChars[bld.style];\n\n if (bld.side === 'left') {\n const bldX = roadLeft - 3 - Math.floor(normalizedDepth * 2);\n for (let h = 0; h < bld.height && screenY - h >= gameTop; h++) {\n const char = chars[Math.min(h, chars.length - 1)];\n output += `\\x1b[${screenY - h};${bldX}H${dim}\\x1b[35m${char}${char}\\x1b[0m`;\n }\n } else {\n const bldX = roadRight + 2 + Math.floor(normalizedDepth * 2);\n for (let h = 0; h < bld.height && screenY - h >= gameTop; h++) {\n const char = chars[Math.min(h, chars.length - 1)];\n output += `\\x1b[${screenY - h};${bldX}H${dim}\\x1b[35m${char}${char}\\x1b[0m`;\n }\n }\n }\n\n // Draw speed streaks when going fast\n if (speed > 1.5) {\n for (const streak of speedStreaks) {\n if (streak.life <= 0) continue;\n const intensity = streak.life > 2 ? '│' : streak.life > 1 ? '¦' : '·';\n output += `\\x1b[${streak.y};${streak.x}H\\x1b[2m${themeColor}${intensity}\\x1b[0m`;\n }\n }\n\n // Draw road with proper perspective\n for (let row = 0; row < TRACK_HEIGHT; row++) {\n const screenY = gameTop + row;\n const roadWidth = getRoadWidth(row);\n const roadLeft = centerX - Math.floor(roadWidth / 2);\n const roadRight = centerX + Math.floor(roadWidth / 2);\n const normalizedDepth = row / TRACK_HEIGHT;\n\n // Road edge style based on distance\n const edgeChar = normalizedDepth < 0.2 ? '·' : normalizedDepth < 0.4 ? '│' : normalizedDepth < 0.7 ? '┃' : '█';\n const edgeDim = normalizedDepth < 0.4 ? '\\x1b[2m' : '';\n\n // Draw road edges (solid white lines)\n output += `\\x1b[${screenY};${roadLeft}H${edgeDim}\\x1b[97m${edgeChar}\\x1b[0m`;\n output += `\\x1b[${screenY};${roadRight}H${edgeDim}\\x1b[97m${edgeChar}\\x1b[0m`;\n\n // Road surface (dark fill between edges)\n const surfaceChar = normalizedDepth < 0.3 ? ' ' : normalizedDepth < 0.6 ? '░' : '▒';\n if (normalizedDepth >= 0.3) {\n for (let x = roadLeft + 1; x < roadRight; x++) {\n // Skip lane divider positions\n const laneWidth = (roadRight - roadLeft) / LANES;\n const inLaneDivider = Math.abs((x - roadLeft) % laneWidth) < 0.5;\n if (!inLaneDivider) {\n output += `\\x1b[${screenY};${x}H\\x1b[2m\\x1b[90m${surfaceChar}\\x1b[0m`;\n }\n }\n }\n\n // Lane dividers (dashed white lines)\n const dashPhase = (Math.floor(trackOffset * 3) + row) % 4;\n for (let lane = 1; lane < LANES; lane++) {\n const laneX = roadLeft + Math.floor((lane / LANES) * roadWidth);\n const laneDim = normalizedDepth < 0.4 ? '\\x1b[2m' : '';\n\n if (dashPhase < 2) {\n // Dashed line - visible\n const laneChar = normalizedDepth < 0.25 ? '·' : normalizedDepth < 0.5 ? '¦' : '│';\n output += `\\x1b[${screenY};${laneX}H${laneDim}\\x1b[97m${laneChar}\\x1b[0m`;\n } else {\n // Gap in dashed line\n if (normalizedDepth >= 0.3) {\n output += `\\x1b[${screenY};${laneX}H\\x1b[2m\\x1b[90m${surfaceChar}\\x1b[0m`;\n }\n }\n }\n }\n\n if (paused) {\n const pauseMsg = '══ PAUSED ══';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseY = gameTop + Math.floor(TRACK_HEIGHT / 2) - 2;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO RUN ]';\n const startX = Math.floor((cols - startMsg.length) / 2);\n const startY = gameTop + Math.floor(TRACK_HEIGHT / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = '←→ LANE ↑/SPC JUMP ↓ SLIDE ESC MENU';\n const ctrlX = Math.floor((cols - controls.length) / 2);\n output += `\\x1b[${trackBottom + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n } else if (gameOver) {\n // Flashing crash banner\n const crashColor = crashFlashFrames > 0 && crashFlashFrames % 4 < 2 ? '\\x1b[41;97m' : '\\x1b[1;91m';\n const overMsg = '╔══ CRASHED! ══╗';\n const overX = Math.floor((cols - overMsg.length) / 2);\n const overY = gameTop + Math.floor(TRACK_HEIGHT / 2) - 1;\n output += `\\x1b[${overY};${overX}H${crashColor}${overMsg}\\x1b[0m`;\n\n const scoreLine = ` DISTANCE: ${Math.floor(distance)}m `;\n const coinsLine = ` COINS: ${coins} SCORE: ${score} `;\n output += `\\x1b[${overY + 1};${Math.floor((cols - scoreLine.length) / 2)}H${themeColor}${scoreLine}\\x1b[0m`;\n output += `\\x1b[${overY + 2};${Math.floor((cols - coinsLine.length) / 2)}H${themeColor}${coinsLine}\\x1b[0m`;\n\n const restart = '╚ [R] RESTART [Q] QUIT ╝';\n output += `\\x1b[${overY + 3};${Math.floor((cols - restart.length) / 2)}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n\n // Draw crash particles even on game over screen\n for (const p of particles) {\n const px = Math.round(actualLeft + p.x);\n const py = Math.round(gameTop + p.y);\n if (px > actualLeft && px < actualLeft + GAME_WIDTH && py >= gameTop && py < trackBottom) {\n const alpha = p.life > 6 ? '' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n } else {\n // Draw coins\n for (const coin of coinItems) {\n if (coin.y < 0 || coin.y > TRACK_HEIGHT) continue;\n const row = TRACK_HEIGHT - Math.floor(coin.y);\n if (row < 0 || row >= TRACK_HEIGHT) continue;\n\n const screenY = gameTop + row;\n const roadWidth = getRoadWidth(row);\n const roadLeft = centerX - Math.floor(roadWidth / 2);\n const coinX = roadLeft + Math.floor(((coin.lane + 0.5) / LANES) * roadWidth);\n const normalizedDepth = row / TRACK_HEIGHT;\n\n const coinChar = normalizedDepth < 0.3 ? '·' : normalizedDepth < 0.6 ? '●' : '◉';\n const coinDim = normalizedDepth < 0.4 ? '\\x1b[2m' : '\\x1b[1m';\n output += `\\x1b[${screenY};${coinX}H${coinDim}\\x1b[93m${coinChar}\\x1b[0m`;\n }\n\n // Draw obstacles\n for (const obs of obstacles) {\n if (obs.y < 0 || obs.y > TRACK_HEIGHT + 1) continue;\n const row = TRACK_HEIGHT - Math.floor(obs.y);\n if (row < 0 || row >= TRACK_HEIGHT) continue;\n\n const screenY = gameTop + row;\n const roadWidth = getRoadWidth(row);\n const roadLeft = centerX - Math.floor(roadWidth / 2);\n const obsCenter = roadLeft + Math.floor(((obs.lane + 0.5) / LANES) * roadWidth);\n const normalizedDepth = row / TRACK_HEIGHT;\n\n let obsChar: string;\n let obsColor: string;\n\n // Scale obstacle size with perspective\n if (normalizedDepth < 0.25) {\n // Far - tiny\n if (obs.type === 'car') { obsChar = '▪'; obsColor = '\\x1b[91m'; }\n else if (obs.type === 'drone') { obsChar = '·'; obsColor = '\\x1b[95m'; }\n else { obsChar = '▬'; obsColor = '\\x1b[93m'; }\n } else if (normalizedDepth < 0.5) {\n // Medium distance\n if (obs.type === 'car') { obsChar = '▐▌'; obsColor = '\\x1b[91m'; }\n else if (obs.type === 'drone') { obsChar = '◇'; obsColor = '\\x1b[95m'; }\n else { obsChar = '▄▄'; obsColor = '\\x1b[93m'; }\n } else if (normalizedDepth < 0.75) {\n // Closer\n if (obs.type === 'car') { obsChar = '▐█▌'; obsColor = '\\x1b[91m'; }\n else if (obs.type === 'drone') { obsChar = '◆◇◆'; obsColor = '\\x1b[95m'; }\n else { obsChar = '███'; obsColor = '\\x1b[93m'; }\n } else {\n // Near - largest\n if (obs.type === 'car') { obsChar = '▐███▌'; obsColor = '\\x1b[1;91m'; }\n else if (obs.type === 'drone') { obsChar = '◆◆◆◆'; obsColor = '\\x1b[1;95m'; }\n else { obsChar = '█████'; obsColor = '\\x1b[1;93m'; }\n }\n\n const obsX = obsCenter - Math.floor(obsChar.length / 2);\n const obsDim = normalizedDepth < 0.35 ? '\\x1b[2m' : '';\n output += `\\x1b[${screenY};${obsX}H${obsDim}${obsColor}${obsChar}\\x1b[0m`;\n\n // Draw top row for tall obstacles when close\n if (obs.height === 'high' && normalizedDepth > 0.6 && row > 0) {\n const topChar = obs.type === 'drone' ? '◆◆◆◆' : obs.type === 'car' ? '▐▀▀▀▌' : '█████';\n output += `\\x1b[${screenY - 1};${obsX}H${obsColor}${topChar}\\x1b[0m`;\n }\n }\n\n // Draw player\n const playerRow = TRACK_HEIGHT - 1;\n const playerScreenY = gameTop + playerRow;\n const roadWidth = getRoadWidth(playerRow);\n const roadLeft = centerX - Math.floor(roadWidth / 2);\n const playerCenter = roadLeft + Math.floor(((playerLane + 0.5) / LANES) * roadWidth);\n\n let playerChars: string[];\n let playerColor = themeColor;\n const jumpHeight = getJumpHeight();\n\n if (isJumping) {\n playerChars = ['╱▲╲', ' ▼ '];\n playerColor = '\\x1b[1m' + themeColor;\n } else if (isSliding) {\n playerChars = ['▬▬▬'];\n playerColor = themeColor;\n } else {\n const runFrame = Math.floor(distance * 3) % 4;\n if (runFrame === 0) playerChars = ['◢█◣', '╱ ╲'];\n else if (runFrame === 1) playerChars = ['◢█◣', '│ │'];\n else if (runFrame === 2) playerChars = ['◢█◣', '╲ ╱'];\n else playerChars = ['◢█◣', '│ │'];\n }\n\n const playerX = playerCenter - Math.floor(playerChars[0].length / 2);\n const playerYOffset = Math.floor(jumpHeight);\n const finalPlayerY = playerScreenY - playerYOffset;\n\n // Draw player character (multi-row)\n for (let i = 0; i < playerChars.length; i++) {\n if (finalPlayerY - (playerChars.length - 1 - i) >= gameTop) {\n output += `\\x1b[${finalPlayerY - (playerChars.length - 1 - i)};${playerX}H${playerColor}${playerChars[i]}\\x1b[0m`;\n }\n }\n\n // Shadow when jumping\n if (jumpHeight > 0.5) {\n const shadowSize = Math.max(1, 3 - Math.floor(jumpHeight));\n const shadow = '░'.repeat(shadowSize);\n output += `\\x1b[${playerScreenY};${playerCenter - Math.floor(shadowSize / 2)}H\\x1b[2m${themeColor}${shadow}\\x1b[0m`;\n }\n\n // Draw particles\n for (const p of particles) {\n const px = Math.round(actualLeft + p.x);\n const py = Math.round(gameTop + p.y);\n if (px > actualLeft && px < actualLeft + GAME_WIDTH && py >= gameTop && py < trackBottom) {\n const alpha = p.life > 6 ? '' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const px = Math.round(popup.x);\n const py = Math.round(popup.y);\n if (py >= gameTop && py < trackBottom) {\n const alpha = popup.frames > 10 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n }\n\n // Bottom hint\n const hint = gameStarted && !gameOver && !paused ? `HIGH: ${highScore} [ ESC ] MENU` : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${trackBottom + 1};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n function update() {\n if (!gameStarted || gameOver || paused) return;\n\n if (screenShake > 0) screenShake--;\n if (nearMissFlash > 0) nearMissFlash--;\n if (comboTimer > 0) {\n comboTimer--;\n if (comboTimer === 0) combo = 0;\n }\n\n trackOffset += speed * 0.4;\n\n // Update jump\n if (isJumping) {\n jumpFrame++;\n if (jumpFrame >= JUMP_DURATION) {\n isJumping = false;\n jumpFrame = 0;\n }\n }\n\n // Update slide\n if (isSliding) {\n slideFrame++;\n if (slideFrame >= SLIDE_DURATION) {\n isSliding = false;\n slideFrame = 0;\n }\n }\n\n // Move objects\n const moveSpeed = 0.35 * speed;\n obstacles = obstacles.filter(obs => {\n obs.y -= moveSpeed;\n return obs.y > -2;\n });\n coinItems = coinItems.filter(coin => {\n coin.y -= moveSpeed;\n return coin.y > -2;\n });\n buildings = buildings.filter(bld => {\n bld.y -= moveSpeed * 0.7; // Buildings move slower (parallax)\n return bld.y > -3;\n });\n\n // Update speed streaks\n if (speed > 1.5 && Math.random() > 0.7) {\n speedStreaks.push({\n y: gameTop + Math.floor(Math.random() * TRACK_HEIGHT),\n x: gameLeft + Math.floor(Math.random() * GAME_WIDTH),\n life: 3,\n });\n }\n speedStreaks = speedStreaks.filter(s => {\n s.life--;\n return s.life > 0;\n });\n\n // Spawn obstacles\n spawnTimer++;\n const spawnRate = Math.max(15, 35 - speed * 6);\n if (spawnTimer >= spawnRate) {\n spawnTimer = 0;\n spawnObstacle();\n }\n\n // Spawn buildings\n buildingTimer++;\n if (buildingTimer >= 20) {\n buildingTimer = 0;\n spawnBuilding();\n }\n\n // Near miss detection\n if (checkNearMiss()) {\n combo++;\n comboTimer = 40; // Combo lasts ~2 seconds\n nearMissFlash = 10;\n const nearMissPoints = 25 * combo;\n score += nearMissPoints;\n\n // Near miss effects - just particles, no popup (combo counter shows progress)\n const cols = terminal.cols;\n const centerX = Math.max(2, Math.floor((cols - GAME_WIDTH) / 2)) + Math.floor(GAME_WIDTH / 2);\n const roadWidth = getRoadWidth(TRACK_HEIGHT - 1);\n const roadLeft = centerX - Math.floor(roadWidth / 2);\n const playerCenter = roadLeft + Math.floor(((playerLane + 0.5) / LANES) * roadWidth);\n spawnParticles(playerCenter - gameLeft, TRACK_HEIGHT - 2, 4, '\\x1b[96m', ['✦', '★', '◇']);\n }\n\n collectCoins();\n\n if (checkCollision()) {\n gameOver = true;\n screenShake = 15;\n crashFlashFrames = 20;\n if (score > highScore) highScore = score;\n\n // Crash particles\n const cols = terminal.cols;\n const centerX = Math.max(2, Math.floor((cols - GAME_WIDTH) / 2)) + Math.floor(GAME_WIDTH / 2);\n const roadWidth = getRoadWidth(TRACK_HEIGHT - 1);\n const roadLeft = centerX - Math.floor(roadWidth / 2);\n const playerCenter = roadLeft + Math.floor(((playerLane + 0.5) / LANES) * roadWidth);\n spawnParticles(playerCenter - gameLeft, TRACK_HEIGHT - 1, 15, '\\x1b[1;91m', ['✗', '☠', '×', '▓', '░']);\n return;\n }\n\n distance += 0.18 * speed;\n score += Math.floor(speed * (1 + combo * 0.1));\n speed = Math.min(4, 1 + Math.floor(distance / 60) * 0.3);\n }\n\n // Start game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) { clearInterval(gameInterval); return; }\n update();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // Handle ESC key - toggle pause (works on start screen too)\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Q to quit (from start screen, pause, or game over)\n if (key === 'q') {\n if (paused || gameOver || !gameStarted) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n }\n\n // Start screen - any key (except ESC/Q handled above) starts the game\n // Skip if paused (ESC menu open on start screen)\n if (!gameStarted && !paused) {\n gameStarted = true;\n return;\n }\n\n if (gameOver) {\n if (key === 'r') {\n initGame();\n gameStarted = true;\n }\n return;\n }\n\n // Pause menu actions\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n initGame();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (key === 'r') {\n initGame();\n gameStarted = true;\n paused = false;\n } else if (key === 'l') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (key === 'n') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n switch (domEvent.key) {\n case 'ArrowLeft':\n case 'a':\n if (playerLane > 0) playerLane--;\n break;\n case 'ArrowRight':\n case 'd':\n if (playerLane < LANES - 1) playerLane++;\n break;\n case 'ArrowUp':\n case 'w':\n case ' ':\n if (!isJumping && !isSliding) {\n isJumping = true;\n jumpFrame = 0;\n }\n break;\n case 'ArrowDown':\n case 's':\n if (!isJumping && !isSliding) {\n isSliding = true;\n slideFrame = 0;\n }\n break;\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Simon\n *\n * Cyberpunk memory sequence game - \"hack the mainframe\" by repeating patterns.\n * Features 4 quadrants (1/2/3/4 or arrow keys), visual flash effects,\n * speed increases, and particle bursts on success.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Simon Game Controller\n */\nexport interface SimonController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\ntype Quadrant = 0 | 1 | 2 | 3; // 0=top, 1=right, 2=bottom, 3=left\n\n// ============================================================================\n// MAIN GAME FUNCTION\n// ============================================================================\n\nexport function runSimonGame(terminal: Terminal): SimonController {\n const themeColor = getCurrentThemeColor();\n\n // -------------------------------------------------------------------------\n // CONSTANTS\n // -------------------------------------------------------------------------\n const MIN_COLS = 40;\n const MIN_ROWS = 18;\n const GAME_WIDTH = 40;\n const GAME_HEIGHT = 18;\n\n // Quadrant colors\n const QUADRANT_COLORS = [\n '\\x1b[1;91m', // 0 - Top (Red)\n '\\x1b[1;92m', // 1 - Right (Green)\n '\\x1b[1;94m', // 2 - Bottom (Blue)\n '\\x1b[1;93m', // 3 - Left (Yellow)\n ];\n\n const QUADRANT_DIM_COLORS = [\n '\\x1b[2;31m', // 0 - Top (Dim Red)\n '\\x1b[2;32m', // 1 - Right (Dim Green)\n '\\x1b[2;34m', // 2 - Bottom (Dim Blue)\n '\\x1b[2;33m', // 3 - Left (Dim Yellow)\n ];\n\n const QUADRANT_CHARS = ['1', '2', '3', '4'];\n const QUADRANT_NAMES = ['UP', 'RIGHT', 'DOWN', 'LEFT'];\n\n // Timing\n const BASE_FLASH_DURATION = 12; // frames\n const BASE_PAUSE_DURATION = 6; // frames between flashes\n const SPEED_MULTIPLIER = 0.92; // Speed up each round\n\n // -------------------------------------------------------------------------\n // STATE\n // -------------------------------------------------------------------------\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let won = false;\n let score = 0;\n let highScore = 0;\n\n // Positioning\n let gameLeft = 2;\n let gameTop = 5;\n\n // Visual effects\n let glitchFrame = 0;\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let shakeFrames = 0;\n let shakeIntensity = 0;\n\n // Simon-specific state\n let sequence: Quadrant[] = [];\n let playerIndex = 0;\n let currentRound = 1;\n let flashSpeed = 1.0;\n\n // Animation states\n type GamePhase = 'waiting' | 'showing' | 'player_turn' | 'success' | 'failure';\n let phase: GamePhase = 'waiting';\n let showingIndex = 0;\n let flashTimer = 0;\n let pauseTimer = 0;\n let successTimer = 0;\n let failureTimer = 0;\n\n // Which quadrant is currently lit\n let litQuadrant: Quadrant | null = null;\n let playerLitQuadrant: Quadrant | null = null;\n let playerLitTimer = 0;\n\n // Message display\n let statusMessage = '';\n let statusColor = themeColor;\n let statusBlink = false;\n\n // Suppress unused variable warnings\n void won;\n void failureTimer;\n\n // -------------------------------------------------------------------------\n // CONTROLLER\n // -------------------------------------------------------------------------\n const controller: SimonController = {\n stop: () => {\n if (!running) return;\n running = false;\n },\n get isRunning() { return running; }\n };\n\n // -------------------------------------------------------------------------\n // ASCII ART TITLE\n // -------------------------------------------------------------------------\n const title = [\n '\\u2588 \\u2588 \\u2588\\u2584\\u2588 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2580 \\u2588 \\u2588\\u2580\\u2580\\u2588 \\u2580\\u2588\\u2580\\u2588 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2588',\n '\\u2588\\u2580\\u2588 \\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2588\\u2584 \\u2588\\u2580\\u2584 \\u2584\\u2584\\u2588 \\u2588 \\u2588\\u2588\\u2584 \\u2588 \\u2588 \\u2588 \\u2588\\u2580\\u2584 \\u2588 \\u2588',\n ];\n\n // -------------------------------------------------------------------------\n // EFFECTS\n // -------------------------------------------------------------------------\n\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['\\u2726', '\\u2605', '\\u25C6', '\\u25CF']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.3 + Math.random() * 0.5;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 12 + Math.floor(Math.random() * 8),\n });\n }\n }\n\n function spawnBurstParticles(quadrant: Quadrant) {\n const centerX = GAME_WIDTH / 2;\n const centerY = GAME_HEIGHT / 2;\n const offset = 5;\n\n let x = centerX;\n let y = centerY;\n\n switch (quadrant) {\n case 0: y = centerY - offset; break;\n case 1: x = centerX + offset * 2; break;\n case 2: y = centerY + offset; break;\n case 3: x = centerX - offset * 2; break;\n }\n\n spawnParticles(x, y, 8, QUADRANT_COLORS[quadrant], ['\\u2726', '\\u2605', '\\u25C6', '\\u25CF']);\n }\n\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 20, color });\n }\n\n function triggerShake(frames: number, intensity: number) {\n shakeFrames = frames;\n shakeIntensity = intensity;\n }\n\n // -------------------------------------------------------------------------\n // GAME LOGIC\n // -------------------------------------------------------------------------\n\n function initGame() {\n score = 0;\n gameOver = false;\n won = false;\n paused = false;\n\n // Reset effects\n particles = [];\n scorePopups = [];\n shakeFrames = 0;\n\n // Reset Simon state\n sequence = [];\n playerIndex = 0;\n currentRound = 1;\n flashSpeed = 1.0;\n phase = 'waiting';\n showingIndex = 0;\n flashTimer = 0;\n pauseTimer = 0;\n successTimer = 0;\n failureTimer = 0;\n litQuadrant = null;\n playerLitQuadrant = null;\n playerLitTimer = 0;\n\n statusMessage = 'INITIATING SEQUENCE...';\n statusColor = themeColor;\n statusBlink = true;\n\n // Start first round after brief delay\n setTimeout(() => {\n if (running && gameStarted && !paused && !gameOver) {\n startNewRound();\n }\n }, 1000);\n }\n\n function startNewRound() {\n // Add a new random quadrant to the sequence\n sequence.push(Math.floor(Math.random() * 4) as Quadrant);\n\n // Start showing the sequence\n phase = 'showing';\n showingIndex = 0;\n flashTimer = 0;\n pauseTimer = Math.floor(BASE_PAUSE_DURATION * 2); // Initial pause before showing\n\n statusMessage = `LEVEL ${currentRound}: DECRYPTING...`;\n statusColor = '\\x1b[1;96m';\n statusBlink = false;\n }\n\n function handlePlayerInput(quadrant: Quadrant) {\n if (phase !== 'player_turn' || paused || gameOver) return;\n\n // Light up the quadrant player pressed\n playerLitQuadrant = quadrant;\n playerLitTimer = 8;\n\n // Check if correct\n if (quadrant === sequence[playerIndex]) {\n // Correct!\n playerIndex++;\n spawnBurstParticles(quadrant);\n\n if (playerIndex >= sequence.length) {\n // Completed the sequence!\n phase = 'success';\n successTimer = 30;\n score += currentRound * 10;\n\n const centerX = GAME_WIDTH / 2;\n const centerY = GAME_HEIGHT / 2;\n addScorePopup(centerX - 2, centerY - 2, `+${currentRound * 10}`, '\\x1b[1;92m');\n\n // Big particle burst\n spawnParticles(centerX, centerY, 20, '\\x1b[1;92m', ['\\u2726', '\\u2605', '\\u2606', '\\u25C8']);\n\n statusMessage = 'PATTERN ACCEPTED';\n statusColor = '\\x1b[1;92m';\n statusBlink = true;\n\n triggerShake(6, 1);\n }\n } else {\n // Wrong!\n phase = 'failure';\n failureTimer = 40;\n gameOver = true;\n\n if (score > highScore) {\n highScore = score;\n }\n\n statusMessage = 'ACCESS DENIED';\n statusColor = '\\x1b[1;91m';\n statusBlink = true;\n\n triggerShake(15, 3);\n\n // Error particles\n const centerX = GAME_WIDTH / 2;\n const centerY = GAME_HEIGHT / 2;\n spawnParticles(centerX, centerY, 15, '\\x1b[1;91m', ['\\u2717', '\\u2716', '\\u00D7', '\\u2573']);\n }\n }\n\n function update() {\n if (!gameStarted || gameOver || paused) return;\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.03;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.2;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n // Update player lit timer\n if (playerLitTimer > 0) {\n playerLitTimer--;\n if (playerLitTimer <= 0) {\n playerLitQuadrant = null;\n }\n }\n\n // Phase-specific updates\n switch (phase) {\n case 'showing':\n updateShowingPhase();\n break;\n case 'success':\n updateSuccessPhase();\n break;\n }\n }\n\n function updateShowingPhase() {\n const flashDuration = Math.floor(BASE_FLASH_DURATION * flashSpeed);\n const pauseDuration = Math.floor(BASE_PAUSE_DURATION * flashSpeed);\n\n if (pauseTimer > 0) {\n // Waiting between flashes\n pauseTimer--;\n litQuadrant = null;\n return;\n }\n\n if (flashTimer > 0) {\n // Currently showing a quadrant\n flashTimer--;\n if (flashTimer <= 0) {\n litQuadrant = null;\n showingIndex++;\n\n if (showingIndex >= sequence.length) {\n // Done showing, player's turn\n phase = 'player_turn';\n playerIndex = 0;\n statusMessage = 'YOUR TURN: REPEAT PATTERN';\n statusColor = '\\x1b[1;93m';\n statusBlink = true;\n } else {\n pauseTimer = pauseDuration;\n }\n }\n return;\n }\n\n // Start showing next quadrant\n if (showingIndex < sequence.length) {\n litQuadrant = sequence[showingIndex];\n flashTimer = flashDuration;\n }\n }\n\n function updateSuccessPhase() {\n successTimer--;\n if (successTimer <= 0) {\n // Start next round\n currentRound++;\n playerIndex = 0;\n flashSpeed *= SPEED_MULTIPLIER;\n startNewRound();\n }\n }\n\n // -------------------------------------------------------------------------\n // RENDERING\n // -------------------------------------------------------------------------\n\n function renderQuadrant(output: string[], quadrant: Quadrant, isLit: boolean, renderLeft: number, renderTop: number): void {\n const centerX = Math.floor(GAME_WIDTH / 2);\n const centerY = Math.floor(GAME_HEIGHT / 2);\n const color = isLit ? QUADRANT_COLORS[quadrant] : QUADRANT_DIM_COLORS[quadrant];\n\n // Quadrant dimensions\n const qWidth = 12;\n const qHeight = 4;\n\n let startX = renderLeft + 1;\n let startY = renderTop + 1;\n\n // Position based on quadrant\n switch (quadrant) {\n case 0: // Top\n startX = renderLeft + centerX - Math.floor(qWidth / 2);\n startY = renderTop + 2;\n break;\n case 1: // Right\n startX = renderLeft + centerX + 3;\n startY = renderTop + centerY - Math.floor(qHeight / 2);\n break;\n case 2: // Bottom\n startX = renderLeft + centerX - Math.floor(qWidth / 2);\n startY = renderTop + GAME_HEIGHT - qHeight - 1;\n break;\n case 3: // Left\n startX = renderLeft + centerX - qWidth - 2;\n startY = renderTop + centerY - Math.floor(qHeight / 2);\n break;\n }\n\n // Draw quadrant box\n const fillChar = isLit ? '\\u2588' : '\\u2591';\n const topBorder = '\\u250C' + '\\u2500'.repeat(qWidth) + '\\u2510';\n const bottomBorder = '\\u2514' + '\\u2500'.repeat(qWidth) + '\\u2518';\n\n output.push(`\\x1b[${startY};${startX}H${color}${topBorder}\\x1b[0m`);\n\n for (let row = 0; row < qHeight; row++) {\n const y = startY + 1 + row;\n // Draw filled or empty content\n if (row === Math.floor(qHeight / 2)) {\n // Center row with label\n const label = `${QUADRANT_NAMES[quadrant]} [${QUADRANT_CHARS[quadrant]}]`;\n const padding = Math.floor((qWidth - label.length) / 2);\n const leftPad = fillChar.repeat(Math.max(0, padding));\n const rightPad = fillChar.repeat(Math.max(0, qWidth - padding - label.length));\n output.push(`\\x1b[${y};${startX}H${color}\\u2502${leftPad}${isLit ? '\\x1b[1;97m' : '\\x1b[2m'}${label}${color}${rightPad}\\u2502\\x1b[0m`);\n } else {\n output.push(`\\x1b[${y};${startX}H${color}\\u2502${fillChar.repeat(qWidth)}\\u2502\\x1b[0m`);\n }\n }\n\n output.push(`\\x1b[${startY + qHeight + 1};${startX}H${color}${bottomBorder}\\x1b[0m`);\n }\n\n function render() {\n const outputParts: string[] = [];\n outputParts.push('\\x1b[2J\\x1b[H');\n\n // Effect timers\n if (shakeFrames > 0) shakeFrames--;\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n const hint = needWidth && needHeight ? 'Make pane larger'\n : needWidth ? 'Make pane wider \\u2192' : 'Make pane taller \\u2193';\n const msg2 = `Need: ${MIN_COLS}\\u00D7${MIN_ROWS} Have: ${cols}\\u00D7${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n outputParts.push(`\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`);\n outputParts.push(`\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`);\n outputParts.push(`\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`);\n terminal.write(outputParts.join(''));\n return;\n }\n\n // Center game area\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH - 2) / 2));\n gameTop = Math.max(4, Math.floor((rows - GAME_HEIGHT - 8) / 2));\n\n // Apply screen shake\n let renderLeft = gameLeft;\n let renderTop = gameTop;\n if (shakeFrames > 0) {\n renderLeft += Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n renderTop += Math.floor((Math.random() - 0.5) * shakeIntensity);\n }\n\n // Glitch title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n if (glitchFrame >= 55 && glitchFrame < 58) {\n outputParts.push(`\\x1b[1;${titleX}H\\x1b[91m${title[0]}\\x1b[0m`);\n outputParts.push(`\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`);\n } else {\n outputParts.push(`\\x1b[1;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`);\n outputParts.push(`\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`);\n }\n\n // Stats bar\n const stats = `LEVEL: ${currentRound} SCORE: ${score.toString().padStart(5, '0')} HIGH: ${highScore.toString().padStart(5, '0')}`;\n const statsX = Math.floor((cols - stats.length) / 2);\n outputParts.push(`\\x1b[${gameTop - 1};${statsX}H${themeColor}${stats}\\x1b[0m`);\n\n // Game border\n outputParts.push(`\\x1b[${renderTop};${renderLeft}H${themeColor}\\u2554${'\\u2550'.repeat(GAME_WIDTH)}\\u2557\\x1b[0m`);\n for (let y = 0; y < GAME_HEIGHT; y++) {\n outputParts.push(`\\x1b[${renderTop + 1 + y};${renderLeft}H${themeColor}\\u2551\\x1b[0m`);\n outputParts.push(`\\x1b[${renderTop + 1 + y};${renderLeft + GAME_WIDTH + 1}H${themeColor}\\u2551\\x1b[0m`);\n }\n outputParts.push(`\\x1b[${renderTop + GAME_HEIGHT + 1};${renderLeft}H${themeColor}\\u255A${'\\u2550'.repeat(GAME_WIDTH)}\\u255D\\x1b[0m`);\n\n // PAUSE MENU\n if (paused) {\n const pauseMsg = '\\u2550\\u2550 PAUSED \\u2550\\u2550';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseY = gameTop + Math.floor(GAME_HEIGHT / 2) - 2;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n outputParts.push(`\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`);\n\n outputParts.push(renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n }));\n\n const navHint = '\\u2191\\u2193 select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n outputParts.push(`\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`);\n }\n // START SCREEN\n else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO HACK ]';\n const startX = gameLeft + Math.floor((GAME_WIDTH - startMsg.length) / 2) + 1;\n const startY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n outputParts.push(`\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`);\n\n const controls = '\\u2191\\u2193\\u2190\\u2192 or 1234 to match pattern';\n const ctrlX = gameLeft + Math.floor((GAME_WIDTH - controls.length) / 2) + 1;\n outputParts.push(`\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`);\n\n const desc = 'Watch. Remember. Repeat.';\n const descX = gameLeft + Math.floor((GAME_WIDTH - desc.length) / 2) + 1;\n outputParts.push(`\\x1b[${startY + 4};${descX}H\\x1b[2m${themeColor}${desc}\\x1b[0m`);\n }\n // GAME OVER\n else if (gameOver) {\n // Draw quadrants dimmed\n for (let q = 0; q < 4; q++) {\n renderQuadrant(outputParts, q as Quadrant, false, renderLeft, renderTop);\n }\n\n const overMsg = '\\u2554\\u2550\\u2550 SECURITY LOCKOUT \\u2550\\u2550\\u2557';\n const overX = gameLeft + Math.floor((GAME_WIDTH - overMsg.length) / 2) + 1;\n const overY = gameTop + Math.floor(GAME_HEIGHT / 2) - 2;\n outputParts.push(`\\x1b[${overY};${overX}H\\x1b[1;91m${overMsg}\\x1b[0m`);\n\n const scoreLine = `LEVELS CLEARED: ${currentRound - 1} SCORE: ${score}`;\n const scoreX = gameLeft + Math.floor((GAME_WIDTH - scoreLine.length) / 2) + 1;\n outputParts.push(`\\x1b[${overY + 1};${scoreX}H${themeColor}${scoreLine}\\x1b[0m`);\n\n const highLine = score >= highScore ? '\\u2606 NEW HIGH SCORE! \\u2606' : `HIGH SCORE: ${highScore}`;\n const highX = gameLeft + Math.floor((GAME_WIDTH - highLine.length) / 2) + 1;\n const highColor = score >= highScore ? '\\x1b[1;93m' : themeColor;\n outputParts.push(`\\x1b[${overY + 2};${highX}H${highColor}${highLine}\\x1b[0m`);\n\n const restart = '\\u255A [R] RESTART [Q] QUIT \\u255D';\n const restartX = gameLeft + Math.floor((GAME_WIDTH - restart.length) / 2) + 1;\n outputParts.push(`\\x1b[${overY + 4};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`);\n }\n // GAMEPLAY\n else {\n // Determine which quadrant is lit\n const activeLit = playerLitQuadrant !== null ? playerLitQuadrant : litQuadrant;\n\n // Draw all quadrants\n for (let q = 0; q < 4; q++) {\n renderQuadrant(outputParts, q as Quadrant, activeLit === q, renderLeft, renderTop);\n }\n\n // Status message in center\n const blinkStyle = statusBlink && glitchFrame % 20 < 10 ? '\\x1b[5m' : '';\n const msgX = gameLeft + Math.floor((GAME_WIDTH - statusMessage.length) / 2) + 1;\n const msgY = gameTop + Math.floor(GAME_HEIGHT / 2);\n outputParts.push(`\\x1b[${msgY};${msgX}H${blinkStyle}${statusColor}${statusMessage}\\x1b[0m`);\n\n // Progress indicator during player turn\n if (phase === 'player_turn') {\n const progress = `[${playerIndex + 1}/${sequence.length}]`;\n const progX = gameLeft + Math.floor((GAME_WIDTH - progress.length) / 2) + 1;\n outputParts.push(`\\x1b[${msgY + 1};${progX}H\\x1b[2m${themeColor}${progress}\\x1b[0m`);\n }\n\n // Draw particles\n for (const p of particles) {\n const screenX = Math.round(renderLeft + 1 + p.x);\n const screenY = Math.round(renderTop + 1 + p.y);\n if (screenX > renderLeft && screenX < renderLeft + GAME_WIDTH + 1 &&\n screenY > renderTop && screenY < renderTop + GAME_HEIGHT + 1) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n outputParts.push(`\\x1b[${screenY};${screenX}H${alpha}${p.color}${p.char}\\x1b[0m`);\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const screenX = Math.round(renderLeft + 1 + popup.x);\n const screenY = Math.round(renderTop + 1 + popup.y);\n if (screenY > renderTop && screenY < renderTop + GAME_HEIGHT + 1) {\n const alpha = popup.frames > 10 ? '\\x1b[1m' : '\\x1b[2m';\n outputParts.push(`\\x1b[${screenY};${screenX}H${alpha}${popup.color}${popup.text}\\x1b[0m`);\n }\n }\n }\n\n // Bottom hint\n const hint = gameStarted && !gameOver && !paused ? `SEQUENCE LENGTH: ${sequence.length} [ ESC ] MENU` : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n outputParts.push(`\\x1b[${gameTop + GAME_HEIGHT + 3};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`);\n\n terminal.write(outputParts.join(''));\n }\n\n // -------------------------------------------------------------------------\n // GAME LOOP\n // -------------------------------------------------------------------------\n\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h'); // Alternate buffer\n terminal.write('\\x1b[?25l'); // Hide cursor\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) { clearInterval(gameInterval); return; }\n update();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // ESC toggles pause\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Q to quit from pause/game over/start screen\n if (key === 'q' && (paused || gameOver || !gameStarted)) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n\n // Start screen - any key starts\n if (!gameStarted && !paused) {\n gameStarted = true;\n initGame();\n gameStarted = true;\n return;\n }\n\n // Game over - R to restart\n if (gameOver) {\n if (key === 'r') {\n initGame();\n gameStarted = true;\n }\n return;\n }\n\n // Pause menu navigation\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: paused = false; break;\n case 1: initGame(); gameStarted = true; paused = false; break;\n case 2:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcuts\n if (key === 'r') { initGame(); gameStarted = true; paused = false; }\n else if (key === 'l') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGamesMenu(terminal); }\n else if (key === 'n') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGameSwitch(terminal); }\n return;\n }\n\n // GAMEPLAY INPUT - Simon quadrant selection\n if (phase === 'player_turn') {\n switch (domEvent.key) {\n case 'ArrowUp':\n case '1':\n handlePlayerInput(0);\n break;\n case 'ArrowRight':\n case '2':\n handlePlayerInput(1);\n break;\n case 'ArrowDown':\n case '3':\n handlePlayerInput(2);\n break;\n case 'ArrowLeft':\n case '4':\n handlePlayerInput(3);\n break;\n }\n }\n });\n\n // Clean up on stop\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 50);\n\n return controller;\n}\n","/**\n * Hyper Snake Game\n *\n * Cyberpunk-themed snake game with glitchy title,\n * neon borders, and theme-aware colors.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor, getVerticalAnchor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Snake Game Controller\n */\nexport interface SnakeController {\n stop: () => void;\n isRunning: boolean;\n}\n\ntype Direction = 'up' | 'down' | 'left' | 'right';\n\n/**\n * Cyberpunk Snake Game\n */\nexport function runSnakeGame(terminal: Terminal): SnakeController {\n const themeColor = getCurrentThemeColor();\n\n // Minimum terminal size for playable game\n const MIN_COLS = 36;\n const MIN_ROWS = 16;\n\n // Game area (dynamically updated on resize)\n let cols = terminal.cols;\n let rows = terminal.rows;\n let gameTop = 6;\n let gameWidth = Math.min(cols - 4, 60);\n let gameHeight = Math.min(rows - 10, 20);\n let gameLeft = Math.max(2, Math.floor((cols - gameWidth - 2) / 2));\n\n // Update game dimensions when terminal resizes\n const updateDimensions = () => {\n cols = terminal.cols;\n rows = terminal.rows;\n gameWidth = Math.min(cols - 4, 60);\n gameHeight = Math.min(rows - 10, 20);\n gameTop = getVerticalAnchor(rows, gameHeight + 2, {\n headerRows: 4,\n footerRows: 3,\n minTop: 5,\n });\n gameLeft = Math.max(2, Math.floor((cols - gameWidth - 2) / 2));\n };\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let score = 0;\n let highScore = 0;\n\n // Snake state\n let snake: { x: number; y: number }[] = [];\n let direction: Direction = 'right';\n let nextDirection: Direction = 'right';\n let food: { x: number; y: number } = { x: 0, y: 0 };\n\n // Glitch effect state\n let glitchFrame = 0;\n\n // Juicy effects\n let shakeFrames = 0;\n let shakeIntensity = 0;\n let flashFrames = 0;\n let eatFlashFrames = 0;\n let deathFlashFrames = 0;\n let scorePopup: { x: number; y: number; text: string; frames: number } | null = null;\n let particles: { x: number; y: number; char: string; color: string; vx: number; vy: number; life: number }[] = [];\n let comboCount = 0; // Track rapid eating\n let lastEatTime = 0;\n\n const controller: SnakeController = {\n stop: () => {\n if (!running) return;\n running = false;\n // Note: Buffer exit is handled by TerminalPool via dispatchGameQuit\n },\n get isRunning() { return running; }\n };\n\n // ASCII art title\n const titleFrames = [\n [\n '█ █ █▄█ █▀█ █▀▀ █▀█ █▀▀ █▄ █ ▄▀█ █▄▀ █▀▀',\n '█▀█ █ █▀▀ ██▄ █▀▄ ▄▄█ █ ▀█ █▀█ █ █ ██▄',\n ],\n ];\n\n // Initialize game\n function initGame() {\n snake = [\n { x: Math.floor(gameWidth / 2), y: Math.floor(gameHeight / 2) },\n { x: Math.floor(gameWidth / 2) - 1, y: Math.floor(gameHeight / 2) },\n { x: Math.floor(gameWidth / 2) - 2, y: Math.floor(gameHeight / 2) },\n ];\n direction = 'right';\n nextDirection = 'right';\n score = 0;\n gameOver = false;\n paused = false;\n // Reset effects\n shakeFrames = 0;\n shakeIntensity = 0;\n flashFrames = 0;\n eatFlashFrames = 0;\n deathFlashFrames = 0;\n scorePopup = null;\n particles = [];\n comboCount = 0;\n lastEatTime = 0;\n spawnFood();\n }\n\n // Spawn food at random position\n function spawnFood() {\n let attempts = 0;\n do {\n food = {\n x: Math.floor(Math.random() * (gameWidth - 2)) + 1,\n y: Math.floor(Math.random() * (gameHeight - 2)) + 1,\n };\n attempts++;\n } while (snake.some(s => s.x === food.x && s.y === food.y) && attempts < 100);\n }\n\n // Spawn particles at a position\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['✦', '★', '◆', '●']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.3 + Math.random() * 0.4;\n particles.push({\n x: x,\n y: y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color: color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5, // Less vertical movement due to terminal aspect ratio\n life: 15 + Math.floor(Math.random() * 10),\n });\n }\n }\n\n // Update particles\n function updateParticles() {\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.05; // Gravity\n p.life--;\n if (p.life <= 0) {\n particles.splice(i, 1);\n }\n }\n }\n\n // Draw the game\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n updateDimensions();\n\n // Update effect timers\n if (shakeFrames > 0) shakeFrames--;\n if (flashFrames > 0) flashFrames--;\n if (eatFlashFrames > 0) eatFlashFrames--;\n if (deathFlashFrames > 0) deathFlashFrames--;\n if (scorePopup && scorePopup.frames > 0) {\n scorePopup.frames--;\n scorePopup.y -= 0.3; // Float upward\n if (scorePopup.frames <= 0) scorePopup = null;\n }\n updateParticles();\n\n // Apply screen shake\n let renderGameLeft = gameLeft;\n let renderGameTop = gameTop;\n if (shakeFrames > 0) {\n const shakeX = Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n const shakeY = Math.floor((Math.random() - 0.5) * shakeIntensity);\n renderGameLeft = Math.max(1, gameLeft + shakeX);\n renderGameTop = Math.max(3, gameTop + shakeY);\n }\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = '';\n if (needWidth && needHeight) {\n hint = 'Make pane larger';\n } else if (needWidth) {\n hint = 'Make pane wider →';\n } else {\n hint = 'Make pane taller ↓';\n }\n const msg2 = `Need: ${MIN_COLS}×${MIN_ROWS} Have: ${cols}×${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Glitchy title\n glitchFrame = (glitchFrame + 1) % 60;\n const titleIndex = glitchFrame < 55 ? 0 : Math.floor(Math.random() * titleFrames.length);\n const title = titleFrames[titleIndex];\n\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n const titleTop = Math.max(1, gameTop - 4);\n\n output += `\\x1b[${titleTop};${titleX}H`;\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n // Score display with eat flash effect\n const scoreText = `SCORE: ${score.toString().padStart(4, '0')}`;\n const highText = `HIGH: ${highScore.toString().padStart(4, '0')}`;\n const scoreColor = eatFlashFrames > 0 ? '\\x1b[1;33m' : themeColor;\n const scoreY = Math.max(3, gameTop - 2);\n output += `\\x1b[${scoreY};${renderGameLeft}H${scoreColor}${scoreText} ${highText}\\x1b[0m`;\n\n // Game border with death flash effect\n const borderColor = deathFlashFrames > 0 && deathFlashFrames % 4 < 2 ? '\\x1b[1;31m' : themeColor;\n output += `\\x1b[${renderGameTop};${renderGameLeft}H${borderColor}╔${'═'.repeat(gameWidth)}╗\\x1b[0m`;\n for (let y = 1; y <= gameHeight; y++) {\n output += `\\x1b[${renderGameTop + y};${renderGameLeft}H${borderColor}║\\x1b[0m`;\n output += `\\x1b[${renderGameTop + y};${renderGameLeft + gameWidth + 1}H${borderColor}║\\x1b[0m`;\n }\n output += `\\x1b[${renderGameTop + gameHeight + 1};${renderGameLeft}H${borderColor}╚${'═'.repeat(gameWidth)}╝\\x1b[0m`;\n\n if (paused) {\n const pauseMsg = '══ PAUSED ══';\n const pauseCenterX = renderGameLeft + Math.floor(gameWidth / 2) + 1;\n const pauseY = renderGameTop + Math.floor(gameHeight / 2) - 2;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n // Use shared menu rendering\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO START ]';\n const startX = renderGameLeft + Math.floor((gameWidth - startMsg.length) / 2) + 1;\n const startY = renderGameTop + Math.floor(gameHeight / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = '↑↓←→ MOVE ESC MENU';\n const ctrlX = renderGameLeft + Math.floor((gameWidth - controls.length) / 2) + 1;\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n } else if (gameOver) {\n const overMsg = '══ GAME OVER ══';\n const overX = renderGameLeft + Math.floor((gameWidth - overMsg.length) / 2) + 1;\n const overY = renderGameTop + Math.floor(gameHeight / 2) - 1;\n output += `\\x1b[${overY};${overX}H\\x1b[1;31m${overMsg}\\x1b[0m`;\n\n const finalScore = `FINAL SCORE: ${score}`;\n const scoreX = renderGameLeft + Math.floor((gameWidth - finalScore.length) / 2) + 1;\n output += `\\x1b[${overY + 2};${scoreX}H${themeColor}${finalScore}\\x1b[0m`;\n\n const restart = '[ R ] RESTART [ Q ] QUIT';\n const restartX = renderGameLeft + Math.floor((gameWidth - restart.length) / 2) + 1;\n output += `\\x1b[${overY + 4};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n } else {\n // Draw food (pulsing effect with enhanced glow)\n const foodChar = glitchFrame % 10 < 5 ? '◆' : '◇';\n const foodGlow = eatFlashFrames > 0 ? '\\x1b[1;97m' : '\\x1b[1;33m';\n output += `\\x1b[${renderGameTop + food.y};${renderGameLeft + food.x + 1}H${foodGlow}${foodChar}\\x1b[0m`;\n\n // Draw snake with eat flash effect\n const snakeColor = eatFlashFrames > 0 ? '\\x1b[1;33m' : themeColor;\n for (let i = 0; i < snake.length; i++) {\n const seg = snake[i];\n const char = i === 0 ? '█' : '▓';\n const brightness = i === 0 ? '\\x1b[1m' : (i < 3 ? '' : '\\x1b[2m');\n output += `\\x1b[${renderGameTop + seg.y};${renderGameLeft + seg.x + 1}H${brightness}${snakeColor}${char}\\x1b[0m`;\n }\n\n // Draw particles\n for (const p of particles) {\n const px = Math.round(renderGameLeft + p.x + 1);\n const py = Math.round(renderGameTop + p.y);\n if (px > renderGameLeft && px < renderGameLeft + gameWidth + 1 &&\n py > renderGameTop && py < renderGameTop + gameHeight + 1) {\n const alpha = p.life > 10 ? '' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popup\n if (scorePopup) {\n const popX = Math.round(renderGameLeft + scorePopup.x + 1);\n const popY = Math.round(renderGameTop + scorePopup.y);\n if (popY > renderGameTop && popY < renderGameTop + gameHeight + 1) {\n const popAlpha = scorePopup.frames > 10 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${popY};${popX}H${popAlpha}\\x1b[33m${scorePopup.text}\\x1b[0m`;\n }\n }\n\n // Draw combo message\n if (comboCount >= 3) {\n const comboMsg = comboCount >= 5 ? `★ ${comboCount}x COMBO! ★` : `${comboCount}x COMBO!`;\n const comboX = renderGameLeft + Math.floor((gameWidth - comboMsg.length) / 2) + 1;\n const comboColor = glitchFrame % 6 < 3 ? '\\x1b[1;33m' : '\\x1b[1;35m';\n output += `\\x1b[${renderGameTop + 2};${comboX}H${comboColor}${comboMsg}\\x1b[0m`;\n }\n }\n\n const hint = gameStarted && !gameOver && !paused ? '[ ESC ] MENU' : '';\n output += `\\x1b[${renderGameTop + gameHeight + 3};${renderGameLeft}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n // Update game state\n function update() {\n if (!gameStarted || gameOver || paused) return;\n\n direction = nextDirection;\n\n const head = { ...snake[0] };\n switch (direction) {\n case 'up': head.y--; break;\n case 'down': head.y++; break;\n case 'left': head.x--; break;\n case 'right': head.x++; break;\n }\n\n // Check wall collision\n if (head.x <= 0 || head.x >= gameWidth || head.y <= 0 || head.y >= gameHeight) {\n gameOver = true;\n if (score > highScore) highScore = score;\n // Death effects\n shakeFrames = 20;\n shakeIntensity = 3;\n deathFlashFrames = 30;\n // Death particles\n spawnParticles(snake[0].x, snake[0].y, 12, '\\x1b[1;31m', ['✗', '☠', '×', '▒']);\n comboCount = 0;\n return;\n }\n\n // Check self collision\n if (snake.some(s => s.x === head.x && s.y === head.y)) {\n gameOver = true;\n if (score > highScore) highScore = score;\n // Death effects\n shakeFrames = 20;\n shakeIntensity = 3;\n deathFlashFrames = 30;\n // Death particles\n spawnParticles(snake[0].x, snake[0].y, 12, '\\x1b[1;31m', ['✗', '☠', '×', '▒']);\n comboCount = 0;\n return;\n }\n\n snake.unshift(head);\n\n if (head.x === food.x && head.y === food.y) {\n const now = Date.now();\n\n // Track combo (eating within 2 seconds)\n if (now - lastEatTime < 2000) {\n comboCount++;\n } else {\n comboCount = 1;\n }\n lastEatTime = now;\n\n // Calculate points with combo bonus\n const basePoints = 10;\n const comboBonus = comboCount >= 3 ? Math.floor(comboCount * 2) : 0;\n const totalPoints = basePoints + comboBonus;\n score += totalPoints;\n\n // Eat effects - intensity scales with combo\n shakeFrames = 4 + Math.min(comboCount, 5);\n shakeIntensity = 1 + Math.floor(comboCount / 3);\n eatFlashFrames = 8;\n\n // Score popup\n const popupText = comboCount >= 3 ? `+${totalPoints}!` : `+${totalPoints}`;\n scorePopup = {\n x: food.x,\n y: food.y,\n text: popupText,\n frames: 20,\n };\n\n // Particles - more for higher combos\n const particleCount = 4 + Math.min(comboCount * 2, 10);\n spawnParticles(food.x, food.y, particleCount, '\\x1b[1;33m', ['✦', '★', '◆', '♦']);\n\n spawnFood();\n } else {\n snake.pop();\n }\n }\n\n // Start the game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n\n const renderInterval = setInterval(() => {\n if (!running) {\n clearInterval(renderInterval);\n return;\n }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) {\n clearInterval(gameInterval);\n return;\n }\n update();\n }, 120);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener.dispose();\n return;\n }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // Handle ESC key - toggle pause (works on start screen too)\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Q to quit (from start screen, pause, or game over)\n if (key === 'q') {\n if (paused || gameOver || !gameStarted) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n }\n\n // Start screen - any key (except ESC/Q handled above) starts the game\n // Skip if paused (ESC menu open on start screen)\n if (!gameStarted && !paused) {\n gameStarted = true;\n return;\n }\n\n if (gameOver) {\n if (key === 'r') {\n initGame();\n gameStarted = true;\n }\n return;\n }\n\n // Pause menu actions\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n initGame();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (key === 'r') {\n initGame();\n gameStarted = true;\n paused = false;\n } else if (key === 'l') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (key === 'n') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n switch (domEvent.key) {\n case 'ArrowUp':\n case 'w':\n if (direction !== 'down') nextDirection = 'up';\n break;\n case 'ArrowDown':\n case 's':\n if (direction !== 'up') nextDirection = 'down';\n break;\n case 'ArrowLeft':\n case 'a':\n if (direction !== 'right') nextDirection = 'left';\n break;\n case 'ArrowRight':\n case 'd':\n if (direction !== 'left') nextDirection = 'right';\n break;\n }\n });\n\n // Listen for terminal resize to update game dimensions\n const resizeListener = terminal.onResize(() => {\n updateDimensions();\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n resizeListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Space Invaders\n *\n * Cyberpunk-themed Space Invaders with glitchy effects,\n * neon visuals, and theme-aware colors.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Space Invaders Game Controller\n */\nexport interface SpaceInvadersController {\n stop: () => void;\n isRunning: boolean;\n}\n\ninterface Invader {\n x: number;\n y: number;\n alive: boolean;\n type: 0 | 1 | 2; // Different invader types\n}\n\ninterface Bullet {\n x: number;\n y: number;\n isPlayer: boolean;\n}\n\ninterface Explosion {\n x: number;\n y: number;\n frame: number;\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\n/**\n * Cyberpunk Space Invaders\n */\nexport function runSpaceInvadersGame(terminal: Terminal): SpaceInvadersController {\n const themeColor = getCurrentThemeColor();\n\n // Minimum terminal size (reduced for better compatibility)\n const MIN_COLS = 40;\n const MIN_ROWS = 16;\n\n // Game dimensions - adaptive based on terminal size\n const getGameDimensions = () => {\n const cols = terminal.cols;\n const rows = terminal.rows;\n const width = Math.min(50, Math.max(40, cols - 6));\n const height = Math.min(20, Math.max(14, rows - 6));\n return { width, height };\n };\n\n let { width: GAME_WIDTH, height: GAME_HEIGHT } = getGameDimensions();\n const INVADER_ROWS = 4;\n const INVADER_COLS = 8;\n const INVADER_SPACING_X = 5;\n const INVADER_SPACING_Y = 2;\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let won = false;\n let score = 0;\n let highScore = 0;\n let lives = 3;\n let level = 1;\n\n // Game area positioning\n let gameLeft = 2;\n let gameTop = 4;\n\n // Player state\n let playerX = GAME_WIDTH / 2;\n let playerY = GAME_HEIGHT - 1;\n\n // Invaders\n let invaders: Invader[] = [];\n let invaderDirection = 1; // 1 = right, -1 = left\n let invaderMoveTimer = 0;\n let invaderMoveDelay = 30; // Frames between moves\n let invaderDropAmount = 0;\n\n // Bullets\n let bullets: Bullet[] = [];\n let playerShootCooldown = 0;\n let invaderShootTimer = 0;\n\n // Explosions\n let explosions: Explosion[] = [];\n\n // Shields/barriers\n let shields: boolean[][][] = [];\n const SHIELD_COUNT = 4;\n const SHIELD_WIDTH = 6;\n const SHIELD_HEIGHT = 3;\n\n // Visual effects\n let glitchFrame = 0;\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let shakeFrames = 0;\n let shakeIntensity = 0;\n let hitFlashFrames = 0;\n let killStreakCount = 0;\n let killStreakTimer = 0;\n let gameOverFlashFrames = 0;\n\n const controller: SpaceInvadersController = {\n stop: () => {\n if (!running) return;\n running = false;\n // Note: Buffer exit is handled by TerminalPool via dispatchGameQuit\n },\n get isRunning() { return running; }\n };\n\n // ASCII art title\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ █ █▄ █ █ █ ▄▀█ █▀▄ █▀▀ █▀█ █▀',\n '█▀█ █ █▀▀ ██▄ █▀▄ █ █ ▀█ ▀▄▀ █▀█ █▄▀ ██▄ █▀▄ ▄█',\n ];\n\n // Invader sprites (different types)\n const invaderSprites = [\n ['<O>', '</\\\\>'], // Type 0 - bottom rows\n ['/V\\\\', '\\\\^/'], // Type 1 - middle rows\n ['|=|', '|#|'], // Type 2 - top rows\n ];\n\n // Spawn particles at position\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['✦', '★', '◆', '●']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.2 + Math.random() * 0.4;\n particles.push({\n x: x,\n y: y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color: color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 10 + Math.floor(Math.random() * 8),\n });\n }\n }\n\n // Add score popup\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 18, color });\n }\n\n function initGame() {\n playerX = GAME_WIDTH / 2;\n score = won ? score : 0; // Keep score if advancing levels\n lives = won ? lives : 3;\n gameOver = false;\n won = false;\n paused = false;\n bullets = [];\n explosions = [];\n playerShootCooldown = 0;\n invaderShootTimer = 0;\n invaderDirection = 1;\n invaderMoveTimer = 0;\n invaderDropAmount = 0;\n // Reset effects\n particles = [];\n scorePopups = [];\n shakeFrames = 0;\n shakeIntensity = 0;\n hitFlashFrames = 0;\n killStreakCount = 0;\n killStreakTimer = 0;\n gameOverFlashFrames = 0;\n\n // Speed increases with level\n invaderMoveDelay = Math.max(10, 30 - (level - 1) * 4);\n\n // Initialize invaders\n invaders = [];\n const startX = Math.floor((GAME_WIDTH - INVADER_COLS * INVADER_SPACING_X) / 2);\n const startY = 2;\n\n for (let row = 0; row < INVADER_ROWS; row++) {\n for (let col = 0; col < INVADER_COLS; col++) {\n invaders.push({\n x: startX + col * INVADER_SPACING_X,\n y: startY + row * INVADER_SPACING_Y,\n alive: true,\n type: row === 0 ? 2 : row === 1 ? 1 : 0,\n });\n }\n }\n\n // Initialize shields\n shields = [];\n for (let i = 0; i < SHIELD_COUNT; i++) {\n const shield: boolean[][] = [];\n for (let y = 0; y < SHIELD_HEIGHT; y++) {\n shield[y] = [];\n for (let x = 0; x < SHIELD_WIDTH; x++) {\n // Create arch shape\n if (y === 0 && (x === 0 || x === SHIELD_WIDTH - 1)) {\n shield[y][x] = false;\n } else if (y === SHIELD_HEIGHT - 1 && x >= 2 && x <= 3) {\n shield[y][x] = false; // Gap at bottom\n } else {\n shield[y][x] = true;\n }\n }\n }\n shields.push(shield);\n }\n }\n\n function getShieldX(shieldIndex: number): number {\n const shieldSpacing = Math.floor(GAME_WIDTH / (SHIELD_COUNT + 1));\n return shieldSpacing * (shieldIndex + 1) - Math.floor(SHIELD_WIDTH / 2);\n }\n\n function getShieldY(): number {\n return GAME_HEIGHT - 5;\n }\n\n function shootBullet(x: number, y: number, isPlayer: boolean) {\n bullets.push({ x, y, isPlayer });\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Update effect timers\n if (shakeFrames > 0) shakeFrames--;\n if (hitFlashFrames > 0) hitFlashFrames--;\n if (gameOverFlashFrames > 0) gameOverFlashFrames--;\n if (killStreakTimer > 0) {\n killStreakTimer--;\n if (killStreakTimer === 0) killStreakCount = 0;\n }\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.02;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.25;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = '';\n if (needWidth && needHeight) {\n hint = 'Make pane larger';\n } else if (needWidth) {\n hint = 'Make pane wider \\u2192';\n } else {\n hint = 'Make pane taller \\u2193';\n }\n const msg2 = `Need: ${MIN_COLS}\\u00d7${MIN_ROWS} Have: ${cols}\\u00d7${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Update game dimensions on resize\n const newDims = getGameDimensions();\n if (newDims.width !== GAME_WIDTH || newDims.height !== GAME_HEIGHT) {\n // Scale positions to new dimensions\n playerX = (playerX / GAME_WIDTH) * newDims.width;\n playerY = newDims.height - 1;\n GAME_WIDTH = newDims.width;\n GAME_HEIGHT = newDims.height;\n }\n\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH - 2) / 2));\n gameTop = Math.max(3, Math.floor((rows - GAME_HEIGHT - 4) / 2));\n\n // Apply screen shake\n let renderGameLeft = gameLeft;\n let renderGameTop = gameTop;\n if (shakeFrames > 0) {\n const shakeX = Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n const shakeY = Math.floor((Math.random() - 0.5) * shakeIntensity);\n renderGameLeft = Math.max(1, gameLeft + shakeX);\n renderGameTop = Math.max(3, gameTop + shakeY);\n }\n\n // Glitchy title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n output += `\\x1b[1;${titleX}H`;\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n // Stats bar\n const livesDisplay = '\\u2665'.repeat(lives);\n const stats = `SCORE: ${score.toString().padStart(5, '0')} LVL: ${level} ${livesDisplay}`;\n const statsX = Math.floor((cols - stats.length) / 2);\n output += `\\x1b[4;${statsX}H${themeColor}${stats}\\x1b[0m`;\n\n // Game border with flash effect\n const borderColor = hitFlashFrames > 0 && hitFlashFrames % 4 < 2 ? '\\x1b[1;91m' : themeColor;\n output += `\\x1b[${renderGameTop};${renderGameLeft}H${borderColor}\\u2554${'═'.repeat(GAME_WIDTH)}\\u2557\\x1b[0m`;\n for (let y = 0; y < GAME_HEIGHT; y++) {\n output += `\\x1b[${renderGameTop + 1 + y};${renderGameLeft}H${borderColor}\\u2551\\x1b[0m`;\n output += `\\x1b[${renderGameTop + 1 + y};${renderGameLeft + GAME_WIDTH + 1}H${borderColor}\\u2551\\x1b[0m`;\n }\n output += `\\x1b[${renderGameTop + GAME_HEIGHT + 1};${renderGameLeft}H${borderColor}\\u255a${'═'.repeat(GAME_WIDTH)}\\u255d\\x1b[0m`;\n\n if (paused) {\n const pauseMsg = '\\u2550\\u2550 PAUSED \\u2550\\u2550';\n const pauseCenterX = gameLeft + Math.floor(GAME_WIDTH / 2) + 1;\n const pauseY = gameTop + Math.floor(GAME_HEIGHT / 2) - 3;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO PLAY ]';\n const startX = gameLeft + Math.floor((GAME_WIDTH - startMsg.length) / 2) + 1;\n const startY = gameTop + Math.floor(GAME_HEIGHT / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = '←→ MOVE SPC FIRE ESC MENU';\n const ctrlX = gameLeft + Math.floor((GAME_WIDTH - controls.length) / 2) + 1;\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n } else if (gameOver) {\n const overMsg = won ? '╔══ LEVEL COMPLETE! ══╗' : '╔══ GAME OVER ══╗';\n const overX = gameLeft + Math.floor((GAME_WIDTH - overMsg.length) / 2) + 1;\n const overY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n output += `\\x1b[${overY};${overX}H${won ? '\\x1b[1;92m' : '\\x1b[1;91m'}${overMsg}\\x1b[0m`;\n\n const scoreLine = `SCORE: ${score} HIGH: ${highScore}`;\n output += `\\x1b[${overY + 1};${gameLeft + Math.floor((GAME_WIDTH - scoreLine.length) / 2) + 1}H${themeColor}${scoreLine}\\x1b[0m`;\n\n const restart = won ? '╚ [R] NEXT LEVEL [Q] QUIT ╝' : '╚ [R] RESTART [Q] QUIT ╝';\n output += `\\x1b[${overY + 2};${gameLeft + Math.floor((GAME_WIDTH - restart.length) / 2) + 1}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n } else {\n // Draw shields\n const shieldY = getShieldY();\n for (let i = 0; i < SHIELD_COUNT; i++) {\n const shieldX = getShieldX(i);\n for (let y = 0; y < SHIELD_HEIGHT; y++) {\n for (let x = 0; x < SHIELD_WIDTH; x++) {\n if (shields[i][y][x]) {\n const screenX = renderGameLeft + 1 + shieldX + x;\n const screenY = renderGameTop + 1 + shieldY + y;\n output += `\\x1b[${screenY};${screenX}H\\x1b[92m\\u2588\\x1b[0m`;\n }\n }\n }\n }\n\n // Draw invaders\n const animFrame = Math.floor(glitchFrame / 15) % 2;\n for (const invader of invaders) {\n if (!invader.alive) continue;\n const sprite = invaderSprites[invader.type][animFrame];\n const screenX = renderGameLeft + 1 + invader.x;\n const screenY = renderGameTop + 1 + invader.y;\n\n // Color based on type\n const colors = ['\\x1b[92m', '\\x1b[93m', '\\x1b[95m']; // Green, Yellow, Magenta\n output += `\\x1b[${screenY};${screenX}H${colors[invader.type]}${sprite}\\x1b[0m`;\n }\n\n // Draw bullets\n for (const bullet of bullets) {\n const screenX = renderGameLeft + 1 + Math.floor(bullet.x);\n const screenY = renderGameTop + 1 + Math.floor(bullet.y);\n if (bullet.isPlayer) {\n output += `\\x1b[${screenY};${screenX}H\\x1b[97m\\u2502\\x1b[0m`;\n } else {\n output += `\\x1b[${screenY};${screenX}H\\x1b[91m\\u25cf\\x1b[0m`;\n }\n }\n\n // Draw explosions\n for (const exp of explosions) {\n const screenX = renderGameLeft + 1 + exp.x;\n const screenY = renderGameTop + 1 + exp.y;\n const expChars = ['*', '+', '\\u00d7', '\\u00b7'];\n const char = expChars[Math.min(exp.frame, expChars.length - 1)];\n output += `\\x1b[${screenY};${screenX}H\\x1b[93m${char}\\x1b[0m`;\n }\n\n // Draw particles\n for (const p of particles) {\n const screenX = Math.round(renderGameLeft + 1 + p.x);\n const screenY = Math.round(renderGameTop + 1 + p.y);\n if (screenX > renderGameLeft && screenX < renderGameLeft + GAME_WIDTH + 1 &&\n screenY > renderGameTop && screenY < renderGameTop + GAME_HEIGHT + 1) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const screenX = Math.round(renderGameLeft + 1 + popup.x);\n const screenY = Math.round(renderGameTop + 1 + popup.y);\n if (screenY > renderGameTop && screenY < renderGameTop + GAME_HEIGHT + 1) {\n const alpha = popup.frames > 10 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n\n // Draw kill streak message\n if (killStreakCount >= 3) {\n const streakMsg = killStreakCount >= 5 ? `★ ${killStreakCount}x KILL STREAK! ★` : `${killStreakCount}x STREAK!`;\n const streakX = renderGameLeft + Math.floor((GAME_WIDTH - streakMsg.length) / 2) + 1;\n const streakColor = glitchFrame % 6 < 3 ? '\\x1b[1;91m' : '\\x1b[1;93m';\n output += `\\x1b[${renderGameTop + 2};${streakX}H${streakColor}${streakMsg}\\x1b[0m`;\n }\n\n // Draw player with hit flash\n const playerScreenX = renderGameLeft + 1 + Math.floor(playerX) - 1;\n const playerScreenY = renderGameTop + 1 + playerY;\n const playerColor = hitFlashFrames > 0 && hitFlashFrames % 4 < 2 ? '\\x1b[1;91m' : themeColor;\n output += `\\x1b[${playerScreenY};${playerScreenX}H${playerColor}/\\u2588\\\\\\x1b[0m`;\n }\n\n // Hint\n const hint = gameStarted && !gameOver && !paused ? `HIGH: ${highScore} [ ESC ] MENU` : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${gameTop + GAME_HEIGHT + 3};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n function update() {\n if (!gameStarted || gameOver || paused) return;\n\n // Update cooldowns\n if (playerShootCooldown > 0) playerShootCooldown--;\n invaderShootTimer++;\n\n // Update explosions\n explosions = explosions.filter(exp => {\n exp.frame++;\n return exp.frame < 4;\n });\n\n // Move invaders\n invaderMoveTimer++;\n if (invaderMoveTimer >= invaderMoveDelay) {\n invaderMoveTimer = 0;\n\n // Check if any invader hit the edge\n let hitEdge = false;\n for (const invader of invaders) {\n if (!invader.alive) continue;\n const nextX = invader.x + invaderDirection * 2;\n if (nextX <= 0 || nextX >= GAME_WIDTH - 3) {\n hitEdge = true;\n break;\n }\n }\n\n if (hitEdge) {\n invaderDirection *= -1;\n invaderDropAmount = 1;\n }\n\n // Move invaders\n for (const invader of invaders) {\n if (!invader.alive) continue;\n if (invaderDropAmount > 0) {\n invader.y += invaderDropAmount;\n } else {\n invader.x += invaderDirection * 2;\n }\n\n // Check if invaders reached the player\n if (invader.y >= playerY - 1) {\n gameOver = true;\n if (score > highScore) highScore = score;\n return;\n }\n }\n invaderDropAmount = 0;\n }\n\n // Invader shooting\n const aliveInvaders = invaders.filter(i => i.alive);\n if (aliveInvaders.length > 0 && invaderShootTimer >= 60) {\n invaderShootTimer = 0;\n // Random invader shoots\n const shooter = aliveInvaders[Math.floor(Math.random() * aliveInvaders.length)];\n shootBullet(shooter.x + 1, shooter.y + 1, false);\n }\n\n // Move bullets\n bullets = bullets.filter(bullet => {\n if (bullet.isPlayer) {\n bullet.y -= 0.8;\n } else {\n bullet.y += 0.5;\n }\n return bullet.y >= 0 && bullet.y < GAME_HEIGHT;\n });\n\n // Bullet collision with invaders\n for (const bullet of bullets) {\n if (!bullet.isPlayer) continue;\n\n for (const invader of invaders) {\n if (!invader.alive) continue;\n if (bullet.y >= invader.y && bullet.y <= invader.y + 1 &&\n bullet.x >= invader.x && bullet.x <= invader.x + 2) {\n invader.alive = false;\n bullet.y = -100; // Mark for removal\n explosions.push({ x: invader.x + 1, y: invader.y, frame: 0 });\n\n // Kill streak tracking\n killStreakCount++;\n killStreakTimer = 30; // Reset streak timer\n\n // Calculate score with streak bonus\n const baseScore = (invader.type + 1) * 10;\n const streakBonus = killStreakCount >= 3 ? Math.floor(killStreakCount * 5) : 0;\n const totalScore = baseScore + streakBonus;\n score += totalScore;\n\n // Effects\n shakeFrames = 3 + Math.min(killStreakCount, 5);\n shakeIntensity = 1 + Math.floor(killStreakCount / 3);\n\n // Particles - color based on invader type\n const invaderColors = ['\\x1b[1;92m', '\\x1b[1;93m', '\\x1b[1;95m'];\n spawnParticles(invader.x + 1, invader.y, 6 + Math.min(killStreakCount, 6), invaderColors[invader.type], ['✦', '★', '◆', '×']);\n\n // Score popup\n const popupText = killStreakCount >= 3 ? `+${totalScore}!` : `+${totalScore}`;\n const popupColor = killStreakCount >= 3 ? '\\x1b[1;91m' : '\\x1b[1;93m';\n addScorePopup(invader.x + 1, invader.y - 1, popupText, popupColor);\n }\n }\n }\n\n // Bullet collision with shields\n const shieldY = getShieldY();\n for (const bullet of bullets) {\n for (let i = 0; i < SHIELD_COUNT; i++) {\n const shieldX = getShieldX(i);\n const relX = Math.floor(bullet.x - shieldX);\n const relY = Math.floor(bullet.y - shieldY);\n\n if (relX >= 0 && relX < SHIELD_WIDTH && relY >= 0 && relY < SHIELD_HEIGHT) {\n if (shields[i][relY][relX]) {\n shields[i][relY][relX] = false;\n bullet.y = -100; // Mark for removal\n }\n }\n }\n }\n\n // Bullet collision with player\n for (const bullet of bullets) {\n if (bullet.isPlayer) continue;\n if (bullet.y >= playerY && bullet.y <= playerY + 1 &&\n bullet.x >= playerX - 1 && bullet.x <= playerX + 1) {\n bullet.y = -100;\n explosions.push({ x: Math.floor(playerX), y: playerY, frame: 0 });\n lives--;\n\n // Player hit effects\n shakeFrames = 12;\n shakeIntensity = 3;\n hitFlashFrames = 15;\n killStreakCount = 0; // Reset kill streak on hit\n spawnParticles(Math.floor(playerX), playerY, 10, '\\x1b[1;91m', ['✗', '☠', '×', '▒']);\n\n if (lives <= 0) {\n gameOver = true;\n gameOverFlashFrames = 30;\n shakeFrames = 20;\n shakeIntensity = 4;\n spawnParticles(Math.floor(playerX), playerY, 15, '\\x1b[1;91m', ['✗', '☠', '×', '▓', '░']);\n if (score > highScore) highScore = score;\n }\n }\n }\n\n // Remove destroyed bullets\n bullets = bullets.filter(b => b.y >= 0);\n\n // Check win condition\n if (aliveInvaders.length === 0) {\n won = true;\n gameOver = true;\n level++;\n if (score > highScore) highScore = score;\n }\n }\n\n // Start game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) {\n clearInterval(renderInterval);\n return;\n }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) {\n clearInterval(gameInterval);\n return;\n }\n update();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener.dispose();\n return;\n }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // Handle ESC key - toggle pause (works on start screen too)\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Q to quit (from start screen, pause, or game over)\n if (key === 'q') {\n if (paused || gameOver || !gameStarted) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n }\n\n // Start screen - any key (except ESC/Q handled above) starts the game\n // Skip if paused (ESC menu open on start screen)\n if (!gameStarted && !paused) {\n gameStarted = true;\n return;\n }\n\n if (gameOver) {\n if (key === 'r') {\n if (won) {\n // Continue to next level\n initGame();\n } else {\n // Full restart\n level = 1;\n initGame();\n }\n gameStarted = true;\n }\n return;\n }\n\n // Pause menu actions\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n level = 1;\n initGame();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (key === 'r') {\n level = 1;\n initGame();\n gameStarted = true;\n paused = false;\n } else if (key === 'l') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (key === 'n') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n switch (domEvent.key) {\n case 'ArrowLeft':\n case 'a':\n if (playerX > 2) playerX -= 2;\n break;\n case 'ArrowRight':\n case 'd':\n if (playerX < GAME_WIDTH - 2) playerX += 2;\n break;\n case ' ':\n if (playerShootCooldown === 0) {\n shootBullet(playerX, playerY - 1, true);\n playerShootCooldown = 10;\n }\n break;\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Tetris\n *\n * Cyberpunk-themed Tetris with glitchy effects,\n * neon borders, and theme-aware colors.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor, getVerticalAnchor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Tetris Game Controller\n */\nexport interface TetrisController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// Tetromino shapes (rotations included)\nconst TETROMINOES = {\n I: [\n [[1, 1, 1, 1]],\n [[1], [1], [1], [1]],\n ],\n O: [\n [[1, 1], [1, 1]],\n ],\n T: [\n [[0, 1, 0], [1, 1, 1]],\n [[1, 0], [1, 1], [1, 0]],\n [[1, 1, 1], [0, 1, 0]],\n [[0, 1], [1, 1], [0, 1]],\n ],\n S: [\n [[0, 1, 1], [1, 1, 0]],\n [[1, 0], [1, 1], [0, 1]],\n ],\n Z: [\n [[1, 1, 0], [0, 1, 1]],\n [[0, 1], [1, 1], [1, 0]],\n ],\n J: [\n [[1, 0, 0], [1, 1, 1]],\n [[1, 1], [1, 0], [1, 0]],\n [[1, 1, 1], [0, 0, 1]],\n [[0, 1], [0, 1], [1, 1]],\n ],\n L: [\n [[0, 0, 1], [1, 1, 1]],\n [[1, 0], [1, 0], [1, 1]],\n [[1, 1, 1], [1, 0, 0]],\n [[1, 1], [0, 1], [0, 1]],\n ],\n};\n\nconst PIECE_COLORS: Record<string, string> = {\n I: '\\x1b[96m', // Cyan\n O: '\\x1b[93m', // Yellow\n T: '\\x1b[95m', // Magenta\n S: '\\x1b[92m', // Green\n Z: '\\x1b[91m', // Red\n J: '\\x1b[94m', // Blue\n L: '\\x1b[33m', // Orange (dark yellow)\n};\n\ntype PieceType = keyof typeof TETROMINOES;\ntype GameMode = 'marathon' | 'sprint';\n\n/**\n * Cyberpunk Tetris Game\n */\nexport function runTetrisGame(terminal: Terminal): TetrisController {\n const themeColor = getCurrentThemeColor();\n\n // Game dimensions\n const BOARD_WIDTH = 12; // Wider board for better text fit\n const BOARD_HEIGHT = 20;\n const SIDE_PANEL_WIDTH = 14;\n const BOARD_ONLY_WIDTH = BOARD_WIDTH * 2 + 2; // Just board + borders\n const TOTAL_WIDTH = BOARD_WIDTH * 2 + SIDE_PANEL_WIDTH + 4; // Board + panel + gaps\n const TICK_MS = 25;\n const SPRINT_TARGET_LINES = 40;\n\n // Minimum terminal size (compact mode - just the board)\n const MIN_COLS = BOARD_ONLY_WIDTH + 2;\n const MIN_ROWS = BOARD_HEIGHT + 3; // Board + controls (title hides automatically on short panes)\n const MIN_ROWS_WITH_TITLE = BOARD_HEIGHT + 4;\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let won = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let score = 0;\n let level = 1;\n let lines = 0;\n let highScore = 0;\n let selectedMode: GameMode = 'marathon';\n let mode: GameMode = 'marathon';\n\n // Game board (0 = empty, string = color code)\n let board: (string | 0)[][] = [];\n\n // Current piece state\n let currentPiece: PieceType = 'T';\n let currentRotation = 0;\n let pieceX = 0;\n let pieceY = 0;\n let nextPiece: PieceType = 'T';\n\n // Glitch effect\n let glitchFrame = 0;\n\n // Drop timing\n let dropCounter = 0;\n let dropInterval = 1000;\n\n // Hard drop animation\n let hardDropping = false;\n let hardDropConsumed = false; // Prevents holding space from dropping multiple pieces\n\n // Line clear effects\n let shakeFrames = 0;\n let shakeIntensity = 0;\n let flashRows: number[] = [];\n let flashFrames = 0;\n let comboMessage = '';\n let comboFrames = 0;\n let comboChain = 0;\n let backToBackTetris = false;\n let particles: { x: number; y: number; char: string; color: string; vx: number; vy: number; life: number }[] = [];\n\n const controller: TetrisController = {\n stop: () => {\n if (!running) return;\n running = false;\n // Note: Buffer exit is handled by TerminalPool via dispatchGameQuit\n },\n get isRunning() { return running; }\n };\n\n // ASCII art title\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ ▀█▀ █▀▀ ▀█▀ █▀█ █ █▀',\n '█▀█ █ █▀▀ ██▄ █▀▄ █ ██▄ █ █▀▄ █ ▄█',\n ];\n\n function initGame(newMode: GameMode) {\n mode = newMode;\n board = Array(BOARD_HEIGHT).fill(null).map(() => Array(BOARD_WIDTH).fill(0));\n score = 0;\n level = 1;\n lines = 0;\n dropInterval = 1000;\n dropCounter = 0;\n gameOver = false;\n won = false;\n paused = false;\n comboChain = 0;\n backToBackTetris = false;\n hardDropping = false;\n hardDropConsumed = false;\n shakeFrames = 0;\n shakeIntensity = 0;\n flashRows = [];\n flashFrames = 0;\n comboMessage = '';\n comboFrames = 0;\n particles = [];\n spawnPiece();\n nextPiece = randomPiece();\n }\n\n function randomPiece(): PieceType {\n const pieces: PieceType[] = ['I', 'O', 'T', 'S', 'Z', 'J', 'L'];\n return pieces[Math.floor(Math.random() * pieces.length)];\n }\n\n function spawnPiece() {\n currentPiece = nextPiece || randomPiece();\n nextPiece = randomPiece();\n currentRotation = 0;\n const shape = TETROMINOES[currentPiece][0];\n pieceX = Math.floor((BOARD_WIDTH - shape[0].length) / 2);\n pieceY = 0;\n\n if (!isValidPosition(pieceX, pieceY, currentRotation)) {\n gameOver = true;\n if (score > highScore) highScore = score;\n }\n }\n\n function getShape(rotation: number = currentRotation): number[][] {\n const rotations = TETROMINOES[currentPiece];\n return rotations[rotation % rotations.length];\n }\n\n function isValidPosition(x: number, y: number, rotation: number): boolean {\n const shape = TETROMINOES[currentPiece][rotation % TETROMINOES[currentPiece].length];\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n const newX = x + col;\n const newY = y + row;\n if (newX < 0 || newX >= BOARD_WIDTH || newY >= BOARD_HEIGHT) {\n return false;\n }\n if (newY >= 0 && board[newY][newX]) {\n return false;\n }\n }\n }\n }\n return true;\n }\n\n function lockPiece() {\n const shape = getShape();\n const color = PIECE_COLORS[currentPiece];\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n const boardY = pieceY + row;\n const boardX = pieceX + col;\n if (boardY >= 0 && boardY < BOARD_HEIGHT && boardX >= 0 && boardX < BOARD_WIDTH) {\n board[boardY][boardX] = color;\n }\n }\n }\n }\n clearLines();\n if (!gameOver) {\n spawnPiece();\n }\n }\n\n function clearLines() {\n // First, find rows to clear and trigger flash effect\n const rowsToClear: number[] = [];\n for (let row = BOARD_HEIGHT - 1; row >= 0; row--) {\n if (board[row].every(cell => cell !== 0)) {\n rowsToClear.push(row);\n }\n }\n\n const clearedLines = rowsToClear.length;\n if (clearedLines > 0) {\n // Trigger flash effect on these rows\n flashRows = [...rowsToClear];\n flashFrames = 8; // Flash for 8 frames\n\n // Spawn particles from cleared rows\n const particleChars = ['█', '▓', '▒', '░', '✦', '✧', '◆', '◇'];\n const particleColors = ['\\x1b[91m', '\\x1b[93m', '\\x1b[92m', '\\x1b[96m', '\\x1b[95m', '\\x1b[97m'];\n for (const row of rowsToClear) {\n for (let x = 0; x < BOARD_WIDTH; x++) {\n if (Math.random() < 0.4) { // 40% chance for each cell\n particles.push({\n x: x * 2,\n y: row,\n char: particleChars[Math.floor(Math.random() * particleChars.length)],\n color: particleColors[Math.floor(Math.random() * particleColors.length)],\n vx: (Math.random() - 0.5) * 4,\n vy: (Math.random() - 0.8) * 3,\n life: 15 + Math.floor(Math.random() * 10),\n });\n }\n }\n }\n\n // Combo & back-to-back scoring\n comboChain++;\n const isTetris = clearedLines === 4;\n const b2bBonus = isTetris && backToBackTetris ? 400 * level : 0;\n const comboBonus = comboChain > 1 ? (comboChain - 1) * 50 * level : 0;\n backToBackTetris = isTetris;\n\n // Screen shake based on clear strength and combo\n shakeIntensity = clearedLines + Math.min(2, comboChain - 1);\n shakeFrames = clearedLines * 5 + (comboChain > 1 ? 6 : 4);\n\n // Combo message\n if (isTetris && b2bBonus > 0) {\n comboMessage = '⚡ B2B TETRIS! ⚡';\n comboFrames = 45;\n } else if (isTetris) {\n comboMessage = '★ TETRIS! ★';\n comboFrames = 40;\n } else if (clearedLines === 3) {\n comboMessage = 'TRIPLE!';\n comboFrames = 25;\n } else if (clearedLines === 2) {\n comboMessage = 'DOUBLE!';\n comboFrames = 20;\n } else {\n comboMessage = 'SINGLE!';\n comboFrames = 16;\n }\n\n if (comboChain > 1) {\n comboMessage += ` COMBO x${comboChain}`;\n comboFrames = Math.max(comboFrames, 24);\n }\n\n // Rebuild board to avoid index-shift bugs when clearing multiple rows.\n const remainingRows = board.filter(row => !row.every(cell => cell !== 0));\n board = [\n ...Array(clearedLines).fill(null).map(() => Array(BOARD_WIDTH).fill(0)),\n ...remainingRows,\n ];\n\n // Update flash indices to match the newly-inserted empty rows at the top.\n flashRows = Array.from({ length: clearedLines }, (_, i) => i);\n\n const pointsTable = [0, 100, 300, 500, 800];\n const points = (pointsTable[Math.min(clearedLines, pointsTable.length - 1)] ?? 0) * level + comboBonus + b2bBonus;\n score += points;\n lines += clearedLines;\n\n // Level up every 10 lines\n const newLevel = Math.floor(lines / 10) + 1;\n if (newLevel > level) {\n level = newLevel;\n dropInterval = Math.max(100, 1000 - (level - 1) * 100);\n }\n\n if (mode === 'sprint' && lines >= SPRINT_TARGET_LINES) {\n won = true;\n gameOver = true;\n if (score > highScore) highScore = score;\n }\n } else {\n comboChain = 0;\n }\n }\n\n function moveLeft() {\n if (isValidPosition(pieceX - 1, pieceY, currentRotation)) {\n pieceX--;\n }\n }\n\n function moveRight() {\n if (isValidPosition(pieceX + 1, pieceY, currentRotation)) {\n pieceX++;\n }\n }\n\n function moveDown(): boolean {\n if (isValidPosition(pieceX, pieceY + 1, currentRotation)) {\n pieceY++;\n return true;\n }\n return false;\n }\n\n function hardDrop() {\n if (hardDropping) return; // Already dropping\n if (hardDropConsumed) return; // Must release space before dropping again\n hardDropping = true;\n hardDropConsumed = true; // Mark as consumed until space is released\n }\n\n function rotate() {\n const newRotation = (currentRotation + 1) % TETROMINOES[currentPiece].length;\n // Try normal rotation\n if (isValidPosition(pieceX, pieceY, newRotation)) {\n currentRotation = newRotation;\n return;\n }\n // Wall kicks\n const kicks = [-1, 1, -2, 2];\n for (const kick of kicks) {\n if (isValidPosition(pieceX + kick, pieceY, newRotation)) {\n pieceX += kick;\n currentRotation = newRotation;\n return;\n }\n }\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = '';\n if (needWidth && needHeight) {\n hint = 'Make pane larger';\n } else if (needWidth) {\n hint = 'Make pane wider →';\n } else {\n hint = 'Make pane taller ↓';\n }\n const msg2 = `Need: ${MIN_COLS}×${MIN_ROWS} Have: ${cols}×${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Determine layout mode based on available space\n const showSidePanel = cols >= TOTAL_WIDTH + 4;\n const showTitle = rows >= MIN_ROWS_WITH_TITLE;\n const compactTitle = showTitle && rows < 30; // Use compact title if limited height\n const displayWidth = showSidePanel ? TOTAL_WIDTH : BOARD_ONLY_WIDTH;\n let gameLeft = Math.max(2, Math.floor((cols - displayWidth) / 2));\n const titleRows = showTitle ? (compactTitle ? 1 : 2) : 0;\n const gapAfterTitle = showTitle ? 1 : 0;\n const boardRows = BOARD_HEIGHT + 2;\n const footerRows = 2;\n const layoutRows = titleRows + gapAfterTitle + boardRows + footerRows;\n const titleTop = getVerticalAnchor(rows, layoutRows, {\n minTop: 1,\n footerRows: 1,\n });\n let gameTop = titleTop + titleRows + gapAfterTitle;\n\n // Apply screen shake\n if (shakeFrames > 0) {\n const shakeX = Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n const shakeY = Math.floor((Math.random() - 0.5) * shakeIntensity);\n gameLeft = Math.max(1, gameLeft + shakeX);\n gameTop = Math.max(2, gameTop + shakeY);\n }\n\n // Glitchy title (hidden first when height is constrained)\n if (showTitle) {\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n\n if (compactTitle) {\n const shortTitle = 'HYPER TETRIS';\n const titleX = Math.floor((cols - shortTitle.length) / 2) + glitchOffset;\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[${titleTop};${titleX}H\\x1b[91m${shortTitle}\\x1b[0m`;\n } else {\n output += `\\x1b[${titleTop};${titleX}H${themeColor}\\x1b[1m${shortTitle}\\x1b[0m`;\n }\n } else {\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n output += `\\x1b[${titleTop};${titleX}H`;\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n }\n }\n\n // Game border (double-width cells)\n output += `\\x1b[${gameTop};${gameLeft}H${themeColor}╔${'══'.repeat(BOARD_WIDTH)}╗\\x1b[0m`;\n for (let y = 0; y < BOARD_HEIGHT; y++) {\n output += `\\x1b[${gameTop + 1 + y};${gameLeft}H${themeColor}║\\x1b[0m`;\n output += `\\x1b[${gameTop + 1 + y};${gameLeft + 1 + BOARD_WIDTH * 2}H${themeColor}║\\x1b[0m`;\n }\n output += `\\x1b[${gameTop + BOARD_HEIGHT + 1};${gameLeft}H${themeColor}╚${'══'.repeat(BOARD_WIDTH)}╝\\x1b[0m`;\n\n if (paused) {\n const pauseMsg = '══ PAUSED ══';\n const pauseCenterX = gameLeft + Math.floor(BOARD_WIDTH * 2 / 2) + 1;\n const pauseY = gameTop + Math.floor(BOARD_HEIGHT / 2) - 3;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY ]';\n const startX = gameLeft + Math.floor((BOARD_WIDTH * 2 - startMsg.length) / 2) + 1;\n const startY = gameTop + Math.floor(BOARD_HEIGHT / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const modeY = startY + 2;\n const marathonLabel = selectedMode === 'marathon' ? '[1] MARATHON' : ' 1 MARATHON';\n const sprintLabel = selectedMode === 'sprint' ? '[2] SPRINT 40L' : ' 2 SPRINT 40L';\n const modePrompt = `MODE: ${marathonLabel} ${sprintLabel}`;\n const modeX = Math.floor((cols - modePrompt.length) / 2);\n output += `\\x1b[${modeY};${modeX}H\\x1b[1m${themeColor}${modePrompt}\\x1b[0m`;\n\n const controls = '←→ MODE ↓ MOVE ↑ ROT SPC DROP ESC MENU';\n const ctrlX = Math.floor((cols - controls.length) / 2);\n output += `\\x1b[${gameTop + BOARD_HEIGHT + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n } else if (gameOver) {\n const overMsg = won ? '══ YOU WIN ══' : '══ GAME OVER ══';\n const overX = gameLeft + Math.floor((BOARD_WIDTH * 2 - overMsg.length) / 2) + 1;\n const overY = gameTop + Math.floor(BOARD_HEIGHT / 2) - 1;\n const overColor = won ? '\\x1b[1;92m' : '\\x1b[1;31m';\n output += `\\x1b[${overY};${overX}H${overColor}${overMsg}\\x1b[0m`;\n\n const finalScore = `SCORE: ${score}`;\n const scoreX = gameLeft + Math.floor((BOARD_WIDTH * 2 - finalScore.length) / 2) + 1;\n output += `\\x1b[${overY + 2};${scoreX}H${themeColor}${finalScore}\\x1b[0m`;\n\n const finalLines = `LINES: ${lines} MODE: ${mode === 'sprint' ? 'SPRINT' : 'MARATHON'}`;\n const linesX = gameLeft + Math.floor((BOARD_WIDTH * 2 - finalLines.length) / 2) + 1;\n output += `\\x1b[${overY + 3};${linesX}H${themeColor}${finalLines}\\x1b[0m`;\n\n const restart = '[ R ] RESTART [ Q ] QUIT';\n const restartX = gameLeft + Math.floor((BOARD_WIDTH * 2 - restart.length) / 2) + 1;\n output += `\\x1b[${overY + 5};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n } else {\n // Draw board with flash effect\n for (let y = 0; y < BOARD_HEIGHT; y++) {\n const isFlashing = flashFrames > 0 && flashRows.includes(y);\n for (let x = 0; x < BOARD_WIDTH; x++) {\n const cell = board[y][x];\n if (cell) {\n if (isFlashing) {\n // Flash effect - alternate between white and original color\n const flashColor = flashFrames % 2 === 0 ? '\\x1b[97m\\x1b[47m' : cell;\n output += `\\x1b[${gameTop + 1 + y};${gameLeft + 1 + x * 2}H${flashColor}██\\x1b[0m`;\n } else {\n output += `\\x1b[${gameTop + 1 + y};${gameLeft + 1 + x * 2}H${cell}██\\x1b[0m`;\n }\n } else if (isFlashing) {\n // Flash empty cells too for full row flash\n const flashColor = flashFrames % 2 === 0 ? '\\x1b[97m\\x1b[47m' : '\\x1b[100m';\n output += `\\x1b[${gameTop + 1 + y};${gameLeft + 1 + x * 2}H${flashColor}██\\x1b[0m`;\n }\n }\n }\n\n // Draw current piece\n const shape = getShape();\n const pieceColor = PIECE_COLORS[currentPiece];\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n const screenY = gameTop + 1 + pieceY + row;\n const screenX = gameLeft + 1 + (pieceX + col) * 2;\n if (pieceY + row >= 0) {\n output += `\\x1b[${screenY};${screenX}H${pieceColor}██\\x1b[0m`;\n }\n }\n }\n }\n\n // Ghost piece (preview where piece will land)\n let ghostY = pieceY;\n while (isValidPosition(pieceX, ghostY + 1, currentRotation)) {\n ghostY++;\n }\n if (ghostY !== pieceY) {\n for (let row = 0; row < shape.length; row++) {\n for (let col = 0; col < shape[row].length; col++) {\n if (shape[row][col]) {\n const screenY = gameTop + 1 + ghostY + row;\n const screenX = gameLeft + 1 + (pieceX + col) * 2;\n if (ghostY + row >= 0) {\n output += `\\x1b[${screenY};${screenX}H\\x1b[2m${pieceColor}░░\\x1b[0m`;\n }\n }\n }\n }\n }\n\n // Draw particles\n for (const p of particles) {\n if (p.life > 0) {\n const px = Math.round(gameLeft + 1 + p.x);\n const py = Math.round(gameTop + 1 + p.y);\n if (px > 0 && px < cols && py > 0 && py < rows) {\n output += `\\x1b[${py};${px}H${p.color}${p.char}\\x1b[0m`;\n }\n }\n }\n\n // Draw combo message\n if (comboFrames > 0 && comboMessage) {\n const msgX = gameLeft + Math.floor((BOARD_WIDTH * 2 - comboMessage.length) / 2) + 1;\n const msgY = gameTop + Math.floor(BOARD_HEIGHT / 2);\n // Pulsing effect\n const pulse = comboFrames % 4 < 2;\n const msgColor = comboMessage.includes('TETRIS') ? (pulse ? '\\x1b[1;93m' : '\\x1b[1;91m') : (pulse ? '\\x1b[1;97m' : '\\x1b[1;96m');\n output += `\\x1b[${msgY};${msgX}H${msgColor}${comboMessage}\\x1b[0m`;\n }\n }\n\n // Stats display - either side panel or compact bar\n if (showSidePanel) {\n // Side panel\n const panelX = gameLeft + BOARD_WIDTH * 2 + 4;\n\n // Score\n output += `\\x1b[${gameTop};${panelX}H${themeColor}┌──────────┐\\x1b[0m`;\n output += `\\x1b[${gameTop + 1};${panelX}H${themeColor}│ SCORE │\\x1b[0m`;\n output += `\\x1b[${gameTop + 2};${panelX}H${themeColor}│ ${score.toString().padStart(8, ' ')} │\\x1b[0m`;\n output += `\\x1b[${gameTop + 3};${panelX}H${themeColor}├──────────┤\\x1b[0m`;\n output += `\\x1b[${gameTop + 4};${panelX}H${themeColor}│ LEVEL │\\x1b[0m`;\n output += `\\x1b[${gameTop + 5};${panelX}H${themeColor}│ ${level.toString().padStart(8, ' ')} │\\x1b[0m`;\n output += `\\x1b[${gameTop + 6};${panelX}H${themeColor}├──────────┤\\x1b[0m`;\n output += `\\x1b[${gameTop + 7};${panelX}H${themeColor}│ LINES │\\x1b[0m`;\n output += `\\x1b[${gameTop + 8};${panelX}H${themeColor}│ ${lines.toString().padStart(8, ' ')} │\\x1b[0m`;\n output += `\\x1b[${gameTop + 9};${panelX}H${themeColor}├──────────┤\\x1b[0m`;\n output += `\\x1b[${gameTop + 10};${panelX}H${themeColor}│ HIGH │\\x1b[0m`;\n output += `\\x1b[${gameTop + 11};${panelX}H${themeColor}│ ${highScore.toString().padStart(8, ' ')} │\\x1b[0m`;\n output += `\\x1b[${gameTop + 12};${panelX}H${themeColor}└──────────┘\\x1b[0m`;\n\n // Next piece preview\n output += `\\x1b[${gameTop + 14};${panelX}H${themeColor}┌──────────┐\\x1b[0m`;\n output += `\\x1b[${gameTop + 15};${panelX}H${themeColor}│ NEXT │\\x1b[0m`;\n output += `\\x1b[${gameTop + 16};${panelX}H${themeColor}│ │\\x1b[0m`;\n output += `\\x1b[${gameTop + 17};${panelX}H${themeColor}│ │\\x1b[0m`;\n output += `\\x1b[${gameTop + 18};${panelX}H${themeColor}│ │\\x1b[0m`;\n output += `\\x1b[${gameTop + 19};${panelX}H${themeColor}└──────────┘\\x1b[0m`;\n\n if (gameStarted && !gameOver) {\n const nextShape = TETROMINOES[nextPiece][0];\n const nextColor = PIECE_COLORS[nextPiece];\n const offsetX = Math.floor((4 - nextShape[0].length) / 2);\n const offsetY = Math.floor((2 - nextShape.length) / 2);\n for (let row = 0; row < nextShape.length; row++) {\n for (let col = 0; col < nextShape[row].length; col++) {\n if (nextShape[row][col]) {\n output += `\\x1b[${gameTop + 16 + offsetY + row};${panelX + 2 + (offsetX + col) * 2}H${nextColor}██\\x1b[0m`;\n }\n }\n }\n }\n\n const modeLabel = mode === 'sprint'\n ? `M:S ${Math.max(0, SPRINT_TARGET_LINES - lines).toString().padStart(3, ' ')}`\n : 'M:MARATHON';\n const modeLabelX = panelX + Math.max(0, Math.floor((12 - modeLabel.length) / 2));\n output += `\\x1b[${gameTop + 20};${modeLabelX}H\\x1b[2m${themeColor}${modeLabel}\\x1b[0m`;\n } else {\n // Compact mode - stats bar above board\n const sprintTail = mode === 'sprint' ? ` TGT:${Math.max(0, SPRINT_TARGET_LINES - lines).toString().padStart(2, '0')}` : '';\n const statsBar = `SCR:${score.toString().padStart(5)} LVL:${level} LNS:${lines.toString().padStart(3)}${sprintTail}`;\n const statsX = gameLeft + Math.floor((BOARD_WIDTH * 2 - statsBar.length) / 2) + 1;\n const statsY = gameTop - 1;\n if (statsY >= 1) {\n output += `\\x1b[${statsY};${statsX}H${themeColor}${statsBar}\\x1b[0m`;\n }\n }\n\n terminal.write(output);\n }\n\n function update() {\n if (!gameStarted || gameOver || paused) return;\n\n // Handle animated hard drop\n if (hardDropping) {\n // Move down 2 rows per frame for fast animation\n let moved = false;\n for (let i = 0; i < 2; i++) {\n if (moveDown()) {\n score += 2;\n moved = true;\n } else {\n break;\n }\n }\n if (!moved) {\n // Can't move down anymore, lock the piece\n hardDropping = false;\n lockPiece();\n }\n return; // Skip normal drop during hard drop animation\n }\n\n dropCounter++;\n if (dropCounter * TICK_MS >= dropInterval) {\n dropCounter = 0;\n if (!moveDown()) {\n lockPiece();\n }\n }\n\n // Update effect timers\n if (shakeFrames > 0) shakeFrames--;\n if (flashFrames > 0) flashFrames--;\n if (comboFrames > 0) comboFrames--;\n\n // Update particles\n for (const p of particles) {\n if (p.life > 0) {\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.2; // Gravity\n p.life--;\n }\n }\n // Remove dead particles\n particles = particles.filter(p => p.life > 0);\n }\n\n // Start game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h'); // Enter alternate buffer\n terminal.write('\\x1b[?25l'); // Hide cursor\n\n initGame(mode);\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) {\n clearInterval(renderInterval);\n return;\n }\n render();\n }, TICK_MS);\n\n const gameInterval = setInterval(() => {\n if (!running) {\n clearInterval(gameInterval);\n return;\n }\n update();\n }, TICK_MS);\n\n // Track space key release to allow next hard drop\n const handleKeyUp = (e: KeyboardEvent) => {\n if (e.key === ' ') {\n hardDropConsumed = false;\n }\n };\n window.addEventListener('keyup', handleKeyUp);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener.dispose();\n window.removeEventListener('keyup', handleKeyUp);\n return;\n }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // Handle ESC key - toggle pause (works on start screen too)\n if (key === 'escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Q to quit (from start screen, pause, or game over)\n if (key === 'q') {\n if (paused || gameOver || !gameStarted) {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n window.removeEventListener('keyup', handleKeyUp);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n }\n\n // Start screen - any key (except ESC/Q handled above) starts the game\n // Skip if paused (ESC menu open on start screen)\n if (!gameStarted && !paused) {\n if (key === 'arrowleft' || key === 'a' || key === '1') {\n selectedMode = 'marathon';\n return;\n }\n if (key === 'arrowright' || key === 'd' || key === '2') {\n selectedMode = 'sprint';\n return;\n }\n if (key === 'tab' || key === 'm') {\n selectedMode = selectedMode === 'marathon' ? 'sprint' : 'marathon';\n return;\n }\n initGame(selectedMode);\n gameStarted = true;\n return;\n }\n\n // Game over - only R to restart\n if (gameOver) {\n if (key === 'r') {\n initGame(mode);\n gameStarted = true;\n }\n return;\n }\n\n // Pause menu actions\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n initGame(mode);\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n window.removeEventListener('keyup', handleKeyUp);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n window.removeEventListener('keyup', handleKeyUp);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n window.removeEventListener('keyup', handleKeyUp);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (key === 'r') {\n initGame(mode);\n gameStarted = true;\n paused = false;\n } else if (key === 'l') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n window.removeEventListener('keyup', handleKeyUp);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (key === 'n') {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n window.removeEventListener('keyup', handleKeyUp);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n // Gameplay controls\n switch (domEvent.key) {\n case 'ArrowLeft':\n case 'a':\n moveLeft();\n break;\n case 'ArrowRight':\n case 'd':\n moveRight();\n break;\n case 'ArrowDown':\n case 's':\n if (moveDown()) score += 1;\n break;\n case 'ArrowUp':\n case 'w':\n rotate();\n break;\n case ' ':\n hardDrop();\n break;\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n window.removeEventListener('keyup', handleKeyUp);\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Tower\n *\n * Stack falling blocks perfectly to build the tallest tower.\n * Blocks swing left/right - press space to drop.\n * Overhanging parts fall off, making subsequent blocks narrower.\n * Perfect alignments give bonus points and combo multipliers.\n * Cyberpunk-themed with glitchy effects and theme-aware colors.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Tower Game Controller\n */\nexport interface TowerController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface Block {\n x: number; // Left edge position\n width: number; // Block width\n color: string; // ANSI color code\n}\n\ninterface FallingPiece {\n x: number;\n y: number;\n width: number;\n color: string;\n vy: number;\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\n// Block colors - cyberpunk neon palette\nconst BLOCK_COLORS = [\n '\\x1b[96m', // Cyan\n '\\x1b[95m', // Magenta\n '\\x1b[93m', // Yellow\n '\\x1b[92m', // Green\n '\\x1b[91m', // Red\n '\\x1b[94m', // Blue\n '\\x1b[97m', // White\n];\n\n// ============================================================================\n// MAIN GAME FUNCTION\n// ============================================================================\n\nexport function runTowerGame(terminal: Terminal): TowerController {\n const themeColor = getCurrentThemeColor();\n\n // -------------------------------------------------------------------------\n // CONSTANTS - Lowered minimums for better compatibility\n // -------------------------------------------------------------------------\n const MIN_COLS = 30;\n const MIN_ROWS = 16;\n const INITIAL_BLOCK_WIDTH = 8;\n const MIN_BLOCK_WIDTH = 2;\n const PERFECT_THRESHOLD = 0.5;\n\n // Game dimensions - adaptive\n let GAME_WIDTH = 24;\n let GAME_HEIGHT = 12;\n\n // -------------------------------------------------------------------------\n // STATE\n // -------------------------------------------------------------------------\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let score = 0;\n let highScore = 0;\n let height = 0;\n\n // Positioning\n let gameLeft = 2;\n let gameTop = 4;\n\n // Swinging block state\n let swingX = 0;\n let swingDirection = 1;\n let swingSpeed = 0.2; // Halved for 2x frame rate\n let currentBlockWidth = INITIAL_BLOCK_WIDTH;\n let currentBlockColor = BLOCK_COLORS[0];\n\n // Tower state - blocks stack upward, index 0 = bottom\n let tower: Block[] = [];\n\n // Combo system\n let perfectCombo = 0;\n let maxCombo = 0;\n\n // Visual effects\n let glitchFrame = 0;\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let fallingPieces: FallingPiece[] = [];\n let shakeFrames = 0;\n let shakeIntensity = 0;\n let flashFrames = 0;\n\n // Dropping animation\n let isDropping = false;\n let dropY = 0;\n let dropX = 0;\n let dropWidth = 0;\n let dropColor = '';\n\n // -------------------------------------------------------------------------\n // CONTROLLER\n // -------------------------------------------------------------------------\n const controller: TowerController = {\n stop: () => {\n if (!running) return;\n running = false;\n },\n get isRunning() { return running; }\n };\n\n // -------------------------------------------------------------------------\n // ASCII ART TITLE\n // -------------------------------------------------------------------------\n const title = [\n '▀█▀ █▀█ █ █ █ █▀▀ █▀█',\n ' █ █▄█ ▀▄▀▄▀ ██▄ █▀▄',\n ];\n\n // -------------------------------------------------------------------------\n // EFFECTS\n // -------------------------------------------------------------------------\n\n function spawnParticles(x: number, y: number, count: number, color: string) {\n const chars = ['✦', '★', '◆', '●'];\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.15 + Math.random() * 0.25; // Halved for 2x frame rate\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5 - 0.1, // Halved for 2x frame rate\n life: 24 + Math.floor(Math.random() * 16), // Doubled for 2x frame rate\n });\n }\n }\n\n function spawnFallingPiece(x: number, y: number, width: number, color: string) {\n fallingPieces.push({\n x,\n y,\n width,\n color,\n vy: 0.1,\n });\n }\n\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 24, color });\n }\n\n function triggerShake(frames: number, intensity: number) {\n shakeFrames = frames;\n shakeIntensity = intensity;\n }\n\n // -------------------------------------------------------------------------\n // GAME LOGIC\n // -------------------------------------------------------------------------\n\n function initGame() {\n // Adaptive sizing\n const cols = terminal.cols;\n const rows = terminal.rows;\n GAME_WIDTH = Math.min(32, Math.max(20, cols - 8));\n GAME_HEIGHT = Math.min(16, Math.max(8, rows - 10));\n\n score = 0;\n height = 0;\n gameOver = false;\n paused = false;\n perfectCombo = 0;\n maxCombo = 0;\n\n // Reset swinging block\n currentBlockWidth = Math.min(INITIAL_BLOCK_WIDTH, Math.floor(GAME_WIDTH / 3));\n swingX = Math.floor((GAME_WIDTH - currentBlockWidth) / 2);\n swingDirection = 1;\n swingSpeed = 0.2; // Halved for 2x frame rate\n currentBlockColor = BLOCK_COLORS[0];\n\n // Reset tower with initial platform\n tower = [];\n const platformWidth = currentBlockWidth;\n const platformX = Math.floor((GAME_WIDTH - platformWidth) / 2);\n tower.push({\n x: platformX,\n width: platformWidth,\n color: '\\x1b[2m\\x1b[90m',\n });\n\n // Reset effects\n particles = [];\n scorePopups = [];\n fallingPieces = [];\n shakeFrames = 0;\n flashFrames = 0;\n isDropping = false;\n }\n\n function getTopBlock(): Block {\n return tower[tower.length - 1];\n }\n\n function dropBlock() {\n if (isDropping || gameOver) return;\n\n isDropping = true;\n dropX = swingX;\n dropY = 0; // Start at top\n dropWidth = currentBlockWidth;\n dropColor = currentBlockColor;\n }\n\n function landBlock() {\n const topBlock = getTopBlock();\n\n // Calculate overlap\n const dropLeft = dropX;\n const dropRight = dropX + dropWidth;\n const topLeft = topBlock.x;\n const topRight = topBlock.x + topBlock.width;\n\n const overlapLeft = Math.max(dropLeft, topLeft);\n const overlapRight = Math.min(dropRight, topRight);\n const overlapWidth = overlapRight - overlapLeft;\n\n // Landing Y position (in game coordinates, 0 = top of visible area)\n const landY = GAME_HEIGHT - tower.length - 1;\n\n if (overlapWidth < MIN_BLOCK_WIDTH) {\n // Block missed - game over\n gameOver = true;\n if (score > highScore) highScore = score;\n if (perfectCombo > maxCombo) maxCombo = perfectCombo;\n\n spawnParticles(dropX + dropWidth / 2, landY, 15, '\\x1b[91m');\n triggerShake(10, 3);\n return;\n }\n\n // Check for perfect alignment\n const isPerfect = Math.abs(dropLeft - topLeft) < PERFECT_THRESHOLD &&\n Math.abs(dropRight - topRight) < PERFECT_THRESHOLD;\n\n let points = 10;\n\n if (isPerfect) {\n perfectCombo++;\n const comboBonus = Math.min(perfectCombo * 5, 50);\n points += 10 + comboBonus;\n\n flashFrames = 6;\n spawnParticles(dropX + dropWidth / 2, landY, 12, '\\x1b[93m');\n\n const popupText = perfectCombo > 1 ? `PERFECT! x${perfectCombo}` : 'PERFECT!';\n addScorePopup(\n Math.floor(GAME_WIDTH / 2) - Math.floor(popupText.length / 2),\n Math.floor(GAME_HEIGHT / 2),\n popupText,\n perfectCombo > 3 ? '\\x1b[1;91m' : '\\x1b[1;93m'\n );\n\n triggerShake(4, 1);\n } else {\n if (perfectCombo > maxCombo) maxCombo = perfectCombo;\n perfectCombo = 0;\n\n // Spawn falling pieces for overhanging parts\n if (dropLeft < topLeft) {\n const overhangWidth = topLeft - dropLeft;\n spawnFallingPiece(dropLeft, landY, overhangWidth, dropColor);\n spawnParticles(dropLeft + overhangWidth / 2, landY, 5, dropColor);\n }\n if (dropRight > topRight) {\n const overhangWidth = dropRight - topRight;\n spawnFallingPiece(topRight, landY, overhangWidth, dropColor);\n spawnParticles(topRight + overhangWidth / 2, landY, 5, dropColor);\n }\n\n triggerShake(3, 1);\n }\n\n score += points;\n height++;\n\n if (points > 10) {\n addScorePopup(overlapLeft + overlapWidth / 2, landY - 1, `+${points}`, '\\x1b[92m');\n }\n\n // Add the landed block to tower\n tower.push({\n x: overlapLeft,\n width: overlapWidth,\n color: dropColor,\n });\n\n // Update next block\n currentBlockWidth = overlapWidth;\n currentBlockColor = BLOCK_COLORS[tower.length % BLOCK_COLORS.length];\n\n // Reset swing position\n swingX = Math.floor((GAME_WIDTH - currentBlockWidth) / 2);\n swingDirection = Math.random() > 0.5 ? 1 : -1;\n\n // Increase speed slightly (halved for 2x frame rate)\n swingSpeed = Math.min(0.5, swingSpeed + 0.01);\n\n // Reset drop state\n isDropping = false;\n }\n\n function update() {\n if (paused || !gameStarted || gameOver) return;\n\n // Update swinging block\n if (!isDropping) {\n swingX += swingDirection * swingSpeed;\n if (swingX <= 0) {\n swingX = 0;\n swingDirection = 1;\n } else if (swingX + currentBlockWidth >= GAME_WIDTH) {\n swingX = GAME_WIDTH - currentBlockWidth;\n swingDirection = -1;\n }\n }\n\n // Update dropping animation (dropY is 0-1 progress)\n if (isDropping) {\n dropY += 0.08; // Progress speed (0.08 = ~12 frames to land)\n\n if (dropY >= 1) {\n dropY = 1;\n landBlock();\n }\n }\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.015; // Halved for 2x frame rate\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update falling pieces\n for (let i = fallingPieces.length - 1; i >= 0; i--) {\n const piece = fallingPieces[i];\n piece.y += piece.vy;\n piece.vy += 0.1;\n if (piece.y > GAME_HEIGHT + 5) {\n fallingPieces.splice(i, 1);\n }\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.15;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n if (flashFrames > 0) flashFrames--;\n }\n\n // -------------------------------------------------------------------------\n // RENDERING\n // -------------------------------------------------------------------------\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n if (shakeFrames > 0) shakeFrames--;\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n const hint = needWidth && needHeight ? 'Make pane larger'\n : needWidth ? 'Make pane wider →' : 'Make pane taller ↓';\n const msg2 = `Need: ${MIN_COLS}×${MIN_ROWS} Have: ${cols}×${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Center game area\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH - 2) / 2));\n gameTop = Math.max(4, Math.floor((rows - GAME_HEIGHT - 6) / 2));\n\n // Apply screen shake\n let renderLeft = gameLeft;\n let renderTop = gameTop;\n if (shakeFrames > 0) {\n renderLeft += Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n renderTop += Math.floor((Math.random() - 0.5) * shakeIntensity);\n }\n\n // Glitch title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[1;${titleX}H\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `\\x1b[1;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n // Stats bar\n const stats = `HEIGHT: ${height} SCORE: ${score.toString().padStart(5, '0')} COMBO: ${perfectCombo}`;\n const statsX = Math.floor((cols - stats.length) / 2);\n output += `\\x1b[${gameTop - 1};${statsX}H${themeColor}${stats}\\x1b[0m`;\n\n // Game border with flash effect\n const borderColor = flashFrames > 0 ? '\\x1b[1;93m' : themeColor;\n output += `\\x1b[${renderTop};${renderLeft}H${borderColor}╔${'═'.repeat(GAME_WIDTH)}╗\\x1b[0m`;\n for (let y = 0; y < GAME_HEIGHT; y++) {\n output += `\\x1b[${renderTop + 1 + y};${renderLeft}H${borderColor}║\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + y};${renderLeft + GAME_WIDTH + 1}H${borderColor}║\\x1b[0m`;\n }\n output += `\\x1b[${renderTop + GAME_HEIGHT + 1};${renderLeft}H${borderColor}╚${'═'.repeat(GAME_WIDTH)}╝\\x1b[0m`;\n\n // PAUSE MENU\n if (paused) {\n const pauseMsg = '══ PAUSED ══';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseY = gameTop + Math.floor(GAME_HEIGHT / 2) - 2;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n }\n // START SCREEN\n else if (!gameStarted) {\n const startMsg = '[ PRESS SPACE TO START ]';\n const startX = gameLeft + Math.floor((GAME_WIDTH - startMsg.length) / 2) + 1;\n const startY = gameTop + Math.floor(GAME_HEIGHT / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = 'SPACE to drop block';\n const ctrlX = gameLeft + Math.floor((GAME_WIDTH - controls.length) / 2) + 1;\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n\n const hint1 = 'Stack blocks perfectly!';\n const hint1X = gameLeft + Math.floor((GAME_WIDTH - hint1.length) / 2) + 1;\n output += `\\x1b[${startY + 4};${hint1X}H\\x1b[2m${themeColor}${hint1}\\x1b[0m`;\n }\n // GAME OVER\n else if (gameOver) {\n const overMsg = '╔══ GAME OVER ══╗';\n const overX = gameLeft + Math.floor((GAME_WIDTH - overMsg.length) / 2) + 1;\n const overY = gameTop + Math.floor(GAME_HEIGHT / 2) - 2;\n output += `\\x1b[${overY};${overX}H\\x1b[1;91m${overMsg}\\x1b[0m`;\n\n const scoreLine = `HEIGHT: ${height} SCORE: ${score}`;\n const scoreX = gameLeft + Math.floor((GAME_WIDTH - scoreLine.length) / 2) + 1;\n output += `\\x1b[${overY + 1};${scoreX}H${themeColor}${scoreLine}\\x1b[0m`;\n\n const highLine = `HIGH: ${highScore} BEST COMBO: ${maxCombo}`;\n const highX = gameLeft + Math.floor((GAME_WIDTH - highLine.length) / 2) + 1;\n output += `\\x1b[${overY + 2};${highX}H\\x1b[2m${themeColor}${highLine}\\x1b[0m`;\n\n const restart = '╚ [R] RESTART [Q] QUIT ╝';\n const restartX = gameLeft + Math.floor((GAME_WIDTH - restart.length) / 2) + 1;\n output += `\\x1b[${overY + 4};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n }\n // GAMEPLAY\n else {\n // Fixed swing position at upper portion of screen\n const SWING_ROW = 3; // Fixed row for swinging block (near top)\n\n // SIMPLIFIED: No camera scrolling for now - just render all blocks\n // Block 0 at bottom (row GAME_HEIGHT), each subsequent block one row up\n for (let i = 0; i < tower.length; i++) {\n const block = tower[i];\n // i=0 at bottom (highest screenY), i=N-1 at top (lowest screenY)\n const screenY = renderTop + GAME_HEIGHT - i;\n\n if (screenY > renderTop && screenY <= renderTop + GAME_HEIGHT) {\n const blockStr = '█'.repeat(Math.max(1, Math.round(block.width)));\n const blockX = renderLeft + 1 + Math.round(block.x);\n output += `\\x1b[${screenY};${blockX}H${block.color}${blockStr}\\x1b[0m`;\n }\n }\n\n // Swinging block at fixed position\n const swingScreenY = renderTop + SWING_ROW;\n\n // Landing position: one row above the current top of tower\n // Top block is at i = tower.length - 1, which is at screenY = renderTop + GAME_HEIGHT - (tower.length - 1)\n // New block lands one row above = screenY - 1 = renderTop + GAME_HEIGHT - tower.length\n const landingScreenY = renderTop + GAME_HEIGHT - tower.length;\n const dropDistance = landingScreenY - swingScreenY; // How far to drop\n\n // Draw dropping block (animates from swing down to landing)\n if (isDropping) {\n const dropProgress = dropY; // 0 to 1\n const dropScreenY = Math.round(swingScreenY + dropProgress * dropDistance);\n if (dropScreenY > renderTop && dropScreenY <= renderTop + GAME_HEIGHT) {\n const blockStr = '█'.repeat(Math.round(dropWidth));\n output += `\\x1b[${dropScreenY};${renderLeft + 1 + Math.round(dropX)}H${dropColor}${blockStr}\\x1b[0m`;\n }\n }\n\n // Draw swinging block at fixed position\n if (!isDropping) {\n const blockStr = '█'.repeat(Math.round(currentBlockWidth));\n output += `\\x1b[${swingScreenY};${renderLeft + 1 + Math.round(swingX)}H${currentBlockColor}${blockStr}\\x1b[0m`;\n\n // Draw guide line at landing position\n if (landingScreenY > swingScreenY && landingScreenY <= renderTop + GAME_HEIGHT) {\n const guideStr = '░'.repeat(Math.round(currentBlockWidth));\n output += `\\x1b[${landingScreenY};${renderLeft + 1 + Math.round(swingX)}H\\x1b[2m${currentBlockColor}${guideStr}\\x1b[0m`;\n }\n }\n\n // Draw falling pieces\n for (const piece of fallingPieces) {\n const screenY = Math.round(renderTop + 1 + piece.y);\n if (screenY > renderTop && screenY <= renderTop + GAME_HEIGHT + 2) {\n const pieceStr = '▓'.repeat(Math.round(piece.width));\n output += `\\x1b[${screenY};${renderLeft + 1 + Math.round(piece.x)}H\\x1b[2m${piece.color}${pieceStr}\\x1b[0m`;\n }\n }\n\n // Draw particles\n for (const p of particles) {\n const screenX = Math.round(renderLeft + 1 + p.x);\n const screenY = Math.round(renderTop + 1 + p.y);\n if (screenX > renderLeft && screenX < renderLeft + GAME_WIDTH + 1 &&\n screenY > renderTop && screenY < renderTop + GAME_HEIGHT + 1) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const screenX = Math.round(renderLeft + 1 + popup.x);\n const screenY = Math.round(renderTop + 1 + popup.y);\n if (screenY > renderTop && screenY < renderTop + GAME_HEIGHT + 1) {\n const alpha = popup.frames > 10 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n }\n\n // Bottom hint\n const hint = gameStarted && !gameOver && !paused ? `HIGH: ${highScore} [ ESC ] MENU` : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${gameTop + GAME_HEIGHT + 3};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n // -------------------------------------------------------------------------\n // GAME LOOP\n // -------------------------------------------------------------------------\n\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) { clearInterval(gameInterval); return; }\n update();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key;\n const keyLower = key.toLowerCase();\n\n // Pause menu handling\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(pauseMenuSelection, PAUSE_MENU_ITEMS.length, key, domEvent);\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: paused = false; break; // Resume\n case 1: initGame(); gameStarted = true; paused = false; break; // Restart\n case 2: controller.stop(); dispatchGameQuit(terminal); break; // Quit\n case 3: controller.stop(); dispatchGamesMenu(terminal); break; // List Games\n case 4: controller.stop(); dispatchGameSwitch(terminal); break; // Next Game\n }\n return;\n }\n return;\n }\n\n // Game over controls\n if (gameOver) {\n if (keyLower === 'r') {\n initGame();\n gameStarted = true;\n return;\n }\n if (keyLower === 'q' || key === 'Escape') {\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n return;\n }\n\n // In-game controls\n if (key === 'Escape') {\n paused = true;\n pauseMenuSelection = 0;\n return;\n }\n\n if (!gameStarted) {\n if (key === ' ') {\n gameStarted = true;\n }\n return;\n }\n\n // Drop block\n if (key === ' ') {\n dropBlock();\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n keyListener.dispose();\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n terminal.write('\\x1b[?25h');\n terminal.write('\\x1b[?1049l');\n originalStop();\n };\n }, 50);\n\n return controller;\n}\n","/**\n * Hyper Tron\n *\n * Light cycles - you vs AI. Don't hit walls or trails.\n * Cyberpunk-themed with glitchy effects and theme-aware colors.\n * Best of 5 rounds, speed increases each round, optional shrinking arena.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Tron Game Controller\n */\nexport interface TronController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ntype Direction = 'up' | 'down' | 'left' | 'right';\n\ninterface Position {\n x: number;\n y: number;\n}\n\ninterface LightCycle {\n x: number;\n y: number;\n direction: Direction;\n trail: Position[];\n alive: boolean;\n color: string;\n char: string;\n trailChar: string;\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\n// ============================================================================\n// MAIN GAME FUNCTION\n// ============================================================================\n\nexport function runTronGame(terminal: Terminal): TronController {\n const themeColor = getCurrentThemeColor();\n\n // -------------------------------------------------------------------------\n // CONSTANTS\n // -------------------------------------------------------------------------\n const MIN_COLS = 40;\n const MIN_ROWS = 18;\n const GAME_WIDTH = 46;\n const GAME_HEIGHT = 18;\n const ROUNDS_TO_WIN = 3;\n const BASE_SPEED = 100; // ms per move\n const SPEED_DECREASE_PER_ROUND = 12; // Faster each round\n const COUNTDOWN_SECONDS = 3;\n const SHRINK_INTERVAL = 150; // ticks before arena shrinks\n const SHRINK_AMOUNT = 1; // How much to shrink per side\n\n // -------------------------------------------------------------------------\n // STATE\n // -------------------------------------------------------------------------\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let matchOver = false;\n\n // Positioning\n let gameLeft = 2;\n let gameTop = 5;\n\n // Round state\n let currentRound = 1;\n let playerWins = 0;\n let aiWins = 0;\n let countdown = 0; // Countdown before round starts\n let countdownTimer: ReturnType<typeof setInterval> | null = null;\n let roundInProgress = false;\n\n // Arena shrinking\n const shrinkEnabled = true;\n let shrinkTicks = 0;\n let arenaMinX = 0;\n let arenaMaxX = GAME_WIDTH - 1;\n let arenaMinY = 0;\n let arenaMaxY = GAME_HEIGHT - 1;\n\n // Light cycles\n let player: LightCycle;\n let ai: LightCycle;\n let nextPlayerDirection: Direction = 'right';\n\n // Visual effects\n let glitchFrame = 0;\n let particles: Particle[] = [];\n let shakeFrames = 0;\n let shakeIntensity = 0;\n let winnerMessage = '';\n let gameSpeed = BASE_SPEED;\n let gameInterval: ReturnType<typeof setInterval> | null = null;\n\n // -------------------------------------------------------------------------\n // CONTROLLER\n // -------------------------------------------------------------------------\n const controller: TronController = {\n stop: () => {\n if (!running) return;\n running = false;\n },\n get isRunning() { return running; }\n };\n\n // -------------------------------------------------------------------------\n // ASCII ART TITLE\n // -------------------------------------------------------------------------\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ ▀█▀ █▀█ █▀█ █▄ █',\n '█▀█ █ █▀▀ ██▄ █▀▄ █ █▀▄ █▄█ █ ▀█',\n ];\n\n // -------------------------------------------------------------------------\n // EFFECTS\n // -------------------------------------------------------------------------\n\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['░', '▒', '▓', '█', '◆']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.3 + Math.random() * 0.5;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5,\n life: 12 + Math.floor(Math.random() * 10),\n });\n }\n }\n\n function spawnExplosion(x: number, y: number, color: string) {\n // Big explosion on crash\n spawnParticles(x, y, 20, color, ['✗', '×', '░', '▒', '▓', '█']);\n triggerShake(12, 3);\n }\n\n function triggerShake(frames: number, intensity: number) {\n shakeFrames = frames;\n shakeIntensity = intensity;\n }\n\n // -------------------------------------------------------------------------\n // GAME LOGIC\n // -------------------------------------------------------------------------\n\n function initGame() {\n currentRound = 1;\n playerWins = 0;\n aiWins = 0;\n matchOver = false;\n gameOver = false;\n paused = false;\n\n // Reset effects\n particles = [];\n shakeFrames = 0;\n winnerMessage = '';\n\n initRound();\n }\n\n function initRound() {\n // Reset arena\n arenaMinX = 0;\n arenaMaxX = GAME_WIDTH - 1;\n arenaMinY = 0;\n arenaMaxY = GAME_HEIGHT - 1;\n shrinkTicks = 0;\n\n // Calculate speed for this round\n gameSpeed = Math.max(40, BASE_SPEED - (currentRound - 1) * SPEED_DECREASE_PER_ROUND);\n\n // Initialize player (left side, moving right)\n player = {\n x: 5,\n y: Math.floor(GAME_HEIGHT / 2),\n direction: 'right',\n trail: [],\n alive: true,\n color: themeColor,\n char: '█',\n trailChar: '│',\n };\n\n // Initialize AI (right side, moving left)\n ai = {\n x: GAME_WIDTH - 6,\n y: Math.floor(GAME_HEIGHT / 2),\n direction: 'left',\n trail: [],\n alive: true,\n color: '\\x1b[91m', // Red for AI\n char: '█',\n trailChar: '│',\n };\n\n nextPlayerDirection = 'right';\n roundInProgress = false;\n particles = [];\n winnerMessage = '';\n\n // Start countdown\n countdown = COUNTDOWN_SECONDS;\n if (countdownTimer) clearInterval(countdownTimer);\n countdownTimer = setInterval(() => {\n countdown--;\n if (countdown <= 0) {\n if (countdownTimer) clearInterval(countdownTimer);\n countdownTimer = null;\n roundInProgress = true;\n startGameLoop();\n }\n }, 1000);\n }\n\n function startGameLoop() {\n if (gameInterval) clearInterval(gameInterval);\n gameInterval = setInterval(() => {\n if (!running) {\n if (gameInterval) clearInterval(gameInterval);\n return;\n }\n update();\n }, gameSpeed);\n }\n\n function stopGameLoop() {\n if (gameInterval) {\n clearInterval(gameInterval);\n gameInterval = null;\n }\n }\n\n function getTrailChar(dir: Direction): string {\n switch (dir) {\n case 'up':\n case 'down':\n return '│';\n case 'left':\n case 'right':\n return '─';\n }\n }\n\n function moveCycle(cycle: LightCycle) {\n if (!cycle.alive) return;\n\n // Add current position to trail\n cycle.trail.push({ x: cycle.x, y: cycle.y });\n cycle.trailChar = getTrailChar(cycle.direction);\n\n // Move\n switch (cycle.direction) {\n case 'up': cycle.y--; break;\n case 'down': cycle.y++; break;\n case 'left': cycle.x--; break;\n case 'right': cycle.x++; break;\n }\n }\n\n function checkCollision(cycle: LightCycle): boolean {\n // Wall collision (including shrinking arena)\n if (cycle.x <= arenaMinX || cycle.x >= arenaMaxX ||\n cycle.y <= arenaMinY || cycle.y >= arenaMaxY) {\n return true;\n }\n\n // Self trail collision\n for (const pos of cycle.trail) {\n if (pos.x === cycle.x && pos.y === cycle.y) {\n return true;\n }\n }\n\n // Other cycle trail collision\n const other = cycle === player ? ai : player;\n for (const pos of other.trail) {\n if (pos.x === cycle.x && pos.y === cycle.y) {\n return true;\n }\n }\n\n // Head-on collision with other cycle\n if (cycle.x === other.x && cycle.y === other.y) {\n return true;\n }\n\n return false;\n }\n\n function updateAI() {\n if (!ai.alive || !player.alive) return;\n\n // AI pathfinding - avoid walls and trails\n const possibleMoves: Direction[] = [];\n const opposite: Record<Direction, Direction> = {\n 'up': 'down',\n 'down': 'up',\n 'left': 'right',\n 'right': 'left',\n };\n\n const directions: Direction[] = ['up', 'down', 'left', 'right'];\n const currentOpposite = opposite[ai.direction];\n\n for (const dir of directions) {\n // Can't reverse\n if (dir === currentOpposite) continue;\n\n const testX = ai.x + (dir === 'left' ? -1 : dir === 'right' ? 1 : 0);\n const testY = ai.y + (dir === 'up' ? -1 : dir === 'down' ? 1 : 0);\n\n // Check if move is safe\n if (isSafePosition(testX, testY)) {\n possibleMoves.push(dir);\n }\n }\n\n if (possibleMoves.length === 0) {\n // No safe moves, keep going (will crash)\n return;\n }\n\n // Score each move - prefer moves that lead to more open space\n let bestMove = possibleMoves[0];\n let bestScore = -Infinity;\n\n for (const move of possibleMoves) {\n const testX = ai.x + (move === 'left' ? -1 : move === 'right' ? 1 : 0);\n const testY = ai.y + (move === 'up' ? -1 : move === 'down' ? 1 : 0);\n const score = evaluatePosition(testX, testY, move);\n if (score > bestScore) {\n bestScore = score;\n bestMove = move;\n }\n }\n\n // Add some randomness to make AI less predictable\n if (possibleMoves.length > 1 && Math.random() < 0.15) {\n bestMove = possibleMoves[Math.floor(Math.random() * possibleMoves.length)];\n }\n\n ai.direction = bestMove;\n }\n\n function isSafePosition(x: number, y: number): boolean {\n // Wall check\n if (x <= arenaMinX || x >= arenaMaxX || y <= arenaMinY || y >= arenaMaxY) {\n return false;\n }\n\n // Trail check\n for (const pos of player.trail) {\n if (pos.x === x && pos.y === y) return false;\n }\n for (const pos of ai.trail) {\n if (pos.x === x && pos.y === y) return false;\n }\n\n // Player position check\n if (player.x === x && player.y === y) return false;\n\n return true;\n }\n\n function evaluatePosition(x: number, y: number, direction: Direction): number {\n let score = 0;\n\n // Count open spaces in a cone in front\n const dx = direction === 'left' ? -1 : direction === 'right' ? 1 : 0;\n const dy = direction === 'up' ? -1 : direction === 'down' ? 1 : 0;\n\n // Look ahead 5 cells\n for (let i = 1; i <= 5; i++) {\n const checkX = x + dx * i;\n const checkY = y + dy * i;\n if (isSafePosition(checkX, checkY)) {\n score += 5 - i; // Closer cells worth more\n } else {\n break;\n }\n }\n\n // Prefer staying in center of arena\n const centerX = (arenaMinX + arenaMaxX) / 2;\n const centerY = (arenaMinY + arenaMaxY) / 2;\n const distFromCenter = Math.abs(x - centerX) + Math.abs(y - centerY);\n score -= distFromCenter * 0.1;\n\n // Try to cut off player - head toward their direction\n const distToPlayer = Math.abs(x - player.x) + Math.abs(y - player.y);\n if (distToPlayer < 10) {\n score += (10 - distToPlayer) * 0.5;\n }\n\n return score;\n }\n\n function updateArena() {\n if (!shrinkEnabled) return;\n\n shrinkTicks++;\n if (shrinkTicks >= SHRINK_INTERVAL) {\n shrinkTicks = 0;\n\n // Shrink arena\n const canShrinkX = arenaMaxX - arenaMinX > 20;\n const canShrinkY = arenaMaxY - arenaMinY > 10;\n\n if (canShrinkX || canShrinkY) {\n if (canShrinkX) {\n arenaMinX += SHRINK_AMOUNT;\n arenaMaxX -= SHRINK_AMOUNT;\n }\n if (canShrinkY) {\n arenaMinY += SHRINK_AMOUNT;\n arenaMaxY -= SHRINK_AMOUNT;\n }\n\n // Light shake to indicate shrink\n triggerShake(4, 1);\n }\n }\n }\n\n function update() {\n if (!gameStarted || gameOver || paused || !roundInProgress) return;\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.03;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update AI\n updateAI();\n\n // Apply player direction change\n player.direction = nextPlayerDirection;\n\n // Move cycles\n moveCycle(player);\n moveCycle(ai);\n\n // Check collisions\n const playerCollided = checkCollision(player);\n const aiCollided = checkCollision(ai);\n\n if (playerCollided && aiCollided) {\n // Both crashed - tie, no points\n player.alive = false;\n ai.alive = false;\n spawnExplosion(player.x, player.y, player.color);\n spawnExplosion(ai.x, ai.y, ai.color);\n winnerMessage = 'DRAW!';\n endRound();\n } else if (playerCollided) {\n player.alive = false;\n spawnExplosion(player.x, player.y, player.color);\n aiWins++;\n winnerMessage = 'AI WINS ROUND!';\n endRound();\n } else if (aiCollided) {\n ai.alive = false;\n spawnExplosion(ai.x, ai.y, ai.color);\n playerWins++;\n winnerMessage = 'YOU WIN ROUND!';\n endRound();\n }\n\n // Update arena shrinking\n updateArena();\n }\n\n function endRound() {\n stopGameLoop();\n roundInProgress = false;\n\n // Check for match end\n if (playerWins >= ROUNDS_TO_WIN) {\n matchOver = true;\n gameOver = true;\n winnerMessage = 'VICTORY! YOU WIN THE MATCH!';\n } else if (aiWins >= ROUNDS_TO_WIN) {\n matchOver = true;\n gameOver = true;\n winnerMessage = 'DEFEAT! AI WINS THE MATCH!';\n }\n }\n\n function nextRound() {\n if (!matchOver && !gameOver) {\n currentRound++;\n initRound();\n }\n }\n\n // -------------------------------------------------------------------------\n // RENDERING\n // -------------------------------------------------------------------------\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Effect timers\n if (shakeFrames > 0) shakeFrames--;\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n const hint = needWidth && needHeight ? 'Make pane larger'\n : needWidth ? 'Make pane wider \\u2192' : 'Make pane taller \\u2193';\n const msg2 = `Need: ${MIN_COLS}\\u00d7${MIN_ROWS} Have: ${cols}\\u00d7${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Center game area\n gameLeft = Math.max(2, Math.floor((cols - GAME_WIDTH - 2) / 2));\n gameTop = Math.max(4, Math.floor((rows - GAME_HEIGHT - 8) / 2));\n\n // Apply screen shake\n let renderLeft = gameLeft;\n let renderTop = gameTop;\n if (shakeFrames > 0) {\n renderLeft += Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n renderTop += Math.floor((Math.random() - 0.5) * shakeIntensity);\n }\n\n // Glitch title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[1;${titleX}H\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `\\x1b[1;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n // Stats bar\n const roundInfo = `ROUND ${currentRound}`;\n const scoreInfo = `YOU: ${playerWins} AI: ${aiWins} (First to ${ROUNDS_TO_WIN})`;\n const statsX = Math.floor((cols - scoreInfo.length) / 2);\n output += `\\x1b[${gameTop - 1};${statsX}H${themeColor}${roundInfo} ${scoreInfo}\\x1b[0m`;\n\n // Game border - draw full arena, then overlay shrink borders\n output += `\\x1b[${renderTop};${renderLeft}H${themeColor}\\x1b[2m\\u2554${'═'.repeat(GAME_WIDTH)}\\u2557\\x1b[0m`;\n for (let y = 0; y < GAME_HEIGHT; y++) {\n output += `\\x1b[${renderTop + 1 + y};${renderLeft}H${themeColor}\\x1b[2m\\u2551\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + y};${renderLeft + GAME_WIDTH + 1}H${themeColor}\\x1b[2m\\u2551\\x1b[0m`;\n }\n output += `\\x1b[${renderTop + GAME_HEIGHT + 1};${renderLeft}H${themeColor}\\x1b[2m\\u255a${'═'.repeat(GAME_WIDTH)}\\u255d\\x1b[0m`;\n\n // Draw shrinking arena borders (bright)\n if (shrinkEnabled && (arenaMinX > 0 || arenaMinY > 0)) {\n // Draw active arena boundary\n const shrinkColor = '\\x1b[1;93m'; // Bright yellow warning\n for (let x = arenaMinX; x <= arenaMaxX; x++) {\n output += `\\x1b[${renderTop + 1 + arenaMinY};${renderLeft + 1 + x}H${shrinkColor}\\u2500\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + arenaMaxY};${renderLeft + 1 + x}H${shrinkColor}\\u2500\\x1b[0m`;\n }\n for (let y = arenaMinY; y <= arenaMaxY; y++) {\n output += `\\x1b[${renderTop + 1 + y};${renderLeft + 1 + arenaMinX}H${shrinkColor}\\u2502\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + y};${renderLeft + 1 + arenaMaxX}H${shrinkColor}\\u2502\\x1b[0m`;\n }\n }\n\n // PAUSE MENU\n if (paused) {\n const pauseMsg = '\\u2550\\u2550 PAUSED \\u2550\\u2550';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseY = gameTop + Math.floor(GAME_HEIGHT / 2) - 3;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '\\u2191\\u2193 select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n }\n // START SCREEN\n else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO PLAY ]';\n const startX = gameLeft + Math.floor((GAME_WIDTH - startMsg.length) / 2) + 1;\n const startY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const controls = '\\u2190\\u2191\\u2192\\u2193 TURN (no reverse)';\n const ctrlX = gameLeft + Math.floor((GAME_WIDTH - controls.length) / 2) + 1;\n output += `\\x1b[${startY + 2};${ctrlX}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n\n const info = 'Last cycle alive wins!';\n const infoX = gameLeft + Math.floor((GAME_WIDTH - info.length) / 2) + 1;\n output += `\\x1b[${startY + 3};${infoX}H\\x1b[2m${themeColor}${info}\\x1b[0m`;\n }\n // COUNTDOWN\n else if (countdown > 0) {\n // Draw cycles at starting positions\n output += `\\x1b[${renderTop + 1 + player.y};${renderLeft + 1 + player.x}H${player.color}${player.char}\\x1b[0m`;\n output += `\\x1b[${renderTop + 1 + ai.y};${renderLeft + 1 + ai.x}H${ai.color}${ai.char}\\x1b[0m`;\n\n const countdownStr = countdown.toString();\n const countdownX = gameLeft + Math.floor(GAME_WIDTH / 2);\n const countdownY = gameTop + Math.floor(GAME_HEIGHT / 2);\n output += `\\x1b[${countdownY};${countdownX}H\\x1b[1;97m${countdownStr}\\x1b[0m`;\n }\n // ROUND END (not match over)\n else if (!roundInProgress && !matchOver && gameStarted) {\n // Draw final state\n output = renderTrailsAndCycles(output, renderLeft, renderTop);\n\n // Winner message\n const msgX = gameLeft + Math.floor((GAME_WIDTH - winnerMessage.length) / 2) + 1;\n const msgY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n const msgColor = winnerMessage.includes('YOU') ? '\\x1b[1;92m' : '\\x1b[1;91m';\n output += `\\x1b[${msgY};${msgX}H${msgColor}${winnerMessage}\\x1b[0m`;\n\n const nextMsg = 'Press SPACE for next round';\n const nextX = gameLeft + Math.floor((GAME_WIDTH - nextMsg.length) / 2) + 1;\n output += `\\x1b[${msgY + 2};${nextX}H\\x1b[2m${themeColor}${nextMsg}\\x1b[0m`;\n\n // Draw particles\n output = renderParticles(output, renderLeft, renderTop);\n }\n // MATCH OVER\n else if (gameOver) {\n // Draw final state\n output = renderTrailsAndCycles(output, renderLeft, renderTop);\n\n const overColor = playerWins >= ROUNDS_TO_WIN ? '\\x1b[1;92m' : '\\x1b[1;91m';\n const overMsg = playerWins >= ROUNDS_TO_WIN\n ? '\\u2554\\u2550\\u2550 VICTORY! \\u2550\\u2550\\u2557'\n : '\\u2554\\u2550\\u2550 DEFEAT \\u2550\\u2550\\u2557';\n const overX = gameLeft + Math.floor((GAME_WIDTH - overMsg.length) / 2) + 1;\n const overY = gameTop + Math.floor(GAME_HEIGHT / 2) - 1;\n output += `\\x1b[${overY};${overX}H${overColor}${overMsg}\\x1b[0m`;\n\n const scoreLine = `FINAL: YOU ${playerWins} - ${aiWins} AI`;\n const scoreX = gameLeft + Math.floor((GAME_WIDTH - scoreLine.length) / 2) + 1;\n output += `\\x1b[${overY + 1};${scoreX}H${themeColor}${scoreLine}\\x1b[0m`;\n\n const restart = '\\u255a [R] RESTART [Q] QUIT \\u255d';\n const restartX = gameLeft + Math.floor((GAME_WIDTH - restart.length) / 2) + 1;\n output += `\\x1b[${overY + 2};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n\n // Draw particles\n output = renderParticles(output, renderLeft, renderTop);\n }\n // GAMEPLAY\n else {\n // Draw trails\n for (const pos of player.trail) {\n if (pos.x > arenaMinX && pos.x < arenaMaxX && pos.y > arenaMinY && pos.y < arenaMaxY) {\n output += `\\x1b[${renderTop + 1 + pos.y};${renderLeft + 1 + pos.x}H\\x1b[2m${player.color}\\u2502\\x1b[0m`;\n }\n }\n for (const pos of ai.trail) {\n if (pos.x > arenaMinX && pos.x < arenaMaxX && pos.y > arenaMinY && pos.y < arenaMaxY) {\n output += `\\x1b[${renderTop + 1 + pos.y};${renderLeft + 1 + pos.x}H\\x1b[2m${ai.color}\\u2502\\x1b[0m`;\n }\n }\n\n // Draw cycles\n if (player.alive) {\n output += `\\x1b[${renderTop + 1 + player.y};${renderLeft + 1 + player.x}H\\x1b[1m${player.color}${player.char}\\x1b[0m`;\n }\n if (ai.alive) {\n output += `\\x1b[${renderTop + 1 + ai.y};${renderLeft + 1 + ai.x}H\\x1b[1m${ai.color}${ai.char}\\x1b[0m`;\n }\n\n // Draw particles\n output = renderParticles(output, renderLeft, renderTop);\n }\n\n // Bottom hint\n const hint = gameStarted && !gameOver && !paused\n ? `SPEED: ${Math.round((1 - gameSpeed / BASE_SPEED) * 100) + 100}% [ ESC ] MENU`\n : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${gameTop + GAME_HEIGHT + 3};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n function renderTrailsAndCycles(output: string, renderLeft: number, renderTop: number): string {\n // Draw trails\n for (const pos of player.trail) {\n output += `\\x1b[${renderTop + 1 + pos.y};${renderLeft + 1 + pos.x}H\\x1b[2m${player.color}\\u2502\\x1b[0m`;\n }\n for (const pos of ai.trail) {\n output += `\\x1b[${renderTop + 1 + pos.y};${renderLeft + 1 + pos.x}H\\x1b[2m${ai.color}\\u2502\\x1b[0m`;\n }\n\n // Draw cycles (if alive)\n if (player.alive) {\n output += `\\x1b[${renderTop + 1 + player.y};${renderLeft + 1 + player.x}H\\x1b[1m${player.color}${player.char}\\x1b[0m`;\n }\n if (ai.alive) {\n output += `\\x1b[${renderTop + 1 + ai.y};${renderLeft + 1 + ai.x}H\\x1b[1m${ai.color}${ai.char}\\x1b[0m`;\n }\n\n return output;\n }\n\n function renderParticles(output: string, renderLeft: number, renderTop: number): string {\n for (const p of particles) {\n const screenX = Math.round(renderLeft + 1 + p.x);\n const screenY = Math.round(renderTop + 1 + p.y);\n if (screenX > renderLeft && screenX < renderLeft + GAME_WIDTH + 1 &&\n screenY > renderTop && screenY < renderTop + GAME_HEIGHT + 1) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${screenY};${screenX}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n return output;\n }\n\n // -------------------------------------------------------------------------\n // GAME LOOP\n // -------------------------------------------------------------------------\n\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const particleInterval = setInterval(() => {\n if (!running) { clearInterval(particleInterval); return; }\n // Update particles even when paused for visual continuity\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.03;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key.toLowerCase();\n\n // ESC toggles pause\n if (key === 'escape') {\n paused = !paused;\n if (paused) {\n pauseMenuSelection = 0;\n stopGameLoop();\n } else if (roundInProgress) {\n startGameLoop();\n }\n return;\n }\n\n // Q to quit from pause/game over/start screen\n if (key === 'q' && (paused || gameOver || !gameStarted)) {\n if (countdownTimer) clearInterval(countdownTimer);\n stopGameLoop();\n clearInterval(renderInterval);\n clearInterval(particleInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n return;\n }\n\n // Start screen - any key starts\n if (!gameStarted && !paused) {\n gameStarted = true;\n initRound();\n return;\n }\n\n // Game over - R to restart\n if (gameOver) {\n if (key === 'r') {\n initGame();\n gameStarted = true;\n initRound();\n }\n return;\n }\n\n // Round end (not match over) - space for next round\n if (!roundInProgress && !matchOver && gameStarted && !paused) {\n if (key === ' ' || domEvent.key === ' ') {\n nextRound();\n }\n return;\n }\n\n // Pause menu navigation\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n key,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n if (roundInProgress) startGameLoop();\n break;\n case 1: // Restart\n initGame();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n if (countdownTimer) clearInterval(countdownTimer);\n stopGameLoop();\n clearInterval(renderInterval);\n clearInterval(particleInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n if (countdownTimer) clearInterval(countdownTimer);\n stopGameLoop();\n clearInterval(renderInterval);\n clearInterval(particleInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n if (countdownTimer) clearInterval(countdownTimer);\n stopGameLoop();\n clearInterval(renderInterval);\n clearInterval(particleInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcuts\n if (key === 'r') {\n initGame();\n gameStarted = true;\n paused = false;\n } else if (key === 'l') {\n if (countdownTimer) clearInterval(countdownTimer);\n stopGameLoop();\n clearInterval(renderInterval);\n clearInterval(particleInterval);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (key === 'n') {\n if (countdownTimer) clearInterval(countdownTimer);\n stopGameLoop();\n clearInterval(renderInterval);\n clearInterval(particleInterval);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n // GAMEPLAY INPUT - arrow keys to turn\n if (roundInProgress && player.alive) {\n const opposite: Record<Direction, Direction> = {\n 'up': 'down',\n 'down': 'up',\n 'left': 'right',\n 'right': 'left',\n };\n\n let newDir: Direction | null = null;\n\n switch (domEvent.key) {\n case 'ArrowUp':\n case 'w':\n newDir = 'up';\n break;\n case 'ArrowDown':\n case 's':\n newDir = 'down';\n break;\n case 'ArrowLeft':\n case 'a':\n newDir = 'left';\n break;\n case 'ArrowRight':\n case 'd':\n newDir = 'right';\n break;\n }\n\n // Can't reverse direction\n if (newDir && newDir !== opposite[player.direction]) {\n nextPlayerDirection = newDir;\n }\n }\n });\n\n // Clean up on stop\n const originalStop = controller.stop;\n controller.stop = () => {\n if (countdownTimer) clearInterval(countdownTimer);\n stopGameLoop();\n clearInterval(renderInterval);\n clearInterval(particleInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Hyper Typing Test\n *\n * Cyberpunk-themed typing speed test with glitchy effects,\n * neon visuals, and theme-aware colors.\n * Tests WPM (words per minute) and accuracy.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor, getVerticalAnchor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Typing Test Game Controller\n */\nexport interface TypingTestController {\n stop: () => void;\n isRunning: boolean;\n}\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\n// Word lists for different difficulty levels\nconst WORDS_EASY = [\n 'the', 'be', 'to', 'of', 'and', 'a', 'in', 'that', 'have', 'it',\n 'for', 'not', 'on', 'with', 'he', 'as', 'you', 'do', 'at', 'this',\n 'but', 'his', 'by', 'from', 'they', 'we', 'say', 'her', 'she', 'or',\n 'an', 'will', 'my', 'one', 'all', 'would', 'there', 'their', 'what',\n 'so', 'up', 'out', 'if', 'about', 'who', 'get', 'which', 'go', 'me',\n];\n\nconst WORDS_CYBER = [\n 'hack', 'code', 'data', 'byte', 'node', 'link', 'sync', 'scan', 'port',\n 'wire', 'grid', 'core', 'disk', 'chip', 'loop', 'ping', 'host', 'root',\n 'shell', 'queue', 'cache', 'stack', 'proxy', 'query', 'parse', 'debug',\n 'input', 'output', 'array', 'index', 'string', 'float', 'class', 'yield',\n 'async', 'await', 'spawn', 'forge', 'trace', 'patch', 'flush', 'crash',\n 'neural', 'matrix', 'cipher', 'vector', 'binary', 'kernel', 'daemon',\n 'buffer', 'socket', 'thread', 'signal', 'stream', 'packet', 'router',\n 'firewall', 'protocol', 'encrypt', 'decrypt', 'compile', 'runtime',\n];\n\n// Sentence templates for harder mode\nconst SENTENCES = [\n 'The quick brown fox jumps over the lazy dog',\n 'Pack my box with five dozen liquor jugs',\n 'How vexingly quick daft zebras jump',\n 'The five boxing wizards jump quickly',\n 'Sphinx of black quartz judge my vow',\n 'Two driven jocks help fax my big quiz',\n 'The system is online and ready for input',\n 'Neural network processing data packets',\n 'Executing quantum encryption protocol',\n 'Compiling source code into binary',\n 'Initializing secure connection tunnel',\n 'Decrypting incoming transmission stream',\n 'Accessing mainframe through backdoor',\n 'Uploading virus payload to target system',\n 'Bypassing firewall security measures',\n 'Tracing network route to server node',\n];\n\n/**\n * Cyberpunk Typing Test\n */\nexport function runTypingTest(terminal: Terminal): TypingTestController {\n const themeColor = getCurrentThemeColor();\n\n // Game dimensions\n const GAME_WIDTH = 60;\n\n // Minimum terminal size (reduced for tolerance)\n const MIN_COLS = 40;\n const MIN_ROWS = 18;\n\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n\n // Game settings\n let mode: 'words' | 'sentences' = 'words';\n let duration = 30; // seconds\n\n // Test state\n let currentText = '';\n let typedText = '';\n let startTime = 0;\n let timeRemaining = duration;\n let correctChars = 0;\n let totalChars = 0;\n let wordsCompleted = 0;\n let words: string[] = [];\n\n // Stats\n let wpm = 0;\n let accuracy = 100;\n let highWpm = 0;\n\n // Game area positioning\n let gameTop = 5;\n\n // Visual effects\n let glitchFrame = 0;\n let cursorBlink = 0;\n let resultAnimation = 0;\n let isNewBest = false;\n\n // Juicy effects\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let correctStreak = 0;\n let screenShake = 0;\n let borderFlash = 0;\n let errorFlash = 0;\n\n const controller: TypingTestController = {\n stop: () => {\n if (!running) return;\n running = false;\n // Note: Buffer exit is handled by TerminalPool via dispatchGameQuit\n },\n get isRunning() { return running; }\n };\n\n // ASCII art title\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ ▀█▀ █▄█ █▀█ █ █▄ █ █▀▀',\n '█▀█ █ █▀▀ ██▄ █▀▄ █ █ █▀▀ █ █ ▀█ █▄█',\n ];\n\n function updateLayout(rows: number) {\n // Gameplay body spans stats/progress/text/hints area.\n gameTop = getVerticalAnchor(rows, 10, {\n headerRows: 3,\n footerRows: 2,\n minTop: 5,\n });\n }\n\n function generateText() {\n if (mode === 'sentences') {\n // Pick random sentences\n const shuffled = [...SENTENCES].sort(() => Math.random() - 0.5);\n currentText = shuffled.slice(0, 3).join(' ');\n } else {\n // Generate word list\n const allWords = [...WORDS_EASY, ...WORDS_CYBER];\n words = [];\n for (let i = 0; i < 50; i++) {\n words.push(allWords[Math.floor(Math.random() * allWords.length)]);\n }\n currentText = words.join(' ');\n }\n }\n\n function initGame() {\n generateText();\n typedText = '';\n startTime = 0;\n timeRemaining = duration;\n correctChars = 0;\n totalChars = 0;\n wordsCompleted = 0;\n wpm = 0;\n accuracy = 100;\n gameOver = false;\n paused = false;\n resultAnimation = 0;\n isNewBest = false;\n // Reset juicy effects\n particles = [];\n scorePopups = [];\n correctStreak = 0;\n screenShake = 0;\n borderFlash = 0;\n errorFlash = 0;\n }\n\n // Spawn particles at position\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['✦', '★', '◆', '●']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.2 + Math.random() * 0.3;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5 - 0.15,\n life: 10 + Math.floor(Math.random() * 6),\n });\n }\n }\n\n // Add score popup\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 18, color });\n }\n\n function calculateStats() {\n if (startTime === 0) return;\n\n const elapsed = (Date.now() - startTime) / 1000;\n timeRemaining = Math.max(0, duration - elapsed);\n\n // Calculate WPM: (characters / 5) / minutes\n // A \"word\" in typing tests is standardized as 5 characters\n const minutes = elapsed / 60;\n if (minutes > 0) {\n wpm = Math.round((correctChars / 5) / minutes);\n }\n\n // Calculate accuracy\n if (totalChars > 0) {\n accuracy = Math.round((correctChars / totalChars) * 100);\n }\n\n if (timeRemaining <= 0) {\n gameOver = true;\n isNewBest = wpm > highWpm;\n if (isNewBest) highWpm = wpm;\n resultAnimation = 40; // Start result animation\n }\n }\n\n function handleChar(char: string) {\n if (gameOver || paused) return;\n\n // Start timer on first keypress\n if (startTime === 0) {\n startTime = Date.now();\n }\n\n const expectedChar = currentText[typedText.length];\n totalChars++;\n\n // Calculate cursor position for effects\n const cols = terminal.cols;\n const displayWidth = Math.min(60, cols - 4);\n const textStartX = Math.floor((cols - displayWidth) / 2);\n const cursorX = textStartX + Math.min(typedText.length, displayWidth / 2);\n const textY = gameTop + 4;\n\n if (char === expectedChar) {\n correctChars++;\n typedText += char;\n correctStreak++;\n\n // Effects based on streak\n if (correctStreak >= 5 && correctStreak % 5 === 0) {\n // Milestone streak effects\n borderFlash = 6;\n spawnParticles(cursorX, textY, 4 + Math.floor(correctStreak / 5), '\\x1b[1;92m', ['✦', '★', '◆']);\n addScorePopup(cursorX, textY - 1, `${correctStreak}!`, '\\x1b[1;96m');\n } else if (correctStreak >= 10) {\n // High streak - continuous small particles\n if (Math.random() < 0.3) {\n spawnParticles(cursorX, textY, 2, '\\x1b[1;92m', ['·', '•', '○']);\n }\n }\n\n // Count completed words\n if (char === ' ' || typedText.length === currentText.length) {\n wordsCompleted++;\n // Word complete effect\n spawnParticles(cursorX - 2, textY, 3, '\\x1b[1;96m', ['✦', '·', '○']);\n }\n\n // Check if we need more text\n if (typedText.length >= currentText.length - 20) {\n // Extend the text\n if (mode === 'words') {\n const allWords = [...WORDS_EASY, ...WORDS_CYBER];\n for (let i = 0; i < 20; i++) {\n words.push(allWords[Math.floor(Math.random() * allWords.length)]);\n }\n currentText = words.join(' ');\n }\n }\n } else {\n // Wrong character - still add it but it won't count as correct\n typedText += char;\n correctStreak = 0; // Reset streak on error\n errorFlash = 6;\n screenShake = 3;\n // Error particles\n spawnParticles(cursorX, textY, 3, '\\x1b[1;91m', ['✗', '×', '·']);\n }\n }\n\n function handleBackspace() {\n if (typedText.length > 0 && !gameOver && !paused && startTime > 0) {\n // Check if the character we're deleting was correct\n const removedChar = typedText[typedText.length - 1];\n const expectedChar = currentText[typedText.length - 1];\n if (removedChar === expectedChar) {\n correctChars--;\n }\n totalChars--;\n typedText = typedText.slice(0, -1);\n }\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Update effect timers\n if (screenShake > 0) screenShake--;\n if (borderFlash > 0) borderFlash--;\n if (errorFlash > 0) errorFlash--;\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.025;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.15;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = '';\n if (needWidth && needHeight) {\n hint = 'Make pane larger';\n } else if (needWidth) {\n hint = 'Make pane wider →';\n } else {\n hint = 'Make pane taller ↓';\n }\n const msg2 = `Need: ${MIN_COLS}×${MIN_ROWS} Have: ${cols}×${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n updateLayout(rows);\n\n // Glitchy title\n glitchFrame = (glitchFrame + 1) % 60;\n cursorBlink = (cursorBlink + 1) % 20;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset;\n\n const titleTop = Math.max(1, gameTop - 3);\n output += `\\x1b[${titleTop};${titleX}H`;\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX + 1}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[${titleTop + 1};${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n if (paused) {\n const pauseMsg = '══ PAUSED ══';\n const pauseCenterX = Math.floor(cols / 2);\n const pauseY = Math.floor(rows / 2) - 3;\n const pauseMsgX = pauseCenterX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX: pauseCenterX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = '↑↓ select ENTER confirm';\n const navHintX = pauseCenterX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n } else if (!gameStarted) {\n // Show start screen\n const startMsg = '[ PRESS ANY KEY TO START ]';\n const startX = Math.floor((cols - startMsg.length) / 2);\n const startY = Math.floor(rows / 2) - 2;\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const modeMsg = `MODE: ${mode.toUpperCase()} DURATION: ${duration}s`;\n const modeX = Math.floor((cols - modeMsg.length) / 2);\n output += `\\x1b[${startY + 2};${modeX}H${themeColor}${modeMsg}\\x1b[0m`;\n\n const controls1 = 'M: MODE 1/2/3: TIME (30/60/120s)';\n const ctrlX1 = Math.floor((cols - controls1.length) / 2);\n output += `\\x1b[${startY + 4};${ctrlX1}H\\x1b[2m${themeColor}${controls1}\\x1b[0m`;\n\n const controls2 = 'ESC: MENU';\n const ctrlX2 = Math.floor((cols - controls2.length) / 2);\n output += `\\x1b[${startY + 5};${ctrlX2}H\\x1b[2m${themeColor}${controls2}\\x1b[0m`;\n\n // High score\n if (highWpm > 0) {\n const highMsg = `BEST: ${highWpm} WPM`;\n const highX = Math.floor((cols - highMsg.length) / 2);\n output += `\\x1b[${startY + 7};${highX}H\\x1b[93m${highMsg}\\x1b[0m`;\n }\n } else if (gameOver) {\n // Show results with animation\n const overY = gameTop + 2;\n\n // Animated header based on performance\n const sparkles = ['✦', '✧', '★', '☆', '·'];\n const colors = ['\\x1b[92m', '\\x1b[96m', '\\x1b[93m', '\\x1b[95m'];\n const sparkleColor = colors[Math.floor(glitchFrame / 5) % colors.length];\n\n // Add sparkles for good performance\n if (wpm >= 40 && resultAnimation > 0) {\n for (let i = 0; i < 4; i++) {\n const sx = Math.floor(cols / 2) + Math.floor(Math.cos(glitchFrame * 0.3 + i) * 12);\n const sy = overY + Math.floor(Math.sin(glitchFrame * 0.2 + i) * 2);\n const sparkle = sparkles[Math.floor(Math.random() * sparkles.length)];\n output += `\\x1b[${sy};${sx}H${sparkleColor}${sparkle}\\x1b[0m`;\n }\n }\n\n const overMsg = resultAnimation > 20 ? '═══ TIME UP! ═══' : '══ TIME UP! ══';\n const overMsgColor = resultAnimation > 0 && Math.floor(glitchFrame / 3) % 2 === 0 ? '\\x1b[1;96m' : `\\x1b[1m${themeColor}`;\n const overX = Math.floor((cols - overMsg.length) / 2);\n output += `\\x1b[${overY};${overX}H${overMsgColor}${overMsg}\\x1b[0m`;\n\n // Results box with glow effect\n const boxColor = resultAnimation > 0 && Math.floor(glitchFrame / 4) % 2 === 0 ? '\\x1b[96m' : themeColor;\n const results = [\n `┌────────────────────────┐`,\n `│ TYPING RESULTS │`,\n `├────────────────────────┤`,\n `│ WPM: ${wpm.toString().padStart(5)} │`,\n `│ ACCURACY: ${accuracy.toString().padStart(4)}% │`,\n `│ WORDS: ${wordsCompleted.toString().padStart(5)} │`,\n `│ CHARS: ${correctChars.toString().padStart(5)} │`,\n `└────────────────────────┘`,\n ];\n\n const resultY = overY + 2;\n for (let i = 0; i < results.length; i++) {\n const lineX = Math.floor((cols - results[i].length) / 2);\n output += `\\x1b[${resultY + i};${lineX}H${boxColor}${results[i]}\\x1b[0m`;\n }\n\n // Rating with animation\n let rating = '';\n let ratingColor = '';\n if (wpm >= 80) { rating = '★ ELITE HACKER ★'; ratingColor = '\\x1b[1;95m'; }\n else if (wpm >= 60) { rating = '◆ SKILLED CODER ◆'; ratingColor = '\\x1b[1;96m'; }\n else if (wpm >= 40) { rating = '▸ KEYBOARD NINJA ◂'; ratingColor = '\\x1b[1;92m'; }\n else if (wpm >= 25) { rating = '· TRAINEE ·'; ratingColor = '\\x1b[1;93m'; }\n else { rating = 'NEEDS PRACTICE'; ratingColor = '\\x1b[1;91m'; }\n\n // Pulse rating color\n if (resultAnimation > 0 && wpm >= 40) {\n const pulse = Math.floor(glitchFrame / 2) % 2 === 0;\n ratingColor = pulse ? ratingColor : '\\x1b[1;97m';\n }\n\n const ratingX = Math.floor((cols - rating.length) / 2);\n output += `\\x1b[${resultY + results.length + 1};${ratingX}H${ratingColor}${rating}\\x1b[0m`;\n\n // Best score celebration\n if (isNewBest && wpm > 0) {\n const celebChars = ['★', '✦', '✧', '◆'];\n const newBest = resultAnimation > 0\n ? `${celebChars[Math.floor(glitchFrame / 4) % celebChars.length]} NEW PERSONAL BEST! ${celebChars[(Math.floor(glitchFrame / 4) + 2) % celebChars.length]}`\n : '★ NEW PERSONAL BEST! ★';\n const newBestColor = resultAnimation > 0 && Math.floor(glitchFrame / 2) % 2 === 0 ? '\\x1b[1;93m' : '\\x1b[1;97m';\n const newBestX = Math.floor((cols - newBest.length) / 2);\n output += `\\x1b[${resultY + results.length + 3};${newBestX}H${newBestColor}${newBest}\\x1b[0m`;\n }\n\n const restart = '[ R ] RETRY [ ESC ] QUIT';\n const restartX = Math.floor((cols - restart.length) / 2);\n output += `\\x1b[${resultY + results.length + 5};${restartX}H\\x1b[2m${themeColor}${restart}\\x1b[0m`;\n } else {\n // Apply screen shake offset\n const shakeOffsetX = screenShake > 0 ? Math.floor((Math.random() - 0.5) * 2) : 0;\n const shakeOffsetY = screenShake > 0 ? Math.floor(Math.random() * 2) : 0;\n\n // Stats bar with effects\n const timeColor = timeRemaining <= 5 ? '\\x1b[91m' : (borderFlash > 0 && borderFlash % 4 < 2 ? '\\x1b[1;92m' : themeColor);\n const errorColor = errorFlash > 0 && errorFlash % 4 < 2 ? '\\x1b[1;91m' : '';\n const stats = `TIME: ${Math.ceil(timeRemaining).toString().padStart(3)}s WPM: ${wpm.toString().padStart(3)} ACC: ${accuracy}%`;\n const statsX = Math.floor((cols - stats.length) / 2) + shakeOffsetX;\n output += `\\x1b[${gameTop + shakeOffsetY};${statsX}H${errorColor || timeColor}${stats}\\x1b[0m`;\n\n // Progress bar\n const progress = Math.max(0, (duration - timeRemaining) / duration);\n const barWidth = GAME_WIDTH - 4;\n const filled = Math.floor(barWidth * progress);\n const empty = barWidth - filled;\n const progressBar = '█'.repeat(filled) + '░'.repeat(empty);\n const barX = Math.floor((cols - barWidth) / 2) + shakeOffsetX;\n output += `\\x1b[${gameTop + 1 + shakeOffsetY};${barX}H${timeColor}${progressBar}\\x1b[0m`;\n\n // Show streak if active\n if (correctStreak >= 10) {\n const streakMsg = correctStreak >= 25 ? `★ ${correctStreak} STREAK! ★` : `${correctStreak} STREAK!`;\n const streakColor = glitchFrame % 6 < 3 ? '\\x1b[1;93m' : '\\x1b[1;96m';\n const streakX = Math.floor((cols - streakMsg.length) / 2);\n output += `\\x1b[${gameTop + 2 + shakeOffsetY};${streakX}H${streakColor}${streakMsg}\\x1b[0m`;\n }\n\n // Text display area\n const textY = gameTop + 4 + shakeOffsetY;\n const displayWidth = Math.min(GAME_WIDTH, cols - 4);\n const textStartX = Math.floor((cols - displayWidth) / 2) + shakeOffsetX;\n\n // Calculate visible text window\n const typedLen = typedText.length;\n const startIndex = Math.max(0, typedLen - Math.floor(displayWidth / 2));\n const visibleText = currentText.slice(startIndex, startIndex + displayWidth);\n const visibleTyped = typedText.slice(startIndex);\n\n // Draw text character by character\n output += `\\x1b[${textY};${textStartX}H`;\n for (let i = 0; i < visibleText.length; i++) {\n const char = visibleText[i];\n const typedChar = visibleTyped[i];\n\n if (typedChar === undefined) {\n // Not typed yet - show dimmed\n if (i === visibleTyped.length && cursorBlink < 10) {\n // Cursor position - flash on error\n const cursorColor = errorFlash > 0 ? '\\x1b[1;91m' : themeColor;\n output += `\\x1b[7m${cursorColor}${char}\\x1b[0m`;\n } else {\n output += `\\x1b[2m${themeColor}${char}\\x1b[0m`;\n }\n } else if (typedChar === char) {\n // Correct - show green (brighter during streak)\n const greenColor = correctStreak >= 10 ? '\\x1b[1;92m' : '\\x1b[92m';\n output += `${greenColor}${char}\\x1b[0m`;\n } else {\n // Wrong - show red with the typed char (flash on error)\n const redColor = errorFlash > 0 && errorFlash % 4 < 2 ? '\\x1b[1;97;41m' : '\\x1b[91m';\n output += `${redColor}${typedChar}\\x1b[0m`;\n }\n }\n\n // Draw particles\n for (const p of particles) {\n const px = Math.round(p.x);\n const py = Math.round(p.y);\n if (px > 0 && px < cols && py > 0 && py < rows) {\n const alpha = p.life > 4 ? '' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const px = Math.round(popup.x);\n const py = Math.round(popup.y);\n if (py > 0 && py < rows) {\n const alpha = popup.frames > 10 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n\n // Instructions\n const hint = startTime === 0 ? 'START TYPING TO BEGIN!' : '';\n if (hint) {\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${textY + 3};${hintX}H\\x1b[5m${themeColor}${hint}\\x1b[0m`;\n }\n }\n\n // Hint at bottom\n const hint = gameStarted && !gameOver && !paused ? '[ ESC ] MENU' : '';\n const hintX = Math.floor((cols - hint.length) / 2);\n output += `\\x1b[${rows - 1};${hintX}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n\n // Update animation counters\n if (resultAnimation > 0) resultAnimation--;\n\n terminal.write(output);\n }\n\n // Start game loop\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) {\n clearInterval(renderInterval);\n return;\n }\n if (gameStarted && !gameOver && !paused) {\n calculateStats();\n }\n render();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener.dispose();\n return;\n }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key;\n const keyLower = key.toLowerCase();\n\n // Handle ESC key - toggle pause (works on start screen too)\n if (key === 'Escape') {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n return;\n }\n\n // Start screen - pre-game controls (ESC handled above)\n // Skip if paused (ESC menu open on start screen)\n if (!gameStarted && !paused) {\n // Mode toggle\n if (keyLower === 'm') {\n mode = mode === 'words' ? 'sentences' : 'words';\n initGame();\n return;\n }\n if (key === '1') { duration = 30; initGame(); return; }\n if (key === '2') { duration = 60; initGame(); return; }\n if (key === '3') { duration = 120; initGame(); return; }\n\n // Any other key starts the game\n if (key.length === 1 || key === 'Enter' || key === ' ') {\n gameStarted = true;\n initGame();\n // If it's a typeable character, process it\n if (key.length === 1 && /[a-zA-Z0-9 .,!?;:'\"-]/.test(key)) {\n handleChar(key);\n }\n }\n return;\n }\n\n // Game over - R to restart\n if (gameOver) {\n if (keyLower === 'r') {\n initGame();\n gameStarted = true;\n }\n return;\n }\n\n // Pause menu actions\n if (paused) {\n // Use shared menu navigation\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n keyLower,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: // Resume\n paused = false;\n break;\n case 1: // Restart\n initGame();\n gameStarted = true;\n paused = false;\n break;\n case 2: // Quit\n clearInterval(renderInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3: // List Games\n clearInterval(renderInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4: // Next Game\n clearInterval(renderInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcut keys still work\n if (keyLower === 'r') {\n initGame();\n gameStarted = true;\n paused = false;\n } else if (keyLower === 'l') {\n clearInterval(renderInterval);\n running = false;\n dispatchGamesMenu(terminal);\n } else if (keyLower === 'n') {\n clearInterval(renderInterval);\n running = false;\n dispatchGameSwitch(terminal);\n }\n return;\n }\n\n // Handle typing\n if (key === 'Backspace') {\n handleBackspace();\n } else if (key.length === 1) {\n // Regular character\n handleChar(key);\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 50);\n\n return controller;\n}\n","/**\n * Hyper Wordle\n *\n * Classic 5-letter word guessing game with cyberpunk aesthetics.\n * Crack the cipher in 6 attempts. Green = correct, Yellow = wrong position, Gray = absent.\n * Features on-screen keyboard, statistics tracking, and particle celebrations.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor } from '../utils';\nimport { dispatchGameQuit, dispatchGameSwitch, dispatchGamesMenu } from '../gameTransitions';\nimport { PAUSE_MENU_ITEMS, renderSimpleMenu, navigateMenu } from '../shared/menu';\n\n/**\n * Wordle Game Controller\n */\nexport interface WordleController {\n stop: () => void;\n isRunning: boolean;\n}\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface Particle {\n x: number;\n y: number;\n char: string;\n color: string;\n vx: number;\n vy: number;\n life: number;\n}\n\ninterface ScorePopup {\n x: number;\n y: number;\n text: string;\n frames: number;\n color: string;\n}\n\ntype LetterState = 'correct' | 'present' | 'absent' | 'unused';\n\ninterface Statistics {\n gamesPlayed: number;\n gamesWon: number;\n currentStreak: number;\n maxStreak: number;\n guessDistribution: number[]; // index 0 = won in 1, etc.\n}\n\n// ============================================================================\n// WORD LIST - ~200 common 5-letter words\n// ============================================================================\n\nconst WORDS = [\n // Common everyday words\n 'ABOUT', 'ABOVE', 'AFTER', 'AGAIN', 'ALIEN', 'ALLOW', 'ALONE', 'ALONG',\n 'ANGEL', 'ANGRY', 'APPLE', 'ARENA', 'ARGUE', 'ARISE', 'ARRAY', 'ASIDE',\n 'AVOID', 'AWAKE', 'AWARD', 'BASIC', 'BEACH', 'BEAST', 'BEGIN', 'BEING',\n 'BELOW', 'BIRTH', 'BLACK', 'BLADE', 'BLAME', 'BLANK', 'BLAST', 'BLAZE',\n 'BLEED', 'BLEND', 'BLIND', 'BLOCK', 'BLOOD', 'BOARD', 'BOOST', 'BOUND',\n 'BRAIN', 'BRAND', 'BRAVE', 'BREAD', 'BREAK', 'BRICK', 'BRIDE', 'BRIEF',\n 'BRING', 'BROAD', 'BROKE', 'BROWN', 'BUILD', 'BUILT', 'BURST', 'BUYER',\n 'CABLE', 'CARRY', 'CATCH', 'CAUSE', 'CHAIN', 'CHAIR', 'CHAOS', 'CHARM',\n 'CHART', 'CHASE', 'CHEAP', 'CHECK', 'CHESS', 'CHEST', 'CHIEF', 'CHILD',\n 'CHILL', 'CLAIM', 'CLASS', 'CLEAN', 'CLEAR', 'CLIMB', 'CLOCK', 'CLOSE',\n 'CLOUD', 'COACH', 'COAST', 'CORAL', 'COUNT', 'COURT', 'COVER', 'CRAFT',\n 'CRASH', 'CRAZY', 'CREAM', 'CRIME', 'CROSS', 'CROWD', 'CROWN', 'CRUEL',\n 'CRUSH', 'DANCE', 'DEATH', 'DEBUT', 'DECAY', 'DEPTH', 'DIARY', 'DIRTY',\n 'DOUBT', 'DOZEN', 'DRAFT', 'DRAIN', 'DRAMA', 'DRANK', 'DRAWN', 'DREAM',\n 'DRESS', 'DRINK', 'DRIVE', 'DROWN', 'EARLY', 'EARTH', 'EIGHT', 'ELECT',\n 'ELITE', 'EMPTY', 'ENEMY', 'ENJOY', 'ENTER', 'ENTRY', 'EQUAL', 'ERROR',\n 'EVENT', 'EVERY', 'EXACT', 'EXIST', 'EXTRA', 'FAINT', 'FAITH', 'FALSE',\n 'FANCY', 'FATAL', 'FAULT', 'FEAST', 'FIBER', 'FIELD', 'FIFTH', 'FIFTY',\n 'FIGHT', 'FINAL', 'FIRST', 'FIXED', 'FLAME', 'FLASH', 'FLESH', 'FLOAT',\n 'FLOOD', 'FLOOR', 'FLOUR', 'FLUID', 'FOCUS', 'FORCE', 'FORGE', 'FORTH',\n 'FORTY', 'FORUM', 'FOUND', 'FRAME', 'FRANK', 'FRAUD', 'FRESH', 'FRONT',\n 'FROST', 'FRUIT', 'GHOST', 'GIANT', 'GIVEN', 'GLASS', 'GLOBE', 'GLORY',\n 'GRACE', 'GRADE', 'GRAIN', 'GRAND', 'GRANT', 'GRAPE', 'GRAPH', 'GRASP',\n 'GRASS', 'GRAVE', 'GREAT', 'GREEN', 'GRIND', 'GROUP', 'GROVE', 'GROWN',\n 'GUARD', 'GUESS', 'GUEST', 'GUIDE', 'GUILD', 'HABIT', 'HANDS', 'HAPPY',\n 'HARSH', 'HASTE', 'HAUNT', 'HEART', 'HEAVY', 'HENCE', 'HONEY', 'HONOR',\n 'HORSE', 'HOTEL', 'HOUSE', 'HUMAN', 'IDEAL', 'IMAGE', 'INDEX', 'INNER',\n 'INPUT', 'IRONY', 'ISSUE', 'IVORY', 'JOINT', 'JONES', 'JUDGE', 'JUICE',\n 'KNIFE', 'KNOCK', 'KNOWN', 'LABEL', 'LABOR', 'LARGE', 'LASER', 'LATER',\n 'LAUGH', 'LAYER', 'LEARN', 'LEAST', 'LEAVE', 'LEGAL', 'LEVEL', 'LIGHT',\n 'LIMIT', 'LINKS', 'LIVER', 'LOCAL', 'LOGIC', 'LOOSE', 'LOVER', 'LOWER',\n 'LUCKY', 'LUNCH', 'LYING', 'MAGIC', 'MAJOR', 'MAKER', 'MARCH', 'MATCH',\n 'MAYBE', 'MAYOR', 'MEANS', 'MEDAL', 'MEDIA', 'MERCY', 'MERGE', 'METAL',\n 'METER', 'MIGHT', 'MINOR', 'MINUS', 'MIXED', 'MODEL', 'MONEY', 'MONTH',\n 'MORAL', 'MOTOR', 'MOUNT', 'MOUSE', 'MOUTH', 'MOVIE', 'MUSIC', 'NAIVE',\n 'NAKED', 'NERVE', 'NEVER', 'NEWLY', 'NIGHT', 'NINTH', 'NOBLE', 'NOISE',\n 'NORTH', 'NOVEL', 'NURSE', 'OCCUR', 'OCEAN', 'OFFER', 'OFTEN', 'OLIVE',\n 'ORDER', 'OTHER', 'OUGHT', 'OUTER', 'OWNED', 'OWNER', 'OXIDE', 'OZONE',\n];\n\n// ============================================================================\n// MAIN GAME FUNCTION\n// ============================================================================\n\nexport function runWordleGame(terminal: Terminal): WordleController {\n const themeColor = getCurrentThemeColor();\n\n // -------------------------------------------------------------------------\n // CONSTANTS\n // -------------------------------------------------------------------------\n const MIN_COLS = 36;\n const MIN_ROWS = 20;\n const MAX_GUESSES = 6;\n const WORD_LENGTH = 5;\n\n // Keyboard layout\n const KEYBOARD_ROWS = [\n ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'],\n ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'],\n ['Z', 'X', 'C', 'V', 'B', 'N', 'M'],\n ];\n\n // -------------------------------------------------------------------------\n // STATE\n // -------------------------------------------------------------------------\n let running = true;\n let gameStarted = false;\n let gameOver = false;\n let paused = false;\n let pauseMenuSelection = 0;\n let won = false;\n let showStats = false;\n\n // Game state\n let targetWord = '';\n let guesses: string[] = [];\n let currentGuess = '';\n let letterStates: Map<string, LetterState> = new Map();\n\n // Statistics\n let stats: Statistics = {\n gamesPlayed: 0,\n gamesWon: 0,\n currentStreak: 0,\n maxStreak: 0,\n guessDistribution: [0, 0, 0, 0, 0, 0],\n };\n\n // Positioning\n let cols = terminal.cols;\n let rows = terminal.rows;\n\n // Visual effects\n let glitchFrame = 0;\n let particles: Particle[] = [];\n let scorePopups: ScorePopup[] = [];\n let shakeFrames = 0;\n let shakeIntensity = 0;\n let revealRow = -1;\n let revealCol = -1;\n let revealFrame = 0;\n let borderFlash = 0;\n\n // -------------------------------------------------------------------------\n // CONTROLLER\n // -------------------------------------------------------------------------\n const controller: WordleController = {\n stop: () => {\n if (!running) return;\n running = false;\n },\n get isRunning() { return running; }\n };\n\n // -------------------------------------------------------------------------\n // ASCII ART TITLE\n // -------------------------------------------------------------------------\n const title = [\n '█ █ █▄█ █▀█ █▀▀ █▀█ █ █ █ █▀█ █▀█ █▀▄ █ █▀▀',\n '█▀█ █ █▀▀ ██▄ █▀▄ ▀▄▀▄▀ █▄█ █▀▄ █▄▀ █▄▄ ██▄',\n ];\n\n // -------------------------------------------------------------------------\n // EFFECTS\n // -------------------------------------------------------------------------\n\n function spawnParticles(x: number, y: number, count: number, color: string, chars: string[] = ['*', '+', 'o', '.']) {\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + Math.random() * 0.5;\n const speed = 0.3 + Math.random() * 0.5;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.5 - 0.2,\n life: 15 + Math.floor(Math.random() * 10),\n });\n }\n }\n\n function spawnFirework(x: number, y: number) {\n const colors = ['\\x1b[1;92m', '\\x1b[1;93m', '\\x1b[1;96m', '\\x1b[1;95m'];\n const color = colors[Math.floor(Math.random() * colors.length)];\n const chars = ['*', '+', 'o', '.', '`', \"'\"];\n for (let i = 0; i < 12; i++) {\n const angle = (Math.PI * 2 * i) / 12;\n const speed = 0.4 + Math.random() * 0.3;\n particles.push({\n x,\n y,\n char: chars[Math.floor(Math.random() * chars.length)],\n color,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed * 0.6 - 0.1,\n life: 20 + Math.floor(Math.random() * 10),\n });\n }\n }\n\n function addScorePopup(x: number, y: number, text: string, color: string = '\\x1b[1;33m') {\n scorePopups.push({ x, y, text, frames: 25, color });\n }\n\n function triggerShake(frames: number, intensity: number) {\n shakeFrames = frames;\n shakeIntensity = intensity;\n }\n\n // -------------------------------------------------------------------------\n // GAME LOGIC\n // -------------------------------------------------------------------------\n\n function initGame() {\n targetWord = WORDS[Math.floor(Math.random() * WORDS.length)];\n guesses = [];\n currentGuess = '';\n letterStates = new Map();\n gameOver = false;\n won = false;\n paused = false;\n showStats = false;\n revealRow = -1;\n revealCol = -1;\n revealFrame = 0;\n\n particles = [];\n scorePopups = [];\n shakeFrames = 0;\n borderFlash = 0;\n }\n\n function checkGuess(guess: string): LetterState[] {\n const result: LetterState[] = new Array(WORD_LENGTH).fill('absent');\n const targetChars = targetWord.split('');\n const guessChars = guess.split('');\n const used = new Array(WORD_LENGTH).fill(false);\n\n // First pass: exact matches\n for (let i = 0; i < WORD_LENGTH; i++) {\n if (guessChars[i] === targetChars[i]) {\n result[i] = 'correct';\n used[i] = true;\n }\n }\n\n // Second pass: present but wrong position\n for (let i = 0; i < WORD_LENGTH; i++) {\n if (result[i] === 'correct') continue;\n const idx = targetChars.findIndex((c, j) => c === guessChars[i] && !used[j]);\n if (idx !== -1) {\n result[i] = 'present';\n used[idx] = true;\n }\n }\n\n return result;\n }\n\n function updateLetterStates(guess: string, result: LetterState[]) {\n for (let i = 0; i < WORD_LENGTH; i++) {\n const letter = guess[i];\n const currentState = letterStates.get(letter);\n const newState = result[i];\n\n // Only upgrade state, never downgrade\n if (!currentState || currentState === 'unused') {\n letterStates.set(letter, newState);\n } else if (currentState === 'absent' && (newState === 'present' || newState === 'correct')) {\n letterStates.set(letter, newState);\n } else if (currentState === 'present' && newState === 'correct') {\n letterStates.set(letter, newState);\n }\n }\n }\n\n function submitGuess() {\n if (currentGuess.length !== WORD_LENGTH) {\n triggerShake(4, 2);\n addScorePopup(Math.floor(cols / 2), 8, 'NOT ENOUGH LETTERS', '\\x1b[1;91m');\n return;\n }\n\n const result = checkGuess(currentGuess);\n guesses.push(currentGuess);\n updateLetterStates(currentGuess, result);\n\n // Start reveal animation\n revealRow = guesses.length - 1;\n revealCol = 0;\n revealFrame = 0;\n\n const allCorrect = result.every(r => r === 'correct');\n const correctCount = result.filter(r => r === 'correct').length;\n const presentCount = result.filter(r => r === 'present').length;\n\n const centerX = Math.floor(cols / 2);\n const guessY = 6 + guesses.length * 2;\n\n if (allCorrect) {\n won = true;\n gameOver = true;\n stats.gamesPlayed++;\n stats.gamesWon++;\n stats.currentStreak++;\n if (stats.currentStreak > stats.maxStreak) {\n stats.maxStreak = stats.currentStreak;\n }\n stats.guessDistribution[guesses.length - 1]++;\n\n // Celebration effects\n borderFlash = 20;\n triggerShake(10, 3);\n\n const messages = ['CIPHER BREACHED!', 'CODE CRACKED!', 'DECRYPTED!', 'BRILLIANT!'];\n addScorePopup(centerX, guessY - 2, messages[Math.floor(Math.random() * messages.length)], '\\x1b[1;92m');\n\n // Fireworks\n setTimeout(() => {\n if (running) {\n for (let i = 0; i < 5; i++) {\n setTimeout(() => {\n if (running && won) {\n spawnFirework(\n 10 + Math.random() * (cols - 20),\n 5 + Math.random() * 10\n );\n }\n }, i * 200);\n }\n }\n }, 500);\n } else if (guesses.length >= MAX_GUESSES) {\n gameOver = true;\n stats.gamesPlayed++;\n stats.currentStreak = 0;\n\n triggerShake(8, 4);\n borderFlash = 15;\n addScorePopup(centerX, guessY - 2, 'DECRYPTION FAILED', '\\x1b[1;91m');\n spawnParticles(centerX, guessY, 10, '\\x1b[1;91m', ['X', 'x', '.', '*']);\n } else {\n // Feedback for partial matches\n if (correctCount > 0 || presentCount > 0) {\n const hint = correctCount > 0 ? `${correctCount} EXACT` : `${presentCount} CLOSE`;\n addScorePopup(centerX, guessY - 1, hint, correctCount > 0 ? '\\x1b[1;92m' : '\\x1b[1;93m');\n spawnParticles(centerX, guessY, 3 + correctCount * 2, correctCount > 0 ? '\\x1b[1;92m' : '\\x1b[1;93m');\n }\n }\n\n currentGuess = '';\n }\n\n function update() {\n if (!gameStarted || paused || showStats) return;\n\n // Update particles\n for (let i = particles.length - 1; i >= 0; i--) {\n const p = particles[i];\n p.x += p.vx;\n p.y += p.vy;\n p.vy += 0.02;\n p.life--;\n if (p.life <= 0) particles.splice(i, 1);\n }\n\n // Update score popups\n for (let i = scorePopups.length - 1; i >= 0; i--) {\n const popup = scorePopups[i];\n popup.y -= 0.15;\n popup.frames--;\n if (popup.frames <= 0) scorePopups.splice(i, 1);\n }\n\n // Update reveal animation\n if (revealRow >= 0 && revealCol < WORD_LENGTH) {\n revealFrame++;\n if (revealFrame >= 4) {\n revealCol++;\n revealFrame = 0;\n }\n }\n }\n\n // -------------------------------------------------------------------------\n // RENDERING\n // -------------------------------------------------------------------------\n\n function getLetterColor(state: LetterState): string {\n switch (state) {\n case 'correct': return '\\x1b[1;42;97m'; // Green bg, white text\n case 'present': return '\\x1b[1;43;30m'; // Yellow bg, black text\n case 'absent': return '\\x1b[2;100;97m'; // Dark gray bg\n default: return themeColor;\n }\n }\n\n function getLetterBorderColor(state: LetterState): string {\n switch (state) {\n case 'correct': return '\\x1b[1;32m';\n case 'present': return '\\x1b[1;33m';\n case 'absent': return '\\x1b[2m';\n default: return themeColor;\n }\n }\n\n function render() {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n // Update dimensions\n cols = terminal.cols;\n rows = terminal.rows;\n\n // Effect timers\n if (shakeFrames > 0) shakeFrames--;\n if (borderFlash > 0) borderFlash--;\n\n // Check minimum terminal size\n if (cols < MIN_COLS || rows < MIN_ROWS) {\n const msg1 = 'Terminal too small!';\n const needWidth = cols < MIN_COLS;\n const needHeight = rows < MIN_ROWS;\n let hint = needWidth && needHeight ? 'Make pane larger'\n : needWidth ? 'Make pane wider' : 'Make pane taller';\n const msg2 = `Need: ${MIN_COLS}x${MIN_ROWS} Have: ${cols}x${rows}`;\n const centerX = Math.floor(cols / 2);\n const centerY = Math.floor(rows / 2);\n output += `\\x1b[${centerY - 1};${Math.max(1, centerX - Math.floor(msg1.length / 2))}H${themeColor}${msg1}\\x1b[0m`;\n output += `\\x1b[${centerY + 1};${Math.max(1, centerX - Math.floor(msg2.length / 2))}H\\x1b[2m${msg2}\\x1b[0m`;\n output += `\\x1b[${centerY + 3};${Math.max(1, centerX - Math.floor(hint.length / 2))}H\\x1b[1m${themeColor}${hint}\\x1b[0m`;\n terminal.write(output);\n return;\n }\n\n // Calculate shake offset\n let shakeX = 0, shakeY = 0;\n if (shakeFrames > 0) {\n shakeX = Math.floor((Math.random() - 0.5) * shakeIntensity * 2);\n shakeY = Math.floor((Math.random() - 0.5) * shakeIntensity);\n }\n\n const centerX = Math.floor(cols / 2);\n\n // Glitch title\n glitchFrame = (glitchFrame + 1) % 60;\n const glitchOffset = glitchFrame >= 55 ? Math.floor(Math.random() * 3) - 1 : 0;\n const titleX = Math.floor((cols - title[0].length) / 2) + glitchOffset + shakeX;\n\n let titleColor = themeColor;\n if (borderFlash > 0 && borderFlash % 4 < 2) {\n titleColor = won ? '\\x1b[1;92m' : '\\x1b[1;91m';\n }\n\n if (glitchFrame >= 55 && glitchFrame < 58) {\n output += `\\x1b[1;${Math.max(1, titleX)}H\\x1b[91m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${Math.max(1, titleX + 1)}H\\x1b[96m${title[1]}\\x1b[0m`;\n } else {\n output += `\\x1b[1;${Math.max(1, titleX)}H${titleColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[2;${Math.max(1, titleX)}H${titleColor}\\x1b[1m${title[1]}\\x1b[0m`;\n }\n\n // PAUSE MENU\n if (paused) {\n const pauseMsg = '== PAUSED ==';\n const pauseY = 8;\n const pauseMsgX = centerX - Math.floor(pauseMsg.length / 2);\n output += `\\x1b[${pauseY};${pauseMsgX}H\\x1b[5m${themeColor}${pauseMsg}\\x1b[0m`;\n\n output += renderSimpleMenu(PAUSE_MENU_ITEMS, pauseMenuSelection, {\n centerX,\n startY: pauseY + 2,\n showShortcuts: false,\n });\n\n const navHint = 'Use arrows, ENTER to select';\n const navHintX = centerX - Math.floor(navHint.length / 2);\n output += `\\x1b[${pauseY + 8};${navHintX}H\\x1b[2m${themeColor}${navHint}\\x1b[0m`;\n }\n // STATS SCREEN\n else if (showStats) {\n const statsY = 5;\n const boxWidth = 32;\n const boxX = centerX - Math.floor(boxWidth / 2);\n\n output += `\\x1b[${statsY};${boxX}H${themeColor}+${'='.repeat(boxWidth - 2)}+\\x1b[0m`;\n output += `\\x1b[${statsY + 1};${boxX}H${themeColor}| CIPHER STATISTICS |\\x1b[0m`;\n output += `\\x1b[${statsY + 2};${boxX}H${themeColor}+${'='.repeat(boxWidth - 2)}+\\x1b[0m`;\n\n const winPct = stats.gamesPlayed > 0 ? Math.round((stats.gamesWon / stats.gamesPlayed) * 100) : 0;\n\n output += `\\x1b[${statsY + 4};${boxX + 2}H${themeColor}Games Played: ${stats.gamesPlayed}\\x1b[0m`;\n output += `\\x1b[${statsY + 5};${boxX + 2}H${themeColor}Win Rate: ${winPct}%\\x1b[0m`;\n output += `\\x1b[${statsY + 6};${boxX + 2}H${themeColor}Current Streak: ${stats.currentStreak}\\x1b[0m`;\n output += `\\x1b[${statsY + 7};${boxX + 2}H${themeColor}Max Streak: ${stats.maxStreak}\\x1b[0m`;\n\n output += `\\x1b[${statsY + 9};${boxX + 2}H${themeColor}GUESS DISTRIBUTION:\\x1b[0m`;\n\n const maxDist = Math.max(...stats.guessDistribution, 1);\n for (let i = 0; i < 6; i++) {\n const count = stats.guessDistribution[i];\n const barLen = Math.round((count / maxDist) * 15);\n const bar = '#'.repeat(Math.max(barLen, count > 0 ? 1 : 0));\n const barColor = i === guesses.length - 1 && won ? '\\x1b[1;92m' : themeColor;\n output += `\\x1b[${statsY + 10 + i};${boxX + 2}H${themeColor}${i + 1}: ${barColor}${bar}\\x1b[0m ${count}`;\n }\n\n output += `\\x1b[${statsY + 17};${boxX}H${themeColor}+${'='.repeat(boxWidth - 2)}+\\x1b[0m`;\n\n const hint = '[ ENTER ] New Game [ Q ] Quit';\n output += `\\x1b[${statsY + 19};${centerX - Math.floor(hint.length / 2)}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n }\n // START SCREEN\n else if (!gameStarted) {\n const startMsg = '[ PRESS ANY KEY TO CRACK THE CIPHER ]';\n const startY = Math.floor(rows / 2) - 2;\n const startX = centerX - Math.floor(startMsg.length / 2);\n output += `\\x1b[${startY};${startX}H\\x1b[5m${themeColor}${startMsg}\\x1b[0m`;\n\n const rules = [\n 'Guess the 5-letter cipher in 6 tries',\n '',\n '\\x1b[42;97m G \\x1b[0m = Correct position',\n '\\x1b[43;30m Y \\x1b[0m = Wrong position',\n '\\x1b[100;97m X \\x1b[0m = Not in word',\n ];\n\n for (let i = 0; i < rules.length; i++) {\n const ruleX = centerX - 15;\n output += `\\x1b[${startY + 3 + i};${ruleX}H${rules[i]}\\x1b[0m`;\n }\n\n const controls = 'A-Z type ENTER submit BACKSPACE delete ESC menu';\n output += `\\x1b[${rows - 2};${centerX - Math.floor(controls.length / 2)}H\\x1b[2m${themeColor}${controls}\\x1b[0m`;\n }\n // MAIN GAMEPLAY\n else {\n const gridY = 4 + shakeY;\n const gridX = centerX - 8 + shakeX;\n\n // Draw guess grid\n for (let row = 0; row < MAX_GUESSES; row++) {\n const y = gridY + row * 2;\n\n for (let col = 0; col < WORD_LENGTH; col++) {\n const x = gridX + col * 4;\n\n let letter = ' ';\n let state: LetterState = 'unused';\n let isRevealing = false;\n\n if (row < guesses.length) {\n letter = guesses[row][col];\n const result = checkGuess(guesses[row]);\n\n // Check if this cell is being revealed\n if (row === revealRow && col <= revealCol) {\n state = result[col];\n } else if (row === revealRow) {\n isRevealing = true;\n } else {\n state = result[col];\n }\n } else if (row === guesses.length && col < currentGuess.length) {\n letter = currentGuess[col];\n }\n\n // Draw cell\n const cellColor = getLetterBorderColor(state);\n const bgColor = getLetterColor(state);\n\n if (isRevealing) {\n // Flip animation - show back of card\n output += `\\x1b[${y};${x}H${themeColor}[?]\\x1b[0m`;\n } else if (letter !== ' ') {\n output += `\\x1b[${y};${x}H${cellColor}[\\x1b[0m${bgColor} ${letter} \\x1b[0m${cellColor}]\\x1b[0m`;\n } else {\n output += `\\x1b[${y};${x}H${themeColor}[ ]\\x1b[0m`;\n }\n }\n }\n\n // Draw on-screen keyboard\n const kbY = gridY + MAX_GUESSES * 2 + 1;\n\n for (let rowIdx = 0; rowIdx < KEYBOARD_ROWS.length; rowIdx++) {\n const kbRow = KEYBOARD_ROWS[rowIdx];\n const rowOffset = rowIdx === 1 ? 1 : rowIdx === 2 ? 3 : 0;\n const rowX = centerX - Math.floor(kbRow.length * 2 / 2) + rowOffset + shakeX;\n\n for (let i = 0; i < kbRow.length; i++) {\n const key = kbRow[i];\n const state = letterStates.get(key) || 'unused';\n const keyColor = getLetterColor(state);\n\n output += `\\x1b[${kbY + rowIdx};${rowX + i * 2}H${keyColor}${key}\\x1b[0m`;\n }\n }\n\n // Game over overlay\n if (gameOver) {\n const overY = kbY + 4;\n\n if (won) {\n const winMsg = 'CIPHER CRACKED!';\n output += `\\x1b[${overY};${centerX - Math.floor(winMsg.length / 2)}H\\x1b[1;92m${winMsg}\\x1b[0m`;\n } else {\n const loseMsg = 'DECRYPTION FAILED';\n output += `\\x1b[${overY};${centerX - Math.floor(loseMsg.length / 2)}H\\x1b[1;91m${loseMsg}\\x1b[0m`;\n const wordMsg = `The cipher was: ${targetWord}`;\n output += `\\x1b[${overY + 1};${centerX - Math.floor(wordMsg.length / 2)}H${themeColor}${wordMsg}\\x1b[0m`;\n }\n\n const restartHint = '[ ENTER ] Stats [ R ] New Game [ Q ] Quit';\n output += `\\x1b[${overY + 3};${centerX - Math.floor(restartHint.length / 2)}H\\x1b[2m${themeColor}${restartHint}\\x1b[0m`;\n }\n\n // Draw particles\n for (const p of particles) {\n const px = Math.round(p.x);\n const py = Math.round(p.y);\n if (px > 0 && px < cols && py > 0 && py < rows) {\n const alpha = p.life > 5 ? '' : '\\x1b[2m';\n output += `\\x1b[${py};${px}H${alpha}${p.color}${p.char}\\x1b[0m`;\n }\n }\n\n // Draw score popups\n for (const popup of scorePopups) {\n const px = Math.round(popup.x - popup.text.length / 2);\n const py = Math.round(popup.y);\n if (py > 0 && py < rows && px > 0) {\n const alpha = popup.frames > 15 ? '\\x1b[1m' : '\\x1b[2m';\n output += `\\x1b[${py};${Math.max(1, px)}H${alpha}${popup.color}${popup.text}\\x1b[0m`;\n }\n }\n\n // Bottom hint\n if (!gameOver) {\n const hint = `Attempt ${guesses.length + 1}/${MAX_GUESSES} | [ ESC ] Menu`;\n output += `\\x1b[${rows - 1};${centerX - Math.floor(hint.length / 2)}H\\x1b[2m${themeColor}${hint}\\x1b[0m`;\n }\n }\n\n // Border flash effect\n if (borderFlash > 0) {\n const flashColor = won ? '\\x1b[32m' : '\\x1b[31m';\n const flashChar = borderFlash % 4 < 2 ? '#' : '=';\n for (let x = 1; x <= cols; x += 4) {\n output += `\\x1b[1;${x}H${flashColor}${flashChar}\\x1b[0m`;\n output += `\\x1b[${rows};${x}H${flashColor}${flashChar}\\x1b[0m`;\n }\n }\n\n terminal.write(output);\n }\n\n // -------------------------------------------------------------------------\n // GAME LOOP\n // -------------------------------------------------------------------------\n\n setTimeout(() => {\n if (!running) return;\n\n terminal.write('\\x1b[?1049h');\n terminal.write('\\x1b[?25l');\n\n initGame();\n gameStarted = false;\n\n const renderInterval = setInterval(() => {\n if (!running) { clearInterval(renderInterval); return; }\n render();\n }, 25);\n\n const gameInterval = setInterval(() => {\n if (!running) { clearInterval(gameInterval); return; }\n update();\n }, 25);\n\n const keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) { keyListener.dispose(); return; }\n\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key;\n const keyLower = key.toLowerCase();\n\n // ESC toggles pause\n if (key === 'Escape') {\n if (showStats) {\n showStats = false;\n } else {\n paused = !paused;\n if (paused) pauseMenuSelection = 0;\n }\n return;\n }\n\n // Stats screen\n if (showStats) {\n if (key === 'Enter') {\n initGame();\n gameStarted = true;\n showStats = false;\n }\n return;\n }\n\n // Start screen - any key starts\n if (!gameStarted && !paused) {\n gameStarted = true;\n return;\n }\n\n // Game over\n if (gameOver && !showStats) {\n if (keyLower === 'r') {\n initGame();\n gameStarted = true;\n } else if (key === 'Enter') {\n showStats = true;\n }\n return;\n }\n\n // Pause menu navigation\n if (paused) {\n const { newSelection, confirmed } = navigateMenu(\n pauseMenuSelection,\n PAUSE_MENU_ITEMS.length,\n keyLower,\n domEvent\n );\n\n if (newSelection !== pauseMenuSelection) {\n pauseMenuSelection = newSelection;\n return;\n }\n\n if (confirmed) {\n switch (pauseMenuSelection) {\n case 0: paused = false; break;\n case 1: initGame(); gameStarted = true; paused = false; break;\n case 2:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n controller.stop();\n dispatchGameQuit(terminal);\n break;\n case 3:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGamesMenu(terminal);\n break;\n case 4:\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n running = false;\n dispatchGameSwitch(terminal);\n break;\n }\n return;\n }\n\n // Legacy shortcuts\n if (keyLower === 'r') { initGame(); gameStarted = true; paused = false; }\n else if (keyLower === 'l') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGamesMenu(terminal); }\n else if (keyLower === 'n') { clearInterval(renderInterval); clearInterval(gameInterval); running = false; dispatchGameSwitch(terminal); }\n return;\n }\n\n // GAMEPLAY INPUT\n if (key === 'Backspace') {\n currentGuess = currentGuess.slice(0, -1);\n } else if (key === 'Enter') {\n submitGuess();\n } else if (key.length === 1 && /[a-zA-Z]/.test(key) && currentGuess.length < WORD_LENGTH) {\n currentGuess += key.toUpperCase();\n // Small typing feedback\n spawnParticles(\n Math.floor(cols / 2) - 8 + currentGuess.length * 4,\n 4 + guesses.length * 2,\n 2,\n themeColor,\n ['.', '*']\n );\n }\n });\n\n // Clean up on stop\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(renderInterval);\n clearInterval(gameInterval);\n keyListener.dispose();\n originalStop();\n };\n }, 25);\n\n return controller;\n}\n","/**\n * Games Menu\n *\n * Interactive game selection menu accessible via ::games command\n * or by pressing L in any game's pause menu.\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { getCurrentThemeColor, isLightTheme, enterAlternateBuffer, exitAlternateBuffer, forceExitAlternateBuffer, isTerminalValid } from './utils';\nimport { games } from './index';\nimport { playSelectTransition } from './gameTransitions';\n\nexport interface GamesMenuController {\n stop: () => void;\n isRunning: boolean;\n}\n\nexport interface GamesMenuOptions {\n onGameSelect?: (gameId: string) => void;\n onQuit?: () => void;\n}\n\n/**\n * Show interactive games menu\n */\nexport function showGamesMenu(terminal: Terminal, optionsOrCallback?: GamesMenuOptions | ((gameId: string) => void)): GamesMenuController {\n // Support both options object and simple callback for backwards compatibility\n const options: GamesMenuOptions = typeof optionsOrCallback === 'function'\n ? { onGameSelect: optionsOrCallback }\n : optionsOrCallback || {};\n const { onGameSelect, onQuit } = options;\n const themeColor = getCurrentThemeColor();\n const lightTheme = isLightTheme();\n\n let running = true;\n let selectedIndex = 0;\n let scrollOffset = 0;\n\n const controller: GamesMenuController = {\n stop: () => {\n if (!running) return;\n running = false;\n },\n get isRunning() { return running; }\n };\n\n const title = [\n '\\u2588\\u2580\\u2580 \\u2584\\u2580\\u2588 \\u2588\\u2580\\u2584\\u2580\\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2580',\n '\\u2588\\u2584\\u2588 \\u2588\\u2580\\u2588 \\u2588 \\u2580 \\u2588 \\u2588\\u2588\\u2584 \\u2584\\u2588',\n ];\n\n function render(): void {\n let output = '';\n output += '\\x1b[2J\\x1b[H';\n\n const cols = terminal.cols;\n const rows = terminal.rows;\n\n // Title\n const titleX = Math.floor((cols - title[0].length) / 2);\n output += `\\x1b[2;${titleX}H${themeColor}\\x1b[1m${title[0]}\\x1b[0m`;\n output += `\\x1b[3;${titleX}H${themeColor}\\x1b[1m${title[1]}\\x1b[0m`;\n\n // Subtitle with game count\n const subtitle = `Select a game to play (${games.length} games)`;\n output += `\\x1b[5;${Math.floor((cols - subtitle.length) / 2)}H\\x1b[2m${subtitle}\\x1b[0m`;\n\n // Determine if we should use 2 columns\n const boxWidth = 38;\n const columnGap = 2;\n const twoColumnWidth = boxWidth * 2 + columnGap;\n const useTwoColumns = cols >= twoColumnWidth + 8; // 8 for margins\n\n const listStartY = 6;\n const availableRows = rows - listStartY - 4;\n const maxVisibleGames = Math.max(1, Math.floor(availableRows / 2));\n\n if (useTwoColumns) {\n renderTwoColumns(output, cols, rows, boxWidth, columnGap, listStartY, maxVisibleGames);\n } else {\n renderSingleColumn(output, cols, rows, boxWidth, listStartY, maxVisibleGames);\n }\n }\n\n function renderSingleColumn(\n baseOutput: string,\n cols: number,\n rows: number,\n boxWidth: number,\n listStartY: number,\n maxVisibleGames: number\n ): void {\n let output = baseOutput;\n const boxX = Math.floor((cols - boxWidth) / 2);\n const visibleGames = Math.min(maxVisibleGames, games.length);\n\n // Adjust scroll offset to keep selected item visible\n if (selectedIndex < scrollOffset) {\n scrollOffset = selectedIndex;\n } else if (selectedIndex >= scrollOffset + visibleGames) {\n scrollOffset = selectedIndex - visibleGames + 1;\n }\n scrollOffset = Math.max(0, Math.min(scrollOffset, games.length - visibleGames));\n\n const hasScrollUp = scrollOffset > 0;\n const hasScrollDown = scrollOffset + visibleGames < games.length;\n\n // Top border\n const topScrollIndicator = hasScrollUp ? ' \\u25b2 more ' : '\\u2550'.repeat(8);\n const topBorderWidth = boxWidth - 2 - topScrollIndicator.length;\n const topLeftPad = Math.floor(topBorderWidth / 2);\n const topRightPad = topBorderWidth - topLeftPad;\n output += `\\x1b[${listStartY};${boxX}H${themeColor}\\u2554${'\\u2550'.repeat(topLeftPad)}${hasScrollUp ? '\\x1b[33m' : ''}${topScrollIndicator}${hasScrollUp ? themeColor : ''}${'\\u2550'.repeat(topRightPad)}\\u2557\\x1b[0m`;\n\n // Render visible games\n for (let vi = 0; vi < visibleGames; vi++) {\n const i = scrollOffset + vi;\n const game = games[i];\n const y = listStartY + 1 + vi * 2;\n const isSelected = i === selectedIndex;\n\n output += renderGameEntry(game, i, isSelected, y, boxX, boxWidth);\n }\n\n // Bottom border\n const bottomY = listStartY + 1 + visibleGames * 2;\n const bottomScrollIndicator = hasScrollDown ? ' \\u25bc more ' : '\\u2550'.repeat(8);\n const bottomBorderWidth = boxWidth - 2 - bottomScrollIndicator.length;\n const bottomLeftPad = Math.floor(bottomBorderWidth / 2);\n const bottomRightPad = bottomBorderWidth - bottomLeftPad;\n output += `\\x1b[${bottomY};${boxX}H${themeColor}\\u255a${'\\u2550'.repeat(bottomLeftPad)}${hasScrollDown ? '\\x1b[33m' : ''}${bottomScrollIndicator}${hasScrollDown ? themeColor : ''}${'\\u2550'.repeat(bottomRightPad)}\\u255d\\x1b[0m`;\n\n // Controls\n const controls = `\\u2191\\u2193 Navigate | ENTER Select | 1-9 Quick | Q Quit`;\n output += `\\x1b[${rows - 1};${Math.floor((cols - controls.length) / 2)}H\\x1b[2m${controls}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n function renderTwoColumns(\n baseOutput: string,\n cols: number,\n rows: number,\n boxWidth: number,\n columnGap: number,\n listStartY: number,\n maxVisibleGames: number\n ): void {\n let output = baseOutput;\n\n // With 2 columns, we can show 2x as many games\n const gamesPerColumn = Math.min(maxVisibleGames, Math.ceil(games.length / 2));\n\n // Calculate scroll based on rows of 2 games\n const selectedRow = Math.floor(selectedIndex / 2);\n if (selectedRow < scrollOffset) {\n scrollOffset = selectedRow;\n } else if (selectedRow >= scrollOffset + gamesPerColumn) {\n scrollOffset = selectedRow - gamesPerColumn + 1;\n }\n const maxScroll = Math.max(0, Math.ceil(games.length / 2) - gamesPerColumn);\n scrollOffset = Math.max(0, Math.min(scrollOffset, maxScroll));\n\n const hasScrollUp = scrollOffset > 0;\n const hasScrollDown = (scrollOffset + gamesPerColumn) * 2 < games.length;\n\n // Calculate positions for two columns\n const totalWidth = boxWidth * 2 + columnGap;\n const startX = Math.floor((cols - totalWidth) / 2);\n const leftBoxX = startX;\n const rightBoxX = startX + boxWidth + columnGap;\n\n // Top borders\n const topScrollIndicator = hasScrollUp ? ' \\u25b2 ' : '\\u2550\\u2550\\u2550';\n const topBorderContent = boxWidth - 2 - topScrollIndicator.length;\n const topLeft = Math.floor(topBorderContent / 2);\n const topRight = topBorderContent - topLeft;\n\n output += `\\x1b[${listStartY};${leftBoxX}H${themeColor}\\u2554${'\\u2550'.repeat(topLeft)}${hasScrollUp ? '\\x1b[33m' : ''}${topScrollIndicator}${hasScrollUp ? themeColor : ''}${'\\u2550'.repeat(topRight)}\\u2557\\x1b[0m`;\n output += `\\x1b[${listStartY};${rightBoxX}H${themeColor}\\u2554${'\\u2550'.repeat(topLeft)}${hasScrollUp ? '\\x1b[33m' : ''}${topScrollIndicator}${hasScrollUp ? themeColor : ''}${'\\u2550'.repeat(topRight)}\\u2557\\x1b[0m`;\n\n // Render games in two columns\n for (let row = 0; row < gamesPerColumn; row++) {\n const leftIdx = (scrollOffset + row) * 2;\n const rightIdx = leftIdx + 1;\n const y = listStartY + 1 + row * 2;\n\n // Left column\n if (leftIdx < games.length) {\n output += renderGameEntry(games[leftIdx], leftIdx, leftIdx === selectedIndex, y, leftBoxX, boxWidth);\n } else {\n // Empty slot\n output += `\\x1b[${y};${leftBoxX}H${themeColor}\\u2551${' '.repeat(boxWidth - 2)}\\u2551\\x1b[0m`;\n output += `\\x1b[${y + 1};${leftBoxX}H${themeColor}\\u2551${' '.repeat(boxWidth - 2)}\\u2551\\x1b[0m`;\n }\n\n // Right column\n if (rightIdx < games.length) {\n output += renderGameEntry(games[rightIdx], rightIdx, rightIdx === selectedIndex, y, rightBoxX, boxWidth);\n } else {\n // Empty slot\n output += `\\x1b[${y};${rightBoxX}H${themeColor}\\u2551${' '.repeat(boxWidth - 2)}\\u2551\\x1b[0m`;\n output += `\\x1b[${y + 1};${rightBoxX}H${themeColor}\\u2551${' '.repeat(boxWidth - 2)}\\u2551\\x1b[0m`;\n }\n }\n\n // Bottom borders\n const bottomY = listStartY + 1 + gamesPerColumn * 2;\n const bottomScrollIndicator = hasScrollDown ? ' \\u25bc ' : '\\u2550\\u2550\\u2550';\n const bottomBorderContent = boxWidth - 2 - bottomScrollIndicator.length;\n const bottomLeft = Math.floor(bottomBorderContent / 2);\n const bottomRight = bottomBorderContent - bottomLeft;\n\n output += `\\x1b[${bottomY};${leftBoxX}H${themeColor}\\u255a${'\\u2550'.repeat(bottomLeft)}${hasScrollDown ? '\\x1b[33m' : ''}${bottomScrollIndicator}${hasScrollDown ? themeColor : ''}${'\\u2550'.repeat(bottomRight)}\\u255d\\x1b[0m`;\n output += `\\x1b[${bottomY};${rightBoxX}H${themeColor}\\u255a${'\\u2550'.repeat(bottomLeft)}${hasScrollDown ? '\\x1b[33m' : ''}${bottomScrollIndicator}${hasScrollDown ? themeColor : ''}${'\\u2550'.repeat(bottomRight)}\\u255d\\x1b[0m`;\n\n // Controls\n const controls = `\\u2191\\u2193\\u2190\\u2192 Navigate | ENTER Select | 1-9 Quick | Q Quit`;\n output += `\\x1b[${rows - 1};${Math.floor((cols - controls.length) / 2)}H\\x1b[2m${controls}\\x1b[0m`;\n\n terminal.write(output);\n }\n\n function renderGameEntry(\n game: typeof games[number],\n index: number,\n isSelected: boolean,\n y: number,\n boxX: number,\n boxWidth: number\n ): string {\n let output = '';\n const contentWidth = boxWidth - 2; // Account for box borders on each side\n\n const prefix = isSelected ? '\\u25b6' : ' ';\n const highlight = isSelected ? (lightTheme ? '\\x1b[1;7;97m' : '\\x1b[1;7m') : '';\n const keyColor = isSelected ? '' : '\\x1b[33m';\n const keyNum = index + 1;\n const keyDisplay = keyNum <= 9 ? `${keyNum}` : ' ';\n\n // Build the line content\n const lineContent = `${prefix} [${keyDisplay}] ${game.name}`;\n const padding = Math.max(0, contentWidth - lineContent.length);\n\n output += `\\x1b[${y};${boxX}H${themeColor}\\u2551\\x1b[0m${highlight}${keyColor}${lineContent}${' '.repeat(padding)}\\x1b[0m${themeColor}\\u2551\\x1b[0m`;\n\n // Description line\n const descContent = ` ${game.description}`;\n const descPadding = Math.max(0, contentWidth - descContent.length);\n const descColor = isSelected ? (lightTheme ? '\\x1b[2;7;97m' : '\\x1b[2;7m') : '\\x1b[2m';\n\n output += `\\x1b[${y + 1};${boxX}H${themeColor}\\u2551\\x1b[0m${descColor}${descContent}${' '.repeat(descPadding)}\\x1b[0m${themeColor}\\u2551\\x1b[0m`;\n\n return output;\n }\n\n // Start menu\n setTimeout(() => {\n if (!running) return;\n\n // Verify terminal is still valid before proceeding\n if (!isTerminalValid(terminal)) {\n console.warn('[GamesMenu] Terminal became invalid before menu could start');\n running = false;\n return;\n }\n\n let keyListener: ReturnType<typeof terminal.onKey> | null = null;\n\n try {\n // Enter alternate buffer\n enterAlternateBuffer(terminal, 'games-menu');\n\n render();\n\n keyListener = terminal.onKey(({ domEvent }) => {\n if (!running) {\n keyListener?.dispose();\n return;\n }\n\n try {\n domEvent.preventDefault();\n domEvent.stopPropagation();\n\n const key = domEvent.key;\n const keyLower = key.toLowerCase();\n const cols = terminal.cols;\n const boxWidth = 38;\n const columnGap = 2;\n const twoColumnWidth = boxWidth * 2 + columnGap;\n const useTwoColumns = cols >= twoColumnWidth + 8;\n\n // Quit\n if (key === 'Escape' || keyLower === 'q') {\n keyListener?.dispose();\n controller.stop();\n exitAlternateBuffer(terminal, 'games-menu-quit');\n if (onQuit) {\n onQuit();\n }\n return;\n }\n\n // Navigate\n if (key === 'ArrowUp') {\n if (useTwoColumns) {\n selectedIndex = Math.max(0, selectedIndex - 2);\n } else {\n selectedIndex = (selectedIndex - 1 + games.length) % games.length;\n }\n render();\n return;\n }\n if (key === 'ArrowDown') {\n if (useTwoColumns) {\n selectedIndex = Math.min(games.length - 1, selectedIndex + 2);\n } else {\n selectedIndex = (selectedIndex + 1) % games.length;\n }\n render();\n return;\n }\n if (key === 'ArrowLeft' && useTwoColumns) {\n if (selectedIndex % 2 === 1) {\n selectedIndex--;\n }\n render();\n return;\n }\n if (key === 'ArrowRight' && useTwoColumns) {\n if (selectedIndex % 2 === 0 && selectedIndex + 1 < games.length) {\n selectedIndex++;\n }\n render();\n return;\n }\n\n // Helper to launch game with transition\n const launchGame = async (game: typeof games[number]) => {\n keyListener?.dispose();\n running = false;\n // Exit alternate buffer BEFORE transition so menu stops drawing\n exitAlternateBuffer(terminal, 'games-menu-launch');\n\n try {\n await playSelectTransition(terminal, game.name);\n if (onGameSelect) {\n onGameSelect(game.id);\n }\n } catch (err) {\n console.error('[GamesMenu] Failed to launch game:', err);\n // Ensure terminal is in usable state on error\n forceExitAlternateBuffer(terminal, 'games-menu-launch-error');\n terminal.write(`\\x1b[91mError launching game: ${err}\\x1b[0m\\r\\n`);\n }\n };\n\n // Select\n if (key === 'Enter') {\n launchGame(games[selectedIndex]).catch(err => {\n console.error('[GamesMenu] Unhandled launch error:', err);\n });\n return;\n }\n\n // Quick select by number (1-9)\n const numKey = parseInt(key);\n if (numKey >= 1 && numKey <= games.length && numKey <= 9) {\n launchGame(games[numKey - 1]).catch(err => {\n console.error('[GamesMenu] Unhandled launch error:', err);\n });\n return;\n }\n } catch (err) {\n console.error('[GamesMenu] Key handler error:', err);\n controller.stop();\n }\n });\n\n const originalStop = controller.stop;\n controller.stop = () => {\n keyListener?.dispose();\n exitAlternateBuffer(terminal, 'games-menu-stop');\n originalStop();\n };\n } catch (err) {\n console.error('[GamesMenu] Failed to initialize menu:', err);\n forceExitAlternateBuffer(terminal, 'games-menu-init-error');\n running = false;\n }\n }, 50);\n\n return controller;\n}\n","/**\n * @hypersocial/cli-games\n *\n * Terminal games for xterm.js and CLI\n *\n * Usage:\n * 1. Set the theme: setTheme('cyan')\n * 2. Run a game: games.snake.run(terminal)\n * 3. Handle game events: listen for GAME_EVENTS on window\n */\n\n// Re-export utilities\nexport {\n setTheme,\n getTheme,\n getCurrentThemeColor,\n isLightTheme,\n getSubtleBackgroundColor,\n getVerticalAnchor,\n getThemeColorCode,\n enterAlternateBuffer,\n exitAlternateBuffer,\n isInAlternateBuffer,\n forceExitAlternateBuffer,\n isTerminalValid,\n} from './utils';\n\nexport type { PhosphorMode } from './utils';\n\n// Re-export transitions\nexport {\n GAME_EVENTS,\n playBootTransition,\n playExitTransition,\n playSwitchTransition,\n playQuickBoot,\n playSelectTransition,\n dispatchGameQuit,\n dispatchGameSwitch,\n dispatchGamesMenu,\n dispatchLaunchGame,\n} from './gameTransitions';\n\n// Re-export menu utilities\nexport {\n createMenuState,\n menuUp,\n menuDown,\n menuReset,\n menuConfirm,\n handleMenuInput,\n renderMenu,\n createPauseMenuItems,\n createGameOverMenuItems,\n createModeSelectMenuItems,\n navigateMenu,\n checkShortcut,\n renderSimpleMenu,\n PAUSE_MENU_ITEMS,\n MODE_SELECT_ITEMS,\n} from './shared/menu';\n\nexport type {\n MenuItem,\n MenuState,\n RenderMenuOptions,\n SimpleMenuItem,\n} from './shared/menu';\n\n// Import game modules\nimport { run2048Game } from './2048';\nimport { runAsteroidsGame } from './asteroids';\nimport { runBreakoutGame } from './breakout';\nimport { runCourierGame } from './chopper';\nimport { runCrackGame } from './crack';\nimport { runFroggerGame } from './frogger';\nimport { runHangmanGame } from './hangman';\nimport { runMinesweeperGame } from './minesweeper';\nimport { runPongGame } from './pong';\nimport { runRunnerGame } from './runner';\nimport { runSimonGame } from './simon';\nimport { runSnakeGame } from './snake';\nimport { runSpaceInvadersGame } from './spaceinvaders';\nimport { runTetrisGame } from './tetris';\nimport { runTowerGame } from './tower';\nimport { runTronGame } from './tron';\nimport { runTypingTest } from './typingtest';\nimport { runWordleGame } from './wordle';\n\n/**\n * Game registry with metadata\n */\nexport interface GameInfo {\n id: string;\n name: string;\n description: string;\n run: (terminal: import('@xterm/xterm').Terminal) => { stop: () => void; isRunning: boolean };\n}\n\nexport const games: GameInfo[] = [\n // Ordered for first-time discovery enjoyment (most accessible first).\n { id: 'tetris', name: 'Tetris', description: 'Stack the blocks', run: runTetrisGame },\n { id: 'snake', name: 'Snake', description: 'Eat and grow', run: runSnakeGame },\n { id: '2048', name: '2048', description: 'Slide and combine tiles', run: run2048Game },\n { id: 'runner', name: 'Runner', description: 'Jump and duck', run: runRunnerGame },\n { id: 'pong', name: 'Pong', description: 'Classic paddle game', run: runPongGame },\n { id: 'wordle', name: 'Wordle', description: 'Guess the word', run: runWordleGame },\n { id: 'minesweeper', name: 'Minesweeper', description: 'Clear the mines', run: runMinesweeperGame },\n { id: 'hangman', name: 'Hangman', description: 'Guess the word', run: runHangmanGame },\n { id: 'spaceinvaders', name: 'Space Invaders', description: 'Defend Earth', run: runSpaceInvadersGame },\n { id: 'tower', name: 'Tower', description: 'Build a tower', run: runTowerGame },\n { id: 'simon', name: 'Simon', description: 'Memory game', run: runSimonGame },\n { id: 'frogger', name: 'Frogger', description: 'Cross the road', run: runFroggerGame },\n { id: 'breakout', name: 'Breakout', description: 'Break all the bricks', run: runBreakoutGame },\n { id: 'asteroids', name: 'Asteroids', description: 'Shoot the rocks', run: runAsteroidsGame },\n { id: 'typingtest', name: 'Typing Test', description: 'Test your speed', run: runTypingTest },\n { id: 'tron', name: 'Tron', description: 'Light cycle battle', run: runTronGame },\n { id: 'crack', name: 'Crack', description: 'Hack the system', run: runCrackGame },\n { id: 'chopper', name: 'Chopper', description: 'Deliver passengers', run: runCourierGame },\n];\n\n/**\n * Get a game by ID\n */\nexport function getGame(id: string): GameInfo | undefined {\n return games.find(g => g.id === id);\n}\n\n/**\n * Get a random game\n */\nexport function getRandomGame(): GameInfo {\n return games[Math.floor(Math.random() * games.length)];\n}\n\n/**\n * Run a game by ID\n */\nexport function runGame(\n id: string,\n terminal: import('@xterm/xterm').Terminal\n): { stop: () => void; isRunning: boolean } | undefined {\n const game = getGame(id);\n return game?.run(terminal);\n}\n\n// Also export individual game runners for direct imports\nexport {\n run2048Game,\n runAsteroidsGame,\n runBreakoutGame,\n runCourierGame,\n runCrackGame,\n runFroggerGame,\n runHangmanGame,\n runMinesweeperGame,\n runPongGame,\n runRunnerGame,\n runSimonGame,\n runSnakeGame,\n runSpaceInvadersGame,\n runTetrisGame,\n runTowerGame,\n runTronGame,\n runTypingTest,\n runWordleGame,\n};\n\n// Re-export games menu\nexport { showGamesMenu } from './gamesMenu';\nexport type { GamesMenuController, GamesMenuOptions } from './gamesMenu';\n\n// Re-export effects\nexport {\n runMatrixEffect,\n startMatrixRain,\n getActiveMatrixController,\n isMatrixWaitingForKey,\n handleMatrixKeypress,\n runHackEffect,\n runRebootEffect,\n} from './effects';\nexport type { MatrixController, HackController, RebootController } from './effects';\n\n// Re-export shared game effects (particles, popups, shake, flash)\nexport {\n spawnParticles,\n spawnFirework,\n spawnSparkleTrail,\n updateParticles,\n addScorePopup,\n updatePopups,\n createShakeState,\n triggerShake,\n applyShake,\n createFlashState,\n triggerFlash,\n updateFlash,\n isFlashVisible,\n MAX_PARTICLES,\n PARTICLE_CHARS,\n FIREWORK_COLORS,\n} from './shared/effects';\nexport type {\n Particle,\n ScorePopup,\n ScreenShakeState,\n FlashState,\n} from './shared/effects';\n","/**\n * CLI entry point for @hypersocial/cli-games\n *\n * Provides a Node.js terminal adapter that maps stdin/stdout\n * to an xterm.js-compatible Terminal interface, allowing all\n * games to run directly in any terminal emulator.\n */\n\n// ---------------------------------------------------------------------------\n// Window polyfill — MUST run before any game code is imported.\n// Games use window.addEventListener('keydown'/'keyup'), window.dispatchEvent,\n// and new CustomEvent.\n// ---------------------------------------------------------------------------\n\ntype EventHandler = (event: Event) => void;\nconst eventListeners = new Map<string, Set<EventHandler>>();\n\nconst windowPolyfill = {\n addEventListener(type: string, handler: EventHandler) {\n if (!eventListeners.has(type)) eventListeners.set(type, new Set());\n eventListeners.get(type)!.add(handler);\n },\n removeEventListener(type: string, handler: EventHandler) {\n eventListeners.get(type)?.delete(handler);\n },\n dispatchEvent(event: Event): boolean {\n const handlers = eventListeners.get(event.type);\n if (handlers) {\n for (const handler of handlers) {\n handler(event);\n }\n }\n return true;\n },\n};\n\nif (typeof globalThis.window === 'undefined') {\n (globalThis as Record<string, unknown>).window = windowPolyfill;\n}\n\n// Now safe to import game code\nimport { games, setTheme, showGamesMenu, type GameInfo, GAME_EVENTS } from './games';\nimport type { PhosphorMode } from './themes';\n\n// ---------------------------------------------------------------------------\n// Node Terminal Adapter\n// ---------------------------------------------------------------------------\n\ninterface KeyEvent {\n key: string;\n domEvent: {\n key: string;\n code: string;\n keyCode: number;\n preventDefault: () => void;\n stopPropagation: () => void;\n };\n}\n\ninterface Disposable {\n dispose: () => void;\n}\n\ninterface NodeTerminal {\n write: (data: string) => void;\n cols: number;\n rows: number;\n element: object;\n onKey: (callback: (event: KeyEvent) => void) => Disposable;\n onData: (callback: (data: string) => void) => Disposable;\n onResize: (callback: (size: { cols: number; rows: number }) => void) => Disposable;\n}\n\n/**\n * Map of key names to approximate keyCodes (for games that check keyCode)\n */\nconst KEY_CODES: Record<string, number> = {\n ArrowUp: 38, ArrowDown: 40, ArrowLeft: 37, ArrowRight: 39,\n Enter: 13, Escape: 27, ' ': 32, Backspace: 8, Tab: 9,\n a: 65, b: 66, c: 67, d: 68, e: 69, f: 70, g: 71, h: 72,\n i: 73, j: 74, k: 75, l: 76, m: 77, n: 78, o: 79, p: 80,\n q: 81, r: 82, s: 83, t: 84, u: 85, v: 86, w: 87, x: 88,\n y: 89, z: 90, '1': 49, '2': 50, '3': 51, '4': 52, '5': 53,\n '6': 54, '7': 55, '8': 56, '9': 57, '0': 48,\n};\n\n/**\n * Parse raw stdin escape sequences into key names\n * compatible with DOM KeyboardEvent.key values\n */\nfunction parseKey(data: string): string {\n if (data === '\\x1b[A' || data === '\\x1bOA') return 'ArrowUp';\n if (data === '\\x1b[B' || data === '\\x1bOB') return 'ArrowDown';\n if (data === '\\x1b[C' || data === '\\x1bOC') return 'ArrowRight';\n if (data === '\\x1b[D' || data === '\\x1bOD') return 'ArrowLeft';\n if (data === '\\r' || data === '\\n') return 'Enter';\n if (data === '\\x1b') return 'Escape';\n if (data === ' ') return ' ';\n if (data === '\\x7f' || data === '\\b') return 'Backspace';\n if (data === '\\t') return 'Tab';\n if (data === '\\x03') return 'c';\n if (data.length === 1) return data;\n return data;\n}\n\nfunction createDomEvent(key: string) {\n const keyCode = KEY_CODES[key] || KEY_CODES[key.toLowerCase()] || 0;\n return {\n key,\n code: key.length === 1 ? `Key${key.toUpperCase()}` : key,\n keyCode,\n which: keyCode,\n preventDefault: () => {},\n stopPropagation: () => {},\n stopImmediatePropagation: () => {},\n // Properties games might check\n ctrlKey: false,\n shiftKey: false,\n altKey: false,\n metaKey: false,\n repeat: false,\n type: 'keydown',\n };\n}\n\n// Track held keys for keyup simulation\nconst heldKeys = new Map<string, ReturnType<typeof setTimeout>>();\n\nfunction createNodeTerminal(): NodeTerminal {\n const keyListeners: ((event: KeyEvent) => void)[] = [];\n const dataListeners: ((data: string) => void)[] = [];\n const resizeListeners: ((size: { cols: number; rows: number }) => void)[] = [];\n\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n }\n process.stdin.resume();\n process.stdin.setEncoding('utf8');\n\n process.stdin.on('data', (data: string) => {\n if (data === '\\x03') {\n cleanup();\n process.exit(0);\n }\n\n const key = parseKey(data);\n const domEvent = createDomEvent(key);\n\n // Dispatch keydown on window (Tetris/Chopper use this)\n // Can't Object.assign onto Event (type is read-only getter), so use a plain object\n const keydownEvent = { ...domEvent, type: 'keydown' } as unknown as Event;\n windowPolyfill.dispatchEvent(keydownEvent);\n\n // Simulate keyup after a short delay (no key-release in raw stdin)\n if (heldKeys.has(key)) {\n clearTimeout(heldKeys.get(key)!);\n }\n heldKeys.set(key, setTimeout(() => {\n const keyupEvent = { ...domEvent, type: 'keyup' } as unknown as Event;\n windowPolyfill.dispatchEvent(keyupEvent);\n heldKeys.delete(key);\n }, 80));\n\n // Fire terminal.onKey listeners\n for (const listener of [...keyListeners]) {\n listener({ key, domEvent });\n }\n\n for (const listener of [...dataListeners]) {\n listener(data);\n }\n });\n\n process.stdout.on('resize', () => {\n const size = { cols: process.stdout.columns || 80, rows: process.stdout.rows || 24 };\n for (const listener of [...resizeListeners]) {\n listener(size);\n }\n });\n\n function cleanup() {\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n process.stdin.pause();\n process.stdout.write('\\x1b[?1049l');\n process.stdout.write('\\x1b[?25h');\n process.stdout.write('\\x1b[0m');\n }\n\n // Synchronized output: wrap writes with DEC sync sequences so the\n // terminal batches clear + redraw into a single atomic paint.\n // Supported by Warp, iTerm2, kitty, foot, WezTerm, etc.\n const SYNC_START = '\\x1b[?2026h';\n const SYNC_END = '\\x1b[?2026l';\n\n const terminal: NodeTerminal = {\n write: (data: string) => {\n process.stdout.write(SYNC_START + data + SYNC_END);\n },\n get cols() { return process.stdout.columns || 80; },\n get rows() { return process.stdout.rows || 24; },\n element: {}, // Truthy for isTerminalValid check\n onKey: (callback: (event: KeyEvent) => void): Disposable => {\n keyListeners.push(callback);\n return {\n dispose: () => {\n const idx = keyListeners.indexOf(callback);\n if (idx !== -1) keyListeners.splice(idx, 1);\n }\n };\n },\n onData: (callback: (data: string) => void): Disposable => {\n dataListeners.push(callback);\n return {\n dispose: () => {\n const idx = dataListeners.indexOf(callback);\n if (idx !== -1) dataListeners.splice(idx, 1);\n }\n };\n },\n onResize: (callback: (size: { cols: number; rows: number }) => void): Disposable => {\n resizeListeners.push(callback);\n return {\n dispose: () => {\n const idx = resizeListeners.indexOf(callback);\n if (idx !== -1) resizeListeners.splice(idx, 1);\n }\n };\n },\n };\n\n process.on('exit', cleanup);\n process.on('SIGINT', () => { cleanup(); process.exit(0); });\n process.on('SIGTERM', () => { cleanup(); process.exit(0); });\n\n return terminal;\n}\n\n// ---------------------------------------------------------------------------\n// Game lifecycle\n// ---------------------------------------------------------------------------\n\nfunction setupGameEvents(terminal: NodeTerminal) {\n // Listen for game quit/switch/menu events dispatched via window\n windowPolyfill.addEventListener(GAME_EVENTS.QUIT, () => {\n setTimeout(() => openMenu(terminal), 100);\n });\n windowPolyfill.addEventListener(GAME_EVENTS.SWITCH, () => {\n // Launch a random game\n const randomGame = games[Math.floor(Math.random() * games.length)];\n setTimeout(() => launchGame(terminal, randomGame), 100);\n });\n windowPolyfill.addEventListener(GAME_EVENTS.GAMES_MENU, () => {\n setTimeout(() => openMenu(terminal), 100);\n });\n windowPolyfill.addEventListener(GAME_EVENTS.LAUNCH_GAME, ((event: CustomEvent) => {\n const gameId = event.detail?.gameId;\n const game = games.find(g => g.id === gameId);\n if (game) {\n setTimeout(() => launchGame(terminal, game), 100);\n }\n }) as EventHandler);\n}\n\nfunction openMenu(terminal: NodeTerminal) {\n // Use the exact same games menu from the library\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n showGamesMenu(terminal as any, {\n onGameSelect: (gameId: string) => {\n const game = games.find(g => g.id === gameId);\n if (game) launchGame(terminal, game);\n },\n onQuit: () => {\n process.exit(0);\n },\n });\n}\n\nfunction launchGame(terminal: NodeTerminal, game: GameInfo) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n game.run(terminal as any);\n}\n\n// ---------------------------------------------------------------------------\n// Main\n// ---------------------------------------------------------------------------\n\nfunction printHelp() {\n console.log(`\n @hypersocial/cli-games — Terminal games\n\n Usage:\n cli-games Interactive game menu\n cli-games <game> Launch a game directly\n cli-games vibe Developer hub (create, vibe code, play, remove, PR)\n cli-games vibe <name> Vibe code a game (creates it if new)\n cli-games remove <name> Remove a game\n cli-games --theme <theme> Set color theme\n cli-games --list List all games\n cli-games --help Show this help\n\n Games:\n ${games.map(g => `${g.id.padEnd(16)} ${g.description}`).join('\\n ')}\n\n Themes:\n cyan (default), amber, green, white, hotpink, blood, ice,\n bladerunner, tron, kawaii, oled, solarized, nord, highcontrast,\n banana, cream — plus Light variants (e.g. cyanLight)\n\n Controls:\n Arrow keys / WASD Move / navigate\n Enter Confirm / select\n ESC Pause menu\n Q Quit\n\n Examples:\n cli-games snake\n cli-games tetris --theme green\n cli-games --theme amber\n`);\n}\n\nfunction main() {\n const args = process.argv.slice(2);\n\n if (args.includes('--help') || args.includes('-h')) {\n printHelp();\n process.exit(0);\n }\n\n if (args.includes('--list') || args.includes('-l')) {\n for (const game of games) {\n console.log(` ${game.id.padEnd(16)} ${game.description}`);\n }\n process.exit(0);\n }\n\n let theme: PhosphorMode = 'cyan';\n const themeIdx = args.indexOf('--theme');\n if (themeIdx !== -1 && args[themeIdx + 1]) {\n theme = args[themeIdx + 1] as PhosphorMode;\n args.splice(themeIdx, 2);\n }\n setTheme(theme);\n\n const terminal = createNodeTerminal();\n setupGameEvents(terminal);\n\n // Direct game launch: cli-games snake\n const gameName = args[0];\n if (gameName) {\n const game = games.find(g => g.id === gameName || g.name.toLowerCase() === gameName.toLowerCase());\n if (!game) {\n console.error(`Unknown game: ${gameName}`);\n console.error(`Available games: ${games.map(g => g.id).join(', ')}`);\n process.exit(1);\n return;\n }\n launchGame(terminal, game);\n return;\n }\n\n openMenu(terminal);\n}\n\n// ---------------------------------------------------------------------------\n// Entry — branch between developer commands and game runtime\n// ---------------------------------------------------------------------------\nconst cliArgs = process.argv.slice(2);\nif (cliArgs[0] === 'vibe' || cliArgs[0] === 'create') {\n import('./create').then(m => m.vibeCommand(cliArgs.slice(1)));\n} else if (cliArgs[0] === 'remove') {\n import('./create').then(m => m.removeCommand(cliArgs.slice(1)));\n} else {\n main();\n}\n"],"mappings":"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,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AACjE;AAMO,SAAS,cAAc,UAAsC;AAClE,QAAM,aAAa,qBAAqB;AAKxC,QAAM,WAAW;AACjB,QAAM,WAAW;AACjB,QAAM,cAAc;AACpB,QAAM,cAAc;AAGpB,QAAM,gBAAgB;AAAA,IACpB,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAAA,IACjD,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAAA,IAC5C,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAAA,EACpC;AAKA,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,qBAAqB;AACzB,MAAI,MAAM;AACV,MAAI,YAAY;AAGhB,MAAI,aAAa;AACjB,MAAI,UAAoB,CAAC;AACzB,MAAI,eAAe;AACnB,MAAI,eAAyC,oBAAI,IAAI;AAGrD,MAAI,QAAoB;AAAA,IACtB,aAAa;AAAA,IACb,UAAU;AAAA,IACV,eAAe;AAAA,IACf,WAAW;AAAA,IACX,mBAAmB,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,EACtC;AAGA,MAAI,OAAO,SAAS;AACpB,MAAI,OAAO,SAAS;AAGpB,MAAI,cAAc;AAClB,MAAI,YAAwB,CAAC;AAC7B,MAAI,cAA4B,CAAC;AACjC,MAAI,cAAc;AAClB,MAAI,iBAAiB;AACrB,MAAI,YAAY;AAChB,MAAI,YAAY;AAChB,MAAI,cAAc;AAClB,MAAI,cAAc;AAKlB,QAAM,aAA+B;AAAA,IACnC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IACZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAKA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAMA,WAASC,gBAAe,GAAW,GAAW,OAAe,OAAe,QAAkB,CAAC,KAAK,KAAK,KAAK,GAAG,GAAG;AAClH,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK,QAAQ,KAAK,OAAO,IAAI;AAC1D,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ,MAAM;AAAA,QACpC,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAASC,eAAc,GAAW,GAAW;AAC3C,UAAM,SAAS,CAAC,cAAc,cAAc,cAAc,YAAY;AACtE,UAAM,QAAQ,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,OAAO,MAAM,CAAC;AAC9D,UAAM,QAAQ,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAC3C,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,YAAM,QAAS,KAAK,KAAK,IAAI,IAAK;AAClC,YAAM,QAAQ,MAAM,KAAK,OAAO,IAAI;AACpC,gBAAU,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,MAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,QACpD;AAAA,QACA,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ,MAAM;AAAA,QACpC,MAAM,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAASC,eAAc,GAAW,GAAW,MAAc,QAAgB,cAAc;AACvF,gBAAY,KAAK,EAAE,GAAG,GAAG,MAAM,QAAQ,IAAI,MAAM,CAAC;AAAA,EACpD;AAEA,WAASC,cAAa,QAAgB,WAAmB;AACvD,kBAAc;AACd,qBAAiB;AAAA,EACnB;AAMA,WAAS,WAAW;AAClB,iBAAaJ,OAAM,KAAK,MAAM,KAAK,OAAO,IAAIA,OAAM,MAAM,CAAC;AAC3D,cAAU,CAAC;AACX,mBAAe;AACf,mBAAe,oBAAI,IAAI;AACvB,eAAW;AACX,UAAM;AACN,aAAS;AACT,gBAAY;AACZ,gBAAY;AACZ,gBAAY;AACZ,kBAAc;AAEd,gBAAY,CAAC;AACb,kBAAc,CAAC;AACf,kBAAc;AACd,kBAAc;AAAA,EAChB;AAEA,WAAS,WAAW,OAA8B;AAChD,UAAM,SAAwB,IAAI,MAAM,WAAW,EAAE,KAAK,QAAQ;AAClE,UAAM,cAAc,WAAW,MAAM,EAAE;AACvC,UAAM,aAAa,MAAM,MAAM,EAAE;AACjC,UAAM,OAAO,IAAI,MAAM,WAAW,EAAE,KAAK,KAAK;AAG9C,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,UAAI,WAAW,CAAC,MAAM,YAAY,CAAC,GAAG;AACpC,eAAO,CAAC,IAAI;AACZ,aAAK,CAAC,IAAI;AAAA,MACZ;AAAA,IACF;AAGA,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,UAAI,OAAO,CAAC,MAAM,UAAW;AAC7B,YAAM,MAAM,YAAY,UAAU,CAAC,GAAG,MAAM,MAAM,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC3E,UAAI,QAAQ,IAAI;AACd,eAAO,CAAC,IAAI;AACZ,aAAK,GAAG,IAAI;AAAA,MACd;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,mBAAmB,OAAe,QAAuB;AAChE,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,YAAM,SAAS,MAAM,CAAC;AACtB,YAAM,eAAe,aAAa,IAAI,MAAM;AAC5C,YAAM,WAAW,OAAO,CAAC;AAGzB,UAAI,CAAC,gBAAgB,iBAAiB,UAAU;AAC9C,qBAAa,IAAI,QAAQ,QAAQ;AAAA,MACnC,WAAW,iBAAiB,aAAa,aAAa,aAAa,aAAa,YAAY;AAC1F,qBAAa,IAAI,QAAQ,QAAQ;AAAA,MACnC,WAAW,iBAAiB,aAAa,aAAa,WAAW;AAC/D,qBAAa,IAAI,QAAQ,QAAQ;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAEA,WAAS,cAAc;AACrB,QAAI,aAAa,WAAW,aAAa;AACvC,MAAAI,cAAa,GAAG,CAAC;AACjB,MAAAD,eAAc,KAAK,MAAM,OAAO,CAAC,GAAG,GAAG,sBAAsB,YAAY;AACzE;AAAA,IACF;AAEA,UAAM,SAAS,WAAW,YAAY;AACtC,YAAQ,KAAK,YAAY;AACzB,uBAAmB,cAAc,MAAM;AAGvC,gBAAY,QAAQ,SAAS;AAC7B,gBAAY;AACZ,kBAAc;AAEd,UAAM,aAAa,OAAO,MAAM,OAAK,MAAM,SAAS;AACpD,UAAM,eAAe,OAAO,OAAO,OAAK,MAAM,SAAS,EAAE;AACzD,UAAM,eAAe,OAAO,OAAO,OAAK,MAAM,SAAS,EAAE;AAEzD,UAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,UAAM,SAAS,IAAI,QAAQ,SAAS;AAEpC,QAAI,YAAY;AACd,YAAM;AACN,iBAAW;AACX,YAAM;AACN,YAAM;AACN,YAAM;AACN,UAAI,MAAM,gBAAgB,MAAM,WAAW;AACzC,cAAM,YAAY,MAAM;AAAA,MAC1B;AACA,YAAM,kBAAkB,QAAQ,SAAS,CAAC;AAG1C,oBAAc;AACd,MAAAC,cAAa,IAAI,CAAC;AAElB,YAAM,WAAW,CAAC,oBAAoB,iBAAiB,cAAc,YAAY;AACjF,MAAAD,eAAc,SAAS,SAAS,GAAG,SAAS,KAAK,MAAM,KAAK,OAAO,IAAI,SAAS,MAAM,CAAC,GAAG,YAAY;AAGtG,iBAAW,MAAM;AACf,YAAI,SAAS;AACX,mBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,uBAAW,MAAM;AACf,kBAAI,WAAW,KAAK;AAClB,gBAAAD;AAAA,kBACE,KAAK,KAAK,OAAO,KAAK,OAAO;AAAA,kBAC7B,IAAI,KAAK,OAAO,IAAI;AAAA,gBACtB;AAAA,cACF;AAAA,YACF,GAAG,IAAI,GAAG;AAAA,UACZ;AAAA,QACF;AAAA,MACF,GAAG,GAAG;AAAA,IACR,WAAW,QAAQ,UAAU,aAAa;AACxC,iBAAW;AACX,YAAM;AACN,YAAM,gBAAgB;AAEtB,MAAAE,cAAa,GAAG,CAAC;AACjB,oBAAc;AACd,MAAAD,eAAc,SAAS,SAAS,GAAG,qBAAqB,YAAY;AACpE,MAAAF,gBAAe,SAAS,QAAQ,IAAI,cAAc,CAAC,KAAK,KAAK,KAAK,GAAG,CAAC;AAAA,IACxE,OAAO;AAEL,UAAI,eAAe,KAAK,eAAe,GAAG;AACxC,cAAM,OAAO,eAAe,IAAI,GAAG,YAAY,WAAW,GAAG,YAAY;AACzE,QAAAE,eAAc,SAAS,SAAS,GAAG,MAAM,eAAe,IAAI,eAAe,YAAY;AACvF,QAAAF,gBAAe,SAAS,QAAQ,IAAI,eAAe,GAAG,eAAe,IAAI,eAAe,YAAY;AAAA,MACtG;AAAA,IACF;AAEA,mBAAe;AAAA,EACjB;AAEA,WAAS,SAAS;AAChB,QAAI,CAAC,eAAe,UAAU,UAAW;AAGzC,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAM,IAAI,UAAU,CAAC;AACrB,QAAE,KAAK,EAAE;AACT,QAAE,KAAK,EAAE;AACT,QAAE,MAAM;AACR,QAAE;AACF,UAAI,EAAE,QAAQ,EAAG,WAAU,OAAO,GAAG,CAAC;AAAA,IACxC;AAGA,aAAS,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAM,QAAQ,YAAY,CAAC;AAC3B,YAAM,KAAK;AACX,YAAM;AACN,UAAI,MAAM,UAAU,EAAG,aAAY,OAAO,GAAG,CAAC;AAAA,IAChD;AAGA,QAAI,aAAa,KAAK,YAAY,aAAa;AAC7C;AACA,UAAI,eAAe,GAAG;AACpB;AACA,sBAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAMA,WAAS,eAAe,OAA4B;AAClD,YAAQ,OAAO;AAAA,MACb,KAAK;AAAW,eAAO;AAAA;AAAA,MACvB,KAAK;AAAW,eAAO;AAAA;AAAA,MACvB,KAAK;AAAU,eAAO;AAAA;AAAA,MACtB;AAAS,eAAO;AAAA,IAClB;AAAA,EACF;AAEA,WAAS,qBAAqB,OAA4B;AACxD,YAAQ,OAAO;AAAA,MACb,KAAK;AAAW,eAAO;AAAA,MACvB,KAAK;AAAW,eAAO;AAAA,MACvB,KAAK;AAAU,eAAO;AAAA,MACtB;AAAS,eAAO;AAAA,IAClB;AAAA,EACF;AAEA,WAAS,SAAS;AAChB,QAAI,SAAS;AACb,cAAU;AAGV,WAAO,SAAS;AAChB,WAAO,SAAS;AAGhB,QAAI,cAAc,EAAG;AACrB,QAAI,cAAc,EAAG;AAGrB,QAAI,OAAO,YAAY,OAAO,UAAU;AACtC,YAAM,OAAO;AACb,YAAM,YAAY,OAAO;AACzB,YAAM,aAAa,OAAO;AAC1B,UAAI,OAAO,aAAa,aAAa,qBACjC,YAAY,oBAAoB;AACpC,YAAM,OAAO,SAAS,QAAQ,IAAI,QAAQ,WAAW,IAAI,IAAI,IAAI;AACjE,YAAMI,WAAU,KAAK,MAAM,OAAO,CAAC;AACnC,YAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AACnC,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAGA,WAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,GAAG,IAAI;AACxG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAGA,WAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI;AAClG,gBAAU,QAAQ,UAAU,CAAC,IAAI,KAAK,IAAI,GAAGA,WAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,UAAU,GAAG,IAAI;AAC/G,eAAS,MAAM,MAAM;AACrB;AAAA,IACF;AAGA,QAAI,SAAS,GAAG,SAAS;AACzB,QAAI,cAAc,GAAG;AACnB,eAAS,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,iBAAiB,CAAC;AAC9D,eAAS,KAAK,OAAO,KAAK,OAAO,IAAI,OAAO,cAAc;AAAA,IAC5D;AAEA,UAAM,UAAU,KAAK,MAAM,OAAO,CAAC;AAGnC,mBAAe,cAAc,KAAK;AAClC,UAAM,eAAe,eAAe,KAAK,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI;AAC7E,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI,eAAe;AAEzE,QAAI,aAAa;AACjB,QAAI,cAAc,KAAK,cAAc,IAAI,GAAG;AAC1C,mBAAa,MAAM,eAAe;AAAA,IACpC;AAEA,QAAI,eAAe,MAAM,cAAc,IAAI;AACzC,gBAAU,UAAU,KAAK,IAAI,GAAG,MAAM,CAAC,YAAY,MAAM,CAAC,CAAC;AAC3D,gBAAU,UAAU,KAAK,IAAI,GAAG,SAAS,CAAC,CAAC,YAAY,MAAM,CAAC,CAAC;AAAA,IACjE,OAAO;AACL,gBAAU,UAAU,KAAK,IAAI,GAAG,MAAM,CAAC,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AACvE,gBAAU,UAAU,KAAK,IAAI,GAAG,MAAM,CAAC,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,IACzE;AAGA,QAAI,QAAQ;AACV,YAAM,WAAW;AACjB,YAAM,SAAS;AACf,YAAM,YAAY,UAAU,KAAK,MAAM,SAAS,SAAS,CAAC;AAC1D,gBAAU,QAAQ,MAAM,IAAI,SAAS,WAAW,UAAU,GAAG,QAAQ;AAErE,gBAAU,iBAAiB,kBAAkB,oBAAoB;AAAA,QAC/D;AAAA,QACA,QAAQ,SAAS;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,UAAU;AAChB,YAAM,WAAW,UAAU,KAAK,MAAM,QAAQ,SAAS,CAAC;AACxD,gBAAU,QAAQ,SAAS,CAAC,IAAI,QAAQ,WAAW,UAAU,GAAG,OAAO;AAAA,IACzE,WAES,WAAW;AAClB,YAAM,SAAS;AACf,YAAM,WAAW;AACjB,YAAM,OAAO,UAAU,KAAK,MAAM,WAAW,CAAC;AAE9C,gBAAU,QAAQ,MAAM,IAAI,IAAI,IAAI,UAAU,IAAI,IAAI,OAAO,WAAW,CAAC,CAAC;AAC1E,gBAAU,QAAQ,SAAS,CAAC,IAAI,IAAI,IAAI,UAAU;AAClD,gBAAU,QAAQ,SAAS,CAAC,IAAI,IAAI,IAAI,UAAU,IAAI,IAAI,OAAO,WAAW,CAAC,CAAC;AAE9E,YAAM,SAAS,MAAM,cAAc,IAAI,KAAK,MAAO,MAAM,WAAW,MAAM,cAAe,GAAG,IAAI;AAEhG,gBAAU,QAAQ,SAAS,CAAC,IAAI,OAAO,CAAC,IAAI,UAAU,kBAAkB,MAAM,WAAW;AACzF,gBAAU,QAAQ,SAAS,CAAC,IAAI,OAAO,CAAC,IAAI,UAAU,kBAAkB,MAAM;AAC9E,gBAAU,QAAQ,SAAS,CAAC,IAAI,OAAO,CAAC,IAAI,UAAU,mBAAmB,MAAM,aAAa;AAC5F,gBAAU,QAAQ,SAAS,CAAC,IAAI,OAAO,CAAC,IAAI,UAAU,kBAAkB,MAAM,SAAS;AAEvF,gBAAU,QAAQ,SAAS,CAAC,IAAI,OAAO,CAAC,IAAI,UAAU;AAEtD,YAAM,UAAU,KAAK,IAAI,GAAG,MAAM,mBAAmB,CAAC;AACtD,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,cAAM,QAAQ,MAAM,kBAAkB,CAAC;AACvC,cAAM,SAAS,KAAK,MAAO,QAAQ,UAAW,EAAE;AAChD,cAAM,MAAM,IAAI,OAAO,KAAK,IAAI,QAAQ,QAAQ,IAAI,IAAI,CAAC,CAAC;AAC1D,cAAM,WAAW,MAAM,QAAQ,SAAS,KAAK,MAAM,eAAe;AAClE,kBAAU,QAAQ,SAAS,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,UAAU,GAAG,IAAI,CAAC,KAAK,QAAQ,GAAG,GAAG,WAAW,KAAK;AAAA,MACxG;AAEA,gBAAU,QAAQ,SAAS,EAAE,IAAI,IAAI,IAAI,UAAU,IAAI,IAAI,OAAO,WAAW,CAAC,CAAC;AAE/E,YAAM,OAAO;AACb,gBAAU,QAAQ,SAAS,EAAE,IAAI,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,WAAW,UAAU,GAAG,IAAI;AAAA,IACpG,WAES,CAAC,aAAa;AACrB,YAAM,WAAW;AACjB,YAAM,SAAS,KAAK,MAAM,OAAO,CAAC,IAAI;AACtC,YAAM,SAAS,UAAU,KAAK,MAAM,SAAS,SAAS,CAAC;AACvD,gBAAU,QAAQ,MAAM,IAAI,MAAM,WAAW,UAAU,GAAG,QAAQ;AAElE,YAAM,QAAQ;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,cAAM,QAAQ,UAAU;AACxB,kBAAU,QAAQ,SAAS,IAAI,CAAC,IAAI,KAAK,IAAI,MAAM,CAAC,CAAC;AAAA,MACvD;AAEA,YAAM,WAAW;AACjB,gBAAU,QAAQ,OAAO,CAAC,IAAI,UAAU,KAAK,MAAM,SAAS,SAAS,CAAC,CAAC,WAAW,UAAU,GAAG,QAAQ;AAAA,IACzG,OAEK;AACH,YAAM,QAAQ,IAAI;AAClB,YAAM,QAAQ,UAAU,IAAI;AAG5B,eAAS,MAAM,GAAG,MAAM,aAAa,OAAO;AAC1C,cAAM,IAAI,QAAQ,MAAM;AAExB,iBAAS,MAAM,GAAG,MAAM,aAAa,OAAO;AAC1C,gBAAM,IAAI,QAAQ,MAAM;AAExB,cAAI,SAAS;AACb,cAAI,QAAqB;AACzB,cAAI,cAAc;AAElB,cAAI,MAAM,QAAQ,QAAQ;AACxB,qBAAS,QAAQ,GAAG,EAAE,GAAG;AACzB,kBAAM,SAAS,WAAW,QAAQ,GAAG,CAAC;AAGtC,gBAAI,QAAQ,aAAa,OAAO,WAAW;AACzC,sBAAQ,OAAO,GAAG;AAAA,YACpB,WAAW,QAAQ,WAAW;AAC5B,4BAAc;AAAA,YAChB,OAAO;AACL,sBAAQ,OAAO,GAAG;AAAA,YACpB;AAAA,UACF,WAAW,QAAQ,QAAQ,UAAU,MAAM,aAAa,QAAQ;AAC9D,qBAAS,aAAa,GAAG;AAAA,UAC3B;AAGA,gBAAM,YAAY,qBAAqB,KAAK;AAC5C,gBAAM,UAAU,eAAe,KAAK;AAEpC,cAAI,aAAa;AAEf,sBAAU,QAAQ,CAAC,IAAI,CAAC,IAAI,UAAU;AAAA,UACxC,WAAW,WAAW,KAAK;AACzB,sBAAU,QAAQ,CAAC,IAAI,CAAC,IAAI,SAAS,WAAW,OAAO,IAAI,MAAM,WAAW,SAAS;AAAA,UACvF,OAAO;AACL,sBAAU,QAAQ,CAAC,IAAI,CAAC,IAAI,UAAU;AAAA,UACxC;AAAA,QACF;AAAA,MACF;AAGA,YAAM,MAAM,QAAQ,cAAc,IAAI;AAEtC,eAAS,SAAS,GAAG,SAAS,cAAc,QAAQ,UAAU;AAC5D,cAAM,QAAQ,cAAc,MAAM;AAClC,cAAM,YAAY,WAAW,IAAI,IAAI,WAAW,IAAI,IAAI;AACxD,cAAM,OAAO,UAAU,KAAK,MAAM,MAAM,SAAS,IAAI,CAAC,IAAI,YAAY;AAEtE,iBAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,gBAAM,MAAM,MAAM,CAAC;AACnB,gBAAM,QAAQ,aAAa,IAAI,GAAG,KAAK;AACvC,gBAAM,WAAW,eAAe,KAAK;AAErC,oBAAU,QAAQ,MAAM,MAAM,IAAI,OAAO,IAAI,CAAC,IAAI,QAAQ,GAAG,GAAG;AAAA,QAClE;AAAA,MACF;AAGA,UAAI,UAAU;AACZ,cAAM,QAAQ,MAAM;AAEpB,YAAI,KAAK;AACP,gBAAM,SAAS;AACf,oBAAU,QAAQ,KAAK,IAAI,UAAU,KAAK,MAAM,OAAO,SAAS,CAAC,CAAC,cAAc,MAAM;AAAA,QACxF,OAAO;AACL,gBAAM,UAAU;AAChB,oBAAU,QAAQ,KAAK,IAAI,UAAU,KAAK,MAAM,QAAQ,SAAS,CAAC,CAAC,cAAc,OAAO;AACxF,gBAAM,UAAU,mBAAmB,UAAU;AAC7C,oBAAU,QAAQ,QAAQ,CAAC,IAAI,UAAU,KAAK,MAAM,QAAQ,SAAS,CAAC,CAAC,IAAI,UAAU,GAAG,OAAO;AAAA,QACjG;AAEA,cAAM,cAAc;AACpB,kBAAU,QAAQ,QAAQ,CAAC,IAAI,UAAU,KAAK,MAAM,YAAY,SAAS,CAAC,CAAC,WAAW,UAAU,GAAG,WAAW;AAAA,MAChH;AAGA,iBAAW,KAAK,WAAW;AACzB,cAAM,KAAK,KAAK,MAAM,EAAE,CAAC;AACzB,cAAM,KAAK,KAAK,MAAM,EAAE,CAAC;AACzB,YAAI,KAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,KAAK,MAAM;AAC9C,gBAAM,QAAQ,EAAE,OAAO,IAAI,KAAK;AAChC,oBAAU,QAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,IAAI;AAAA,QACxD;AAAA,MACF;AAGA,iBAAW,SAAS,aAAa;AAC/B,cAAM,KAAK,KAAK,MAAM,MAAM,IAAI,MAAM,KAAK,SAAS,CAAC;AACrD,cAAM,KAAK,KAAK,MAAM,MAAM,CAAC;AAC7B,YAAI,KAAK,KAAK,KAAK,QAAQ,KAAK,GAAG;AACjC,gBAAM,QAAQ,MAAM,SAAS,KAAK,YAAY;AAC9C,oBAAU,QAAQ,EAAE,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC,IAAI,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM,IAAI;AAAA,QAC7E;AAAA,MACF;AAGA,UAAI,CAAC,UAAU;AACb,cAAM,OAAO,WAAW,QAAQ,SAAS,CAAC,IAAI,WAAW;AACzD,kBAAU,QAAQ,OAAO,CAAC,IAAI,UAAU,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC,WAAW,UAAU,GAAG,IAAI;AAAA,MACjG;AAAA,IACF;AAGA,QAAI,cAAc,GAAG;AACnB,YAAM,aAAa,MAAM,aAAa;AACtC,YAAM,YAAY,cAAc,IAAI,IAAI,MAAM;AAC9C,eAAS,IAAI,GAAG,KAAK,MAAM,KAAK,GAAG;AACjC,kBAAU,UAAU,CAAC,IAAI,UAAU,GAAG,SAAS;AAC/C,kBAAU,QAAQ,IAAI,IAAI,CAAC,IAAI,UAAU,GAAG,SAAS;AAAA,MACvD;AAAA,IACF;AAEA,aAAS,MAAM,MAAM;AAAA,EACvB;AAMA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,aAAS,MAAM,aAAa;AAC5B,aAAS,MAAM,WAAW;AAE1B,aAAS;AACT,kBAAc;AAEd,UAAM,iBAAiB,YAAY,MAAM;AACvC,UAAI,CAAC,SAAS;AAAE,sBAAc,cAAc;AAAG;AAAA,MAAQ;AACvD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,eAAe,YAAY,MAAM;AACrC,UAAI,CAAC,SAAS;AAAE,sBAAc,YAAY;AAAG;AAAA,MAAQ;AACrD,aAAO;AAAA,IACT,GAAG,EAAE;AAEL,UAAM,cAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AACnD,UAAI,CAAC,SAAS;AAAE,oBAAY,QAAQ;AAAG;AAAA,MAAQ;AAE/C,eAAS,eAAe;AACxB,eAAS,gBAAgB;AAEzB,YAAM,MAAM,SAAS;AACrB,YAAM,WAAW,IAAI,YAAY;AAGjC,UAAI,QAAQ,UAAU;AACpB,YAAI,WAAW;AACb,sBAAY;AAAA,QACd,OAAO;AACL,mBAAS,CAAC;AACV,cAAI,OAAQ,sBAAqB;AAAA,QACnC;AACA;AAAA,MACF;AAGA,UAAI,WAAW;AACb,YAAI,QAAQ,SAAS;AACnB,mBAAS;AACT,wBAAc;AACd,sBAAY;AAAA,QACd;AACA;AAAA,MACF;AAGA,UAAI,CAAC,eAAe,CAAC,QAAQ;AAC3B,sBAAc;AACd;AAAA,MACF;AAGA,UAAI,YAAY,CAAC,WAAW;AAC1B,YAAI,aAAa,KAAK;AACpB,mBAAS;AACT,wBAAc;AAAA,QAChB,WAAW,QAAQ,SAAS;AAC1B,sBAAY;AAAA,QACd;AACA;AAAA,MACF;AAGA,UAAI,QAAQ;AACV,cAAM,EAAE,cAAc,UAAU,IAAI;AAAA,UAClC;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AAEA,YAAI,iBAAiB,oBAAoB;AACvC,+BAAqB;AACrB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,kBAAQ,oBAAoB;AAAA,YAC1B,KAAK;AAAG,uBAAS;AAAO;AAAA,YACxB,KAAK;AAAG,uBAAS;AAAG,4BAAc;AAAM,uBAAS;AAAO;AAAA,YACxD,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,yBAAW,KAAK;AAChB,+BAAiB,QAAQ;AACzB;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,gCAAkB,QAAQ;AAC1B;AAAA,YACF,KAAK;AACH,4BAAc,cAAc;AAC5B,4BAAc,YAAY;AAC1B,wBAAU;AACV,iCAAmB,QAAQ;AAC3B;AAAA,UACJ;AACA;AAAA,QACF;AAGA,YAAI,aAAa,KAAK;AAAE,mBAAS;AAAG,wBAAc;AAAM,mBAAS;AAAA,QAAO,WAC/D,aAAa,KAAK;AAAE,wBAAc,cAAc;AAAG,wBAAc,YAAY;AAAG,oBAAU;AAAO,4BAAkB,QAAQ;AAAA,QAAG,WAC9H,aAAa,KAAK;AAAE,wBAAc,cAAc;AAAG,wBAAc,YAAY;AAAG,oBAAU;AAAO,6BAAmB,QAAQ;AAAA,QAAG;AACxI;AAAA,MACF;AAGA,UAAI,QAAQ,aAAa;AACvB,uBAAe,aAAa,MAAM,GAAG,EAAE;AAAA,MACzC,WAAW,QAAQ,SAAS;AAC1B,oBAAY;AAAA,MACd,WAAW,IAAI,WAAW,KAAK,WAAW,KAAK,GAAG,KAAK,aAAa,SAAS,aAAa;AACxF,wBAAgB,IAAI,YAAY;AAEhC,QAAAJ;AAAA,UACE,KAAK,MAAM,OAAO,CAAC,IAAI,IAAI,aAAa,SAAS;AAAA,UACjD,IAAI,QAAQ,SAAS;AAAA,UACrB;AAAA,UACA;AAAA,UACA,CAAC,KAAK,GAAG;AAAA,QACX;AAAA,MACF;AAAA,IACF,CAAC;AAGD,UAAM,eAAe,WAAW;AAChC,eAAW,OAAO,MAAM;AACtB,oBAAc,cAAc;AAC5B,oBAAc,YAAY;AAC1B,kBAAY,QAAQ;AACpB,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;AC9xBO,SAAS,cAAc,UAAoB,mBAAwF;AAExI,QAAM,UAA4B,OAAO,sBAAsB,aAC3D,EAAE,cAAc,kBAAkB,IAClC,qBAAqB,CAAC;AAC1B,QAAM,EAAE,cAAc,OAAO,IAAI;AACjC,QAAM,aAAa,qBAAqB;AACxC,QAAM,aAAaK,cAAa;AAEhC,MAAI,UAAU;AACd,MAAI,gBAAgB;AACpB,MAAI,eAAe;AAEnB,QAAM,aAAkC;AAAA,IACtC,MAAM,MAAM;AACV,UAAI,CAAC,QAAS;AACd,gBAAU;AAAA,IACZ;AAAA,IACA,IAAI,YAAY;AAAE,aAAO;AAAA,IAAS;AAAA,EACpC;AAEA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAEA,WAAS,SAAe;AACtB,QAAI,SAAS;AACb,cAAU;AAEV,UAAM,OAAO,SAAS;AACtB,UAAM,OAAO,SAAS;AAGtB,UAAM,SAAS,KAAK,OAAO,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC;AACtD,cAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAC1D,cAAU,UAAU,MAAM,IAAI,UAAU,UAAU,MAAM,CAAC,CAAC;AAG1D,UAAM,WAAW,0BAA0B,MAAM,MAAM;AACvD,cAAU,UAAU,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC,CAAC,WAAW,QAAQ;AAG/E,UAAM,WAAW;AACjB,UAAM,YAAY;AAClB,UAAM,iBAAiB,WAAW,IAAI;AACtC,UAAM,gBAAgB,QAAQ,iBAAiB;AAE/C,UAAM,aAAa;AACnB,UAAM,gBAAgB,OAAO,aAAa;AAC1C,UAAM,kBAAkB,KAAK,IAAI,GAAG,KAAK,MAAM,gBAAgB,CAAC,CAAC;AAEjE,QAAI,eAAe;AACjB,uBAAiB,QAAQ,MAAM,MAAM,UAAU,WAAW,YAAY,eAAe;AAAA,IACvF,OAAO;AACL,yBAAmB,QAAQ,MAAM,MAAM,UAAU,YAAY,eAAe;AAAA,IAC9E;AAAA,EACF;AAEA,WAAS,mBACP,YACA,MACA,MACA,UACA,YACA,iBACM;AACN,QAAI,SAAS;AACb,UAAM,OAAO,KAAK,OAAO,OAAO,YAAY,CAAC;AAC7C,UAAM,eAAe,KAAK,IAAI,iBAAiB,MAAM,MAAM;AAG3D,QAAI,gBAAgB,cAAc;AAChC,qBAAe;AAAA,IACjB,WAAW,iBAAiB,eAAe,cAAc;AACvD,qBAAe,gBAAgB,eAAe;AAAA,IAChD;AACA,mBAAe,KAAK,IAAI,GAAG,KAAK,IAAI,cAAc,MAAM,SAAS,YAAY,CAAC;AAE9E,UAAM,cAAc,eAAe;AACnC,UAAM,gBAAgB,eAAe,eAAe,MAAM;AAG1D,UAAM,qBAAqB,cAAc,kBAAkB,SAAS,OAAO,CAAC;AAC5E,UAAM,iBAAiB,WAAW,IAAI,mBAAmB;AACzD,UAAM,aAAa,KAAK,MAAM,iBAAiB,CAAC;AAChD,UAAM,cAAc,iBAAiB;AACrC,cAAU,QAAQ,UAAU,IAAI,IAAI,IAAI,UAAU,SAAS,SAAS,OAAO,UAAU,CAAC,GAAG,cAAc,aAAa,EAAE,GAAG,kBAAkB,GAAG,cAAc,aAAa,EAAE,GAAG,SAAS,OAAO,WAAW,CAAC;AAG1M,aAAS,KAAK,GAAG,KAAK,cAAc,MAAM;AACxC,YAAM,IAAI,eAAe;AACzB,YAAM,OAAO,MAAM,CAAC;AACpB,YAAM,IAAI,aAAa,IAAI,KAAK;AAChC,YAAM,aAAa,MAAM;AAEzB,gBAAU,gBAAgB,MAAM,GAAG,YAAY,GAAG,MAAM,QAAQ;AAAA,IAClE;AAGA,UAAM,UAAU,aAAa,IAAI,eAAe;AAChD,UAAM,wBAAwB,gBAAgB,kBAAkB,SAAS,OAAO,CAAC;AACjF,UAAM,oBAAoB,WAAW,IAAI,sBAAsB;AAC/D,UAAM,gBAAgB,KAAK,MAAM,oBAAoB,CAAC;AACtD,UAAM,iBAAiB,oBAAoB;AAC3C,cAAU,QAAQ,OAAO,IAAI,IAAI,IAAI,UAAU,SAAS,SAAS,OAAO,aAAa,CAAC,GAAG,gBAAgB,aAAa,EAAE,GAAG,qBAAqB,GAAG,gBAAgB,aAAa,EAAE,GAAG,SAAS,OAAO,cAAc,CAAC;AAGpN,UAAM,WAAW;AACjB,cAAU,QAAQ,OAAO,CAAC,IAAI,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC,CAAC,WAAW,QAAQ;AAEzF,aAAS,MAAM,MAAM;AAAA,EACvB;AAEA,WAAS,iBACP,YACA,MACA,MACA,UACA,WACA,YACA,iBACM;AACN,QAAI,SAAS;AAGb,UAAM,iBAAiB,KAAK,IAAI,iBAAiB,KAAK,KAAK,MAAM,SAAS,CAAC,CAAC;AAG5E,UAAM,cAAc,KAAK,MAAM,gBAAgB,CAAC;AAChD,QAAI,cAAc,cAAc;AAC9B,qBAAe;AAAA,IACjB,WAAW,eAAe,eAAe,gBAAgB;AACvD,qBAAe,cAAc,iBAAiB;AAAA,IAChD;AACA,UAAM,YAAY,KAAK,IAAI,GAAG,KAAK,KAAK,MAAM,SAAS,CAAC,IAAI,cAAc;AAC1E,mBAAe,KAAK,IAAI,GAAG,KAAK,IAAI,cAAc,SAAS,CAAC;AAE5D,UAAM,cAAc,eAAe;AACnC,UAAM,iBAAiB,eAAe,kBAAkB,IAAI,MAAM;AAGlE,UAAM,aAAa,WAAW,IAAI;AAClC,UAAM,SAAS,KAAK,OAAO,OAAO,cAAc,CAAC;AACjD,UAAM,WAAW;AACjB,UAAM,YAAY,SAAS,WAAW;AAGtC,UAAM,qBAAqB,cAAc,aAAa;AACtD,UAAM,mBAAmB,WAAW,IAAI,mBAAmB;AAC3D,UAAM,UAAU,KAAK,MAAM,mBAAmB,CAAC;AAC/C,UAAM,WAAW,mBAAmB;AAEpC,cAAU,QAAQ,UAAU,IAAI,QAAQ,IAAI,UAAU,SAAS,SAAS,OAAO,OAAO,CAAC,GAAG,cAAc,aAAa,EAAE,GAAG,kBAAkB,GAAG,cAAc,aAAa,EAAE,GAAG,SAAS,OAAO,QAAQ,CAAC;AACxM,cAAU,QAAQ,UAAU,IAAI,SAAS,IAAI,UAAU,SAAS,SAAS,OAAO,OAAO,CAAC,GAAG,cAAc,aAAa,EAAE,GAAG,kBAAkB,GAAG,cAAc,aAAa,EAAE,GAAG,SAAS,OAAO,QAAQ,CAAC;AAGzM,aAAS,MAAM,GAAG,MAAM,gBAAgB,OAAO;AAC7C,YAAM,WAAW,eAAe,OAAO;AACvC,YAAM,WAAW,UAAU;AAC3B,YAAM,IAAI,aAAa,IAAI,MAAM;AAGjC,UAAI,UAAU,MAAM,QAAQ;AAC1B,kBAAU,gBAAgB,MAAM,OAAO,GAAG,SAAS,YAAY,eAAe,GAAG,UAAU,QAAQ;AAAA,MACrG,OAAO;AAEL,kBAAU,QAAQ,CAAC,IAAI,QAAQ,IAAI,UAAU,SAAS,IAAI,OAAO,WAAW,CAAC,CAAC;AAC9E,kBAAU,QAAQ,IAAI,CAAC,IAAI,QAAQ,IAAI,UAAU,SAAS,IAAI,OAAO,WAAW,CAAC,CAAC;AAAA,MACpF;AAGA,UAAI,WAAW,MAAM,QAAQ;AAC3B,kBAAU,gBAAgB,MAAM,QAAQ,GAAG,UAAU,aAAa,eAAe,GAAG,WAAW,QAAQ;AAAA,MACzG,OAAO;AAEL,kBAAU,QAAQ,CAAC,IAAI,SAAS,IAAI,UAAU,SAAS,IAAI,OAAO,WAAW,CAAC,CAAC;AAC/E,kBAAU,QAAQ,IAAI,CAAC,IAAI,SAAS,IAAI,UAAU,SAAS,IAAI,OAAO,WAAW,CAAC,CAAC;AAAA,MACrF;AAAA,IACF;AAGA,UAAM,UAAU,aAAa,IAAI,iBAAiB;AAClD,UAAM,wBAAwB,gBAAgB,aAAa;AAC3D,UAAM,sBAAsB,WAAW,IAAI,sBAAsB;AACjE,UAAM,aAAa,KAAK,MAAM,sBAAsB,CAAC;AACrD,UAAM,cAAc,sBAAsB;AAE1C,cAAU,QAAQ,OAAO,IAAI,QAAQ,IAAI,UAAU,SAAS,SAAS,OAAO,UAAU,CAAC,GAAG,gBAAgB,aAAa,EAAE,GAAG,qBAAqB,GAAG,gBAAgB,aAAa,EAAE,GAAG,SAAS,OAAO,WAAW,CAAC;AAClN,cAAU,QAAQ,OAAO,IAAI,SAAS,IAAI,UAAU,SAAS,SAAS,OAAO,UAAU,CAAC,GAAG,gBAAgB,aAAa,EAAE,GAAG,qBAAqB,GAAG,gBAAgB,aAAa,EAAE,GAAG,SAAS,OAAO,WAAW,CAAC;AAGnN,UAAM,WAAW;AACjB,cAAU,QAAQ,OAAO,CAAC,IAAI,KAAK,OAAO,OAAO,SAAS,UAAU,CAAC,CAAC,WAAW,QAAQ;AAEzF,aAAS,MAAM,MAAM;AAAA,EACvB;AAEA,WAAS,gBACP,MACA,OACA,YACA,GACA,MACA,UACQ;AACR,QAAI,SAAS;AACb,UAAM,eAAe,WAAW;AAEhC,UAAM,SAAS,aAAa,WAAW;AACvC,UAAM,YAAY,aAAc,aAAa,iBAAiB,cAAe;AAC7E,UAAM,WAAW,aAAa,KAAK;AACnC,UAAM,SAAS,QAAQ;AACvB,UAAM,aAAa,UAAU,IAAI,GAAG,MAAM,KAAK;AAG/C,UAAM,cAAc,GAAG,MAAM,KAAK,UAAU,KAAK,KAAK,IAAI;AAC1D,UAAM,UAAU,KAAK,IAAI,GAAG,eAAe,YAAY,MAAM;AAE7D,cAAU,QAAQ,CAAC,IAAI,IAAI,IAAI,UAAU,gBAAgB,SAAS,GAAG,QAAQ,GAAG,WAAW,GAAG,IAAI,OAAO,OAAO,CAAC,UAAU,UAAU;AAGrI,UAAM,cAAc,OAAO,KAAK,WAAW;AAC3C,UAAM,cAAc,KAAK,IAAI,GAAG,eAAe,YAAY,MAAM;AACjE,UAAM,YAAY,aAAc,aAAa,iBAAiB,cAAe;AAE7E,cAAU,QAAQ,IAAI,CAAC,IAAI,IAAI,IAAI,UAAU,gBAAgB,SAAS,GAAG,WAAW,GAAG,IAAI,OAAO,WAAW,CAAC,UAAU,UAAU;AAElI,WAAO;AAAA,EACT;AAGA,aAAW,MAAM;AACf,QAAI,CAAC,QAAS;AAGd,QAAI,CAAC,gBAAgB,QAAQ,GAAG;AAC9B,cAAQ,KAAK,6DAA6D;AAC1E,gBAAU;AACV;AAAA,IACF;AAEA,QAAI,cAAwD;AAE5D,QAAI;AAEF,2BAAqB,UAAU,YAAY;AAE3C,aAAO;AAEP,oBAAc,SAAS,MAAM,CAAC,EAAE,SAAS,MAAM;AAC7C,YAAI,CAAC,SAAS;AACZ,uBAAa,QAAQ;AACrB;AAAA,QACF;AAEA,YAAI;AACF,mBAAS,eAAe;AACxB,mBAAS,gBAAgB;AAEzB,gBAAM,MAAM,SAAS;AACrB,gBAAM,WAAW,IAAI,YAAY;AACjC,gBAAM,OAAO,SAAS;AACtB,gBAAM,WAAW;AACjB,gBAAM,YAAY;AAClB,gBAAM,iBAAiB,WAAW,IAAI;AACtC,gBAAM,gBAAgB,QAAQ,iBAAiB;AAG/C,cAAI,QAAQ,YAAY,aAAa,KAAK;AACxC,yBAAa,QAAQ;AACrB,uBAAW,KAAK;AAChB,gCAAoB,UAAU,iBAAiB;AAC/C,gBAAI,QAAQ;AACV,qBAAO;AAAA,YACT;AACA;AAAA,UACF;AAGA,cAAI,QAAQ,WAAW;AACrB,gBAAI,eAAe;AACjB,8BAAgB,KAAK,IAAI,GAAG,gBAAgB,CAAC;AAAA,YAC/C,OAAO;AACL,+BAAiB,gBAAgB,IAAI,MAAM,UAAU,MAAM;AAAA,YAC7D;AACA,mBAAO;AACP;AAAA,UACF;AACA,cAAI,QAAQ,aAAa;AACvB,gBAAI,eAAe;AACjB,8BAAgB,KAAK,IAAI,MAAM,SAAS,GAAG,gBAAgB,CAAC;AAAA,YAC9D,OAAO;AACL,+BAAiB,gBAAgB,KAAK,MAAM;AAAA,YAC9C;AACA,mBAAO;AACP;AAAA,UACF;AACA,cAAI,QAAQ,eAAe,eAAe;AACxC,gBAAI,gBAAgB,MAAM,GAAG;AAC3B;AAAA,YACF;AACA,mBAAO;AACP;AAAA,UACF;AACA,cAAI,QAAQ,gBAAgB,eAAe;AACzC,gBAAI,gBAAgB,MAAM,KAAK,gBAAgB,IAAI,MAAM,QAAQ;AAC/D;AAAA,YACF;AACA,mBAAO;AACP;AAAA,UACF;AAGA,gBAAMC,cAAa,OAAO,SAA+B;AACvD,yBAAa,QAAQ;AACrB,sBAAU;AAEV,gCAAoB,UAAU,mBAAmB;AAEjD,gBAAI;AACF,oBAAM,qBAAqB,UAAU,KAAK,IAAI;AAC9C,kBAAI,cAAc;AAChB,6BAAa,KAAK,EAAE;AAAA,cACtB;AAAA,YACF,SAAS,KAAK;AACZ,sBAAQ,MAAM,sCAAsC,GAAG;AAEvD,uCAAyB,UAAU,yBAAyB;AAC5D,uBAAS,MAAM,iCAAiC,GAAG;AAAA,CAAa;AAAA,YAClE;AAAA,UACF;AAGA,cAAI,QAAQ,SAAS;AACnB,YAAAA,YAAW,MAAM,aAAa,CAAC,EAAE,MAAM,SAAO;AAC5C,sBAAQ,MAAM,uCAAuC,GAAG;AAAA,YAC1D,CAAC;AACD;AAAA,UACF;AAGA,gBAAM,SAAS,SAAS,GAAG;AAC3B,cAAI,UAAU,KAAK,UAAU,MAAM,UAAU,UAAU,GAAG;AACxD,YAAAA,YAAW,MAAM,SAAS,CAAC,CAAC,EAAE,MAAM,SAAO;AACzC,sBAAQ,MAAM,uCAAuC,GAAG;AAAA,YAC1D,CAAC;AACD;AAAA,UACF;AAAA,QACF,SAAS,KAAK;AACZ,kBAAQ,MAAM,kCAAkC,GAAG;AACnD,qBAAW,KAAK;AAAA,QAClB;AAAA,MACF,CAAC;AAED,YAAM,eAAe,WAAW;AAChC,iBAAW,OAAO,MAAM;AACtB,qBAAa,QAAQ;AACrB,4BAAoB,UAAU,iBAAiB;AAC/C,qBAAa;AAAA,MACf;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,MAAM,0CAA0C,GAAG;AAC3D,+BAAyB,UAAU,uBAAuB;AAC1D,gBAAU;AAAA,IACZ;AAAA,EACF,GAAG,EAAE;AAEL,SAAO;AACT;;;ACvSO,IAAM,QAAoB;AAAA;AAAA,EAE/B,EAAE,IAAI,UAAU,MAAM,UAAU,aAAa,oBAAoB,KAAK,cAAc;AAAA,EACpF,EAAE,IAAI,SAAS,MAAM,SAAS,aAAa,gBAAgB,KAAK,aAAa;AAAA,EAC7E,EAAE,IAAI,QAAQ,MAAM,QAAQ,aAAa,2BAA2B,KAAK,YAAY;AAAA,EACrF,EAAE,IAAI,UAAU,MAAM,UAAU,aAAa,iBAAiB,KAAK,cAAc;AAAA,EACjF,EAAE,IAAI,QAAQ,MAAM,QAAQ,aAAa,uBAAuB,KAAK,YAAY;AAAA,EACjF,EAAE,IAAI,UAAU,MAAM,UAAU,aAAa,kBAAkB,KAAK,cAAc;AAAA,EAClF,EAAE,IAAI,eAAe,MAAM,eAAe,aAAa,mBAAmB,KAAK,mBAAmB;AAAA,EAClG,EAAE,IAAI,WAAW,MAAM,WAAW,aAAa,kBAAkB,KAAK,eAAe;AAAA,EACrF,EAAE,IAAI,iBAAiB,MAAM,kBAAkB,aAAa,gBAAgB,KAAK,qBAAqB;AAAA,EACtG,EAAE,IAAI,SAAS,MAAM,SAAS,aAAa,iBAAiB,KAAK,aAAa;AAAA,EAC9E,EAAE,IAAI,SAAS,MAAM,SAAS,aAAa,eAAe,KAAK,aAAa;AAAA,EAC5E,EAAE,IAAI,WAAW,MAAM,WAAW,aAAa,kBAAkB,KAAK,eAAe;AAAA,EACrF,EAAE,IAAI,YAAY,MAAM,YAAY,aAAa,wBAAwB,KAAK,gBAAgB;AAAA,EAC9F,EAAE,IAAI,aAAa,MAAM,aAAa,aAAa,mBAAmB,KAAK,iBAAiB;AAAA,EAC5F,EAAE,IAAI,cAAc,MAAM,eAAe,aAAa,mBAAmB,KAAK,cAAc;AAAA,EAC5F,EAAE,IAAI,QAAQ,MAAM,QAAQ,aAAa,sBAAsB,KAAK,YAAY;AAAA,EAChF,EAAE,IAAI,SAAS,MAAM,SAAS,aAAa,mBAAmB,KAAK,aAAa;AAAA,EAChF,EAAE,IAAI,WAAW,MAAM,WAAW,aAAa,sBAAsB,KAAK,eAAe;AAC3F;;;ACxGA,IAAM,iBAAiB,oBAAI,IAA+B;AAE1D,IAAM,iBAAiB;AAAA,EACrB,iBAAiB,MAAc,SAAuB;AACpD,QAAI,CAAC,eAAe,IAAI,IAAI,EAAG,gBAAe,IAAI,MAAM,oBAAI,IAAI,CAAC;AACjE,mBAAe,IAAI,IAAI,EAAG,IAAI,OAAO;AAAA,EACvC;AAAA,EACA,oBAAoB,MAAc,SAAuB;AACvD,mBAAe,IAAI,IAAI,GAAG,OAAO,OAAO;AAAA,EAC1C;AAAA,EACA,cAAc,OAAuB;AACnC,UAAM,WAAW,eAAe,IAAI,MAAM,IAAI;AAC9C,QAAI,UAAU;AACZ,iBAAW,WAAW,UAAU;AAC9B,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAEA,IAAI,OAAO,WAAW,WAAW,aAAa;AAC5C,EAAC,WAAuC,SAAS;AACnD;AAsCA,IAAM,YAAoC;AAAA,EACxC,SAAS;AAAA,EAAI,WAAW;AAAA,EAAI,WAAW;AAAA,EAAI,YAAY;AAAA,EACvD,OAAO;AAAA,EAAI,QAAQ;AAAA,EAAI,KAAK;AAAA,EAAI,WAAW;AAAA,EAAG,KAAK;AAAA,EACnD,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EACpD,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EACpD,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,GAAG;AAAA,EACpD,GAAG;AAAA,EAAI,GAAG;AAAA,EAAI,KAAK;AAAA,EAAI,KAAK;AAAA,EAAI,KAAK;AAAA,EAAI,KAAK;AAAA,EAAI,KAAK;AAAA,EACvD,KAAK;AAAA,EAAI,KAAK;AAAA,EAAI,KAAK;AAAA,EAAI,KAAK;AAAA,EAAI,KAAK;AAC3C;AAMA,SAAS,SAAS,MAAsB;AACtC,MAAI,SAAS,YAAY,SAAS,SAAU,QAAO;AACnD,MAAI,SAAS,YAAY,SAAS,SAAU,QAAO;AACnD,MAAI,SAAS,YAAY,SAAS,SAAU,QAAO;AACnD,MAAI,SAAS,YAAY,SAAS,SAAU,QAAO;AACnD,MAAI,SAAS,QAAQ,SAAS,KAAM,QAAO;AAC3C,MAAI,SAAS,OAAQ,QAAO;AAC5B,MAAI,SAAS,IAAK,QAAO;AACzB,MAAI,SAAS,UAAU,SAAS,KAAM,QAAO;AAC7C,MAAI,SAAS,IAAM,QAAO;AAC1B,MAAI,SAAS,IAAQ,QAAO;AAC5B,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,SAAO;AACT;AAEA,SAAS,eAAe,KAAa;AACnC,QAAM,UAAU,UAAU,GAAG,KAAK,UAAU,IAAI,YAAY,CAAC,KAAK;AAClE,SAAO;AAAA,IACL;AAAA,IACA,MAAM,IAAI,WAAW,IAAI,MAAM,IAAI,YAAY,CAAC,KAAK;AAAA,IACrD;AAAA,IACA,OAAO;AAAA,IACP,gBAAgB,MAAM;AAAA,IAAC;AAAA,IACvB,iBAAiB,MAAM;AAAA,IAAC;AAAA,IACxB,0BAA0B,MAAM;AAAA,IAAC;AAAA;AAAA,IAEjC,SAAS;AAAA,IACT,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AACF;AAGA,IAAM,WAAW,oBAAI,IAA2C;AAEhE,SAAS,qBAAmC;AAC1C,QAAM,eAA8C,CAAC;AACrD,QAAM,gBAA4C,CAAC;AACnD,QAAM,kBAAsE,CAAC;AAE7E,MAAI,QAAQ,MAAM,OAAO;AACvB,YAAQ,MAAM,WAAW,IAAI;AAAA,EAC/B;AACA,UAAQ,MAAM,OAAO;AACrB,UAAQ,MAAM,YAAY,MAAM;AAEhC,UAAQ,MAAM,GAAG,QAAQ,CAAC,SAAiB;AACzC,QAAI,SAAS,KAAQ;AACnB,cAAQ;AACR,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,MAAM,SAAS,IAAI;AACzB,UAAM,WAAW,eAAe,GAAG;AAInC,UAAM,eAAe,EAAE,GAAG,UAAU,MAAM,UAAU;AACpD,mBAAe,cAAc,YAAY;AAGzC,QAAI,SAAS,IAAI,GAAG,GAAG;AACrB,mBAAa,SAAS,IAAI,GAAG,CAAE;AAAA,IACjC;AACA,aAAS,IAAI,KAAK,WAAW,MAAM;AACjC,YAAM,aAAa,EAAE,GAAG,UAAU,MAAM,QAAQ;AAChD,qBAAe,cAAc,UAAU;AACvC,eAAS,OAAO,GAAG;AAAA,IACrB,GAAG,EAAE,CAAC;AAGN,eAAW,YAAY,CAAC,GAAG,YAAY,GAAG;AACxC,eAAS,EAAE,KAAK,SAAS,CAAC;AAAA,IAC5B;AAEA,eAAW,YAAY,CAAC,GAAG,aAAa,GAAG;AACzC,eAAS,IAAI;AAAA,IACf;AAAA,EACF,CAAC;AAED,UAAQ,OAAO,GAAG,UAAU,MAAM;AAChC,UAAM,OAAO,EAAE,MAAM,QAAQ,OAAO,WAAW,IAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG;AACnF,eAAW,YAAY,CAAC,GAAG,eAAe,GAAG;AAC3C,eAAS,IAAI;AAAA,IACf;AAAA,EACF,CAAC;AAED,WAAS,UAAU;AACjB,QAAI,QAAQ,MAAM,OAAO;AACvB,cAAQ,MAAM,WAAW,KAAK;AAAA,IAChC;AACA,YAAQ,MAAM,MAAM;AACpB,YAAQ,OAAO,MAAM,aAAa;AAClC,YAAQ,OAAO,MAAM,WAAW;AAChC,YAAQ,OAAO,MAAM,SAAS;AAAA,EAChC;AAKA,QAAM,aAAa;AACnB,QAAM,WAAW;AAEjB,QAAM,WAAyB;AAAA,IAC7B,OAAO,CAAC,SAAiB;AACvB,cAAQ,OAAO,MAAM,aAAa,OAAO,QAAQ;AAAA,IACnD;AAAA,IACA,IAAI,OAAO;AAAE,aAAO,QAAQ,OAAO,WAAW;AAAA,IAAI;AAAA,IAClD,IAAI,OAAO;AAAE,aAAO,QAAQ,OAAO,QAAQ;AAAA,IAAI;AAAA,IAC/C,SAAS,CAAC;AAAA;AAAA,IACV,OAAO,CAAC,aAAoD;AAC1D,mBAAa,KAAK,QAAQ;AAC1B,aAAO;AAAA,QACL,SAAS,MAAM;AACb,gBAAM,MAAM,aAAa,QAAQ,QAAQ;AACzC,cAAI,QAAQ,GAAI,cAAa,OAAO,KAAK,CAAC;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AAAA,IACA,QAAQ,CAAC,aAAiD;AACxD,oBAAc,KAAK,QAAQ;AAC3B,aAAO;AAAA,QACL,SAAS,MAAM;AACb,gBAAM,MAAM,cAAc,QAAQ,QAAQ;AAC1C,cAAI,QAAQ,GAAI,eAAc,OAAO,KAAK,CAAC;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAAA,IACA,UAAU,CAAC,aAAyE;AAClF,sBAAgB,KAAK,QAAQ;AAC7B,aAAO;AAAA,QACL,SAAS,MAAM;AACb,gBAAM,MAAM,gBAAgB,QAAQ,QAAQ;AAC5C,cAAI,QAAQ,GAAI,iBAAgB,OAAO,KAAK,CAAC;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,UAAQ,GAAG,QAAQ,OAAO;AAC1B,UAAQ,GAAG,UAAU,MAAM;AAAE,YAAQ;AAAG,YAAQ,KAAK,CAAC;AAAA,EAAG,CAAC;AAC1D,UAAQ,GAAG,WAAW,MAAM;AAAE,YAAQ;AAAG,YAAQ,KAAK,CAAC;AAAA,EAAG,CAAC;AAE3D,SAAO;AACT;AAMA,SAAS,gBAAgB,UAAwB;AAE/C,iBAAe,iBAAiB,YAAY,MAAM,MAAM;AACtD,eAAW,MAAM,SAAS,QAAQ,GAAG,GAAG;AAAA,EAC1C,CAAC;AACD,iBAAe,iBAAiB,YAAY,QAAQ,MAAM;AAExD,UAAM,aAAa,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AACjE,eAAW,MAAM,WAAW,UAAU,UAAU,GAAG,GAAG;AAAA,EACxD,CAAC;AACD,iBAAe,iBAAiB,YAAY,YAAY,MAAM;AAC5D,eAAW,MAAM,SAAS,QAAQ,GAAG,GAAG;AAAA,EAC1C,CAAC;AACD,iBAAe,iBAAiB,YAAY,cAAc,CAAC,UAAuB;AAChF,UAAM,SAAS,MAAM,QAAQ;AAC7B,UAAM,OAAO,MAAM,KAAK,OAAK,EAAE,OAAO,MAAM;AAC5C,QAAI,MAAM;AACR,iBAAW,MAAM,WAAW,UAAU,IAAI,GAAG,GAAG;AAAA,IAClD;AAAA,EACF,EAAkB;AACpB;AAEA,SAAS,SAAS,UAAwB;AAGxC,gBAAc,UAAiB;AAAA,IAC7B,cAAc,CAAC,WAAmB;AAChC,YAAM,OAAO,MAAM,KAAK,OAAK,EAAE,OAAO,MAAM;AAC5C,UAAI,KAAM,YAAW,UAAU,IAAI;AAAA,IACrC;AAAA,IACA,QAAQ,MAAM;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACH;AAEA,SAAS,WAAW,UAAwB,MAAgB;AAE1D,OAAK,IAAI,QAAe;AAC1B;AAMA,SAAS,YAAY;AACnB,UAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAcR,MAAM,IAAI,OAAK,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,KAAK,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAiBzE;AACD;AAEA,SAAS,OAAO;AACd,QAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AAEjC,MAAI,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,IAAI,GAAG;AAClD,cAAU;AACV,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,IAAI,GAAG;AAClD,eAAW,QAAQ,OAAO;AACxB,cAAQ,IAAI,KAAK,KAAK,GAAG,OAAO,EAAE,CAAC,IAAI,KAAK,WAAW,EAAE;AAAA,IAC3D;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,QAAsB;AAC1B,QAAM,WAAW,KAAK,QAAQ,SAAS;AACvC,MAAI,aAAa,MAAM,KAAK,WAAW,CAAC,GAAG;AACzC,YAAQ,KAAK,WAAW,CAAC;AACzB,SAAK,OAAO,UAAU,CAAC;AAAA,EACzB;AACA,WAAS,KAAK;AAEd,QAAM,WAAW,mBAAmB;AACpC,kBAAgB,QAAQ;AAGxB,QAAM,WAAW,KAAK,CAAC;AACvB,MAAI,UAAU;AACZ,UAAM,OAAO,MAAM,KAAK,OAAK,EAAE,OAAO,YAAY,EAAE,KAAK,YAAY,MAAM,SAAS,YAAY,CAAC;AACjG,QAAI,CAAC,MAAM;AACT,cAAQ,MAAM,iBAAiB,QAAQ,EAAE;AACzC,cAAQ,MAAM,oBAAoB,MAAM,IAAI,OAAK,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AACnE,cAAQ,KAAK,CAAC;AACd;AAAA,IACF;AACA,eAAW,UAAU,IAAI;AACzB;AAAA,EACF;AAEA,WAAS,QAAQ;AACnB;AAKA,IAAM,UAAU,QAAQ,KAAK,MAAM,CAAC;AACpC,IAAI,QAAQ,CAAC,MAAM,UAAU,QAAQ,CAAC,MAAM,UAAU;AACpD,SAAO,sBAAU,EAAE,KAAK,OAAK,EAAE,YAAY,QAAQ,MAAM,CAAC,CAAC,CAAC;AAC9D,WAAW,QAAQ,CAAC,MAAM,UAAU;AAClC,SAAO,sBAAU,EAAE,KAAK,OAAK,EAAE,cAAc,QAAQ,MAAM,CAAC,CAAC,CAAC;AAChE,OAAO;AACL,OAAK;AACP;","names":["isLightTheme","i","spawnParticles","addScorePopup","triggerShake","slide","output","hint","triggerShake","spawnParticles","spawnParticles","addScorePopup","triggerShake","hint","popup","titleX","spawnParticles","addScorePopup","spawnParticles","spawnSplash","lane","hint","spawnParticles","addScorePopup","hint","spawnParticles","addScorePopup","triggerShake","hint","hintX","spawnParticles","addScorePopup","hint","centerX","spawnParticles","speed","addScorePopup","hint","centerX","roadWidth","roadLeft","spawnParticles","addScorePopup","triggerShake","hint","spawnParticles","updateParticles","hint","spawnParticles","addScorePopup","hint","spawnParticles","addScorePopup","triggerShake","hint","spawnParticles","triggerShake","hint","spawnParticles","addScorePopup","hint","hintX","WORDS","spawnParticles","spawnFirework","addScorePopup","triggerShake","centerX","isLightTheme","launchGame"]}