UNPKG

react-ascii-ui

Version:

Complete ASCII-styled React UI library with advanced features: sound system, code editor, network visualizer, and ASCII art generator

1,733 lines (1,709 loc) 386 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { ASCII_CHARACTER_SETS: () => ASCII_CHARACTER_SETS, ASCII_CODE_THEMES: () => ASCII_CODE_THEMES, ASCII_NETWORK_THEMES: () => ASCII_NETWORK_THEMES, AsciiAccordion: () => AsciiAccordion, AsciiAdvancedTable: () => AsciiAdvancedTable, AsciiAlert: () => AsciiAlert, AsciiAnimatedProgressBar: () => AsciiAnimatedProgressBar, AsciiArtGenerator: () => AsciiArtGenerator, AsciiAvatar: () => AsciiAvatar, AsciiBadge: () => AsciiBadge, AsciiBarChart: () => AsciiBarChart, AsciiBox: () => AsciiBox, AsciiButton: () => AsciiButton, AsciiCalendar: () => AsciiCalendar, AsciiCard: () => AsciiCard, AsciiCenter: () => AsciiCenter, AsciiChart: () => AsciiChart, AsciiCheckbox: () => AsciiCheckbox, AsciiCodeEditor: () => AsciiCodeEditor, AsciiContainer: () => AsciiContainer, AsciiDivider: () => AsciiDivider, AsciiDonutChart: () => AsciiDonutChart, AsciiFadeTransition: () => AsciiFadeTransition, AsciiFileUpload: () => AsciiFileUpload, AsciiForm: () => AsciiForm, AsciiFormField: () => AsciiFormField, AsciiGlitchTransition: () => AsciiGlitchTransition, AsciiGrid: () => AsciiGrid, AsciiGridItem: () => AsciiGridItem, AsciiInline: () => AsciiInline, AsciiInput: () => AsciiInput, AsciiLineChart: () => AsciiLineChart, AsciiLoader: () => AsciiLoader, AsciiMatrixRain: () => AsciiMatrixRain, AsciiMatrixRainFullscreen: () => AsciiMatrixRainFullscreen, AsciiMatrixTransition: () => AsciiMatrixTransition, AsciiModal: () => AsciiModal, AsciiMultiStepForm: () => AsciiMultiStepForm, AsciiNavbar: () => AsciiNavbar, AsciiNetworkVisualizer: () => AsciiNetworkVisualizer, AsciiPagination: () => AsciiPagination, AsciiPopover: () => AsciiPopover, AsciiProgressBar: () => AsciiProgressBar, AsciiRadioGroup: () => AsciiRadioGroup, AsciiSelect: () => AsciiSelect, AsciiSidebar: () => AsciiSidebar, AsciiSlideTransition: () => AsciiSlideTransition, AsciiSoundProvider: () => AsciiSoundProvider, AsciiSpacer: () => AsciiSpacer, AsciiSparkline: () => AsciiSparkline, AsciiSpinner: () => AsciiSpinner, AsciiStack: () => AsciiStack, AsciiSwitch: () => AsciiSwitch, AsciiTable: () => AsciiTable, AsciiTabs: () => AsciiTabs, AsciiTerminal: () => AsciiTerminal, AsciiTextarea: () => AsciiTextarea, AsciiThemeProvider: () => AsciiThemeProvider, AsciiThemeSwitcher: () => AsciiThemeSwitcher, AsciiToast: () => AsciiToast, AsciiToastContainer: () => AsciiToastContainer, AsciiTooltip: () => AsciiTooltip, AsciiTransition: () => AsciiTransition, AsciiTree: () => AsciiTree, AsciiTypewriter: () => AsciiTypewriter, AsciiTypewriterLine: () => AsciiTypewriterLine, AsciiTypewriterMulti: () => AsciiTypewriterMulti, AsciiWindow: () => AsciiWindow, AsciiWindowManager: () => AsciiWindowManager, DEFAULT_ASCII_CONFIG: () => DEFAULT_ASCII_CONFIG, DEFAULT_CODE_EDITOR_OPTIONS: () => DEFAULT_CODE_EDITOR_OPTIONS, DEFAULT_NETWORK_OPTIONS: () => DEFAULT_NETWORK_OPTIONS, LANGUAGE_DEFINITIONS: () => LANGUAGE_DEFINITIONS, NetworkLayoutEngine: () => NetworkLayoutEngine, adjustImageData: () => adjustImageData, analyzeNetwork: () => analyzeNetwork, applyFloydSteinbergDithering: () => applyFloydSteinbergDithering, brightnessToCharacter: () => brightnessToCharacter, calculateBrightness: () => calculateBrightness, calculateDistance: () => calculateDistance, calculateNetworkBounds: () => calculateNetworkBounds, captureWebcamFrame: () => captureWebcamFrame, convertToAsciiArt: () => convertToAsciiArt, convertToAsciiArtWithDithering: () => convertToAsciiArtWithDithering, createSweepEffect: () => createSweepEffect, createTokenizer: () => createTokenizer, createValidationRules: () => createValidationRules, defaultAnimationConfig: () => defaultAnimationConfig, defaultTheme: () => defaultTheme, easingFunctions: () => easingFunctions, exportNetwork: () => exportNetwork, generateRandomChar: () => generateRandomChar, generateSampleNetwork: () => generateSampleNetwork, generateWhiteNoise: () => generateWhiteNoise, getAllThemes: () => getAllThemes, getAudioContext: () => getAudioContext, getLanguageDefinition: () => getLanguageDefinition, getLanguageFromExtension: () => getLanguageFromExtension, getTheme: () => getTheme, getThemeNames: () => getThemeNames, glitchCharset: () => glitchCharset, imageDataToAscii: () => imageDataToAscii, isFormValid: () => isFormValid, loadImageData: () => loadImageData, matrixCharset: () => matrixCharset, playBeep: () => playBeep, playSequence: () => playSequence, playWhiteNoise: () => playWhiteNoise, progressChars: () => progressChars, resizeImageData: () => resizeImageData, resumeAudioContext: () => resumeAudioContext, soundGenerators: () => soundGenerators, soundPresets: () => soundPresets, spinnerFrames: () => spinnerFrames, themes: () => themes, useAmbientSounds: () => useAmbientSounds, useAnimation: () => useAnimation, useAnimationFrame: () => useAnimationFrame, useAsciiArt: () => useAsciiArt, useAsciiSound: () => useAsciiSound, useAsciiTheme: () => useAsciiTheme, useBatchAsciiArt: () => useBatchAsciiArt, useButtonSounds: () => useButtonSounds, useCodeEditor: () => useCodeEditor, useCodeTabs: () => useCodeTabs, useFormSounds: () => useFormSounds, useGameSounds: () => useGameSounds, useModalSounds: () => useModalSounds, useNetworkAnalysis: () => useNetworkAnalysis, useNetworkMonitoring: () => useNetworkMonitoring, useNetworkPaths: () => useNetworkPaths, useNetworkVisualizer: () => useNetworkVisualizer, useRealTimeAsciiArt: () => useRealTimeAsciiArt, useSoundEnabled: () => useSoundEnabled, useSystemSounds: () => useSystemSounds, useTerminalSounds: () => useTerminalSounds, useThemeCharacters: () => useThemeCharacters, useThemeColors: () => useThemeColors, useTypewriter: () => useTypewriter, useTypingSounds: () => useTypingSounds, useWebcamAsciiArt: () => useWebcamAsciiArt, validateField: () => validateField, validateForm: () => validateForm, validateRule: () => validateRule }); module.exports = __toCommonJS(src_exports); // src/contexts/ThemeContext.tsx var import_react = __toESM(require("react")); // src/themes/classic.ts var classicTheme = { name: "classic", description: "Traditional ASCII art styling with clean lines", colors: { primary: "#00ff00", // Classic green secondary: "#00ffff", // Cyan success: "#00ff00", // Green warning: "#ffff00", // Yellow error: "#ff0000", // Red errorBackground: "#330000", // Dark red info: "#00ffff", // Cyan background: "#000000", // Black surface: "#111111", // Dark gray text: "#ffffff", // White textSecondary: "#cccccc", // Light gray muted: "#666666", // Medium gray border: "#ffffff", // White accent: "#00ff00" // Green }, characters: { // Box drawing boxTopLeft: "\u250C", boxTopRight: "\u2510", boxBottomLeft: "\u2514", boxBottomRight: "\u2518", boxHorizontal: "\u2500", boxVertical: "\u2502", boxCross: "\u253C", boxTeeTop: "\u252C", boxTeeBottom: "\u2534", boxTeeLeft: "\u251C", boxTeeRight: "\u2524", // UI elements bulletPoint: "\u2022", arrow: "\u2192", arrowUp: "\u2191", arrowDown: "\u2193", arrowLeft: "\u2190", arrowRight: "\u2192", checkmark: "\u2713", cross: "\u2717", radioSelected: "\u25CF", radioUnselected: "\u25CB", expand: "+", collapse: "-", // Progress progressFilled: "\u2588", progressEmpty: "\u2591", loadingSpinner: ["|", "/", "-", "\\"], // Brackets bracketLeft: "[", bracketRight: "]", separator: "|", divider: "\u2500" }, typography: { fontFamily: '"Courier New", "Monaco", "Menlo", monospace', fontSize: { xs: "0.75rem", sm: "0.875rem", base: "1rem", lg: "1.125rem", xl: "1.25rem", "2xl": "1.5rem", "3xl": "1.875rem" }, fontWeight: { normal: "400", bold: "700" }, lineHeight: "1.5" }, spacing: { xs: "0.25rem", sm: "0.5rem", md: "1rem", lg: "1.5rem", xl: "2rem", "2xl": "3rem" }, borderRadius: "0px", shadows: { sm: "none", md: "none", lg: "none" } }; // src/themes/cyberpunk.ts var cyberpunkTheme = { name: "cyberpunk", description: "Futuristic neon aesthetic with angular elements", colors: { primary: "#ff00ff", // Magenta/Pink secondary: "#00ffff", // Cyan success: "#00ff41", // Bright green warning: "#ffaa00", // Orange error: "#ff0040", // Hot pink errorBackground: "#330000", // Dark red info: "#00d4ff", // Electric blue background: "#0a0a0a", // Deep black surface: "#1a0a1a", // Dark magenta tint text: "#ffffff", // White textSecondary: "#ff00ff", // Magenta muted: "#666666", // Medium gray border: "#ff00ff", // Magenta accent: "#00ffff" // Cyan }, characters: { // Box drawing - angular style boxTopLeft: "\u2554", boxTopRight: "\u2557", boxBottomLeft: "\u255A", boxBottomRight: "\u255D", boxHorizontal: "\u2550", boxVertical: "\u2551", boxCross: "\u256C", boxTeeTop: "\u2566", boxTeeBottom: "\u2569", boxTeeLeft: "\u2560", boxTeeRight: "\u2563", // UI elements - cyberpunk style bulletPoint: "\u25C6", arrow: "\u25BA", arrowUp: "\u25B2", arrowDown: "\u25BC", arrowLeft: "\u25C4", arrowRight: "\u25BA", checkmark: "\u25C9", cross: "\u25C8", radioSelected: "\u25C9", radioUnselected: "\u25EF", expand: "\u25B8", collapse: "\u25BE", // Progress - futuristic progressFilled: "\u25B0", progressEmpty: "\u25B1", loadingSpinner: ["\u25D0", "\u25D3", "\u25D1", "\u25D2"], // Brackets - angular bracketLeft: "\u25C0", bracketRight: "\u25B6", separator: "\u25E6", divider: "\u25AC" }, typography: { fontFamily: '"JetBrains Mono", "Fira Code", "Courier New", monospace', fontSize: { xs: "0.75rem", sm: "0.875rem", base: "1rem", lg: "1.125rem", xl: "1.25rem", "2xl": "1.5rem", "3xl": "1.875rem" }, fontWeight: { normal: "400", bold: "600" }, lineHeight: "1.4" }, spacing: { xs: "0.25rem", sm: "0.5rem", md: "1rem", lg: "1.5rem", xl: "2rem", "2xl": "3rem" }, borderRadius: "2px", shadows: { sm: "0 0 4px rgba(255, 0, 255, 0.3)", md: "0 0 8px rgba(255, 0, 255, 0.4)", lg: "0 0 16px rgba(255, 0, 255, 0.5)" } }; // src/themes/matrix.ts var matrixTheme = { name: "matrix", description: "Digital rain aesthetic with green-on-black styling", colors: { primary: "#00ff41", // Matrix green secondary: "#008f11", // Dark green success: "#00ff41", // Matrix green warning: "#41ff00", // Light green error: "#ff4141", // Red (anomaly) errorBackground: "#330000", // Dark red info: "#00aa22", // Medium green background: "#000000", // Pure black surface: "#001100", // Very dark green text: "#00ff41", // Matrix green textSecondary: "#008f11", // Dark green muted: "#666666", // Medium gray border: "#00ff41", // Matrix green accent: "#41ff00" // Light green }, characters: { // Box drawing - digital style boxTopLeft: "\u256D", boxTopRight: "\u256E", boxBottomLeft: "\u2570", boxBottomRight: "\u256F", boxHorizontal: "\u2500", boxVertical: "\u2502", boxCross: "\u253C", boxTeeTop: "\u252C", boxTeeBottom: "\u2534", boxTeeLeft: "\u251C", boxTeeRight: "\u2524", // UI elements - matrix inspired bulletPoint: "\u203B", arrow: "\u21D2", arrowUp: "\u21E1", arrowDown: "\u21E3", arrowLeft: "\u21E0", arrowRight: "\u21E2", checkmark: "\u2713", cross: "\u2715", radioSelected: "\u25C9", radioUnselected: "\u25CB", expand: "\u229E", collapse: "\u229F", // Progress - digital progressFilled: "\u2593", progressEmpty: "\u2591", loadingSpinner: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827"], // Brackets - matrix style bracketLeft: "\u27E8", bracketRight: "\u27E9", separator: "\u2219", divider: "\u23AF" }, typography: { fontFamily: '"Source Code Pro", "Consolas", "Monaco", monospace', fontSize: { xs: "0.75rem", sm: "0.875rem", base: "1rem", lg: "1.125rem", xl: "1.25rem", "2xl": "1.5rem", "3xl": "1.875rem" }, fontWeight: { normal: "400", bold: "500" }, lineHeight: "1.6" }, spacing: { xs: "0.25rem", sm: "0.5rem", md: "1rem", lg: "1.5rem", xl: "2rem", "2xl": "3rem" }, borderRadius: "0px", shadows: { sm: "0 0 2px rgba(0, 255, 65, 0.3)", md: "0 0 6px rgba(0, 255, 65, 0.4)", lg: "0 0 12px rgba(0, 255, 65, 0.5)" } }; // src/themes/retro.ts var retroTheme = { name: "retro", description: "Vintage computer terminal with amber phosphor styling", colors: { primary: "#ffb000", // Amber secondary: "#ff8800", // Orange success: "#88ff00", // Light green warning: "#ffff00", // Yellow error: "#ff4400", // Red-orange errorBackground: "#330000", // Dark red info: "#00aaff", // Blue background: "#1a0f00", // Dark amber background surface: "#2a1500", // Darker amber text: "#ffb000", // Amber textSecondary: "#cc8800", // Dark amber muted: "#666666", // Medium gray border: "#ffb000", // Amber accent: "#ff8800" // Orange }, characters: { // Box drawing - retro style boxTopLeft: "+", boxTopRight: "+", boxBottomLeft: "+", boxBottomRight: "+", boxHorizontal: "-", boxVertical: "|", boxCross: "+", boxTeeTop: "+", boxTeeBottom: "+", boxTeeLeft: "+", boxTeeRight: "+", // UI elements - vintage bulletPoint: "*", arrow: ">", arrowUp: "^", arrowDown: "v", arrowLeft: "<", arrowRight: ">", checkmark: "X", cross: "X", radioSelected: "*", radioUnselected: "o", expand: "+", collapse: "-", // Progress - simple blocks progressFilled: "#", progressEmpty: ".", loadingSpinner: ["-", "\\", "|", "/"], // Brackets - simple bracketLeft: "[", bracketRight: "]", separator: "|", divider: "-" }, typography: { fontFamily: '"IBM Plex Mono", "Courier", "monospace"', fontSize: { xs: "0.75rem", sm: "0.875rem", base: "1rem", lg: "1.125rem", xl: "1.25rem", "2xl": "1.5rem", "3xl": "1.875rem" }, fontWeight: { normal: "400", bold: "600" }, lineHeight: "1.8" }, spacing: { xs: "0.25rem", sm: "0.5rem", md: "1rem", lg: "1.5rem", xl: "2rem", "2xl": "3rem" }, borderRadius: "0px", shadows: { sm: "0 0 3px rgba(255, 176, 0, 0.4)", md: "0 0 6px rgba(255, 176, 0, 0.5)", lg: "0 0 12px rgba(255, 176, 0, 0.6)" } }; // src/themes/neon.ts var neonTheme = { name: "neon", description: "Vibrant neon lights with electric blue and pink accents", colors: { primary: "#00d4ff", // Electric blue secondary: "#ff1493", // Deep pink success: "#00ff7f", // Spring green warning: "#ffa500", // Orange error: "#ff006e", // Neon pink errorBackground: "#330000", // Dark red info: "#00bfff", // Deep sky blue background: "#0a0a0f", // Very dark blue surface: "#1a1a2e", // Dark blue-purple text: "#ffffff", // White textSecondary: "#00d4ff", // Electric blue muted: "#666666", // Medium gray border: "#00d4ff", // Electric blue accent: "#ff1493" // Deep pink }, characters: { // Box drawing - neon style boxTopLeft: "\u2554", boxTopRight: "\u2557", boxBottomLeft: "\u255A", boxBottomRight: "\u255D", boxHorizontal: "\u2550", boxVertical: "\u2551", boxCross: "\u256C", boxTeeTop: "\u2566", boxTeeBottom: "\u2569", boxTeeLeft: "\u2560", boxTeeRight: "\u2563", // UI elements - neon inspired bulletPoint: "\u25C9", arrow: "\u27F6", arrowUp: "\u2934", arrowDown: "\u2935", arrowLeft: "\u27F5", arrowRight: "\u27F6", checkmark: "\u2726", cross: "\u2727", radioSelected: "\u25C9", radioUnselected: "\u25CB", expand: "\u2295", collapse: "\u2296", // Progress - glowing progressFilled: "\u25B0", progressEmpty: "\u25B1", loadingSpinner: ["\u25E2", "\u25E3", "\u25E4", "\u25E5"], // Brackets - neon bracketLeft: "\u27EA", bracketRight: "\u27EB", separator: "\u25C8", divider: "\u25AC" }, typography: { fontFamily: '"Roboto Mono", "SF Mono", "Monaco", monospace', fontSize: { xs: "0.75rem", sm: "0.875rem", base: "1rem", lg: "1.125rem", xl: "1.25rem", "2xl": "1.5rem", "3xl": "1.875rem" }, fontWeight: { normal: "300", bold: "500" }, lineHeight: "1.5" }, spacing: { xs: "0.25rem", sm: "0.5rem", md: "1rem", lg: "1.5rem", xl: "2rem", "2xl": "3rem" }, borderRadius: "4px", shadows: { sm: "0 0 8px rgba(0, 212, 255, 0.4)", md: "0 0 16px rgba(0, 212, 255, 0.5)", lg: "0 0 24px rgba(0, 212, 255, 0.6)" } }; // src/themes/terminal.ts var terminalTheme = { name: "terminal", description: "Modern terminal emulator with sharp contrasts", colors: { primary: "#ffffff", // White secondary: "#888888", // Gray success: "#4ade80", // Green warning: "#fbbf24", // Amber error: "#ef4444", // Red errorBackground: "#330000", // Dark red info: "#60a5fa", // Blue background: "#000000", // Black surface: "#1f1f1f", // Dark gray text: "#ffffff", // White textSecondary: "#a3a3a3", // Light gray muted: "#666666", // Medium gray border: "#404040", // Medium gray accent: "#10b981" // Emerald }, characters: { // Box drawing - clean terminal boxTopLeft: "\u250C", boxTopRight: "\u2510", boxBottomLeft: "\u2514", boxBottomRight: "\u2518", boxHorizontal: "\u2500", boxVertical: "\u2502", boxCross: "\u253C", boxTeeTop: "\u252C", boxTeeBottom: "\u2534", boxTeeLeft: "\u251C", boxTeeRight: "\u2524", // UI elements - terminal style bulletPoint: "\u2022", arrow: "\u2192", arrowUp: "\u2191", arrowDown: "\u2193", arrowLeft: "\u2190", arrowRight: "\u2192", checkmark: "\u2713", cross: "\u2717", radioSelected: "\u25CF", radioUnselected: "\u25CB", expand: "\u25B6", collapse: "\u25BC", // Progress - terminal blocks progressFilled: "\u2588", progressEmpty: "\u2500", loadingSpinner: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827"], // Brackets - terminal bracketLeft: "[", bracketRight: "]", separator: "\u2502", divider: "\u2500" }, typography: { fontFamily: '"Ubuntu Mono", "Consolas", "Courier New", monospace', fontSize: { xs: "0.75rem", sm: "0.875rem", base: "1rem", lg: "1.125rem", xl: "1.25rem", "2xl": "1.5rem", "3xl": "1.875rem" }, fontWeight: { normal: "400", bold: "700" }, lineHeight: "1.5" }, spacing: { xs: "0.25rem", sm: "0.5rem", md: "1rem", lg: "1.5rem", xl: "2rem", "2xl": "3rem" }, borderRadius: "0px", shadows: { sm: "none", md: "none", lg: "none" } }; // src/themes/minimal.ts var minimalTheme = { name: "minimal", description: "Clean minimalist design with subtle ASCII elements", colors: { primary: "#000000", // Black secondary: "#666666", // Dark gray success: "#22c55e", // Green warning: "#f59e0b", // Amber error: "#ef4444", // Red errorBackground: "#330000", // Dark red info: "#3b82f6", // Blue background: "#ffffff", // White surface: "#f8f9fa", // Very light gray text: "#000000", // Black textSecondary: "#6b7280", // Medium gray muted: "#666666", // Medium gray border: "#d1d5db", // Light gray accent: "#1f2937" // Dark gray }, characters: { // Box drawing - minimal lines boxTopLeft: "\u250C", boxTopRight: "\u2510", boxBottomLeft: "\u2514", boxBottomRight: "\u2518", boxHorizontal: "\u2500", boxVertical: "\u2502", boxCross: "\u253C", boxTeeTop: "\u252C", boxTeeBottom: "\u2534", boxTeeLeft: "\u251C", boxTeeRight: "\u2524", // UI elements - minimal bulletPoint: "\xB7", arrow: "\u2192", arrowUp: "\u2191", arrowDown: "\u2193", arrowLeft: "\u2190", arrowRight: "\u2192", checkmark: "\u2713", cross: "\xD7", radioSelected: "\u25CF", radioUnselected: "\u25CB", expand: "+", collapse: "\u2212", // Progress - clean progressFilled: "\u25AC", progressEmpty: "\u2500", loadingSpinner: [". ", ".. ", "...", " ..", " .", " "], // Brackets - minimal bracketLeft: "(", bracketRight: ")", separator: "\xB7", divider: "\u2500" }, typography: { fontFamily: '"SF Mono", "Monaco", "Inconsolata", monospace', fontSize: { xs: "0.75rem", sm: "0.875rem", base: "1rem", lg: "1.125rem", xl: "1.25rem", "2xl": "1.5rem", "3xl": "1.875rem" }, fontWeight: { normal: "400", bold: "600" }, lineHeight: "1.6" }, spacing: { xs: "0.25rem", sm: "0.5rem", md: "1rem", lg: "1.5rem", xl: "2rem", "2xl": "3rem" }, borderRadius: "2px", shadows: { sm: "0 1px 2px rgba(0, 0, 0, 0.05)", md: "0 4px 6px rgba(0, 0, 0, 0.07)", lg: "0 10px 15px rgba(0, 0, 0, 0.1)" } }; // src/themes/index.ts var themes = { classic: classicTheme, cyberpunk: cyberpunkTheme, matrix: matrixTheme, retro: retroTheme, neon: neonTheme, terminal: terminalTheme, minimal: minimalTheme, hacker: matrixTheme // Alias for matrix theme }; var getTheme = (name) => { return themes[name] || themes.classic; }; var getAllThemes = () => { return Object.values(themes); }; var getThemeNames = () => { return Object.keys(themes); }; var defaultTheme = themes.classic; // src/contexts/ThemeContext.tsx var import_jsx_runtime = require("react/jsx-runtime"); var ThemeContext = (0, import_react.createContext)(void 0); var AsciiThemeProvider = ({ children, initialTheme = "classic" }) => { const [themeName, setThemeName] = (0, import_react.useState)(initialTheme); const theme = getTheme(themeName); const setTheme = (newThemeName) => { setThemeName(newThemeName); }; const toggleTheme = () => { const themes2 = ["classic", "cyberpunk", "matrix", "retro", "neon", "terminal", "minimal"]; const currentIndex = themes2.indexOf(themeName); const nextIndex = (currentIndex + 1) % themes2.length; setTheme(themes2[nextIndex]); }; import_react.default.useEffect(() => { const root = document.documentElement; root.style.setProperty("--ascii-primary", theme.colors.primary); root.style.setProperty("--ascii-secondary", theme.colors.secondary); root.style.setProperty("--ascii-success", theme.colors.success); root.style.setProperty("--ascii-warning", theme.colors.warning); root.style.setProperty("--ascii-error", theme.colors.error); root.style.setProperty("--ascii-info", theme.colors.info); root.style.setProperty("--ascii-background", theme.colors.background); root.style.setProperty("--ascii-surface", theme.colors.surface); root.style.setProperty("--ascii-text", theme.colors.text); root.style.setProperty("--ascii-text-secondary", theme.colors.textSecondary); root.style.setProperty("--ascii-border", theme.colors.border); root.style.setProperty("--ascii-accent", theme.colors.accent); root.style.setProperty("--ascii-font-family", theme.typography.fontFamily); root.style.setProperty("--ascii-font-size-base", theme.typography.fontSize.base); root.style.setProperty("--ascii-line-height", theme.typography.lineHeight); root.style.setProperty("--ascii-spacing-xs", theme.spacing.xs); root.style.setProperty("--ascii-spacing-sm", theme.spacing.sm); root.style.setProperty("--ascii-spacing-md", theme.spacing.md); root.style.setProperty("--ascii-spacing-lg", theme.spacing.lg); root.style.setProperty("--ascii-spacing-xl", theme.spacing.xl); root.style.setProperty("--ascii-border-radius", theme.borderRadius); root.style.setProperty("--ascii-shadow-sm", theme.shadows.sm); root.style.setProperty("--ascii-shadow-md", theme.shadows.md); root.style.setProperty("--ascii-shadow-lg", theme.shadows.lg); return () => { }; }, [theme]); const value = { theme, themeName, setTheme, toggleTheme }; return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "div", { style: { backgroundColor: theme.colors.background, color: theme.colors.text, fontFamily: theme.typography.fontFamily }, children } ) }); }; var useAsciiTheme = () => { const context = (0, import_react.useContext)(ThemeContext); if (context === void 0) { return { theme: defaultTheme, themeName: "classic", setTheme: () => { }, toggleTheme: () => { } }; } return context; }; var useThemeCharacters = () => { const { theme } = useAsciiTheme(); return theme.characters; }; var useThemeColors = () => { const { theme } = useAsciiTheme(); return theme.colors; }; // src/sound/hooks.ts var import_react3 = require("react"); // src/sound/AsciiSoundContext.tsx var import_react2 = require("react"); // src/sound/types.ts var soundPresets = { // Terminal sounds keyPress: { frequency: 800, duration: 50, type: "square", volume: 0.1 }, enter: { frequency: 600, duration: 100, type: "sine", volume: 0.2 }, backspace: { frequency: 400, duration: 80, type: "square", volume: 0.15 }, // UI interaction sounds buttonClick: { frequency: 1e3, duration: 50, type: "square", volume: 0.1 }, buttonHover: { frequency: 1200, duration: 30, type: "sine", volume: 0.05 }, tabSwitch: { frequency: 800, duration: 100, type: "triangle", volume: 0.1 }, modalOpen: { frequency: 600, duration: 200, type: "sine", volume: 0.15, fadeOut: true }, modalClose: { frequency: 400, duration: 150, type: "sine", volume: 0.12, fadeOut: true }, // Data/form sounds formSubmit: { frequency: 1200, duration: 200, type: "sine", volume: 0.2 }, formError: { frequency: 300, duration: 300, type: "sawtooth", volume: 0.2 }, uploadComplete: { frequency: 1e3, duration: 150, type: "sine", volume: 0.15 }, // Game sounds gameStart: { effects: [ { frequency: 440, duration: 200, type: "square", volume: 0.2 }, { frequency: 554, duration: 200, type: "square", volume: 0.2 }, { frequency: 659, duration: 400, type: "square", volume: 0.2 } ], interval: 100 }, gameOver: { effects: [ { frequency: 659, duration: 200, type: "sawtooth", volume: 0.2 }, { frequency: 554, duration: 200, type: "sawtooth", volume: 0.2 }, { frequency: 440, duration: 400, type: "sawtooth", volume: 0.2 } ], interval: 100 }, // System sounds notification: { frequency: 800, duration: 100, type: "sine", volume: 0.15 }, alert: { frequency: 1e3, duration: 500, type: "square", volume: 0.25 }, success: { effects: [ { frequency: 523, duration: 100, type: "sine", volume: 0.15 }, { frequency: 659, duration: 100, type: "sine", volume: 0.15 }, { frequency: 784, duration: 200, type: "sine", volume: 0.15 } ], interval: 50 }, // Retro computer sounds bootUp: { effects: [ { frequency: 200, duration: 100, type: "square", volume: 0.1 }, { frequency: 400, duration: 100, type: "square", volume: 0.1 }, { frequency: 600, duration: 100, type: "square", volume: 0.1 }, { frequency: 800, duration: 200, type: "sine", volume: 0.15 } ], interval: 50 }, staticNoise: { frequency: 1e3, duration: 200, type: "sawtooth", volume: 0.05 } }; // src/sound/utils.ts var audioContextInstance = null; var getAudioContext = () => { if (typeof window === "undefined") return null; if (!audioContextInstance) { try { const AudioContextClass = window.AudioContext || window.webkitAudioContext; if (AudioContextClass) { audioContextInstance = new AudioContextClass(); } } catch (error) { console.warn("Web Audio API not supported:", error); return null; } } return audioContextInstance; }; var resumeAudioContext = async () => { const context = getAudioContext(); if (context && context.state === "suspended") { try { await context.resume(); } catch (error) { console.warn("Failed to resume audio context:", error); } } }; var playBeep = async (effect, masterVolume = 1) => { const audioContext = getAudioContext(); if (!audioContext) return; try { await resumeAudioContext(); const oscillator = audioContext.createOscillator(); const gainNode = audioContext.createGain(); oscillator.connect(gainNode); gainNode.connect(audioContext.destination); oscillator.frequency.setValueAtTime(effect.frequency, audioContext.currentTime); oscillator.type = effect.type; const volume = (effect.volume || 1) * masterVolume; gainNode.gain.setValueAtTime(volume, audioContext.currentTime); if (effect.fadeOut) { const fadeTime = effect.duration * 0.7; gainNode.gain.setValueAtTime(volume, audioContext.currentTime); gainNode.gain.exponentialRampToValueAtTime(1e-3, audioContext.currentTime + fadeTime / 1e3); } else { gainNode.gain.setValueAtTime(0, audioContext.currentTime); gainNode.gain.linearRampToValueAtTime(volume, audioContext.currentTime + 0.01); gainNode.gain.linearRampToValueAtTime(0, audioContext.currentTime + effect.duration / 1e3); } oscillator.start(audioContext.currentTime); oscillator.stop(audioContext.currentTime + effect.duration / 1e3); } catch (error) { console.warn("Failed to play sound effect:", error); } }; var playSequence = async (sequence, masterVolume = 1) => { if (!sequence.effects || sequence.effects.length === 0) return; for (let i = 0; i < sequence.effects.length; i++) { const effect = sequence.effects[i]; playBeep(effect, masterVolume); if (i < sequence.effects.length - 1 && sequence.interval) { await new Promise((resolve) => setTimeout(resolve, sequence.interval)); } } }; var generateWhiteNoise = (audioContext, duration, volume = 0.1) => { const sampleRate = audioContext.sampleRate; const length = sampleRate * duration; const buffer = audioContext.createBuffer(1, length, sampleRate); const data = buffer.getChannelData(0); for (let i = 0; i < length; i++) { data[i] = (Math.random() * 2 - 1) * volume; } return buffer; }; var playWhiteNoise = async (duration, volume = 0.1, masterVolume = 1) => { const audioContext = getAudioContext(); if (!audioContext) return; try { await resumeAudioContext(); const buffer = generateWhiteNoise(audioContext, duration / 1e3, volume * masterVolume); const source = audioContext.createBufferSource(); const gainNode = audioContext.createGain(); source.buffer = buffer; source.connect(gainNode); gainNode.connect(audioContext.destination); gainNode.gain.setValueAtTime(1, audioContext.currentTime); source.start(audioContext.currentTime); } catch (error) { console.warn("Failed to play white noise:", error); } }; var createSweepEffect = async (startFreq, endFreq, duration, type = "sine", volume = 0.1, masterVolume = 1) => { const audioContext = getAudioContext(); if (!audioContext) return; try { await resumeAudioContext(); const oscillator = audioContext.createOscillator(); const gainNode = audioContext.createGain(); oscillator.connect(gainNode); gainNode.connect(audioContext.destination); oscillator.type = type; oscillator.frequency.setValueAtTime(startFreq, audioContext.currentTime); oscillator.frequency.exponentialRampToValueAtTime(endFreq, audioContext.currentTime + duration / 1e3); const finalVolume = volume * masterVolume; gainNode.gain.setValueAtTime(0, audioContext.currentTime); gainNode.gain.linearRampToValueAtTime(finalVolume, audioContext.currentTime + 0.01); gainNode.gain.linearRampToValueAtTime(0, audioContext.currentTime + duration / 1e3); oscillator.start(audioContext.currentTime); oscillator.stop(audioContext.currentTime + duration / 1e3); } catch (error) { console.warn("Failed to play sweep effect:", error); } }; var soundGenerators = { dial: () => createSweepEffect(800, 400, 300, "sawtooth", 0.1), powerUp: () => createSweepEffect(200, 800, 500, "square", 0.15), powerDown: () => createSweepEffect(800, 200, 800, "square", 0.15), error: () => playBeep({ frequency: 150, duration: 1e3, type: "sawtooth", volume: 0.2 }), coin: () => playSequence({ effects: [ { frequency: 988, duration: 100, type: "square", volume: 0.15 }, { frequency: 1319, duration: 300, type: "square", volume: 0.15 } ], interval: 0 }), laser: () => createSweepEffect(1e3, 200, 150, "sawtooth", 0.1) }; // src/sound/AsciiSoundContext.tsx var import_jsx_runtime2 = require("react/jsx-runtime"); var AsciiSoundContext = (0, import_react2.createContext)(null); var AsciiSoundProvider = ({ children, defaultVolume = 0.5, defaultEnabled = true, autoResume = true }) => { const [audioContext, setAudioContext] = (0, import_react2.useState)(null); const [masterVolume, setMasterVolume] = (0, import_react2.useState)(defaultVolume); const [isEnabled, setIsEnabled] = (0, import_react2.useState)(defaultEnabled); (0, import_react2.useEffect)(() => { const context = getAudioContext(); setAudioContext(context); if (autoResume && context) { const resumeOnInteraction = () => { resumeAudioContext(); document.removeEventListener("click", resumeOnInteraction); document.removeEventListener("keydown", resumeOnInteraction); document.removeEventListener("touchstart", resumeOnInteraction); }; document.addEventListener("click", resumeOnInteraction); document.addEventListener("keydown", resumeOnInteraction); document.addEventListener("touchstart", resumeOnInteraction); return () => { document.removeEventListener("click", resumeOnInteraction); document.removeEventListener("keydown", resumeOnInteraction); document.removeEventListener("touchstart", resumeOnInteraction); }; } }, [autoResume]); const handlePlayBeep = (0, import_react2.useCallback)(async (effect) => { if (!isEnabled || masterVolume === 0) return; await playBeep(effect, masterVolume); }, [isEnabled, masterVolume]); const handlePlaySequence = (0, import_react2.useCallback)(async (sequence) => { if (!isEnabled || masterVolume === 0) return; await playSequence(sequence, masterVolume); }, [isEnabled, masterVolume]); const handlePlayPreset = (0, import_react2.useCallback)(async (presetName) => { if (!isEnabled || masterVolume === 0) return; const preset = soundPresets[presetName]; if ("effects" in preset) { await handlePlaySequence(preset); } else { await handlePlayBeep(preset); } }, [isEnabled, masterVolume, handlePlayBeep, handlePlaySequence]); const contextValue = { audioContext, masterVolume, setMasterVolume, isEnabled, setIsEnabled, playBeep: handlePlayBeep, playSequence: handlePlaySequence, playPreset: handlePlayPreset }; return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AsciiSoundContext.Provider, { value: contextValue, children }); }; var useAsciiSound = () => { const context = (0, import_react2.useContext)(AsciiSoundContext); if (!context) { return { audioContext: null, masterVolume: 0, setMasterVolume: () => { }, isEnabled: false, setIsEnabled: () => { }, playBeep: () => { }, playSequence: () => { }, playPreset: () => { } }; } return context; }; // src/sound/hooks.ts var useButtonSounds = () => { const { playPreset } = useAsciiSound(); const playClick = (0, import_react3.useCallback)(() => { playPreset("buttonClick"); }, [playPreset]); const playHover = (0, import_react3.useCallback)(() => { playPreset("buttonHover"); }, [playPreset]); return { playClick, playHover }; }; var useTerminalSounds = () => { const { playPreset } = useAsciiSound(); const playKeyPress = (0, import_react3.useCallback)(() => { playPreset("keyPress"); }, [playPreset]); const playEnter = (0, import_react3.useCallback)(() => { playPreset("enter"); }, [playPreset]); const playBackspace = (0, import_react3.useCallback)(() => { playPreset("backspace"); }, [playPreset]); return { playKeyPress, playEnter, playBackspace }; }; var useFormSounds = () => { const { playPreset } = useAsciiSound(); const playSubmit = (0, import_react3.useCallback)(() => { playPreset("formSubmit"); }, [playPreset]); const playError = (0, import_react3.useCallback)(() => { playPreset("formError"); }, [playPreset]); const playSuccess = (0, import_react3.useCallback)(() => { playPreset("success"); }, [playPreset]); return { playSubmit, playError, playSuccess }; }; var useModalSounds = () => { const { playPreset } = useAsciiSound(); const playOpen = (0, import_react3.useCallback)(() => { playPreset("modalOpen"); }, [playPreset]); const playClose = (0, import_react3.useCallback)(() => { playPreset("modalClose"); }, [playPreset]); return { playOpen, playClose }; }; var useSystemSounds = () => { const { playPreset } = useAsciiSound(); const playNotification = (0, import_react3.useCallback)(() => { playPreset("notification"); }, [playPreset]); const playAlert = (0, import_react3.useCallback)(() => { playPreset("alert"); }, [playPreset]); const playBootUp = (0, import_react3.useCallback)(() => { playPreset("bootUp"); }, [playPreset]); return { playNotification, playAlert, playBootUp }; }; var useGameSounds = () => { const { playPreset } = useAsciiSound(); const playGameStart = (0, import_react3.useCallback)(() => { playPreset("gameStart"); }, [playPreset]); const playGameOver = (0, import_react3.useCallback)(() => { playPreset("gameOver"); }, [playPreset]); return { playGameStart, playGameOver }; }; var useTypingSounds = (enabled = true) => { const { playPreset } = useAsciiSound(); const lastKeyTime = (0, import_react3.useRef)(0); const typingRate = (0, import_react3.useRef)(0); (0, import_react3.useEffect)(() => { if (!enabled) return; const handleKeyPress = (event) => { const now = Date.now(); if (lastKeyTime.current > 0) { const timeDiff = now - lastKeyTime.current; typingRate.current = Math.max(50, Math.min(200, timeDiff)); } lastKeyTime.current = now; if (event.key === "Enter") { playPreset("enter"); } else if (event.key === "Backspace") { playPreset("backspace"); } else if (event.key.length === 1) { playPreset("keyPress"); } }; document.addEventListener("keydown", handleKeyPress); return () => document.removeEventListener("keydown", handleKeyPress); }, [enabled, playPreset]); const startTyping = (0, import_react3.useCallback)(() => { lastKeyTime.current = 0; typingRate.current = 0; }, []); const stopTyping = (0, import_react3.useCallback)(() => { lastKeyTime.current = 0; }, []); return { startTyping, stopTyping }; }; var useAmbientSounds = () => { const { playBeep: playBeep2 } = useAsciiSound(); const intervalRef = (0, import_react3.useRef)(null); const startAmbient = (0, import_react3.useCallback)((type = "static") => { if (intervalRef.current) return; const playAmbientSound = () => { if (type === "static") { playBeep2({ frequency: Math.random() * 1e3 + 500, duration: Math.random() * 50 + 10, type: "sawtooth", volume: 0.02 }); } else if (type === "hum") { playBeep2({ frequency: 60 + Math.random() * 20, duration: 200, type: "sine", volume: 0.01 }); } }; intervalRef.current = setInterval(() => { if (Math.random() < 0.3) { playAmbientSound(); } }, type === "static" ? 200 : 1e3); }, [playBeep2]); const stopAmbient = (0, import_react3.useCallback)(() => { if (intervalRef.current) { clearInterval(intervalRef.current); intervalRef.current = null; } }, []); (0, import_react3.useEffect)(() => { return () => { stopAmbient(); }; }, [stopAmbient]); return { startAmbient, stopAmbient }; }; var useSoundEnabled = (soundType) => { const { playPreset, isEnabled } = useAsciiSound(); const playSound = (0, import_react3.useCallback)(() => { if (soundType) { playPreset(soundType); } }, [soundType, playPreset]); return { playSound, soundEnabled: isEnabled }; }; // src/components/AsciiButton.tsx var import_jsx_runtime3 = require("react/jsx-runtime"); var AsciiButton = ({ children, className = "", onClick, onMouseEnter, ...props }) => { const { theme } = useAsciiTheme(); const { playClick, playHover } = useButtonSounds(); const handleClick = (e) => { playClick(); onClick?.(e); }; const handleMouseEnter = (e) => { playHover(); onMouseEnter?.(e); }; return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)( "button", { ...props, onClick: handleClick, onMouseEnter: handleMouseEnter, className: ` font-mono px-1 cursor-pointer outline-none focus-visible:outline focus-visible:outline-dashed hover:opacity-80 transition-opacity ${className} `, style: { color: theme.colors.text, fontFamily: theme.typography.fontFamily, borderColor: theme.colors.border, ...props.style }, children: [ theme.characters.bracketLeft, children, theme.characters.bracketRight ] } ); }; // src/components/AsciiInput.tsx var import_jsx_runtime4 = require("react/jsx-runtime"); var AsciiInput = ({ className = "", style, onKeyDown, ...props }) => { const { theme } = useAsciiTheme(); const { playKeyPress, playEnter, playBackspace } = useTerminalSounds(); const handleKeyDown = (e) => { if (e.key === "Enter") { playEnter(); } else if (e.key === "Backspace") { playBackspace(); } else if (e.key.length === 1) { playKeyPress(); } onKeyDown?.(e); }; return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)( "span", { className: "font-mono inline-flex items-center", style: { color: theme.colors.border, fontFamily: theme.typography.fontFamily }, children: [ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "select-none", children: theme.characters.bracketLeft }), /* @__PURE__ */ (0, import_jsx_runtime4.jsx)( "input", { ...props, onKeyDown: handleKeyDown, className: ` font-mono bg-transparent border-none outline-none px-1 w-40 ${className} `, style: { color: theme.colors.text, fontFamily: theme.typography.fontFamily, backgroundColor: "transparent", ...style } } ), /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "select-none", children: theme.characters.bracketRight }) ] } ); }; // src/components/AsciiSelect.tsx var import_jsx_runtime5 = require("react/jsx-runtime"); var AsciiSelect = ({ children, className = "", ...props }) => { return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "font-mono before:content-['['] after:content-[']'] relative", children: [ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)( "select", { ...props, className: ` font-mono bg-transparent border-none outline-none pr-4 appearance-none text-white ${className} `, children } ), /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "absolute right-0 pr-1 pointer-events-none", children: "\u25BC" }) ] }); }; // src/components/AsciiDivider.tsx var import_jsx_runtime6 = require("react/jsx-runtime"); var AsciiDivider = () => { return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "font-mono overflow-hidden text-ellipsis whitespace-nowrap", children: "-".repeat(70) }); }; // src/components/AsciiCheckbox.tsx var import_jsx_runtime7 = require("react/jsx-runtime"); var AsciiCheckbox = ({ label, className = "", ...props }) => { return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: `font-mono text-white cursor-pointer inline-flex items-center ${className}`, children: [ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)( "input", { type: "checkbox", className: "sr-only", ...props } ), /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "select-none", children: [ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "inline-block w-3 text-center", children: props.checked ? "[x]" : "[ ]" }), label && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ml-1", children: label }) ] }) ] }); }; // src/components/AsciiCard.tsx var import_jsx_runtime8 = require("react/jsx-runtime"); var AsciiCard = ({ title, children, className = "", ...props }) => { const { theme } = useAsciiTheme(); return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)( "div", { ...props, className: ` font-mono border p-4 ${className} `, style: { borderColor: theme.colors.border, backgroundColor: theme.colors.surface, color: theme.colors.text, fontFamily: theme.typography.fontFamily, ...props.style }, children: [ title && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)( "div", { className: "mb-2 font-bold border-b border-dashed pb-2", style: { borderBottomColor: theme.colors.border, color: theme.colors.primary }, children: title } ), children ] } ); }; // src/components/AsciiRadioGroup.tsx var import_jsx_runtime9 = require("react/jsx-runtime"); var AsciiRadioGroup = ({ name, options, value, onChange, className = "" }) => { const handleChange = (optionValue) => { if (onChange) { onChange(optionValue); } }; return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `font-mono space-y-1 ${className}`, children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)( "label", { className: "text-white cursor-pointer inline-flex items-center w-full", children: [ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)( "input", { type: "radio", name, value: option.value, checked: value === option.value, onChange: () => handleChange(option.value), className: "sr