@contentgrowth/llm-service 0.9.95 → 0.9.97

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/ui/react/components/index.ts","../../../../src/ui/react/components/ChatBubble.tsx","../../../../src/ui/react/components/MessageBubble.tsx","../../../../src/ui/react/context/ChatConfigContext.tsx","../../../../src/ui/react/components/ChatHeader.tsx","../../../../src/ui/react/components/ChatInputArea.tsx","../../../../src/ui/react/hooks/useSpeechRecognition.ts","../../../../src/ui/react/hooks/useAudioRecorder.ts","../../../../src/ui/react/hooks/useProactiveResize.ts","../../../../src/ui/react/components/TapToTalk.tsx","../../../../src/ui/react/components/ChatMessageList.tsx","../../../../src/ui/react/components/interactive/ConfirmInteraction.tsx","../../../../src/ui/react/components/interactive/SelectInteraction.tsx","../../../../src/ui/react/components/interactive/FormInteraction.tsx","../../../../src/ui/react/components/interactive/PresentInteraction.tsx","../../../../src/ui/react/components/interactive/InteractiveMessageHandler.tsx","../../../../src/ui/react/components/ConnectionStatus.tsx","../../../../src/ui/react/components/Spinner.tsx","../../../../src/ui/react/services/whisper-client.ts","../../../../src/ui/react/utils/voice-utils.ts"],"sourcesContent":["export * from './ChatBubble';\nexport * from './MessageBubble';\nexport * from './ChatHeader';\nexport * from './ChatInputArea';\nexport * from './TapToTalk';\nexport * from './ChatMessageList';\nexport * from './ConnectionStatus';\nexport * from './Spinner';\nexport * from '../hooks/useProactiveResize';\nexport * from '../hooks/useSpeechRecognition';\nexport * from '../hooks/useAudioRecorder';\nexport * from '../types/chat';\nexport * from '../types/interactive';\nexport * from '../context/ChatConfigContext';\nexport * from '../services/whisper-client';\nexport * from '../utils/voice-utils';\n","'use client';\n\nimport React from 'react';\n\ninterface ChatBubbleProps {\n onClick: () => void;\n}\n\nexport function ChatBubble({ onClick }: ChatBubbleProps) {\n return (\n <button\n onClick={onClick}\n className=\"bg-blue-500 hover:bg-blue-600 text-white rounded-full w-12 h-12 flex items-center justify-center shadow-lg animate-pulse\"\n aria-label=\"Open chat assistant\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z\" />\n </svg>\n </button>\n );\n}\n","'use client';\n\nimport React from 'react';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport { SparklesIcon } from '@heroicons/react/24/solid';\nimport { ChatMessage } from '../types/chat';\nimport { useChatConfig } from '../context/ChatConfigContext';\n\nexport interface MessageBubbleProps {\n message: ChatMessage;\n isUser: boolean;\n userAvatarUrl?: string; // Optional user avatar URL\n onViewChanges?: (diff: { oldContent: string; newContent: string }) => void;\n}\n\nexport const MessageBubble: React.FC<MessageBubbleProps> = ({\n message,\n isUser,\n userAvatarUrl,\n onViewChanges\n}) => {\n const { user } = useChatConfig();\n const finalAvatarUrl = userAvatarUrl || user?.avatarUrl;\n const isSystem = message.role === 'system';\n\n if (isSystem) {\n return (\n <div className=\"text-center my-4\">\n <span className=\"text-xs text-gray-500 italic bg-gray-100 px-3 py-1 rounded-full\">\n {message.content}\n {message.diff && onViewChanges && (\n <button\n onClick={() => onViewChanges(message.diff!)}\n className=\"ml-2 font-semibold text-blue-600 hover:underline focus:outline-none\"\n >\n View Changes\n </button>\n )}\n </span>\n </div>\n );\n }\n\n return (\n <div className={`flex items-start gap-3 my-1 ${isUser ? 'justify-end' : 'justify-start'}`}>\n {/* Assistant Avatar */}\n {!isUser && (\n <div className=\"flex-shrink-0 h-8 w-8 rounded-full bg-blue-500 flex items-center justify-center text-white\">\n <SparklesIcon className=\"h-5 w-5\" />\n </div>\n )}\n\n {/* Content Bubble */}\n <div\n className={`max-w-[85%] px-4 py-3 rounded-2xl shadow-sm overflow-hidden ${isUser\n ? 'bg-blue-500 text-white rounded-br-none'\n : 'bg-gray-100 text-gray-800 rounded-bl-none'\n }`}>\n <div className={`text-sm ${!isUser ? 'prose prose-sm max-w-none' : ''}`}>\n {isUser ? (\n <p className=\"whitespace-pre-wrap\">{message.content}</p>\n ) : (\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n components={{\n p: ({ node, ...props }) => <p className=\"mb-2 last:mb-0\" {...props} />,\n ul: ({ node, ...props }) => <ul className=\"list-disc ml-4 mb-2\" {...props} />,\n ol: ({ node, ...props }) => <ol className=\"list-decimal ml-4 mb-2\" {...props} />,\n li: ({ node, ...props }) => <li className=\"mb-0.5\" {...props} />,\n a: ({ node, ...props }) => <a className=\"text-blue-600 hover:underline\" {...props} />,\n code: ({ node, ...props }) => <code className=\"bg-gray-200 rounded px-1 py-0.5 text-xs font-mono\" {...props} />\n }}\n >\n {message.content}\n </ReactMarkdown>\n )}\n </div>\n {message.role === 'assistant' && message.diff && onViewChanges && (\n <button\n onClick={() => onViewChanges(message.diff!)}\n className=\"mt-2 text-sm text-blue-500 hover:underline block\"\n >\n View Changes\n </button>\n )}\n {message.actionResult && message.actionResult.type === 'link' && (\n <div className=\"mt-2 pt-2 border-t border-gray-300\">\n <a\n href={message.actionResult.url}\n target={message.actionResult.target || '_blank'}\n rel=\"noopener noreferrer\"\n onClick={(e) => {\n if (message.actionResult?.target && message.actionResult.target !== '_blank') {\n e.preventDefault();\n window.open(message.actionResult.url, message.actionResult.target);\n }\n }}\n className={`inline-flex items-center gap-1 text-sm font-medium hover:underline ${isUser\n ? 'text-blue-100 hover:text-white'\n : 'text-blue-600 hover:text-blue-800'\n }`}\n >\n {message.actionResult.label}\n <svg className=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\" />\n </svg>\n </a>\n </div>\n )}\n </div>\n\n {/* User Avatar */}\n {isUser && (\n <div className=\"flex-shrink-0 h-8 w-8 rounded-full bg-gray-200 overflow-hidden flex items-center justify-center text-gray-500\">\n {finalAvatarUrl ? (\n <img\n className=\"h-full w-full object-cover\"\n src={finalAvatarUrl}\n alt=\"User\"\n onError={(e) => {\n // Hide image and show fallback icon if load fails involves state, \n // but for a simple component we can just hide it or let the parent handle it.\n // For now, let's just render the icon if no url, \n // preventing the broken image icon requires state or a different approach (like standard Radix Avatar).\n // A simple hack: set src to a transparent pixel or hide display.\n (e.target as HTMLImageElement).style.display = 'none';\n (e.target as HTMLImageElement).parentElement?.classList.remove('bg-gray-200'); // Clean up?\n // Actually, better to just render the fallback SVG behind it?\n // Let's try separate conditional structure.\n }}\n />\n ) : (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" className=\"w-5 h-5\">\n <path fillRule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clipRule=\"evenodd\" />\n </svg>\n )}\n </div>\n )}\n </div>\n );\n};\n","import React, { createContext, useContext, ReactNode } from 'react';\nimport { VoiceConfig } from '../types/chat';\n\nexport interface ChatConfig {\n user?: {\n avatarUrl?: string;\n name?: string;\n };\n voice?: {\n enabled: boolean;\n config?: VoiceConfig;\n };\n}\n\nconst ChatConfigContext = createContext<ChatConfig>({});\n\nexport const ChatConfigProvider: React.FC<{\n config: ChatConfig;\n children: ReactNode;\n}> = ({ config, children }) => {\n return (\n <ChatConfigContext.Provider value={config}>\n {children}\n </ChatConfigContext.Provider>\n );\n};\n\nexport const useChatConfig = () => useContext(ChatConfigContext);\n","'use client';\n\nimport React from 'react';\nimport { ChatTask } from '../types/chat';\n\ninterface ChatHeaderProps {\n contextTitle: string;\n currentTask: ChatTask | null;\n onClose: () => void;\n}\n\nexport function ChatHeader({\n contextTitle,\n currentTask,\n onClose\n}: ChatHeaderProps) {\n return (\n <div className=\"bg-blue-500 text-white px-4 py-4 flex justify-between items-center\">\n <h3 className=\"font-medium text-lg\">\n {currentTask\n ? `DoveText Virtual Assistant (${currentTask.currentStep}/${currentTask.steps})`\n : `DoveText Virtual Assistant (${contextTitle})`}\n </h3>\n <button\n onClick={onClose}\n className=\"bg-blue-600 hover:bg-blue-700 text-white rounded-full p-1.5 flex items-center justify-center transition-colors cursor-pointer\"\n aria-label=\"Close chat\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path fillRule=\"evenodd\" d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\" clipRule=\"evenodd\" />\n </svg>\n </button>\n </div>\n );\n}\n","'use client';\n\nimport React, { useState, useRef, FormEvent, useImperativeHandle, forwardRef, useEffect, useCallback, useLayoutEffect } from 'react';\nimport { MicrophoneIcon, StopIcon, PaperAirplaneIcon, XMarkIcon, Square2StackIcon } from '@heroicons/react/24/outline';\nimport { ChatMessage, ChatTask, VoiceConfig } from '../types/chat';\nimport { InteractiveFunction } from '../types/interactive';\nimport { useSpeechRecognition } from '../hooks/useSpeechRecognition';\nimport { useAudioRecorder } from '../hooks/useAudioRecorder';\nimport { useProactiveResize } from '../hooks/useProactiveResize';\nimport { useChatConfig } from '../context/ChatConfigContext';\n\n// VoiceConfig imported from types/chat\n\ninterface ChatInputAreaProps {\n onSubmit: (message: string) => void;\n isSending: boolean;\n showInputForm: boolean;\n currentTask: ChatTask | null;\n lastInteractiveMessage?: ChatMessage | null;\n voiceConfig?: VoiceConfig;\n onStop?: () => void;\n hintText?: string;\n placeholder?: string;\n // Controlled props\n value?: string;\n onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;\n defaultInputMode?: 'text' | 'voice'; // Deprecated but kept for compatibility\n}\n\n// Define the handle type for the forwarded ref\nexport interface ChatInputAreaHandle {\n focus: () => void;\n setValue: (value: string) => void;\n}\n\nexport const ChatInputArea = forwardRef<ChatInputAreaHandle, ChatInputAreaProps>(({\n onSubmit,\n isSending,\n showInputForm,\n currentTask,\n lastInteractiveMessage,\n voiceConfig: propVoiceConfig, // Rename to distinguish from context\n onStop,\n hintText,\n placeholder,\n value,\n onChange,\n defaultInputMode = 'text'\n}, ref) => {\n const [internalMessage, setInternalMessage] = useState('');\n const [voiceTrigger, setVoiceTrigger] = useState<'click' | 'space' | null>(null);\n const [isTranscribing, setIsTranscribing] = useState(false);\n const [voiceError, setVoiceError] = useState<string | null>(null);\n const [isFocused, setIsFocused] = useState(false);\n\n // Debug Mode State\n const [showDebug, setShowDebug] = useState(false);\n const [logs, setLogs] = useState<string[]>([]);\n const tapCountRef = useRef<{ count: number, lastTap: number }>({ count: 0, lastTap: 0 });\n\n // Console Interceptor for Debug Mode\n useEffect(() => {\n const originalLog = console.log;\n const originalWarn = console.warn;\n const originalError = console.error;\n\n const addLog = (type: string, args: any[]) => {\n // Only keep logs if we are potentially debugging, to save memory? \n // Or just keep last 50 always. Let's keep last 50.\n try {\n const msg = args.map(arg => {\n if (arg instanceof Error) return `${arg.name}: ${arg.message}`;\n if (typeof arg === 'object') return JSON.stringify(arg);\n return String(arg);\n }).join(' ');\n setLogs(prev => [`[${type}] ${msg}`, ...prev].slice(0, 50));\n } catch (e) {\n // Ignore serialization errors\n }\n };\n\n console.log = (...args) => { originalLog(...args); addLog('LOG', args); };\n console.warn = (...args) => { originalWarn(...args); addLog('WRN', args); };\n console.error = (...args) => { originalError(...args); addLog('ERR', args); };\n\n return () => {\n console.log = originalLog;\n console.warn = originalWarn;\n console.error = originalError;\n };\n }, []);\n\n const copyLogs = useCallback(() => {\n navigator.clipboard.writeText(logs.join('\\n'))\n .then(() => alert('Logs copied to clipboard'))\n .catch(err => console.error('Failed to copy logs', err));\n }, [logs]);\n // The left button toggles recording, but input is always text.\n\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const measurementRef = useRef<HTMLSpanElement>(null);\n const pendingSelectionRef = useRef<{ start: number, end: number } | null>(null);\n\n // Determine if controlled or uncontrolled\n const isControlled = value !== undefined;\n const message = isControlled ? value : internalMessage;\n\n // Use refs to access latest state in stable callbacks\n const messageRef = useRef(message);\n messageRef.current = message;\n\n // Use useLayoutEffect to apply selection before browser paint\n useLayoutEffect(() => {\n if (pendingSelectionRef.current && textareaRef.current) {\n const { start, end } = pendingSelectionRef.current;\n textareaRef.current.focus();\n textareaRef.current.setSelectionRange(start, end);\n pendingSelectionRef.current = null;\n }\n }, [message]);\n\n const onChangeRef = useRef(onChange);\n useEffect(() => {\n onChangeRef.current = onChange;\n }, [onChange]);\n\n // Get global config\n const { voice: globalVoice } = useChatConfig();\n\n // Determine effective voice config\n const isVoiceEnabled = globalVoice?.enabled ?? (!!propVoiceConfig);\n const voiceConfig = isVoiceEnabled ? (propVoiceConfig || globalVoice?.config) : undefined;\n\n const voiceConfigRef = useRef(voiceConfig);\n useEffect(() => {\n voiceConfigRef.current = voiceConfig;\n }, [voiceConfig]);\n\n const triggerChange = useCallback((newValue: string) => {\n setVoiceError(null); // Clear any errors when content changes\n if (isControlled && onChangeRef.current) {\n const syntheticEvent = {\n target: { value: newValue },\n currentTarget: { value: newValue }\n } as React.ChangeEvent<HTMLTextAreaElement>;\n onChangeRef.current(syntheticEvent);\n } else {\n setInternalMessage(newValue);\n }\n }, [isControlled]);\n\n // Apply auto-resize\n const isInputDisabled = currentTask?.complete ||\n (lastInteractiveMessage?.interactive &&\n ((lastInteractiveMessage?.interactiveData?.function === 'form' && !lastInteractiveMessage?.isResponseSubmitted) ||\n (lastInteractiveMessage?.interactiveData?.function === 'confirm' && !lastInteractiveMessage?.isResponseSubmitted)));\n\n useProactiveResize(textareaRef, measurementRef, message, isInputDisabled || !!voiceTrigger);\n\n // Helper to insert text at cursor position\n const insertTextAtCursor = useCallback((text: string) => {\n const textarea = textareaRef.current;\n const currentVal = messageRef.current || '';\n\n if (!textarea) {\n triggerChange(currentVal + (currentVal ? ' ' : '') + text);\n return;\n }\n\n const start = textarea.selectionStart;\n const end = textarea.selectionEnd;\n\n const before = currentVal.substring(0, start);\n const after = currentVal.substring(end);\n\n // Add padding space if needed (e.g. not at start and previous char is not space)\n const prefix = (start > 0 && !/\\s$/.test(before)) ? ' ' : '';\n\n const newText = before + prefix + text + after;\n\n // Calculate and store pending selection so it can be applied after render\n const selectionStart = start + prefix.length;\n const selectionEnd = selectionStart + text.length;\n pendingSelectionRef.current = { start: selectionStart, end: selectionEnd };\n\n triggerChange(newText);\n }, [triggerChange]);\n\n // Stable Voice Callbacks\n const handleVoiceResult = useCallback((text: string, isFinal: boolean) => {\n if (isFinal) {\n insertTextAtCursor(text);\n }\n }, [insertTextAtCursor]);\n\n const handleVoiceEnd = useCallback(() => {\n setVoiceTrigger(null);\n // If native and we were listening, it's done. \n // Note: Native recognition result comes via handleVoiceResult\n voiceConfigRef.current?.onVoiceEnd?.();\n }, []);\n\n // Voice Hooks\n const nativeSpeech = useSpeechRecognition(handleVoiceResult, handleVoiceEnd, voiceConfig?.language);\n\n // Sync native errors to UI\n useEffect(() => {\n if (nativeSpeech.error) {\n setVoiceError(nativeSpeech.error);\n // Also ensure it is logged for dev mode\n console.error('[ChatInputArea] Native Speech Error:', nativeSpeech.error);\n }\n }, [nativeSpeech.error]);\n\n const customRecorder = useAudioRecorder(async (blob) => {\n setVoiceTrigger(null);\n setIsTranscribing(true);\n setVoiceError(null);\n voiceConfigRef.current?.onVoiceEnd?.();\n\n if (blob.type === 'audio/simulated') {\n console.log('[ChatInputArea] Handling simulated audio capture');\n // Mock delay for simulation\n await new Promise(resolve => setTimeout(resolve, 1500));\n insertTextAtCursor('This is a simulated transcription for development testing.');\n setIsTranscribing(false);\n return;\n }\n\n if (voiceConfigRef.current?.onAudioCapture) {\n try {\n const text = await voiceConfigRef.current.onAudioCapture(blob);\n if (text) insertTextAtCursor(text);\n } catch (e: any) {\n console.error('[ChatInputArea] Audio capture failed', e);\n setVoiceError(e.message || 'Transcription failed');\n } finally {\n setIsTranscribing(false);\n }\n } else {\n setIsTranscribing(false);\n }\n });\n\n // Expose the focus and setValue method\n useImperativeHandle(ref, () => ({\n focus: () => {\n textareaRef.current?.focus();\n },\n setValue: (newValue: string) => {\n triggerChange(newValue);\n }\n }));\n\n const handleSubmit = (e?: FormEvent) => {\n if (e) e.preventDefault();\n\n if (!message.trim()) {\n setTimeout(() => textareaRef.current?.focus(), 0);\n return;\n }\n\n const currentMessage = message;\n triggerChange(''); // Clear input\n setTimeout(() => textareaRef.current?.focus(), 0);\n onSubmit(currentMessage);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey && !e.metaKey && !e.altKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n // Mobile detection helper\n const isMobile = useCallback(() => {\n if (typeof window === 'undefined') return false;\n return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ||\n ('ontouchstart' in window) ||\n (navigator.maxTouchPoints > 0);\n }, []);\n\n const startRecording = async (trigger: 'click' | 'space') => {\n console.log('[ChatInputArea] startRecording called. trigger:', trigger, 'isMobile:', isMobile());\n console.log('[ChatInputArea] Current state - voiceTrigger:', voiceTrigger, 'isTranscribing:', isTranscribing);\n\n // FIX: Ensure keyboard is dismissed and focus changes are complete BEFORE starting recognition on mobile\n if (isMobile()) {\n console.log('[ChatInputArea] SKIPPING textarea focus on mobile to prevent keyboard conflict');\n // Explicitly blur any active element to ensure keyboard is dismissed and doesn't fight for focus\n if (document.activeElement instanceof HTMLElement) {\n console.log('[ChatInputArea] Blur active element on mobile BEFORE start');\n document.activeElement.blur();\n }\n }\n\n if (voiceTrigger || isTranscribing) {\n console.log('[ChatInputArea] startRecording ignored - already active');\n return;\n }\n\n setVoiceTrigger(trigger);\n setVoiceError(null);\n\n if (voiceConfig?.mode === 'native') {\n console.log('[ChatInputArea] Using native speech recognition');\n if (!nativeSpeech.isSupported) {\n console.error('[ChatInputArea] Native speech not supported');\n alert('Speech recognition is not supported in this browser.');\n setVoiceTrigger(null);\n return;\n }\n console.log('[ChatInputArea] Calling nativeSpeech.start()...');\n nativeSpeech.start();\n console.log('[ChatInputArea] nativeSpeech.start() called');\n\n console.log('[ChatInputArea] Calling voiceConfig.onVoiceStart if exists (after nativeSpeech.start)...');\n try {\n voiceConfig?.onVoiceStart?.();\n console.log('[ChatInputArea] voiceConfig.onVoiceStart completed');\n } catch (e) {\n console.error('[ChatInputArea] voiceConfig.onVoiceStart threw error', e);\n }\n } else {\n console.log('[ChatInputArea] Using custom recorder');\n console.log('[ChatInputArea] Calling voiceConfig.onVoiceStart if exists (custom mode)...');\n try {\n voiceConfig?.onVoiceStart?.();\n console.log('[ChatInputArea] voiceConfig.onVoiceStart completed');\n } catch (e) {\n console.error('[ChatInputArea] voiceConfig.onVoiceStart threw error', e);\n }\n await customRecorder.start();\n console.log('[ChatInputArea] Custom recorder started');\n }\n\n // Desktop only: Refocus textarea for convenience\n if (!isMobile()) {\n console.log('[ChatInputArea] Re-focusing textarea (desktop only)');\n setTimeout(() => textareaRef.current?.focus(), 0);\n }\n };\n\n const stopRecording = () => {\n if (!voiceTrigger) return;\n if (voiceConfig?.mode === 'native') {\n nativeSpeech.stop();\n } else {\n customRecorder.stop();\n }\n };\n\n // Determine placeholder text\n const getPlaceholder = () => {\n if (placeholder) return placeholder;\n if (voiceTrigger) return 'Listening...';\n if (currentTask?.complete) return 'Task completed!';\n\n if (lastInteractiveMessage?.interactive && lastInteractiveMessage?.interactiveData && !lastInteractiveMessage?.isResponseSubmitted) {\n const interactiveType = lastInteractiveMessage.interactiveData.function as InteractiveFunction;\n switch (interactiveType) {\n case 'chat': return 'Type your response...';\n case 'confirm': return 'Select Yes or No, or type your response...';\n case 'select': return 'Choose an option or type your response...';\n case 'form': return 'Fill out the form...';\n default: return 'Type your response...';\n }\n }\n return currentTask ? 'Continue your conversation...' : 'Ask me anything...';\n };\n\n const inputHint = (!isInputDisabled && !lastInteractiveMessage?.interactive) ? null :\n (lastInteractiveMessage?.interactiveData?.function === 'form' ? 'Please provide information by completing above form' : null);\n\n if (!showInputForm) {\n return null;\n }\n\n return (\n <div className=\"flex flex-col w-full relative\">\n {/* Debug Overlay */}\n {showDebug && (\n <div className=\"absolute bottom-full left-0 right-0 mb-2 p-2 bg-black/80 text-green-400 text-xs font-mono h-48 overflow-y-auto rounded z-50 pointer-events-auto\">\n <div className=\"flex justify-between items-center bg-gray-800 p-1 mb-1\">\n <span>Debug Logs</span>\n <div className=\"flex gap-2\">\n <button onClick={copyLogs} className=\"text-white hover:text-blue-400\" title=\"Copy Logs\">\n <Square2StackIcon className=\"w-4 h-4\" />\n </button>\n <button onClick={() => { copyLogs(); setShowDebug(false); }} className=\"text-white hover:text-red-400\" title=\"Copy & Close\">\n <XMarkIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n {logs.map((log, i) => (\n <div key={i} className=\"mb-0.5 border-b border-gray-700/50 pb-0.5 break-all\">\n {log}\n </div>\n ))}\n {logs.length === 0 && <div>No logs yet...</div>}\n </div>\n )}\n\n <div className=\"flex items-center gap-2\">\n {/* Voice Toggle Button (Replacing the Mode Switch) */}\n {voiceConfig && (\n <button\n type=\"button\"\n onClick={() => {\n // Debug Trigger: 5 rapid taps\n const now = Date.now();\n if (now - tapCountRef.current.lastTap < 500) {\n tapCountRef.current.count++;\n } else {\n tapCountRef.current.count = 1;\n }\n tapCountRef.current.lastTap = now;\n\n if (tapCountRef.current.count >= 5) {\n setShowDebug(prev => !prev);\n tapCountRef.current.count = 0;\n // Force stop recording if we accidentally triggered it while tapping\n stopRecording();\n return;\n }\n\n if (voiceTrigger) {\n stopRecording();\n } else if (!isTranscribing) {\n startRecording('click');\n }\n }}\n className={`mb-1 p-2 rounded-full transition-all duration-300 flex-shrink-0 border ${isTranscribing\n ? 'text-white border-indigo-500 bg-indigo-600 scale-110 shadow-lg'\n : voiceTrigger\n ? 'text-white border-orange-400 bg-orange-500 scale-110 shadow-lg'\n : 'text-gray-500 border-gray-300 bg-white hover:text-gray-700 hover:bg-gray-100'\n } ${voiceTrigger ? 'animate-pulse' : ''} ${isTranscribing ? 'cursor-wait' : ''}`}\n disabled={isTranscribing}\n title={isTranscribing ? \"Transcribing...\" : voiceTrigger ? \"Stop Recording\" : \"Start Voice Input\"}\n >\n {isTranscribing ? (\n <div className=\"animate-spin w-5 h-5 flex items-center justify-center\">\n <svg className=\"w-5 h-5 text-white\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" fill=\"none\" />\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\" />\n </svg>\n </div>\n ) : (\n <MicrophoneIcon className=\"w-5 h-5\" />\n )}\n </button>\n )}\n\n {/* Main Input Area */}\n <div\n tabIndex={-1}\n className={`flex-1 flex items-center border border-gray-300 rounded-lg overflow-hidden outline-none bg-white min-h-[42px] mb-1 transition-all ${voiceTrigger ? 'ring-2 ring-orange-100 border-orange-300' : 'focus-within:ring-2 focus-within:ring-blue-500 focus-within:border-blue-500'\n }`}\n >\n {/* Text Input (Always Visible) */}\n <span\n ref={measurementRef}\n className=\"absolute invisible whitespace-pre-wrap p-0 m-0 text-gray-700 leading-6\"\n style={{ fontSize: '1rem' }}\n />\n <textarea\n ref={textareaRef}\n value={message}\n onChange={(e) => {\n if (isControlled && onChange) {\n onChange(e);\n } else {\n setInternalMessage(e.target.value);\n }\n }}\n onKeyDown={handleKeyDown}\n onFocus={() => {\n setIsFocused(true);\n setVoiceError(null); // Clear error on focus\n }}\n onBlur={() => setIsFocused(false)}\n placeholder={getPlaceholder()}\n disabled={isInputDisabled}\n readOnly={!!voiceTrigger || isTranscribing}\n rows={1}\n className={`flex-grow px-4 py-2 outline-none text-gray-700 placeholder-gray-500 resize-none leading-6 w-full ${isInputDisabled ? 'bg-gray-100 cursor-not-allowed' : 'bg-transparent'\n } ${voiceTrigger || isTranscribing ? 'cursor-default' : ''}`}\n />\n\n {/* Send / Stop Button */}\n <div className=\"relative mx-2 flex-shrink-0\">\n {/* Spinner Overlay */}\n {isSending && (\n <div className=\"absolute -inset-1\">\n <svg\n className=\"animate-spin h-full w-full text-blue-500 opacity-75\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n ></circle>\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n ></path>\n </svg>\n </div>\n )}\n\n <button\n type=\"button\"\n onClick={(e) => {\n if (isSending && onStop) {\n e.preventDefault();\n onStop();\n } else {\n handleSubmit();\n }\n }}\n disabled={currentTask?.complete || (isSending && !onStop) || isInputDisabled}\n className={`relative z-10 text-white rounded-full p-2 transition-colors duration-200 disabled:bg-gray-400 disabled:cursor-not-allowed ${isSending && onStop\n ? 'bg-red-500 hover:bg-red-600'\n : 'bg-blue-600 hover:bg-blue-700'\n }`}\n title={isSending && onStop ? \"Stop generating\" : \"Send message\"}\n >\n {isSending ? (\n onStop ? <StopIcon className=\"h-5 w-5\" /> : <div className=\"w-5 h-5\" /> // Spinner handles the visual\n ) : (\n <PaperAirplaneIcon className=\"h-5 w-5\" />\n )}\n </button>\n </div>\n </div>\n </div>\n\n {/* Helper Hints */}\n {inputHint && (\n <div className=\"text-sm text-red-500 bg-red-50 py-1 px-4 rounded-lg mt-1\">\n {inputHint}\n </div>\n )}\n\n {/* Dynamic Interaction Hint */}\n <div className=\"ml-[46px] mb-2 mt-0.5 min-h-[0.75rem]\" style={{ marginLeft: '48px' }}>\n <p className={`text-[10px] leading-tight transition-all duration-200 ${voiceError\n ? 'text-red-500'\n : isTranscribing\n ? 'text-indigo-600 font-bold'\n : voiceTrigger\n ? 'text-orange-600 font-medium'\n : 'text-gray-400'\n }`}>\n {voiceError ? (\n <span className=\"flex items-center gap-1 font-semibold italic\">\n Error: {voiceError}\n </span>\n ) : isTranscribing ? (\n 'Transcribing... please wait'\n ) : voiceTrigger ? (\n 'Transcribing, please wait...'\n ) : voiceTrigger ? (\n 'Listening... tap mic icon again to stop'\n ) : (\n hintText || (voiceConfig ? 'Type in text or tap mic icon to talk' : 'Type your message...')\n )}\n </p>\n </div>\n </div>\n );\n});\n\nChatInputArea.displayName = 'ChatInputArea';\n","import { useState, useEffect, useCallback, useRef } from 'react';\n\nexport interface SpeechRecognitionHook {\n isListening: boolean;\n transcript: string;\n start: () => void;\n stop: () => void;\n resetTranscript: () => void;\n isSupported: boolean;\n error: string | null;\n}\n\ninterface SpeechRecognitionEvent {\n results: {\n [index: number]: {\n [index: number]: {\n transcript: string;\n };\n isFinal: boolean;\n };\n length: number;\n };\n}\n\ninterface SpeechRecognitionErrorEvent {\n error: string;\n}\n\nexport const useSpeechRecognition = (\n onResult?: (text: string, isFinal: boolean) => void,\n onEnd?: () => void,\n language: string = 'en-US'\n): SpeechRecognitionHook => {\n const [isListening, setIsListening] = useState(false);\n const [transcript, setTranscript] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [isSupported, setIsSupported] = useState(false);\n\n const recognitionRef = useRef<any>(null);\n const isSimulatingRef = useRef(false);\n const simulationTimeoutRef = useRef<any>(null);\n const languageRef = useRef(language);\n const instanceIdRef = useRef<string>(Math.random().toString(36).slice(2));\n const lastStartAtRef = useRef<number | null>(null);\n const lastStopAtRef = useRef<number | null>(null);\n\n const onResultRef = useRef(onResult);\n const onEndRef = useRef(onEnd);\n\n useEffect(() => {\n onResultRef.current = onResult;\n onEndRef.current = onEnd;\n }, [onResult, onEnd]);\n\n useEffect(() => {\n languageRef.current = language;\n // Update language on existing instance if present\n if (recognitionRef.current) {\n console.log('[useSpeechRecognition] Updating language to:', language);\n recognitionRef.current.lang = language;\n }\n }, [language]);\n\n const isStartingRef = useRef(false);\n\n // Check if SpeechRecognition is supported (without creating instance)\n useEffect(() => {\n if (typeof window !== 'undefined') {\n const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;\n console.log('[useSpeechRecognition] Env - isSecureContext:', (window as any).isSecureContext, 'protocol:', window.location?.protocol);\n const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ||\n ('ontouchstart' in window) ||\n (navigator.maxTouchPoints > 0);\n console.log('[useSpeechRecognition] Init check - SpeechRecognition available:', !!SpeechRecognition, 'isMobile:', isMobile, 'instanceId:', instanceIdRef.current);\n setIsSupported(!!SpeechRecognition);\n }\n\n return () => {\n console.log('[useSpeechRecognition] Effect cleanup - stopping recognition');\n if (isSimulatingRef.current && simulationTimeoutRef.current) {\n clearTimeout(simulationTimeoutRef.current);\n simulationTimeoutRef.current = null;\n }\n if (recognitionRef.current) {\n try {\n recognitionRef.current.stop();\n } catch (e) {\n // Ignore errors during cleanup\n }\n recognitionRef.current = null;\n }\n\n if (typeof window !== 'undefined') {\n const w = window as any;\n if (w.__llmSpeechRecognitionActiveInstanceId === instanceIdRef.current) {\n console.log('[useSpeechRecognition] Cleanup clearing global active instance lock. instanceId:', instanceIdRef.current);\n w.__llmSpeechRecognitionActiveInstanceId = null;\n }\n }\n }\n }, []);\n\n // Helper to create and configure a fresh recognition instance\n // IMPORTANT: On iOS Safari, this MUST be called within user gesture context (click/tap handler)\n const createRecognitionInstance = useCallback(() => {\n const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;\n if (!SpeechRecognition) {\n console.error('[useSpeechRecognition] SpeechRecognition not available');\n return null;\n }\n\n console.log('[useSpeechRecognition] Creating NEW recognition instance within user gesture context. Timestamp:', Date.now());\n const recognition = new SpeechRecognition();\n const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ||\n ('ontouchstart' in window) ||\n (navigator.maxTouchPoints > 0);\n recognition.continuous = !isMobile;\n recognition.interimResults = true;\n recognition.lang = languageRef.current;\n console.log('[useSpeechRecognition] Instance created. continuous:', recognition.continuous, 'interimResults:', recognition.interimResults, 'lang:', recognition.lang, 'isMobile:', isMobile, 'instanceId:', instanceIdRef.current);\n\n recognition.onaudiostart = () => {\n console.log('[useSpeechRecognition] Native onaudiostart. Timestamp:', Date.now(), 'instanceId:', instanceIdRef.current);\n };\n recognition.onaudioend = () => {\n console.log('[useSpeechRecognition] Native onaudioend. Timestamp:', Date.now(), 'instanceId:', instanceIdRef.current);\n };\n recognition.onsoundstart = () => {\n console.log('[useSpeechRecognition] Native onsoundstart. Timestamp:', Date.now(), 'instanceId:', instanceIdRef.current);\n };\n recognition.onsoundend = () => {\n console.log('[useSpeechRecognition] Native onsoundend. Timestamp:', Date.now(), 'instanceId:', instanceIdRef.current);\n };\n recognition.onspeechstart = () => {\n console.log('[useSpeechRecognition] Native onspeechstart. Timestamp:', Date.now(), 'instanceId:', instanceIdRef.current);\n };\n recognition.onspeechend = () => {\n console.log('[useSpeechRecognition] Native onspeechend. Timestamp:', Date.now(), 'instanceId:', instanceIdRef.current);\n };\n recognition.onnomatch = () => {\n console.log('[useSpeechRecognition] Native onnomatch. Timestamp:', Date.now(), 'instanceId:', instanceIdRef.current);\n };\n\n recognition.onstart = () => {\n console.log('[useSpeechRecognition] Native onstart event fired. Timestamp:', Date.now());\n isStartingRef.current = false;\n setIsListening(true);\n setError(null);\n\n if (typeof window !== 'undefined') {\n const w = window as any;\n w.__llmSpeechRecognitionActiveInstanceId = instanceIdRef.current;\n console.log('[useSpeechRecognition] Set global active instance lock. instanceId:', instanceIdRef.current);\n }\n };\n\n recognition.onend = () => {\n console.log('[useSpeechRecognition] Native onend event fired. Timestamp:', Date.now());\n isStartingRef.current = false;\n if (isSimulatingRef.current) {\n console.log('[useSpeechRecognition] onend ignored - simulating');\n return;\n }\n setIsListening(false);\n if (onEndRef.current) onEndRef.current();\n\n if (typeof window !== 'undefined') {\n const w = window as any;\n if (w.__llmSpeechRecognitionActiveInstanceId === instanceIdRef.current) {\n w.__llmSpeechRecognitionActiveInstanceId = null;\n console.log('[useSpeechRecognition] Cleared global active instance lock. instanceId:', instanceIdRef.current);\n }\n }\n };\n\n recognition.onresult = (event: SpeechRecognitionEvent) => {\n console.log('[useSpeechRecognition] onresult event. results count:', event.results.length);\n let interimTranscript = '';\n let finalTranscript = '';\n\n for (let i = event.results.length - 1; i < event.results.length; ++i) {\n const result = event.results[i];\n if (result.isFinal) {\n finalTranscript += result[0].transcript;\n console.log('[useSpeechRecognition] Final transcript:', finalTranscript);\n if (onResultRef.current) onResultRef.current(finalTranscript, true);\n } else {\n interimTranscript += result[0].transcript;\n console.log('[useSpeechRecognition] Interim transcript:', interimTranscript);\n if (onResultRef.current) onResultRef.current(interimTranscript, false);\n }\n }\n\n setTranscript(prev => prev + finalTranscript);\n };\n\n recognition.onerror = (event: SpeechRecognitionErrorEvent) => {\n console.error('[useSpeechRecognition] Native onerror event:', event.error, 'Timestamp:', Date.now());\n console.error('[useSpeechRecognition] Error context - lastStartAt:', lastStartAtRef.current, 'lastStopAt:', lastStopAtRef.current, 'instanceId:', instanceIdRef.current);\n console.error('[useSpeechRecognition] Error details - This could be caused by:');\n if (event.error === 'aborted') {\n console.error('[useSpeechRecognition] - aborted: Recognition was aborted. Common causes: keyboard appeared, focus changed, another recognition started, or page navigation');\n } else if (event.error === 'not-allowed') {\n console.error('[useSpeechRecognition] - not-allowed: Microphone permission denied');\n } else if (event.error === 'no-speech') {\n console.error('[useSpeechRecognition] - no-speech: No speech detected');\n } else if (event.error === 'network') {\n console.error('[useSpeechRecognition] - network: Network error during recognition');\n }\n isStartingRef.current = false;\n \n // Dev mode fallback: Simulate speech if permission is denied\n if (event.error === 'not-allowed' && process.env.NODE_ENV === 'development') {\n console.warn('Speech recognition blocked. Simulating input for development...');\n isSimulatingRef.current = true;\n setError(null);\n setIsListening(true);\n\n simulationTimeoutRef.current = setTimeout(() => {\n const mockText = \"This is a simulated voice input for testing.\";\n setTranscript(prev => prev + (prev ? ' ' : '') + mockText);\n if (onResultRef.current) onResultRef.current(mockText, true);\n\n isSimulatingRef.current = false;\n setIsListening(false);\n if (onEndRef.current) onEndRef.current();\n simulationTimeoutRef.current = null;\n }, 3000);\n return;\n }\n\n console.error('Speech recognition error', event.error);\n setError(event.error);\n setIsListening(false);\n\n if (typeof window !== 'undefined') {\n const w = window as any;\n if (w.__llmSpeechRecognitionActiveInstanceId === instanceIdRef.current) {\n w.__llmSpeechRecognitionActiveInstanceId = null;\n console.log('[useSpeechRecognition] Cleared global active instance lock after error. instanceId:', instanceIdRef.current);\n }\n }\n };\n\n return recognition;\n }, []);\n\n const start = useCallback(() => {\n const startTimestamp = Date.now();\n console.log('[useSpeechRecognition] start() called. Timestamp:', startTimestamp);\n console.log('[useSpeechRecognition] State check - isListening:', isListening, 'isStarting:', isStartingRef.current, 'hasExistingInstance:', !!recognitionRef.current);\n \n // Check if document has focus (important for mobile)\n if (typeof document !== 'undefined') {\n console.log('[useSpeechRecognition] Document hasFocus:', document.hasFocus(), 'activeElement:', document.activeElement?.tagName);\n }\n\n if (isSimulatingRef.current) {\n console.log('[useSpeechRecognition] isSimulating, ignoring start');\n return;\n }\n\n if (isStartingRef.current) {\n console.warn('[useSpeechRecognition] Already starting - ignoring duplicate call');\n return;\n }\n\n // Use our state as proxy\n if (isListening) {\n console.warn('[useSpeechRecognition] App state says already listening - ignoring');\n return;\n }\n\n if (typeof window !== 'undefined') {\n const w = window as any;\n if (w.__llmSpeechRecognitionActiveInstanceId && w.__llmSpeechRecognitionActiveInstanceId !== instanceIdRef.current) {\n console.error('[useSpeechRecognition] Another recognition instance appears active. activeInstanceId:', w.__llmSpeechRecognitionActiveInstanceId, 'thisInstanceId:', instanceIdRef.current);\n }\n }\n\n try {\n // FIX FOR iOS SAFARI: Create a FRESH recognition instance on each start()\n // iOS requires the instance to be created within user gesture context (click/tap)\n // Reusing an instance created in useEffect doesn't work on iOS Safari\n \n // Stop and clean up any existing instance first\n if (recognitionRef.current) {\n console.log('[useSpeechRecognition] Stopping existing instance before creating new one');\n try {\n recognitionRef.current.stop();\n } catch (e) {\n // Ignore - may not be running\n }\n recognitionRef.current = null;\n }\n\n // Create fresh instance within user gesture context\n const recognition = createRecognitionInstance();\n if (!recognition) {\n console.error('[useSpeechRecognition] Failed to create recognition instance');\n setError('Speech recognition not available');\n return;\n }\n recognitionRef.current = recognition;\n\n setTranscript('');\n isStartingRef.current = true;\n lastStartAtRef.current = Date.now();\n console.log('[useSpeechRecognition] About to call recognition.start(). Timestamp:', Date.now());\n recognitionRef.current.start();\n console.log('[useSpeechRecognition] recognition.start() executed successfully. Timestamp:', Date.now());\n } catch (error: any) {\n isStartingRef.current = false;\n console.error('[useSpeechRecognition] Failed to start recognition:', error?.message || error);\n if (error?.name === 'InvalidStateError') {\n console.error('[useSpeechRecognition] InvalidStateError - recognition may already be running');\n }\n setError(error?.message || 'Failed to start speech recognition');\n }\n }, [isListening, createRecognitionInstance]);\n\n const stop = useCallback(() => {\n console.log('[useSpeechRecognition] stop() called');\n lastStopAtRef.current = Date.now();\n if (isSimulatingRef.current) {\n if (simulationTimeoutRef.current) {\n clearTimeout(simulationTimeoutRef.current);\n simulationTimeoutRef.current = null;\n }\n // If stopped manually during simulation, we can either cancel or complete.\n // Let's complete it so user sees something.\n const mockText = \"This is a simulated voice input for testing.\";\n setTranscript(prev => prev + (prev ? ' ' : '') + mockText);\n if (onResultRef.current) onResultRef.current(mockText, true);\n\n isSimulatingRef.current = false;\n setIsListening(false);\n if (onEndRef.current) onEndRef.current();\n return;\n }\n\n if (recognitionRef.current) {\n recognitionRef.current.stop();\n console.log('[useSpeechRecognition] recognition.stop() executed');\n }\n }, []);\n\n const resetTranscript = useCallback(() => {\n setTranscript('');\n }, []);\n\n return {\n isListening,\n transcript,\n start,\n stop,\n resetTranscript,\n isSupported,\n error\n };\n};\n","import { useState, useRef, useCallback } from 'react';\n\nexport interface AudioRecorderHook {\n isRecording: boolean;\n isSimulated: boolean;\n start: () => Promise<void>;\n stop: () => void;\n blob: Blob | null;\n error: string | null;\n}\n\nexport const useAudioRecorder = (\n onStop?: (blob: Blob) => void\n): AudioRecorderHook => {\n const [isRecording, setIsRecording] = useState(false);\n const [isSimulated, setIsSimulated] = useState(false);\n const [blob, setBlob] = useState<Blob | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const mediaRecorderRef = useRef<MediaRecorder | null>(null);\n const chunksRef = useRef<Blob[]>([]);\n\n const start = useCallback(async () => {\n\n try {\n if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {\n // Dev mode fallback\n if (process.env.NODE_ENV === 'development') {\n console.warn('[useAudioRecorder] MediaDevices not available. Entering simulation mode...');\n setIsRecording(true);\n setIsSimulated(true);\n setError(null);\n return;\n }\n throw new Error('Media devices not available. Ensure you are using HTTPS or localhost.');\n }\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n\n const mediaRecorder = new MediaRecorder(stream);\n\n mediaRecorderRef.current = mediaRecorder;\n chunksRef.current = [];\n\n mediaRecorder.ondataavailable = (e) => {\n if (e.data.size > 0) {\n chunksRef.current.push(e.data);\n }\n };\n\n mediaRecorder.onstop = () => {\n const audioBlob = new Blob(chunksRef.current, { type: 'audio/webm' });\n setBlob(audioBlob);\n setIsRecording(false);\n if (onStop) onStop(audioBlob);\n\n // Stop all tracks\n stream.getTracks().forEach(track => {\n track.stop();\n });\n };\n\n mediaRecorder.start();\n setIsRecording(true);\n setError(null);\n } catch (e: any) {\n console.error('Failed to start audio recording:', e);\n setError(e.message || 'Microphone access denied');\n }\n }, [onStop]);\n\n const stop = useCallback(() => {\n if (isSimulated) {\n setIsRecording(false);\n setIsSimulated(false);\n // Return a special dummy blob that the receiver can recognize as \"simulated\"\n const simulatedBlob = new Blob(['simulated speech'], { type: 'audio/simulated' });\n setBlob(simulatedBlob);\n if (onStop) onStop(simulatedBlob);\n return;\n }\n\n if (mediaRecorderRef.current && mediaRecorderRef.current.state !== 'inactive') {\n mediaRecorderRef.current.stop();\n }\n }, [isSimulated, onStop]);\n\n return {\n isRecording,\n isSimulated,\n start,\n stop,\n blob,\n error\n };\n};\n","import { RefObject, useEffect } from 'react';\n\n/**\n * A hook that proactively resizes a textarea based on the content of a hidden measurement element.\n * This avoids the flickering often seen with standard \"height: auto\" approaches by measuring\n * the content in a hidden span first, then applying the height to the textarea.\n */\nexport function useProactiveResize(\n textareaRef: RefObject<HTMLTextAreaElement>,\n measurementRef: RefObject<HTMLSpanElement>,\n value: string,\n disabled: boolean\n) {\n useEffect(() => {\n if (!textareaRef.current || !measurementRef.current) return;\n\n // Copy styles from textarea to measurement span to ensure accurate sizing\n const styles = window.getComputedStyle(textareaRef.current);\n measurementRef.current.style.width = styles.width;\n measurementRef.current.style.font = styles.font; // Shorthand for font-style, font-variant, font-weight, font-size, line-height, font-family\n measurementRef.current.style.padding = styles.padding;\n measurementRef.current.style.border = styles.border;\n measurementRef.current.style.boxSizing = styles.boxSizing;\n measurementRef.current.style.whiteSpace = 'pre-wrap'; // Important for matching textarea behavior\n measurementRef.current.style.visibility = 'hidden';\n measurementRef.current.style.position = 'absolute';\n measurementRef.current.style.pointerEvents = 'none';\n\n // Set content to measurement span\n // Append a zero-width space to ensure empty lines are counted\n measurementRef.current.textContent = value + '\\u200B';\n\n // Calculate height\n const scrollHeight = measurementRef.current.offsetHeight;\n\n // Apply height to textarea\n // We add a small buffer (e.g., 2px) to prevent scrollbars from appearing due to sub-pixel rendering differences\n // But direct assignment is usually best.\n // Also respect min-height if set in CSS (typically handled by browser, but we set style.height)\n textareaRef.current.style.height = `${scrollHeight}px`;\n\n }, [value, disabled, textareaRef, measurementRef]);\n}\n","import React, { useState, useCallback, useRef } from 'react';\nimport { MicrophoneIcon, StopIcon, XMarkIcon, Square2StackIcon } from '@heroicons/react/24/outline';\nimport { useSpeechRecognition } from '../hooks/useSpeechRecognition';\nimport { useAudioRecorder } from '../hooks/useAudioRecorder';\nimport { VoiceConfig } from '../types/chat';\nimport { useChatConfig } from '../context/ChatConfigContext';\n\ninterface TapToTalkProps {\n onResult: (text: string) => void;\n voiceConfig?: VoiceConfig;\n className?: string;\n disabled?: boolean;\n tooltip?: string;\n onFocusTarget?: () => void;\n accentColor?: string;\n}\n\nexport const TapToTalk: React.FC<TapToTalkProps> = ({\n onResult,\n voiceConfig: propVoiceConfig,\n className = '',\n disabled = false,\n tooltip = 'Tap to speak',\n onFocusTarget,\n accentColor = 'bg-emerald-600'\n}) => {\n const globalConfig = useChatConfig();\n const voiceConfig = propVoiceConfig || globalConfig.voice?.config;\n\n const [isTranscribing, setIsTranscribing] = useState(false);\n const [voiceTrigger, setVoiceTrigger] = useState<'click' | null>(null);\n const [errorMsg, setErrorMsg] = useState<string | null>(null);\n\n // Debug Mode State\n const [showDebug, setShowDebug] = useState(false);\n const [logs, setLogs] = useState<string[]>([]);\n const tapCountRef = useRef<{ count: number, lastTap: number }>({ count: 0, lastTap: 0 });\n\n // Console Interceptor for Debug Mode\n React.useEffect(() => {\n const originalLog = console.log;\n const originalWarn = console.warn;\n const originalError = console.error;\n\n const addLog = (type: string, args: any[]) => {\n try {\n const msg = args.map(arg => {\n if (arg instanceof Error) return `${arg.name}: ${arg.message}`;\n if (typeof arg === 'object') return JSON.stringify(arg);\n return String(arg);\n }).join(' ');\n setLogs(prev => [`[${type}] ${msg}`, ...prev].slice(0, 50));\n } catch (e) {\n // Ignore serialization errors\n }\n };\n\n console.log = (...args) => { originalLog(...args); addLog('LOG', args); };\n console.warn = (...args) => { originalWarn(...args); addLog('WRN', args); };\n console.error = (...args) => { originalError(...args); addLog('ERR', args); };\n\n return () => {\n console.log = originalLog;\n console.warn = originalWarn;\n console.error = originalError;\n };\n }, []);\n\n const copyLogs = useCallback(() => {\n navigator.clipboard.writeText(logs.join('\\n'))\n .then(() => alert('Logs copied to clipboard'))\n .catch(err => console.error('Failed to copy logs', err));\n }, [logs]);\n\n // Native Speech Handler\n const handleVoiceResult = useCallback((text: string, isFinal: boolean) => {\n if (isFinal) {\n onResult(text);\n setErrorMsg(null);\n setVoiceTrigger(null);\n }\n }, [onResult]);\n\n const handleVoiceEnd = useCallback(() => {\n setVoiceTrigger(null);\n }, []);\n\n const nativeSpeech = useSpeechRecognition(handleVoiceResult, handleVoiceEnd, voiceConfig?.language);\n\n React.useEffect(() => {\n if (nativeSpeech.error) {\n setErrorMsg(nativeSpeech.error);\n console.error('[TapToTalk] Native Speech Error:', nativeSpeech.error);\n }\n }, [nativeSpeech.error]);\n\n // Custom Audio Recorder Handler\n const customRecorder = useAudioRecorder(async (blob) => {\n setVoiceTrigger(null);\n setIsTranscribing(true);\n setErrorMsg(null);\n\n if (blob.type === 'audio/simulated') {\n console.log('[TapToTalk] Handling simulated audio capture');\n await new Promise(resolve => setTimeout(resolve, 1500));\n onResult('This is a simulated transcription for development testing.');\n setIsTranscribing(false);\n return;\n }\n\n if (voiceConfig?.mode === 'custom' && voiceConfig.onAudioCapture) {\n try {\n const text = await voiceConfig.onAudioCapture(blob);\n if (text) onResult(text);\n } catch (error: any) {\n console.error('[TapToTalk] Custom transcription failed:', error);\n setErrorMsg(error.message || 'Transcription failed');\n } finally {\n setIsTranscribing(false);\n }\n } else {\n setIsTranscribing(false);\n }\n });\n\n const isListening = !!voiceTrigger || nativeSpeech.isListening || customRecorder.isRecording;\n const isActive = isListening || isTranscribing;\n\n const processingRef = useRef(false);\n\n // Mobile detection helper\n const isMobile = useCallback(() => {\n if (typeof window === 'undefined') return false;\n return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ||\n ('ontouchstart' in window) ||\n (navigator.maxTouchPoints > 0);\n }, []);\n\n const toggleVoice = async (e?: React.MouseEvent) => {\n if (e) {\n e.preventDefault();\n e.stopPropagation();\n }\n\n // Debug Trigger: 5 rapid taps logic check first (bypass processing check)\n const now = Date.now();\n if (now - tapCountRef.current.lastTap < 500) {\n tapCountRef.current.count++;\n } else {\n tapCountRef.current.count = 1;\n }\n tapCountRef.current.lastTap = now;\n\n if (tapCountRef.current.count >= 5) {\n setShowDebug(prev => !prev);\n tapCountRef.current.count = 0;\n // Force stop if we accidentally triggered reading\n if (isActive) {\n console.log('[TapToTalk] Debug trigger force-stop');\n if (voiceConfig?.mode === 'native') nativeSpeech.stop();\n else customRecorder.stop();\n setVoiceTrigger(null);\n }\n return;\n }\n\n console.log('[TapToTalk] toggleVoice called. isMobile:', isMobile());\n if (processingRef.current) {\n console.log('[TapToTalk] toggleVoice ignored - processing');\n return;\n }\n\n // Only set processing to true if we are potentially starting an async operation\n // or if we need to debounce rapid taps.\n processingRef.current = true;\n console.log('[TapToTalk] toggleVoice called. isActive:', isActive, 'isListening:', isListening, 'isTranscribing:', isTranscribing);\n\n try {\n if (isActive) {\n if (isTranscribing && !isListening) {\n console.log('[TapToTalk] Ignoring click during transcription');\n return; // Ignore clicks during transcription (unless forced stop)\n }\n console.log('[TapToTalk] Stopping voice...');\n if (voiceConfig?.mode === 'native') {\n nativeSpeech.stop();\n } else {\n customRecorder.stop();\n }\n setVoiceTrigger(null);\n } else {\n console.log('[TapToTalk] Starting voice... mode:', voiceConfig?.mode);\n setErrorMsg(null);\n\n // FIX: Perform focus management BEFORE starting any recognition mechanism\n if (isMobile()) {\n console.log('[TapToTalk] Mobile: Blurring active element and skipping onFocusTarget');\n if (document.activeElement instanceof HTMLElement) {\n document.activeElement.blur();\n }\n } else if (onFocusTarget) {\n console.log('[TapToTalk] Desktop: calling onFocusTarget()');\n onFocusTarget();\n }\n\n setVoiceTrigger('click');\n console.log('[TapToTalk] voiceTrigger set to click');\n\n if (voiceConfig?.mode === 'custom') {\n console.log('[TapToTalk] Starting custom recorder...');\n try {\n await customRecorder.start();\n console.log('[TapToTalk] Custom recorder started successfully');\n } catch (e: any) {\n console.error('[TapToTalk] Custom recorder failed:', e);\n setErrorMsg('Mic access denied');\n setVoiceTrigger(null);\n }\n } else {\n console.log('[TapToTalk] Starting native speech recognition...');\n if (!nativeSpeech.isSupported) {\n console.error('[TapToTalk] Native speech not supported');\n setErrorMsg('Speech not supported');\n setVoiceTrigger(null);\n return;\n }\n console.log('[TapToTalk] Calling nativeSpeech.start()...');\n nativeSpeech.start();\n console.log('[TapToTalk] nativeSpeech.start() called');\n }\n }\n } finally {\n // Small delay to prevent double-taps being registered immediately\n setTimeout(() => {\n processingRef.current = false;\n }, 300);\n }\n };\n\n // State determination for UI\n let bgColor = accentColor;\n let label = 'Tap to Talk';\n let Icon = <MicrophoneIcon className=\"h-5 w-5\" />;\n\n if (isListening) {\n bgColor = 'bg-orange-500';\n label = 'Listening ... Tap to stop';\n Icon = <MicrophoneIcon className=\"h-5 w-5 animate-pulse\" />;\n } else if (isTranscribing) {\n bgColor = 'bg-indigo-600';\n label = 'Transcribing ...';\n Icon = (\n <svg className=\"animate-spin h-5 w-5 text-white\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\"></circle>\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n );\n }\n\n return (\n <div className=\"flex flex-col w-full relative\">\n {/* Debug Overlay */}\n {showDebug && (\n <div className=\"absolute bottom-full left-0 right-0 mb-2 p-2 bg-black/80 text-green-400 text-xs font-mono h-48 overflow-y-auto rounded z-50 pointer-events-auto\">\n <div className=\"flex justify-between items-center bg-gray-800 p-1 mb-1\">\n <span>Debug Logs</span>\n <div className=\"flex gap-2\">\n <button onClick={(e) => { e.stopPropagation(); copyLogs(); }} className=\"text-white hover:text-blue-400\" title=\"Copy Logs\">\n <Square2StackIcon className=\"w-4 h-4\" />\n </button>\n <button onClick={(e) => { e.stopPropagation(); copyLogs(); setShowDebug(false); }} className=\"text-white hover:text-red-400\" title=\"Copy & Close\">\n <XMarkIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n {logs.map((log, i) => (\n <div key={i} className=\"mb-0.5 border-b border-gray-700/50 pb-0.5 break-all\">\n {log}\n </div>\n ))}\n {logs.length === 0 && <div>No logs yet...</div>}\n </div>\n )}\n <button\n onClick={toggleVoice}\n disabled={disabled || (isTranscribing && !isListening)}\n className={`flex items-center justify-center gap-3 px-6 py-3 rounded-xl transition-all duration-300 w-full font-medium shadow-md active:scale-[0.98]\n ${bgColor} text-white\n ${disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}\n ${className}`}\n title={label}\n >\n <div className=\"flex items-center justify-center shrink-0\">\n {Icon}\n </div>\n <span className=\"truncate\">{label}</span>\n {errorMsg && (\n <span className=\"text-[10px] bg-white/20 px-1.5 py-0.5 rounded text-red-100 animate-in fade-in slide-in-from-right-1\">\n {errorMsg}\n </span>\n )}\n </button>\n </div>\n );\n};\n","'use client';\n\nimport React, { useEffect, useRef } from 'react';\nimport { ChatMessage, ChatTask } from '../types/chat';\nimport InteractiveMessageHandler from './interactive/InteractiveMessageHandler';\nimport { InformationCircleIcon } from '@heroicons/react/24/outline';\nimport { MessageBubble } from './MessageBubble';\n\n// Define the props for the ChatMessageList component\ninterface ChatMessageListProps {\n chatHistory: ChatMessage[];\n isProcessing: boolean;\n processingHint: string;\n currentTask: ChatTask | null;\n getContextExample: () => string;\n onInteractiveResponse?: (messageId: string | number, response: any) => void;\n}\n\n/**\n * ChatMessageList component displays the chat messages and handles scrolling\n * Features:\n * - Displays user and system messages with different styling\n * - Shows a typing indicator when the system is processing\n * - Displays a welcome message when the chat is empty\n * - Auto-scrolls to the bottom when new messages arrive\n * - Handles interactive messages with different UI components\n */\nexport const ChatMessageList: React.FC<ChatMessageListProps> = ({\n chatHistory,\n isProcessing,\n processingHint,\n currentTask,\n getContextExample,\n onInteractiveResponse\n}) => {\n // Reference to the chat container for auto-scrolling\n const chatContainerRef = useRef<HTMLDivElement>(null);\n // Reference to the last message for scrolling into view\n const lastMessageRef = useRef<HTMLDivElement>(null);\n // Reference to the processing indicator\n const processingIndicatorRef = useRef<HTMLDivElement>(null);\n\n // Scroll to the bottom when chat history or processing state changes\n useEffect(() => {\n // If there's a processing indicator, scroll to it\n if (isProcessing && processingIndicatorRef.current) {\n processingIndicatorRef.current.scrollIntoView({ behavior: 'smooth' });\n return;\n }\n\n // If there's a last message, scroll to it\n if (lastMessageRef.current) {\n lastMessageRef.current.scrollIntoView({ behavior: 'smooth' });\n } else if (chatContainerRef.current) {\n // Fallback to scrolling the container\n chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;\n }\n }, [chatHistory, isProcessing]);\n\n // Handle interactive message responses\n const handleInteractiveResponse = (messageId: string | number, response: any) => {\n if (onInteractiveResponse) {\n onInteractiveResponse(messageId, response);\n }\n };\n\n return (\n <div\n ref={chatContainerRef}\n className=\"flex-1 overflow-y-auto p-4 space-y-8 bg-gray-50\"\n >\n {/* Welcome message when chat is empty */}\n {chatHistory.length === 0 && !isProcessing && (\n <div className=\"text-center py-8\">\n <h3 className=\"text-lg font-medium text-gray-700 mb-2\">How can I help you today?</h3>\n <p className=\"text-sm text-gray-500 mb-4\">\n Try asking me something like {getContextExample()}\n </p>\n </div>\n )}\n\n {/* Display chat messages */}\n {chatHistory.map((message, index) => {\n // Determine if this is the last message\n const isLastMessage = index === chatHistory.length - 1;\n const isUser = message.role === 'user';\n const isError = message.role === 'error';\n\n return (\n <div\n key={message.id || `message-${index}`}\n ref={isLastMessage ? lastMessageRef : undefined}\n className={`flex flex-col w-full ${isUser ? 'items-end' : 'items-start'}`}\n >\n {/* Timestamp display */}\n <div className=\"text-xs text-gray-400 mb-1 px-1\">\n {message.timestamp\n ? `${isUser ? 'Sent' : 'Received'} at ${new Date(message.timestamp).toLocaleString()}`\n : ''}\n </div>\n\n {/* Message Content */}\n <div className=\"w-full\">\n {message.interactive && message.interactiveData ? (\n <div className={`max-w-[85%] ${isUser ? 'ml-auto' : 'mr-auto'}`}>\n <InteractiveMessageHandler\n message={message.interactiveData}\n onResponse={(response: any) => {\n const messageId = message.id || `interactive-${index}-${Date.now()}`;\n message.responseValue = response;\n handleInteractiveResponse(messageId, response);\n }}\n isResponseSubmitted={!!message.isResponseSubmitted}\n parentMessage={message}\n />\n </div>\n ) : (\n <MessageBubble\n message={message}\n isUser={isUser}\n />\n )}\n </div>\n\n {isUser && message.interactive && (\n <div className=\"flex items-center mt-1 space-x-1 text-xs text-gray-500 italic\">\n <InformationCircleIcon className=\"h-3 w-3 text-blue-400\" />\n <span>\n {message.request === 'form' && 'Response to form submission'}\n {message.request === 'select' && 'Response to selection prompt'}\n {message.request === 'confirm' && 'Response to confirmation prompt'}\n </span>\n </div>\n )}\n </div>\n );\n })}\n\n {/* Show typing indicator when processing */}\n {isProcessing && (\n <div\n ref={processingIndicatorRef}\n className=\"flex justify-start my-4\"\n >\n <div className=\"bg-white text-gray-800 border border-gray-200 rounded-lg px-4 py-2 max-w-[85%]\">\n <div className=\"flex items-center\">\n <span className=\"text-sm\">{processingHint}</span>\n <span className=\"ml-2 flex space-x-1\">\n <span className=\"h-2 w-2 bg-gray-400 rounded-full animate-bounce\" style={{ animationDelay: '0ms' }}></span>\n <span className=\"h-2 w-2 bg-gray-400 rounded-full animate-bounce\" style={{ animationDelay: '150ms' }}></span>\n <span className=\"h-2 w-2 bg-gray-400 rounded-full animate-bounce\" style={{ animationDelay: '300ms' }}></span>\n </span>\n </div>\n </div>\n </div>\n )}\n\n {/* Show task progress if available */}\n {currentTask && !currentTask.complete && (\n <div className=\"mt-4 bg-blue-50 border border-blue-100 rounded-lg p-3\">\n <div className=\"text-sm text-blue-800 mb-1\">\n Task in progress: Step {currentTask.currentStep} of {currentTask.steps}\n </div>\n <div className=\"w-full bg-blue-200 rounded-full h-2\">\n <div\n className=\"bg-blue-500 h-2 rounded-full\"\n style={{ width: `${(currentTask.currentStep / currentTask.steps) * 100}%` }}\n ></div>\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default ChatMessageList;\n","'use client';\n\nimport React, { useState } from 'react';\nimport { ConfirmInteractionParams } from '../../types/interactive';\n\ninterface ConfirmInteractionProps {\n parameters: Record<string, any>;\n onResponse: (response: boolean) => void;\n isResponseSubmitted: boolean;\n}\n\n/**\n * Component for handling confirm (yes/no) interactions\n */\nconst ConfirmInteraction: React.FC<ConfirmInteractionProps> = ({\n parameters,\n onResponse,\n isResponseSubmitted\n}) => {\n const [selectedOption, setSelectedOption] = useState<string | null>(null);\n const params = parameters as ConfirmInteractionParams;\n\n // Extract parameters\n const { yesPrompt, noPrompt } = params;\n\n console.log('[ConfirmInteraction] Parameters:', params);\n\n const handleOptionClick = (value: boolean, buttonText: string) => {\n if (isResponseSubmitted) return;\n\n // Use the button text (yesPrompt/noPrompt) as the selected option\n setSelectedOption(buttonText);\n onResponse(value);\n };\n\n return (\n <div className=\"mt-2 mb-4\">\n <div className=\"flex space-x-2\">\n <button\n onClick={() => handleOptionClick(true, yesPrompt)}\n disabled={isResponseSubmitted}\n className={`px-4 py-2 rounded-md text-sm transition-colors ${isResponseSubmitted\n ? selectedOption === yesPrompt\n ? 'bg-blue-500 text-white' // Selected and submitted\n : 'bg-gray-200 text-gray-500 cursor-not-allowed' // Not selected and submitted\n : 'bg-blue-100 text-blue-700 hover:bg-blue-200'}`}\n >\n {yesPrompt}\n </button>\n <button\n onClick={() => handleOptionClick(false, noPrompt)}\n disabled={isResponseSubmitted}\n className={`px-4 py-2 rounded-md text-sm transition-colors ${isResponseSubmitted\n ? selectedOption === noPrompt\n ? 'bg-blue-500 text-white' // Selected and submitted\n : 'bg-gray-200 text-gray-500 cursor-not-allowed' // Not selected and submitted\n : 'bg-gray-100 text-gray-700 hover:bg-gray-200'}`}\n >\n {noPrompt}\n </button>\n </div>\n </div>\n );\n};\n\nexport default ConfirmInteraction;\n","'use client';\n\nimport React, { useState, useEffect } from 'react';\nimport { SelectInteractionParams } from '../../types/interactive';\n\ninterface SelectInteractionProps {\n parameters: Record<string, any>;\n onResponse: (response: string) => void;\n isResponseSubmitted: boolean;\n message?: any;\n}\n\n/**\n * Component for handling select interactions (choosing from multiple options)\n */\nconst SelectInteraction: React.FC<SelectInteractionProps> = ({\n parameters,\n onResponse,\n isResponseSubmitted,\n message\n}) => {\n const [selectedOption, setSelectedOption] = useState<string | null>(null);\n const [customOption, setCustomOption] = useState<string | null>(null);\n const params = parameters as SelectInteractionParams;\n\n const { question, options, placeholder } = params;\n\n // Effect to check if there's a responseValue to use\n useEffect(() => {\n if (isResponseSubmitted && message?.responseValue) {\n const responseValueStr = String(message.responseValue);\n setSelectedOption(responseValueStr);\n\n // Check if it's a custom option\n if (!options.includes(responseValueStr)) {\n setCustomOption(responseValueStr);\n }\n }\n }, [isResponseSubmitted, message, options]);\n\n const handleOptionClick = (option: string) => {\n if (isResponseSubmitted) return;\n\n setSelectedOption(option);\n setCustomOption(null); // Clear any custom option when selecting a predefined one\n onResponse(option);\n };\n\n return (\n <div className=\"mt-2 mb-4\">\n <div className=\"flex flex-wrap gap-2\">\n {options.map((option, index) => (\n <button\n key={index}\n onClick={() => handleOptionClick(option)}\n disabled={isResponseSubmitted}\n className={`px-4 py-2 rounded-md text-sm transition-colors ${isResponseSubmitted\n ? selectedOption === option\n ? 'bg-blue-500 text-white' // Selected and submitted\n : 'bg-gray-200 text-gray-500 cursor-not-allowed' // Not selected and submitted\n : 'bg-blue-100 text-blue-700 hover:bg-blue-200'}`}\n >\n {option}\n </button>\n ))}\n </div>\n\n {/* Show custom option message if applicable */}\n {customOption && isResponseSubmitted && (\n <div className=\"mt-2 text-sm text-amber-600 bg-amber-50 p-2 rounded\">\n User provided custom option: <span className=\"font-semibold\">\"{customOption}\"</span>\n </div>\n )}\n </div>\n );\n};\n\nexport default SelectInteraction;\n","'use client';\n\nimport React, { useState, useEffect, useRef } from 'react';\nimport { FormInteractionParams, FormField } from '../../types/interactive';\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-react';\n\ninterface FormInteractionProps {\n parameters: Record<string, any>;\n onResponse: (response: Record<string, any>) => void;\n isResponseSubmitted: boolean;\n submittedValues?: Record<string, any>;\n}\n\n/**\n * Component for handling form interactions (collecting structured data)\n */\nconst FormInteraction: React.FC<FormInteractionProps> = ({\n parameters,\n onResponse,\n isResponseSubmitted,\n submittedValues\n}) => {\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [formValues, setFormValues] = useState<Record<string, any>>({});\n const [isExpanded, setIsExpanded] = useState(false);\n const [parsedFields, setParsedFields] = useState<FormField[]>([]);\n const formButtonsRef = useRef<HTMLDivElement>(null);\n\n // Parse parameters to handle both array and object-based fields\n const parseParameters = () => {\n const { prompt, description, submitText = 'Submit', cancelText = 'Cancel' } = parameters;\n\n // Handle fields that might come as an array of stringified JSON\n let fieldsArray: FormField[] = [];\n\n if (parameters.fields) {\n // If fields is an array, parse each item if it's a string\n if (Array.isArray(parameters.fields)) {\n fieldsArray = parameters.fields.map(field => {\n if (typeof field === 'string') {\n try {\n const fieldData = JSON.parse(field);\n\n const name = fieldData.name;\n\n return {\n name,\n label: fieldData.label || name,\n type: fieldData.type || 'string',\n required: fieldData.required || false,\n options: fieldData.options || [],\n placeholder: fieldData.description || fieldData.label || name,\n defaultValue: fieldData.defaultValue\n } as FormField;\n } catch (error) {\n console.error(`Error parsing field:`, error);\n return null;\n }\n }\n return field;\n }).filter((field): field is FormField => field !== null);\n }\n // If fields is an object with stringified JSON values\n else if (typeof parameters.fields === 'object') {\n fieldsArray = Object.entries(parameters.fields).map(([name, fieldDataStr]) => {\n let fieldData: Record<string, any> = {};\n\n // Try to parse the stringified JSON\n try {\n if (typeof fieldDataStr === 'string') {\n fieldData = JSON.parse(fieldDataStr);\n } else {\n fieldData = fieldDataStr as Record<string, any>;\n }\n } catch (error) {\n console.error(`Error parsing field data for ${name}:`, error);\n }\n\n return {\n name,\n label: fieldData.label || name,\n type: fieldData.type || 'string',\n required: fieldData.required || false,\n options: fieldData.options || [],\n placeholder: fieldData.description || fieldData.label || name,\n defaultValue: fieldData.defaultValue\n } as FormField;\n });\n\n console.log('Field arrays: ', fieldsArray)\n }\n }\n\n return {\n title: prompt || 'Please fill out this form',\n description,\n fields: fieldsArray,\n submitText,\n cancelText\n };\n };\n\n const params = parseParameters();\n\n // Initialize form values with default values\n useEffect(() => {\n const processedParams = parseParameters();\n setParsedFields(processedParams.fields);\n\n const initialValues: Record<string, any> = {};\n processedParams.fields.forEach(field => {\n if (field.defaultValue !== undefined) {\n initialValues[field.name] = field.defaultValue;\n } else if (field.type === 'checkbox') {\n initialValues[field.name] = false;\n } else {\n initialValues[field.name] = '';\n }\n });\n setFormValues(initialValues);\n\n // Automatically open the modal when the component mounts\n if (!isResponseSubmitted) {\n setIsModalOpen(true);\n }\n }, [parameters, isResponseSubmitted]);\n\n // Effect to scroll form buttons into view when modal is opened\n useEffect(() => {\n if (isModalOpen && formButtonsRef.current) {\n setTimeout(() => {\n formButtonsRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }, 100); // Small delay to ensure form is rendered\n }\n }, [isModalOpen]);\n\n const handleInputChange = (field: FormField, value: any) => {\n setFormValues(prev => ({\n ...prev,\n [field.name]: value\n }));\n };\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n onResponse(formValues);\n setIsModalOpen(false);\n };\n\n const handleCancel = () => {\n onResponse({});\n setIsModalOpen(false);\n };\n\n const renderField = (field: FormField) => {\n const { name, label, type, required, options, placeholder } = field;\n\n switch (type) {\n case 'string':\n case 'email':\n case 'number':\n case 'password':\n return (\n <div className=\"mb-4 flex items-center space-x-4\" key={name}>\n <label htmlFor={name} className=\"text-sm font-medium text-gray-700 min-w-[120px]\">\n {label}{required && <span className=\"text-red-500\">*</span>}\n </label>\n <input\n type={type === 'string' ? 'text' : type}\n id={name}\n name={name}\n value={formValues[name] || ''}\n onChange={(e) => handleInputChange(field, e.target.value)}\n placeholder={placeholder}\n required={required}\n disabled={isResponseSubmitted}\n className=\"flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n </div>\n );\n\n case 'textarea':\n return (\n <div className=\"mb-4 flex items-start space-x-4\" key={name}>\n <label htmlFor={name} className=\"text-sm font-medium text-gray-700 min-w-[120px] pt-2\">\n {label}{required && <span className=\"text-red-500\">*</span>}\n </label>\n <textarea\n id={name}\n name={name}\n value={formValues[name] || ''}\n onChange={(e) => handleInputChange(field, e.target.value)}\n placeholder={placeholder}\n required={required}\n disabled={isResponseSubmitted}\n rows={4}\n className=\"flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n </div>\n );\n\n case 'select':\n return (\n <div className=\"mb-4 flex items-center space-x-4\" key={name}>\n <label htmlFor={name} className=\"text-sm font-medium text-gray-700 min-w-[120px]\">\n {label}{required && <span className=\"text-red-500\">*</span>}\n </label>\n <select\n id={name}\n name={name}\n value={formValues[name] || ''}\n onChange={(e) => handleInputChange(field, e.target.value)}\n required={required}\n disabled={isResponseSubmitted}\n className=\"flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n <option value=\"\" disabled>{placeholder || 'Select an option'}</option>\n {options?.map((option, index) => (\n <option key={index} value={option}>{option}</option>\n ))}\n </select>\n </div>\n );\n\n case 'checkbox':\n return (\n <div className=\"mb-4 flex items-center space-x-4\" key={name}>\n <div className=\"min-w-[120px]\" />\n <div className=\"flex items-center\">\n <input\n type=\"checkbox\"\n id={name}\n name={name}\n checked={!!formValues[name]}\n onChange={(e) => handleInputChange(field, e.target.checked)}\n required={required}\n disabled={isResponseSubmitted}\n className=\"h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500\"\n />\n <label htmlFor={name} className=\"ml-2 text-sm text-gray-700\">\n {label}{required && <span className=\"text-red-500\">*</span>}\n </label>\n </div>\n </div>\n );\n\n case 'radio':\n return (\n <div className=\"mb-4 flex space-x-4\" key={name}>\n <div className=\"text-sm font-medium text-gray-700 min-w-[120px] pt-2\">\n {label}{required && <span className=\"text-red-500\">*</span>}\n </div>\n <div className=\"flex-1 space-y-2\">\n {options?.map((option, index) => (\n <div key={index} className=\"flex items-center\">\n <input\n id={`${name}-${index}`}\n name={name}\n type=\"radio\"\n value={option}\n checked={formValues[name] === option}\n onChange={() => handleInputChange(field, option)}\n required={required}\n disabled={isResponseSubmitted}\n className=\"h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500\"\n />\n <label htmlFor={`${name}-${index}`} className=\"ml-2 text-sm text-gray-700\">\n {option}\n </label>\n </div>\n ))}\n </div>\n </div>\n );\n\n default:\n return null;\n }\n };\n\n if (isResponseSubmitted) {\n // For submitted forms, show a summary of the responses\n return (\n <div className=\"mt-2 bg-gray-50 p-3 rounded-md border border-gray-200\">\n <div className=\"flex justify-between items-center cursor-pointer\" onClick={() => setIsExpanded(!isExpanded)}>\n <span className=\"font-medium text-gray-700\">{isExpanded ? 'Hide' : 'Show'} Form Responses</span>\n {isExpanded ?\n <ChevronUpIcon className=\"h-5 w-5 text-gray-500\" /> :\n <ChevronDownIcon className=\"h-5 w-5 text-gray-500\" />\n }\n </div>\n\n {isExpanded && (\n <div className=\"mt-2 space-y-2\">\n {parsedFields.map((field) => (\n <div key={field.name} className=\"flex\">\n <span className=\"text-sm font-medium text-gray-600 mr-2\">{field.label}:</span>\n <span className=\"text-sm text-gray-800\">\n {typeof submittedValues?.[field.name] === 'boolean'\n ? (submittedValues[field.name] ? 'Yes' : 'No')\n : submittedValues?.[field.name] || 'Not provided'}\n </span>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n }\n\n // For new forms, show the modal\n return (\n <div className=\"mt-2\">\n {isModalOpen && (\n <div className=\"p-4\">\n <form onSubmit={handleSubmit} className=\"mt-4\">\n {parsedFields.map(field => renderField(field))}\n\n <div ref={formButtonsRef} className=\"flex justify-end mt-4 space-x-2\">\n <button\n type=\"button\"\n onClick={handleCancel}\n disabled={isResponseSubmitted}\n className=\"px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 border border-gray-300 rounded-md hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n {params.cancelText}\n </button>\n <button\n type=\"submit\"\n disabled={isResponseSubmitted}\n className=\"px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n {params.submitText}\n </button>\n </div>\n </form>\n </div>\n )}\n </div>\n );\n};\n\nexport default FormInteraction;\n","'use client';\n\nimport React from 'react';\nimport { PresentInteractionParams } from '../../types/interactive';\n\n// Try to import ReactMarkdown, but provide a fallback if it's not available\nlet ReactMarkdown: any;\ntry {\n // Dynamic import for ReactMarkdown\n ReactMarkdown = require('react-markdown');\n} catch (error) {\n // Fallback if ReactMarkdown is not available\n ReactMarkdown = ({ children }: { children: string }) => (\n <div className=\"whitespace-pre-wrap\">{children}</div>\n );\n}\n\ninterface PresentInteractionProps {\n parameters: Record<string, any>;\n}\n\n/**\n * Component for handling present interactions (displaying information)\n */\nconst PresentInteraction: React.FC<PresentInteractionProps> = ({\n parameters\n}) => {\n const params = parameters as PresentInteractionParams;\n const { title, content, format = 'text', level = 'info' } = params;\n\n // Define styles based on level\n const getLevelStyles = () => {\n switch (level) {\n case 'error':\n return {\n container: 'bg-red-50 border-red-100',\n title: 'text-red-800',\n content: 'text-red-700'\n };\n case 'warn':\n case 'warning':\n return {\n container: 'bg-amber-50 border-amber-100',\n title: 'text-amber-800',\n content: 'text-amber-700'\n };\n case 'success':\n return {\n container: 'bg-green-50 border-green-100',\n title: 'text-green-800',\n content: 'text-green-700'\n };\n case 'info':\n default:\n return {\n container: 'bg-blue-50 border-blue-100',\n title: 'text-blue-800',\n content: 'text-blue-700'\n };\n }\n };\n\n const styles = getLevelStyles();\n\n return (\n <div className={`mt-2 mb-4 p-4 ${styles.container} border rounded-md`}>\n {title && (\n <div className={`font-medium ${styles.title} mb-2`}>{title}</div>\n )}\n <div className={`text-sm ${styles.content}`}>\n {format === 'markdown' ? (\n <ReactMarkdown className=\"prose prose-sm max-w-none\">\n {content}\n </ReactMarkdown>\n ) : format === 'html' ? (\n <div dangerouslySetInnerHTML={{ __html: content }} />\n ) : (\n <div className=\"whitespace-pre-wrap\">{content}</div>\n )}\n </div>\n </div>\n );\n};\n\nexport default PresentInteraction;\n","'use client';\n\nimport React from 'react';\nimport { InteractiveMessage } from '../../types/interactive';\nimport ConfirmInteraction from './ConfirmInteraction';\nimport SelectInteraction from './SelectInteraction';\nimport FormInteraction from './FormInteraction';\nimport PresentInteraction from './PresentInteraction';\n\ninterface InteractiveMessageHandlerProps {\n message: InteractiveMessage;\n onResponse: (response: any) => void;\n isResponseSubmitted: boolean;\n parentMessage?: any; // Add reference to the parent ChatMessage\n}\n\n/**\n * Component that handles rendering different types of interactive messages\n * based on the function type (chat, confirm, select, form, present)\n */\nconst InteractiveMessageHandler: React.FC<InteractiveMessageHandlerProps> = ({\n message,\n onResponse,\n isResponseSubmitted,\n parentMessage\n}) => {\n const { function: functionType, parameters } = message;\n\n // Extract submitted response from parent message if available\n const submittedResponse = parentMessage?.responseValue;\n\n // Render the appropriate interaction component based on the function type\n switch (functionType) {\n case 'confirm':\n return (\n <ConfirmInteraction\n parameters={parameters}\n onResponse={onResponse}\n isResponseSubmitted={isResponseSubmitted}\n />\n );\n\n case 'select':\n return (\n <SelectInteraction\n parameters={parameters}\n onResponse={onResponse}\n isResponseSubmitted={isResponseSubmitted}\n message={parentMessage}\n />\n );\n\n case 'form':\n return (\n <FormInteraction\n parameters={parameters}\n onResponse={onResponse}\n isResponseSubmitted={isResponseSubmitted}\n submittedValues={submittedResponse}\n />\n );\n\n case 'present':\n return (\n <PresentInteraction\n parameters={parameters}\n />\n );\n\n case 'chat':\n // Chat is handled by the main input form, so we don't need a special component\n return null;\n\n default:\n console.warn(`Unknown interactive function type: ${functionType}`);\n return null;\n }\n};\n\nexport default InteractiveMessageHandler;\n","'use client';\n\nimport React from 'react';\nimport { Wifi, WifiOff, RefreshCw } from 'lucide-react';\n\ninterface ConnectionStatusProps {\n connectionStatus: 'connected' | 'disconnected' | 'reconnecting';\n onReconnect: () => void;\n}\n\nexport const ConnectionStatus: React.FC<ConnectionStatusProps> = ({\n connectionStatus,\n onReconnect\n}) => {\n return (\n <div className=\"bg-amber-100 connection-status flex items-center justify-between px-4 py-1 text-xs\">\n <div className=\"text-gray-700 font-medium\">\n You are talking with your personal Content Strategist\n </div>\n {connectionStatus === 'connected' && (\n <div className=\"flex items-center text-green-600\">\n <Wifi className=\"w-3 h-3 mr-1\" />\n <span>Connected</span>\n </div>\n )}\n {connectionStatus === 'reconnecting' && (\n <div className=\"flex items-center text-amber-600\">\n <RefreshCw className=\"w-3 h-3 mr-1 animate-spin\" />\n <span>Reconnecting...</span>\n </div>\n )}\n {connectionStatus === 'disconnected' && (\n <div className=\"flex items-center gap-2\">\n <div className=\"text-red-600 flex items-center\">\n <WifiOff className=\"w-3 h-3 mr-1\" />\n <span>Disconnected</span>\n </div>\n <button\n onClick={onReconnect}\n className=\"text-blue-600 hover:text-blue-800 flex items-center\"\n >\n <RefreshCw className=\"w-3 h-3 mr-1\" />\n <span>Reconnect</span>\n </button>\n </div>\n )}\n </div>\n );\n}\n","import React from 'react';\n\ninterface SpinnerProps {\n size?: 'sm' | 'md' | 'lg' | 'xl';\n className?: string;\n color?: string;\n}\n\nexport const Spinner: React.FC<SpinnerProps> = ({\n size = 'md',\n className = '',\n color = 'text-blue-600'\n}) => {\n const sizeClasses = {\n sm: 'h-4 w-4',\n md: 'h-6 w-6',\n lg: 'h-8 w-8',\n xl: 'h-12 w-12'\n };\n\n return (\n <svg\n className={`animate-spin ${sizeClasses[size]} ${color} ${className}`}\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n );\n};\n","/**\n * Lightweight client for sending audio to a backend transcription endpoint.\n * This keeps the API key secret on the server.\n */\n\nexport interface TranscriptionConfig {\n endpoint: string;\n language?: string;\n // No headers needed if using standard fetch or cookies\n // Add custom headers support if needed for token auth\n headers?: Record<string, string>;\n}\n\nexport interface TranscriptionResult {\n text: string;\n error?: string;\n}\n\n/**\n * Transcribe audio blob by sending it to the configured backend endpoint.\n */\nexport async function transcribeAudio(\n audioBlob: Blob,\n config: TranscriptionConfig\n): Promise<string> {\n const formData = new FormData();\n formData.append('audio', audioBlob, 'recording.webm');\n\n if (config.language) {\n formData.append('language', config.language);\n }\n\n try {\n const response = await fetch(config.endpoint, {\n method: 'POST',\n body: formData,\n headers: config.headers || {},\n credentials: 'same-origin', // Ensure cookies are sent for same-domain requests\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Transcription failed (${response.status}): ${errorText}`);\n }\n\n const data = await response.json();\n return data.text;\n } catch (error: any) {\n console.error('Transcription client error:', error);\n throw error;\n }\n}\n","import { VoiceConfig } from '../types/chat';\nimport { TranscriptionConfig, transcribeAudio } from '../services/whisper-client';\n\n/**\n * Helper to create a VoiceConfig that uses the backend Whisper transcription service.\n * \n * @param config - Configuration for the transcription endpoint\n * @param callbacks - Optional callbacks for voice events\n * @returns VoiceConfig ready to be used in ChatInputArea\n */\nexport function createWhisperVoiceConfig(\n config: TranscriptionConfig,\n callbacks?: {\n onVoiceStart?: () => void;\n onVoiceEnd?: () => void;\n }\n): VoiceConfig {\n return {\n mode: 'custom',\n onVoiceStart: callbacks?.onVoiceStart,\n onVoiceEnd: callbacks?.onVoiceEnd,\n /**\n * The core handler: takes the recorded blob and sends it to the server.\n */\n onAudioCapture: async (blob: Blob) => {\n return await transcribeAudio(blob, config);\n }\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACgBgB;AART,SAAS,WAAW,EAAE,QAAQ,GAAoB;AACrD,SACI;AAAA,IAAC;AAAA;AAAA,MACG;AAAA,MACA,WAAU;AAAA,MACV,cAAW;AAAA,MAEX,sDAAC,SAAI,OAAM,8BAA6B,WAAU,WAAU,MAAK,QAAO,SAAQ,aAAY,QAAO,gBAC/F,sDAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,6GAA4G,GACrL;AAAA;AAAA,EACJ;AAER;;;ACjBA,4BAA0B;AAC1B,wBAAsB;AACtB,mBAA6B;;;ACL7B,mBAA4D;AAqBpD,IAAAA,sBAAA;AAPR,IAAM,wBAAoB,4BAA0B,CAAC,CAAC;AAE/C,IAAM,qBAGR,CAAC,EAAE,QAAQ,SAAS,MAAM;AAC3B,SACI,6CAAC,kBAAkB,UAAlB,EAA2B,OAAO,QAC9B,UACL;AAER;AAEO,IAAM,gBAAgB,UAAM,yBAAW,iBAAiB;;;ADE/C,IAAAC,sBAAA;AAbT,IAAM,gBAA8C,CAAC;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,MAAM;AACF,QAAM,EAAE,KAAK,IAAI,cAAc;AAC/B,QAAM,iBAAiB,kBAAiB,6BAAM;AAC9C,QAAM,WAAW,QAAQ,SAAS;AAElC,MAAI,UAAU;AACV,WACI,6CAAC,SAAI,WAAU,oBACX,wDAAC,UAAK,WAAU,mEACX;AAAA,cAAQ;AAAA,MACR,QAAQ,QAAQ,iBACb;AAAA,QAAC;AAAA;AAAA,UACG,SAAS,MAAM,cAAc,QAAQ,IAAK;AAAA,UAC1C,WAAU;AAAA,UACb;AAAA;AAAA,MAED;AAAA,OAER,GACJ;AAAA,EAER;AAEA,SACI,8CAAC,SAAI,WAAW,+BAA+B,SAAS,gBAAgB,eAAe,IAElF;AAAA,KAAC,UACE,6CAAC,SAAI,WAAU,8FACX,uDAAC,6BAAa,WAAU,WAAU,GACtC;AAAA,IAIJ;AAAA,MAAC;AAAA;AAAA,QACG,WAAW,+DAA+D,SACpE,2CACA,2CACF;AAAA,QACJ;AAAA,uDAAC,SAAI,WAAW,WAAW,CAAC,SAAS,8BAA8B,EAAE,IAChE,mBACG,6CAAC,OAAE,WAAU,uBAAuB,kBAAQ,SAAQ,IAEpD;AAAA,YAAC,sBAAAC;AAAA,YAAA;AAAA,cACG,eAAe,CAAC,kBAAAC,OAAS;AAAA,cACzB,YAAY;AAAA,gBACR,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,MAAM,6CAAC,OAAE,WAAU,kBAAkB,GAAG,OAAO;AAAA,gBACpE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,MAAM,6CAAC,QAAG,WAAU,uBAAuB,GAAG,OAAO;AAAA,gBAC3E,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,MAAM,6CAAC,QAAG,WAAU,0BAA0B,GAAG,OAAO;AAAA,gBAC9E,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,MAAM,6CAAC,QAAG,WAAU,UAAU,GAAG,OAAO;AAAA,gBAC9D,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,MAAM,6CAAC,OAAE,WAAU,iCAAiC,GAAG,OAAO;AAAA,gBACnF,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,MAAM,6CAAC,UAAK,WAAU,qDAAqD,GAAG,OAAO;AAAA,cACjH;AAAA,cAEC,kBAAQ;AAAA;AAAA,UACb,GAER;AAAA,UACC,QAAQ,SAAS,eAAe,QAAQ,QAAQ,iBAC7C;AAAA,YAAC;AAAA;AAAA,cACG,SAAS,MAAM,cAAc,QAAQ,IAAK;AAAA,cAC1C,WAAU;AAAA,cACb;AAAA;AAAA,UAED;AAAA,UAEH,QAAQ,gBAAgB,QAAQ,aAAa,SAAS,UACnD,6CAAC,SAAI,WAAU,sCACX;AAAA,YAAC;AAAA;AAAA,cACG,MAAM,QAAQ,aAAa;AAAA,cAC3B,QAAQ,QAAQ,aAAa,UAAU;AAAA,cACvC,KAAI;AAAA,cACJ,SAAS,CAAC,MAAM;AA5F5C;AA6FgC,sBAAI,aAAQ,iBAAR,mBAAsB,WAAU,QAAQ,aAAa,WAAW,UAAU;AAC1E,oBAAE,eAAe;AACjB,yBAAO,KAAK,QAAQ,aAAa,KAAK,QAAQ,aAAa,MAAM;AAAA,gBACrE;AAAA,cACJ;AAAA,cACA,WAAW,sEAAsE,SAC3E,mCACA,mCACF;AAAA,cAEH;AAAA,wBAAQ,aAAa;AAAA,gBACtB,6CAAC,SAAI,WAAU,eAAc,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACnE,uDAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,gFAA+E,GACxJ;AAAA;AAAA;AAAA,UACJ,GACJ;AAAA;AAAA;AAAA,IAER;AAAA,IAGC,UACG,6CAAC,SAAI,WAAU,iHACV,2BACG;AAAA,MAAC;AAAA;AAAA,QACG,WAAU;AAAA,QACV,KAAK;AAAA,QACL,KAAI;AAAA,QACJ,SAAS,CAAC,MAAM;AAxH5C;AA8HgC,UAAC,EAAE,OAA4B,MAAM,UAAU;AAC/C,WAAC,OAAE,OAA4B,kBAA9B,mBAA6C,UAAU,OAAO;AAAA,QAGnE;AAAA;AAAA,IACJ,IAEA,6CAAC,SAAI,OAAM,8BAA6B,SAAQ,aAAY,MAAK,gBAAe,WAAU,WACtF,uDAAC,UAAK,UAAS,WAAU,GAAE,6LAA4L,UAAS,WAAU,GAC9O,GAER;AAAA,KAER;AAER;;;AE5HQ,IAAAC,sBAAA;AAND,SAAS,WAAW;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AACJ,GAAoB;AAChB,SACI,8CAAC,SAAI,WAAU,sEACX;AAAA,iDAAC,QAAG,WAAU,uBACT,wBACK,+BAA+B,YAAY,WAAW,IAAI,YAAY,KAAK,MAC3E,+BAA+B,YAAY,KACrD;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACG,SAAS;AAAA,QACT,WAAU;AAAA,QACV,cAAW;AAAA,QAEX,uDAAC,SAAI,OAAM,8BAA6B,WAAU,WAAU,SAAQ,aAAY,MAAK,gBACjF,uDAAC,UAAK,UAAS,WAAU,GAAE,sMAAqM,UAAS,WAAU,GACvP;AAAA;AAAA,IACJ;AAAA,KACJ;AAER;;;AChCA,IAAAC,gBAA6H;AAC7H,qBAAyF;;;ACHzF,IAAAC,gBAAyD;AA4BlD,IAAM,uBAAuB,CAChC,UACA,OACA,WAAmB,YACK;AACxB,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAS,KAAK;AACpD,QAAM,CAAC,YAAY,aAAa,QAAI,wBAAS,EAAE;AAC/C,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAwB,IAAI;AACtD,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAS,KAAK;AAEpD,QAAM,qBAAiB,sBAAY,IAAI;AACvC,QAAM,sBAAkB,sBAAO,KAAK;AACpC,QAAM,2BAAuB,sBAAY,IAAI;AAC7C,QAAM,kBAAc,sBAAO,QAAQ;AACnC,QAAM,oBAAgB,sBAAe,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;AACxE,QAAM,qBAAiB,sBAAsB,IAAI;AACjD,QAAM,oBAAgB,sBAAsB,IAAI;AAEhD,QAAM,kBAAc,sBAAO,QAAQ;AACnC,QAAM,eAAW,sBAAO,KAAK;AAE7B,+BAAU,MAAM;AACZ,gBAAY,UAAU;AACtB,aAAS,UAAU;AAAA,EACvB,GAAG,CAAC,UAAU,KAAK,CAAC;AAEpB,+BAAU,MAAM;AACZ,gBAAY,UAAU;AAEtB,QAAI,eAAe,SAAS;AACxB,cAAQ,IAAI,gDAAgD,QAAQ;AACpE,qBAAe,QAAQ,OAAO;AAAA,IAClC;AAAA,EACJ,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,oBAAgB,sBAAO,KAAK;AAGlC,+BAAU,MAAM;AAlEpB;AAmEQ,QAAI,OAAO,WAAW,aAAa;AAC/B,YAAM,oBAAqB,OAAe,qBAAsB,OAAe;AAC/E,cAAQ,IAAI,iDAAkD,OAAe,iBAAiB,cAAa,YAAO,aAAP,mBAAiB,QAAQ;AACpI,YAAM,WAAW,iEAAiE,KAAK,UAAU,SAAS,KACrG,kBAAkB,UAClB,UAAU,iBAAiB;AAChC,cAAQ,IAAI,oEAAoE,CAAC,CAAC,mBAAmB,aAAa,UAAU,eAAe,cAAc,OAAO;AAChK,qBAAe,CAAC,CAAC,iBAAiB;AAAA,IACtC;AAEA,WAAO,MAAM;AACT,cAAQ,IAAI,8DAA8D;AAC1E,UAAI,gBAAgB,WAAW,qBAAqB,SAAS;AACzD,qBAAa,qBAAqB,OAAO;AACzC,6BAAqB,UAAU;AAAA,MACnC;AACA,UAAI,eAAe,SAAS;AACxB,YAAI;AACA,yBAAe,QAAQ,KAAK;AAAA,QAChC,SAAS,GAAG;AAAA,QAEZ;AACA,uBAAe,UAAU;AAAA,MAC7B;AAEA,UAAI,OAAO,WAAW,aAAa;AAC/B,cAAM,IAAI;AACV,YAAI,EAAE,2CAA2C,cAAc,SAAS;AACpE,kBAAQ,IAAI,oFAAoF,cAAc,OAAO;AACrH,YAAE,yCAAyC;AAAA,QAC/C;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ,GAAG,CAAC,CAAC;AAIL,QAAM,gCAA4B,2BAAY,MAAM;AAChD,UAAM,oBAAqB,OAAe,qBAAsB,OAAe;AAC/E,QAAI,CAAC,mBAAmB;AACpB,cAAQ,MAAM,wDAAwD;AACtE,aAAO;AAAA,IACX;AAEA,YAAQ,IAAI,oGAAoG,KAAK,IAAI,CAAC;AAC1H,UAAM,cAAc,IAAI,kBAAkB;AAC1C,UAAM,WAAW,iEAAiE,KAAK,UAAU,SAAS,KACrG,kBAAkB,UAClB,UAAU,iBAAiB;AAChC,gBAAY,aAAa,CAAC;AAC1B,gBAAY,iBAAiB;AAC7B,gBAAY,OAAO,YAAY;AAC/B,YAAQ,IAAI,wDAAwD,YAAY,YAAY,mBAAmB,YAAY,gBAAgB,SAAS,YAAY,MAAM,aAAa,UAAU,eAAe,cAAc,OAAO;AAEjO,gBAAY,eAAe,MAAM;AAC7B,cAAQ,IAAI,0DAA0D,KAAK,IAAI,GAAG,eAAe,cAAc,OAAO;AAAA,IAC1H;AACA,gBAAY,aAAa,MAAM;AAC3B,cAAQ,IAAI,wDAAwD,KAAK,IAAI,GAAG,eAAe,cAAc,OAAO;AAAA,IACxH;AACA,gBAAY,eAAe,MAAM;AAC7B,cAAQ,IAAI,0DAA0D,KAAK,IAAI,GAAG,eAAe,cAAc,OAAO;AAAA,IAC1H;AACA,gBAAY,aAAa,MAAM;AAC3B,cAAQ,IAAI,wDAAwD,KAAK,IAAI,GAAG,eAAe,cAAc,OAAO;AAAA,IACxH;AACA,gBAAY,gBAAgB,MAAM;AAC9B,cAAQ,IAAI,2DAA2D,KAAK,IAAI,GAAG,eAAe,cAAc,OAAO;AAAA,IAC3H;AACA,gBAAY,cAAc,MAAM;AAC5B,cAAQ,IAAI,yDAAyD,KAAK,IAAI,GAAG,eAAe,cAAc,OAAO;AAAA,IACzH;AACA,gBAAY,YAAY,MAAM;AAC1B,cAAQ,IAAI,uDAAuD,KAAK,IAAI,GAAG,eAAe,cAAc,OAAO;AAAA,IACvH;AAEA,gBAAY,UAAU,MAAM;AACxB,cAAQ,IAAI,iEAAiE,KAAK,IAAI,CAAC;AACvF,oBAAc,UAAU;AACxB,qBAAe,IAAI;AACnB,eAAS,IAAI;AAEb,UAAI,OAAO,WAAW,aAAa;AAC/B,cAAM,IAAI;AACV,UAAE,yCAAyC,cAAc;AACzD,gBAAQ,IAAI,uEAAuE,cAAc,OAAO;AAAA,MAC5G;AAAA,IACJ;AAEA,gBAAY,QAAQ,MAAM;AACtB,cAAQ,IAAI,+DAA+D,KAAK,IAAI,CAAC;AACrF,oBAAc,UAAU;AACxB,UAAI,gBAAgB,SAAS;AACzB,gBAAQ,IAAI,mDAAmD;AAC/D;AAAA,MACJ;AACA,qBAAe,KAAK;AACpB,UAAI,SAAS,QAAS,UAAS,QAAQ;AAEvC,UAAI,OAAO,WAAW,aAAa;AAC/B,cAAM,IAAI;AACV,YAAI,EAAE,2CAA2C,cAAc,SAAS;AACpE,YAAE,yCAAyC;AAC3C,kBAAQ,IAAI,2EAA2E,cAAc,OAAO;AAAA,QAChH;AAAA,MACJ;AAAA,IACJ;AAEA,gBAAY,WAAW,CAAC,UAAkC;AACtD,cAAQ,IAAI,yDAAyD,MAAM,QAAQ,MAAM;AACzF,UAAI,oBAAoB;AACxB,UAAI,kBAAkB;AAEtB,eAAS,IAAI,MAAM,QAAQ,SAAS,GAAG,IAAI,MAAM,QAAQ,QAAQ,EAAE,GAAG;AAClE,cAAM,SAAS,MAAM,QAAQ,CAAC;AAC9B,YAAI,OAAO,SAAS;AAChB,6BAAmB,OAAO,CAAC,EAAE;AAC7B,kBAAQ,IAAI,4CAA4C,eAAe;AACvE,cAAI,YAAY,QAAS,aAAY,QAAQ,iBAAiB,IAAI;AAAA,QACtE,OAAO;AACH,+BAAqB,OAAO,CAAC,EAAE;AAC/B,kBAAQ,IAAI,8CAA8C,iBAAiB;AAC3E,cAAI,YAAY,QAAS,aAAY,QAAQ,mBAAmB,KAAK;AAAA,QACzE;AAAA,MACJ;AAEA,oBAAc,UAAQ,OAAO,eAAe;AAAA,IAChD;AAEA,gBAAY,UAAU,CAAC,UAAuC;AAC1D,cAAQ,MAAM,gDAAgD,MAAM,OAAO,cAAc,KAAK,IAAI,CAAC;AACnG,cAAQ,MAAM,uDAAuD,eAAe,SAAS,eAAe,cAAc,SAAS,eAAe,cAAc,OAAO;AACvK,cAAQ,MAAM,iEAAiE;AAC/E,UAAI,MAAM,UAAU,WAAW;AAC3B,gBAAQ,MAAM,6JAA6J;AAAA,MAC/K,WAAW,MAAM,UAAU,eAAe;AACtC,gBAAQ,MAAM,oEAAoE;AAAA,MACtF,WAAW,MAAM,UAAU,aAAa;AACpC,gBAAQ,MAAM,wDAAwD;AAAA,MAC1E,WAAW,MAAM,UAAU,WAAW;AAClC,gBAAQ,MAAM,oEAAoE;AAAA,MACtF;AACA,oBAAc,UAAU;AAGxB,UAAI,MAAM,UAAU,iBAAiB,QAAQ,IAAI,aAAa,eAAe;AACzE,gBAAQ,KAAK,iEAAiE;AAC9E,wBAAgB,UAAU;AAC1B,iBAAS,IAAI;AACb,uBAAe,IAAI;AAEnB,6BAAqB,UAAU,WAAW,MAAM;AAC5C,gBAAM,WAAW;AACjB,wBAAc,UAAQ,QAAQ,OAAO,MAAM,MAAM,QAAQ;AACzD,cAAI,YAAY,QAAS,aAAY,QAAQ,UAAU,IAAI;AAE3D,0BAAgB,UAAU;AAC1B,yBAAe,KAAK;AACpB,cAAI,SAAS,QAAS,UAAS,QAAQ;AACvC,+BAAqB,UAAU;AAAA,QACnC,GAAG,GAAI;AACP;AAAA,MACJ;AAEA,cAAQ,MAAM,4BAA4B,MAAM,KAAK;AACrD,eAAS,MAAM,KAAK;AACpB,qBAAe,KAAK;AAEpB,UAAI,OAAO,WAAW,aAAa;AAC/B,cAAM,IAAI;AACV,YAAI,EAAE,2CAA2C,cAAc,SAAS;AACpE,YAAE,yCAAyC;AAC3C,kBAAQ,IAAI,uFAAuF,cAAc,OAAO;AAAA,QAC5H;AAAA,MACJ;AAAA,IACJ;AAEA,WAAO;AAAA,EACX,GAAG,CAAC,CAAC;AAEL,QAAM,YAAQ,2BAAY,MAAM;AAvPpC;AAwPQ,UAAM,iBAAiB,KAAK,IAAI;AAChC,YAAQ,IAAI,qDAAqD,cAAc;AAC/E,YAAQ,IAAI,qDAAqD,aAAa,eAAe,cAAc,SAAS,wBAAwB,CAAC,CAAC,eAAe,OAAO;AAGpK,QAAI,OAAO,aAAa,aAAa;AACjC,cAAQ,IAAI,6CAA6C,SAAS,SAAS,GAAG,mBAAkB,cAAS,kBAAT,mBAAwB,OAAO;AAAA,IACnI;AAEA,QAAI,gBAAgB,SAAS;AACzB,cAAQ,IAAI,qDAAqD;AACjE;AAAA,IACJ;AAEA,QAAI,cAAc,SAAS;AACvB,cAAQ,KAAK,mEAAmE;AAChF;AAAA,IACJ;AAGA,QAAI,aAAa;AACb,cAAQ,KAAK,oEAAoE;AACjF;AAAA,IACJ;AAEA,QAAI,OAAO,WAAW,aAAa;AAC/B,YAAM,IAAI;AACV,UAAI,EAAE,0CAA0C,EAAE,2CAA2C,cAAc,SAAS;AAChH,gBAAQ,MAAM,yFAAyF,EAAE,wCAAwC,mBAAmB,cAAc,OAAO;AAAA,MAC7L;AAAA,IACJ;AAEA,QAAI;AAMA,UAAI,eAAe,SAAS;AACxB,gBAAQ,IAAI,2EAA2E;AACvF,YAAI;AACA,yBAAe,QAAQ,KAAK;AAAA,QAChC,SAAS,GAAG;AAAA,QAEZ;AACA,uBAAe,UAAU;AAAA,MAC7B;AAGA,YAAM,cAAc,0BAA0B;AAC9C,UAAI,CAAC,aAAa;AACd,gBAAQ,MAAM,8DAA8D;AAC5E,iBAAS,kCAAkC;AAC3C;AAAA,MACJ;AACA,qBAAe,UAAU;AAEzB,oBAAc,EAAE;AAChB,oBAAc,UAAU;AACxB,qBAAe,UAAU,KAAK,IAAI;AAClC,cAAQ,IAAI,wEAAwE,KAAK,IAAI,CAAC;AAC9F,qBAAe,QAAQ,MAAM;AAC7B,cAAQ,IAAI,gFAAgF,KAAK,IAAI,CAAC;AAAA,IAC1G,SAASC,QAAY;AACjB,oBAAc,UAAU;AACxB,cAAQ,MAAM,wDAAuDA,UAAA,gBAAAA,OAAO,YAAWA,MAAK;AAC5F,WAAIA,UAAA,gBAAAA,OAAO,UAAS,qBAAqB;AACrC,gBAAQ,MAAM,+EAA+E;AAAA,MACjG;AACA,gBAASA,UAAA,gBAAAA,OAAO,YAAW,oCAAoC;AAAA,IACnE;AAAA,EACJ,GAAG,CAAC,aAAa,yBAAyB,CAAC;AAE3C,QAAM,WAAO,2BAAY,MAAM;AAC3B,YAAQ,IAAI,sCAAsC;AAClD,kBAAc,UAAU,KAAK,IAAI;AACjC,QAAI,gBAAgB,SAAS;AACzB,UAAI,qBAAqB,SAAS;AAC9B,qBAAa,qBAAqB,OAAO;AACzC,6BAAqB,UAAU;AAAA,MACnC;AAGA,YAAM,WAAW;AACjB,oBAAc,UAAQ,QAAQ,OAAO,MAAM,MAAM,QAAQ;AACzD,UAAI,YAAY,QAAS,aAAY,QAAQ,UAAU,IAAI;AAE3D,sBAAgB,UAAU;AAC1B,qBAAe,KAAK;AACpB,UAAI,SAAS,QAAS,UAAS,QAAQ;AACvC;AAAA,IACJ;AAEA,QAAI,eAAe,SAAS;AACxB,qBAAe,QAAQ,KAAK;AAC5B,cAAQ,IAAI,oDAAoD;AAAA,IACpE;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,QAAM,sBAAkB,2BAAY,MAAM;AACtC,kBAAc,EAAE;AAAA,EACpB,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ;;;ACxWA,IAAAC,gBAA8C;AAWvC,IAAM,mBAAmB,CAC5B,WACoB;AACpB,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAS,KAAK;AACpD,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAS,KAAK;AACpD,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAsB,IAAI;AAClD,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAwB,IAAI;AAEtD,QAAM,uBAAmB,sBAA6B,IAAI;AAC1D,QAAM,gBAAY,sBAAe,CAAC,CAAC;AAEnC,QAAM,YAAQ,2BAAY,YAAY;AAElC,QAAI;AACA,UAAI,CAAC,UAAU,gBAAgB,CAAC,UAAU,aAAa,cAAc;AAEjE,YAAI,QAAQ,IAAI,aAAa,eAAe;AACxC,kBAAQ,KAAK,4EAA4E;AACzF,yBAAe,IAAI;AACnB,yBAAe,IAAI;AACnB,mBAAS,IAAI;AACb;AAAA,QACJ;AACA,cAAM,IAAI,MAAM,uEAAuE;AAAA,MAC3F;AACA,YAAM,SAAS,MAAM,UAAU,aAAa,aAAa,EAAE,OAAO,KAAK,CAAC;AAExE,YAAM,gBAAgB,IAAI,cAAc,MAAM;AAE9C,uBAAiB,UAAU;AAC3B,gBAAU,UAAU,CAAC;AAErB,oBAAc,kBAAkB,CAAC,MAAM;AACnC,YAAI,EAAE,KAAK,OAAO,GAAG;AACjB,oBAAU,QAAQ,KAAK,EAAE,IAAI;AAAA,QACjC;AAAA,MACJ;AAEA,oBAAc,SAAS,MAAM;AACzB,cAAM,YAAY,IAAI,KAAK,UAAU,SAAS,EAAE,MAAM,aAAa,CAAC;AACpE,gBAAQ,SAAS;AACjB,uBAAe,KAAK;AACpB,YAAI,OAAQ,QAAO,SAAS;AAG5B,eAAO,UAAU,EAAE,QAAQ,WAAS;AAChC,gBAAM,KAAK;AAAA,QACf,CAAC;AAAA,MACL;AAEA,oBAAc,MAAM;AACpB,qBAAe,IAAI;AACnB,eAAS,IAAI;AAAA,IACjB,SAAS,GAAQ;AACb,cAAQ,MAAM,oCAAoC,CAAC;AACnD,eAAS,EAAE,WAAW,0BAA0B;AAAA,IACpD;AAAA,EACJ,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,WAAO,2BAAY,MAAM;AAC3B,QAAI,aAAa;AACb,qBAAe,KAAK;AACpB,qBAAe,KAAK;AAEpB,YAAM,gBAAgB,IAAI,KAAK,CAAC,kBAAkB,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAChF,cAAQ,aAAa;AACrB,UAAI,OAAQ,QAAO,aAAa;AAChC;AAAA,IACJ;AAEA,QAAI,iBAAiB,WAAW,iBAAiB,QAAQ,UAAU,YAAY;AAC3E,uBAAiB,QAAQ,KAAK;AAAA,IAClC;AAAA,EACJ,GAAG,CAAC,aAAa,MAAM,CAAC;AAExB,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ;;;AC9FA,IAAAC,gBAAqC;AAO9B,SAAS,mBACZ,aACA,gBACA,OACA,UACF;AACE,+BAAU,MAAM;AACZ,QAAI,CAAC,YAAY,WAAW,CAAC,eAAe,QAAS;AAGrD,UAAM,SAAS,OAAO,iBAAiB,YAAY,OAAO;AAC1D,mBAAe,QAAQ,MAAM,QAAQ,OAAO;AAC5C,mBAAe,QAAQ,MAAM,OAAO,OAAO;AAC3C,mBAAe,QAAQ,MAAM,UAAU,OAAO;AAC9C,mBAAe,QAAQ,MAAM,SAAS,OAAO;AAC7C,mBAAe,QAAQ,MAAM,YAAY,OAAO;AAChD,mBAAe,QAAQ,MAAM,aAAa;AAC1C,mBAAe,QAAQ,MAAM,aAAa;AAC1C,mBAAe,QAAQ,MAAM,WAAW;AACxC,mBAAe,QAAQ,MAAM,gBAAgB;AAI7C,mBAAe,QAAQ,cAAc,QAAQ;AAG7C,UAAM,eAAe,eAAe,QAAQ;AAM5C,gBAAY,QAAQ,MAAM,SAAS,GAAG,YAAY;AAAA,EAEtD,GAAG,CAAC,OAAO,UAAU,aAAa,cAAc,CAAC;AACrD;;;AHuVwB,IAAAC,sBAAA;AA9VjB,IAAM,oBAAgB,0BAAoD,CAAC;AAAA,EAC9E;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,mBAAmB;AACvB,GAAG,QAAQ;AAhDX;AAiDI,QAAM,CAAC,iBAAiB,kBAAkB,QAAI,wBAAS,EAAE;AACzD,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAmC,IAAI;AAC/E,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,wBAAS,KAAK;AAC1D,QAAM,CAAC,YAAY,aAAa,QAAI,wBAAwB,IAAI;AAChE,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,KAAK;AAGhD,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,KAAK;AAChD,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAmB,CAAC,CAAC;AAC7C,QAAM,kBAAc,sBAA2C,EAAE,OAAO,GAAG,SAAS,EAAE,CAAC;AAGvF,+BAAU,MAAM;AACZ,UAAM,cAAc,QAAQ;AAC5B,UAAM,eAAe,QAAQ;AAC7B,UAAM,gBAAgB,QAAQ;AAE9B,UAAM,SAAS,CAAC,MAAc,SAAgB;AAG1C,UAAI;AACA,cAAM,MAAM,KAAK,IAAI,SAAO;AACxB,cAAI,eAAe,MAAO,QAAO,GAAG,IAAI,IAAI,KAAK,IAAI,OAAO;AAC5D,cAAI,OAAO,QAAQ,SAAU,QAAO,KAAK,UAAU,GAAG;AACtD,iBAAO,OAAO,GAAG;AAAA,QACrB,CAAC,EAAE,KAAK,GAAG;AACX,gBAAQ,UAAQ,CAAC,IAAI,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,MAC9D,SAAS,GAAG;AAAA,MAEZ;AAAA,IACJ;AAEA,YAAQ,MAAM,IAAI,SAAS;AAAE,kBAAY,GAAG,IAAI;AAAG,aAAO,OAAO,IAAI;AAAA,IAAG;AACxE,YAAQ,OAAO,IAAI,SAAS;AAAE,mBAAa,GAAG,IAAI;AAAG,aAAO,OAAO,IAAI;AAAA,IAAG;AAC1E,YAAQ,QAAQ,IAAI,SAAS;AAAE,oBAAc,GAAG,IAAI;AAAG,aAAO,OAAO,IAAI;AAAA,IAAG;AAE5E,WAAO,MAAM;AACT,cAAQ,MAAM;AACd,cAAQ,OAAO;AACf,cAAQ,QAAQ;AAAA,IACpB;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,QAAM,eAAW,2BAAY,MAAM;AAC/B,cAAU,UAAU,UAAU,KAAK,KAAK,IAAI,CAAC,EACxC,KAAK,MAAM,MAAM,0BAA0B,CAAC,EAC5C,MAAM,SAAO,QAAQ,MAAM,uBAAuB,GAAG,CAAC;AAAA,EAC/D,GAAG,CAAC,IAAI,CAAC;AAGT,QAAM,kBAAc,sBAA4B,IAAI;AACpD,QAAM,qBAAiB,sBAAwB,IAAI;AACnD,QAAM,0BAAsB,sBAA8C,IAAI;AAG9E,QAAM,eAAe,UAAU;AAC/B,QAAM,UAAU,eAAe,QAAQ;AAGvC,QAAM,iBAAa,sBAAO,OAAO;AACjC,aAAW,UAAU;AAGrB,qCAAgB,MAAM;AAClB,QAAI,oBAAoB,WAAW,YAAY,SAAS;AACpD,YAAM,EAAE,OAAO,IAAI,IAAI,oBAAoB;AAC3C,kBAAY,QAAQ,MAAM;AAC1B,kBAAY,QAAQ,kBAAkB,OAAO,GAAG;AAChD,0BAAoB,UAAU;AAAA,IAClC;AAAA,EACJ,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,kBAAc,sBAAO,QAAQ;AACnC,+BAAU,MAAM;AACZ,gBAAY,UAAU;AAAA,EAC1B,GAAG,CAAC,QAAQ,CAAC;AAGb,QAAM,EAAE,OAAO,YAAY,IAAI,cAAc;AAG7C,QAAM,kBAAiB,gDAAa,YAAb,YAAyB,CAAC,CAAC;AAClD,QAAM,cAAc,iBAAkB,oBAAmB,2CAAa,UAAU;AAEhF,QAAM,qBAAiB,sBAAO,WAAW;AACzC,+BAAU,MAAM;AACZ,mBAAe,UAAU;AAAA,EAC7B,GAAG,CAAC,WAAW,CAAC;AAEhB,QAAM,oBAAgB,2BAAY,CAAC,aAAqB;AACpD,kBAAc,IAAI;AAClB,QAAI,gBAAgB,YAAY,SAAS;AACrC,YAAM,iBAAiB;AAAA,QACnB,QAAQ,EAAE,OAAO,SAAS;AAAA,QAC1B,eAAe,EAAE,OAAO,SAAS;AAAA,MACrC;AACA,kBAAY,QAAQ,cAAc;AAAA,IACtC,OAAO;AACH,yBAAmB,QAAQ;AAAA,IAC/B;AAAA,EACJ,GAAG,CAAC,YAAY,CAAC;AAGjB,QAAM,mBAAkB,2CAAa,cAChC,iEAAwB,mBACnB,sEAAwB,oBAAxB,mBAAyC,cAAa,UAAU,EAAC,iEAAwB,0BACtF,sEAAwB,oBAAxB,mBAAyC,cAAa,aAAa,EAAC,iEAAwB;AAEzG,qBAAmB,aAAa,gBAAgB,SAAS,mBAAmB,CAAC,CAAC,YAAY;AAG1F,QAAM,yBAAqB,2BAAY,CAAC,SAAiB;AACrD,UAAM,WAAW,YAAY;AAC7B,UAAM,aAAa,WAAW,WAAW;AAEzC,QAAI,CAAC,UAAU;AACX,oBAAc,cAAc,aAAa,MAAM,MAAM,IAAI;AACzD;AAAA,IACJ;AAEA,UAAM,QAAQ,SAAS;AACvB,UAAM,MAAM,SAAS;AAErB,UAAM,SAAS,WAAW,UAAU,GAAG,KAAK;AAC5C,UAAM,QAAQ,WAAW,UAAU,GAAG;AAGtC,UAAM,SAAU,QAAQ,KAAK,CAAC,MAAM,KAAK,MAAM,IAAK,MAAM;AAE1D,UAAM,UAAU,SAAS,SAAS,OAAO;AAGzC,UAAM,iBAAiB,QAAQ,OAAO;AACtC,UAAM,eAAe,iBAAiB,KAAK;AAC3C,wBAAoB,UAAU,EAAE,OAAO,gBAAgB,KAAK,aAAa;AAEzE,kBAAc,OAAO;AAAA,EACzB,GAAG,CAAC,aAAa,CAAC;AAGlB,QAAM,wBAAoB,2BAAY,CAAC,MAAc,YAAqB;AACtE,QAAI,SAAS;AACT,yBAAmB,IAAI;AAAA,IAC3B;AAAA,EACJ,GAAG,CAAC,kBAAkB,CAAC;AAEvB,QAAM,qBAAiB,2BAAY,MAAM;AAnM7C,QAAAC,KAAAC;AAoMQ,oBAAgB,IAAI;AAGpB,KAAAA,OAAAD,MAAA,eAAe,YAAf,gBAAAA,IAAwB,eAAxB,gBAAAC,IAAA,KAAAD;AAAA,EACJ,GAAG,CAAC,CAAC;AAGL,QAAM,eAAe,qBAAqB,mBAAmB,gBAAgB,2CAAa,QAAQ;AAGlG,+BAAU,MAAM;AACZ,QAAI,aAAa,OAAO;AACpB,oBAAc,aAAa,KAAK;AAEhC,cAAQ,MAAM,wCAAwC,aAAa,KAAK;AAAA,IAC5E;AAAA,EACJ,GAAG,CAAC,aAAa,KAAK,CAAC;AAEvB,QAAM,iBAAiB,iBAAiB,OAAO,SAAS;AAtN5D,QAAAA,KAAAC,KAAAC;AAuNQ,oBAAgB,IAAI;AACpB,sBAAkB,IAAI;AACtB,kBAAc,IAAI;AAClB,KAAAD,OAAAD,MAAA,eAAe,YAAf,gBAAAA,IAAwB,eAAxB,gBAAAC,IAAA,KAAAD;AAEA,QAAI,KAAK,SAAS,mBAAmB;AACjC,cAAQ,IAAI,kDAAkD;AAE9D,YAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,IAAI,CAAC;AACtD,yBAAmB,4DAA4D;AAC/E,wBAAkB,KAAK;AACvB;AAAA,IACJ;AAEA,SAAIE,MAAA,eAAe,YAAf,gBAAAA,IAAwB,gBAAgB;AACxC,UAAI;AACA,cAAM,OAAO,MAAM,eAAe,QAAQ,eAAe,IAAI;AAC7D,YAAI,KAAM,oBAAmB,IAAI;AAAA,MACrC,SAAS,GAAQ;AACb,gBAAQ,MAAM,wCAAwC,CAAC;AACvD,sBAAc,EAAE,WAAW,sBAAsB;AAAA,MACrD,UAAE;AACE,0BAAkB,KAAK;AAAA,MAC3B;AAAA,IACJ,OAAO;AACH,wBAAkB,KAAK;AAAA,IAC3B;AAAA,EACJ,CAAC;AAGD,yCAAoB,KAAK,OAAO;AAAA,IAC5B,OAAO,MAAM;AAtPrB,UAAAF;AAuPY,OAAAA,MAAA,YAAY,YAAZ,gBAAAA,IAAqB;AAAA,IACzB;AAAA,IACA,UAAU,CAAC,aAAqB;AAC5B,oBAAc,QAAQ;AAAA,IAC1B;AAAA,EACJ,EAAE;AAEF,QAAM,eAAe,CAAC,MAAkB;AACpC,QAAI,EAAG,GAAE,eAAe;AAExB,QAAI,CAAC,QAAQ,KAAK,GAAG;AACjB,iBAAW,MAAG;AAlQ1B,YAAAA;AAkQ6B,gBAAAA,MAAA,YAAY,YAAZ,gBAAAA,IAAqB;AAAA,SAAS,CAAC;AAChD;AAAA,IACJ;AAEA,UAAM,iBAAiB;AACvB,kBAAc,EAAE;AAChB,eAAW,MAAG;AAxQtB,UAAAA;AAwQyB,cAAAA,MAAA,YAAY,YAAZ,gBAAAA,IAAqB;AAAA,OAAS,CAAC;AAChD,aAAS,cAAc;AAAA,EAC3B;AAEA,QAAM,gBAAgB,CAAC,MAAgD;AACnE,QAAI,EAAE,QAAQ,WAAW,CAAC,EAAE,YAAY,CAAC,EAAE,WAAW,CAAC,EAAE,QAAQ;AAC7D,QAAE,eAAe;AACjB,mBAAa;AAAA,IACjB;AAAA,EACJ;AAGA,QAAM,eAAW,2BAAY,MAAM;AAC/B,QAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,WAAO,iEAAiE,KAAK,UAAU,SAAS,KAC3F,kBAAkB,UAClB,UAAU,iBAAiB;AAAA,EACpC,GAAG,CAAC,CAAC;AAEL,QAAM,iBAAiB,OAAO,YAA+B;AA3RjE,QAAAA,KAAAC;AA4RQ,YAAQ,IAAI,mDAAmD,SAAS,aAAa,SAAS,CAAC;AAC/F,YAAQ,IAAI,iDAAiD,cAAc,mBAAmB,cAAc;AAG5G,QAAI,SAAS,GAAG;AACZ,cAAQ,IAAI,gFAAgF;AAE5F,UAAI,SAAS,yBAAyB,aAAa;AAC/C,gBAAQ,IAAI,4DAA4D;AACxE,iBAAS,cAAc,KAAK;AAAA,MAChC;AAAA,IACJ;AAEA,QAAI,gBAAgB,gBAAgB;AAChC,cAAQ,IAAI,yDAAyD;AACrE;AAAA,IACJ;AAEA,oBAAgB,OAAO;AACvB,kBAAc,IAAI;AAElB,SAAI,2CAAa,UAAS,UAAU;AAChC,cAAQ,IAAI,iDAAiD;AAC7D,UAAI,CAAC,aAAa,aAAa;AAC3B,gBAAQ,MAAM,6CAA6C;AAC3D,cAAM,sDAAsD;AAC5D,wBAAgB,IAAI;AACpB;AAAA,MACJ;AACA,cAAQ,IAAI,iDAAiD;AAC7D,mBAAa,MAAM;AACnB,cAAQ,IAAI,6CAA6C;AAEzD,cAAQ,IAAI,0FAA0F;AACtG,UAAI;AACA,SAAAD,MAAA,2CAAa,iBAAb,gBAAAA,IAAA;AACA,gBAAQ,IAAI,oDAAoD;AAAA,MACpE,SAAS,GAAG;AACR,gBAAQ,MAAM,wDAAwD,CAAC;AAAA,MAC3E;AAAA,IACJ,OAAO;AACH,cAAQ,IAAI,uCAAuC;AACnD,cAAQ,IAAI,6EAA6E;AACzF,UAAI;AACA,SAAAC,MAAA,2CAAa,iBAAb,gBAAAA,IAAA;AACA,gBAAQ,IAAI,oDAAoD;AAAA,MACpE,SAAS,GAAG;AACR,gBAAQ,MAAM,wDAAwD,CAAC;AAAA,MAC3E;AACA,YAAM,eAAe,MAAM;AAC3B,cAAQ,IAAI,yCAAyC;AAAA,IACzD;AAGA,QAAI,CAAC,SAAS,GAAG;AACb,cAAQ,IAAI,qDAAqD;AACjE,iBAAW,MAAG;AApV1B,YAAAD;AAoV6B,gBAAAA,MAAA,YAAY,YAAZ,gBAAAA,IAAqB;AAAA,SAAS,CAAC;AAAA,IACpD;AAAA,EACJ;AAEA,QAAM,gBAAgB,MAAM;AACxB,QAAI,CAAC,aAAc;AACnB,SAAI,2CAAa,UAAS,UAAU;AAChC,mBAAa,KAAK;AAAA,IACtB,OAAO;AACH,qBAAe,KAAK;AAAA,IACxB;AAAA,EACJ;AAGA,QAAM,iBAAiB,MAAM;AACzB,QAAI,YAAa,QAAO;AACxB,QAAI,aAAc,QAAO;AACzB,QAAI,2CAAa,SAAU,QAAO;AAElC,SAAI,iEAAwB,iBAAe,iEAAwB,oBAAmB,EAAC,iEAAwB,sBAAqB;AAChI,YAAM,kBAAkB,uBAAuB,gBAAgB;AAC/D,cAAQ,iBAAiB;AAAA,QACrB,KAAK;AAAQ,iBAAO;AAAA,QACpB,KAAK;AAAW,iBAAO;AAAA,QACvB,KAAK;AAAU,iBAAO;AAAA,QACtB,KAAK;AAAQ,iBAAO;AAAA,QACpB;AAAS,iBAAO;AAAA,MACpB;AAAA,IACJ;AACA,WAAO,cAAc,kCAAkC;AAAA,EAC3D;AAEA,QAAM,YAAa,CAAC,mBAAmB,EAAC,iEAAwB,eAAe,SAC1E,sEAAwB,oBAAxB,mBAAyC,cAAa,SAAS,wDAAwD;AAE5H,MAAI,CAAC,eAAe;AAChB,WAAO;AAAA,EACX;AAEA,SACI,8CAAC,SAAI,WAAU,iCAEV;AAAA,iBACG,8CAAC,SAAI,WAAU,mJACX;AAAA,oDAAC,SAAI,WAAU,0DACX;AAAA,qDAAC,UAAK,wBAAU;AAAA,QAChB,8CAAC,SAAI,WAAU,cACX;AAAA,uDAAC,YAAO,SAAS,UAAU,WAAU,kCAAiC,OAAM,aACxE,uDAAC,mCAAiB,WAAU,WAAU,GAC1C;AAAA,UACA,6CAAC,YAAO,SAAS,MAAM;AAAE,qBAAS;AAAG,yBAAa,KAAK;AAAA,UAAG,GAAG,WAAU,iCAAgC,OAAM,gBACzG,uDAAC,4BAAU,WAAU,WAAU,GACnC;AAAA,WACJ;AAAA,SACJ;AAAA,MACC,KAAK,IAAI,CAAC,KAAK,MACZ,6CAAC,SAAY,WAAU,uDAClB,iBADK,CAEV,CACH;AAAA,MACA,KAAK,WAAW,KAAK,6CAAC,SAAI,4BAAc;AAAA,OAC7C;AAAA,IAGJ,8CAAC,SAAI,WAAU,2BAEV;AAAA,qBACG;AAAA,QAAC;AAAA;AAAA,UACG,MAAK;AAAA,UACL,SAAS,MAAM;AAEX,kBAAM,MAAM,KAAK,IAAI;AACrB,gBAAI,MAAM,YAAY,QAAQ,UAAU,KAAK;AACzC,0BAAY,QAAQ;AAAA,YACxB,OAAO;AACH,0BAAY,QAAQ,QAAQ;AAAA,YAChC;AACA,wBAAY,QAAQ,UAAU;AAE9B,gBAAI,YAAY,QAAQ,SAAS,GAAG;AAChC,2BAAa,UAAQ,CAAC,IAAI;AAC1B,0BAAY,QAAQ,QAAQ;AAE5B,4BAAc;AACd;AAAA,YACJ;AAEA,gBAAI,cAAc;AACd,4BAAc;AAAA,YAClB,WAAW,CAAC,gBAAgB;AACxB,6BAAe,OAAO;AAAA,YAC1B;AAAA,UACJ;AAAA,UACA,WAAW,0EAA0E,iBAC/E,mEACA,eACI,mEACA,8EACN,IAAI,eAAe,kBAAkB,EAAE,IAAI,iBAAiB,gBAAgB,EAAE;AAAA,UAClF,UAAU;AAAA,UACV,OAAO,iBAAiB,oBAAoB,eAAe,mBAAmB;AAAA,UAE7E,2BACG,6CAAC,SAAI,WAAU,yDACX,wDAAC,SAAI,WAAU,sBAAqB,SAAQ,aACxC;AAAA,yDAAC,YAAO,WAAU,cAAa,IAAG,MAAK,IAAG,MAAK,GAAE,MAAK,QAAO,gBAAe,aAAY,KAAI,MAAK,QAAO;AAAA,YACxG,6CAAC,UAAK,WAAU,cAAa,MAAK,gBAAe,GAAE,mHAAkH;AAAA,aACzK,GACJ,IAEA,6CAAC,iCAAe,WAAU,WAAU;AAAA;AAAA,MAE5C;AAAA,MAIJ;AAAA,QAAC;AAAA;AAAA,UACG,UAAU;AAAA,UACV,WAAW,qIAAqI,eAAe,6CAA6C,6EACxM;AAAA,UAGJ;AAAA;AAAA,cAAC;AAAA;AAAA,gBACG,KAAK;AAAA,gBACL,WAAU;AAAA,gBACV,OAAO,EAAE,UAAU,OAAO;AAAA;AAAA,YAC9B;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACG,KAAK;AAAA,gBACL,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM;AACb,sBAAI,gBAAgB,UAAU;AAC1B,6BAAS,CAAC;AAAA,kBACd,OAAO;AACH,uCAAmB,EAAE,OAAO,KAAK;AAAA,kBACrC;AAAA,gBACJ;AAAA,gBACA,WAAW;AAAA,gBACX,SAAS,MAAM;AACX,+BAAa,IAAI;AACjB,gCAAc,IAAI;AAAA,gBACtB;AAAA,gBACA,QAAQ,MAAM,aAAa,KAAK;AAAA,gBAChC,aAAa,eAAe;AAAA,gBAC5B,UAAU;AAAA,gBACV,UAAU,CAAC,CAAC,gBAAgB;AAAA,gBAC5B,MAAM;AAAA,gBACN,WAAW,oGAAoG,kBAAkB,mCAAmC,gBAChK,IAAI,gBAAgB,iBAAiB,mBAAmB,EAAE;AAAA;AAAA,YAClE;AAAA,YAGA,8CAAC,SAAI,WAAU,+BAEV;AAAA,2BACG,6CAAC,SAAI,WAAU,qBACX;AAAA,gBAAC;AAAA;AAAA,kBACG,WAAU;AAAA,kBACV,OAAM;AAAA,kBACN,MAAK;AAAA,kBACL,SAAQ;AAAA,kBAER;AAAA;AAAA,sBAAC;AAAA;AAAA,wBACG,WAAU;AAAA,wBACV,IAAG;AAAA,wBACH,IAAG;AAAA,wBACH,GAAE;AAAA,wBACF,QAAO;AAAA,wBACP,aAAY;AAAA;AAAA,oBACf;AAAA,oBACD;AAAA,sBAAC;AAAA;AAAA,wBACG,WAAU;AAAA,wBACV,MAAK;AAAA,wBACL,GAAE;AAAA;AAAA,oBACL;AAAA;AAAA;AAAA,cACL,GACJ;AAAA,cAGJ;AAAA,gBAAC;AAAA;AAAA,kBACG,MAAK;AAAA,kBACL,SAAS,CAAC,MAAM;AACZ,wBAAI,aAAa,QAAQ;AACrB,wBAAE,eAAe;AACjB,6BAAO;AAAA,oBACX,OAAO;AACH,mCAAa;AAAA,oBACjB;AAAA,kBACJ;AAAA,kBACA,WAAU,2CAAa,aAAa,aAAa,CAAC,UAAW;AAAA,kBAC7D,WAAW,6HAA6H,aAAa,SAC/I,gCACA,+BACF;AAAA,kBACJ,OAAO,aAAa,SAAS,oBAAoB;AAAA,kBAEhD,sBACG,SAAS,6CAAC,2BAAS,WAAU,WAAU,IAAK,6CAAC,SAAI,WAAU,WAAU,IAErE,6CAAC,oCAAkB,WAAU,WAAU;AAAA;AAAA,cAE/C;AAAA,eACJ;AAAA;AAAA;AAAA,MACJ;AAAA,OACJ;AAAA,IAGC,aACG,6CAAC,SAAI,WAAU,4DACV,qBACL;AAAA,IAIJ,6CAAC,SAAI,WAAU,yCAAwC,OAAO,EAAE,YAAY,OAAO,GAC/E,uDAAC,OAAE,WAAW,yDAAyD,aACjE,iBACA,iBACI,8BACA,eACI,gCACA,eACV,IACC,uBACG,8CAAC,UAAK,WAAU,gDAA+C;AAAA;AAAA,MACnD;AAAA,OACZ,IACA,iBACA,gCACA,eACA,iCACA,eACA,4CAEA,aAAa,cAAc,yCAAyC,yBAE5E,GACJ;AAAA,KACJ;AAER,CAAC;AAED,cAAc,cAAc;;;AItkB5B,IAAAG,gBAAqD;AACrD,IAAAC,kBAAsE;AAiPvD,IAAAC,sBAAA;AAjOR,IAAM,YAAsC,CAAC;AAAA,EAChD;AAAA,EACA,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,UAAU;AAAA,EACV;AAAA,EACA,cAAc;AAClB,MAAM;AAzBN;AA0BI,QAAM,eAAe,cAAc;AACnC,QAAM,cAAc,qBAAmB,kBAAa,UAAb,mBAAoB;AAE3D,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,wBAAS,KAAK;AAC1D,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAyB,IAAI;AACrE,QAAM,CAAC,UAAU,WAAW,QAAI,wBAAwB,IAAI;AAG5D,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,KAAK;AAChD,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAmB,CAAC,CAAC;AAC7C,QAAM,kBAAc,sBAA2C,EAAE,OAAO,GAAG,SAAS,EAAE,CAAC;AAGvF,gBAAAC,QAAM,UAAU,MAAM;AAClB,UAAM,cAAc,QAAQ;AAC5B,UAAM,eAAe,QAAQ;AAC7B,UAAM,gBAAgB,QAAQ;AAE9B,UAAM,SAAS,CAAC,MAAc,SAAgB;AAC1C,UAAI;AACA,cAAM,MAAM,KAAK,IAAI,SAAO;AACxB,cAAI,eAAe,MAAO,QAAO,GAAG,IAAI,IAAI,KAAK,IAAI,OAAO;AAC5D,cAAI,OAAO,QAAQ,SAAU,QAAO,KAAK,UAAU,GAAG;AACtD,iBAAO,OAAO,GAAG;AAAA,QACrB,CAAC,EAAE,KAAK,GAAG;AACX,gBAAQ,UAAQ,CAAC,IAAI,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,MAC9D,SAAS,GAAG;AAAA,MAEZ;AAAA,IACJ;AAEA,YAAQ,MAAM,IAAI,SAAS;AAAE,kBAAY,GAAG,IAAI;AAAG,aAAO,OAAO,IAAI;AAAA,IAAG;AACxE,YAAQ,OAAO,IAAI,SAAS;AAAE,mBAAa,GAAG,IAAI;AAAG,aAAO,OAAO,IAAI;AAAA,IAAG;AAC1E,YAAQ,QAAQ,IAAI,SAAS;AAAE,oBAAc,GAAG,IAAI;AAAG,aAAO,OAAO,IAAI;AAAA,IAAG;AAE5E,WAAO,MAAM;AACT,cAAQ,MAAM;AACd,cAAQ,OAAO;AACf,cAAQ,QAAQ;AAAA,IACpB;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,QAAM,eAAW,2BAAY,MAAM;AAC/B,cAAU,UAAU,UAAU,KAAK,KAAK,IAAI,CAAC,EACxC,KAAK,MAAM,MAAM,0BAA0B,CAAC,EAC5C,MAAM,SAAO,QAAQ,MAAM,uBAAuB,GAAG,CAAC;AAAA,EAC/D,GAAG,CAAC,IAAI,CAAC;AAGT,QAAM,wBAAoB,2BAAY,CAAC,MAAc,YAAqB;AACtE,QAAI,SAAS;AACT,eAAS,IAAI;AACb,kBAAY,IAAI;AAChB,sBAAgB,IAAI;AAAA,IACxB;AAAA,EACJ,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,qBAAiB,2BAAY,MAAM;AACrC,oBAAgB,IAAI;AAAA,EACxB,GAAG,CAAC,CAAC;AAEL,QAAM,eAAe,qBAAqB,mBAAmB,gBAAgB,2CAAa,QAAQ;AAElG,gBAAAA,QAAM,UAAU,MAAM;AAClB,QAAI,aAAa,OAAO;AACpB,kBAAY,aAAa,KAAK;AAC9B,cAAQ,MAAM,oCAAoC,aAAa,KAAK;AAAA,IACxE;AAAA,EACJ,GAAG,CAAC,aAAa,KAAK,CAAC;AAGvB,QAAM,iBAAiB,iBAAiB,OAAO,SAAS;AACpD,oBAAgB,IAAI;AACpB,sBAAkB,IAAI;AACtB,gBAAY,IAAI;AAEhB,QAAI,KAAK,SAAS,mBAAmB;AACjC,cAAQ,IAAI,8CAA8C;AAC1D,YAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,IAAI,CAAC;AACtD,eAAS,4DAA4D;AACrE,wBAAkB,KAAK;AACvB;AAAA,IACJ;AAEA,SAAI,2CAAa,UAAS,YAAY,YAAY,gBAAgB;AAC9D,UAAI;AACA,cAAM,OAAO,MAAM,YAAY,eAAe,IAAI;AAClD,YAAI,KAAM,UAAS,IAAI;AAAA,MAC3B,SAAS,OAAY;AACjB,gBAAQ,MAAM,4CAA4C,KAAK;AAC/D,oBAAY,MAAM,WAAW,sBAAsB;AAAA,MACvD,UAAE;AACE,0BAAkB,KAAK;AAAA,MAC3B;AAAA,IACJ,OAAO;AACH,wBAAkB,KAAK;AAAA,IAC3B;AAAA,EACJ,CAAC;AAED,QAAM,cAAc,CAAC,CAAC,gBAAgB,aAAa,eAAe,eAAe;AACjF,QAAM,WAAW,eAAe;AAEhC,QAAM,oBAAgB,sBAAO,KAAK;AAGlC,QAAM,eAAW,2BAAY,MAAM;AAC/B,QAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,WAAO,iEAAiE,KAAK,UAAU,SAAS,KAC3F,kBAAkB,UAClB,UAAU,iBAAiB;AAAA,EACpC,GAAG,CAAC,CAAC;AAEL,QAAM,cAAc,OAAO,MAAyB;AAChD,QAAI,GAAG;AACH,QAAE,eAAe;AACjB,QAAE,gBAAgB;AAAA,IACtB;AAGA,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,MAAM,YAAY,QAAQ,UAAU,KAAK;AACzC,kBAAY,QAAQ;AAAA,IACxB,OAAO;AACH,kBAAY,QAAQ,QAAQ;AAAA,IAChC;AACA,gBAAY,QAAQ,UAAU;AAE9B,QAAI,YAAY,QAAQ,SAAS,GAAG;AAChC,mBAAa,UAAQ,CAAC,IAAI;AAC1B,kBAAY,QAAQ,QAAQ;AAE5B,UAAI,UAAU;AACV,gBAAQ,IAAI,sCAAsC;AAClD,aAAI,2CAAa,UAAS,SAAU,cAAa,KAAK;AAAA,YACjD,gBAAe,KAAK;AACzB,wBAAgB,IAAI;AAAA,MACxB;AACA;AAAA,IACJ;AAEA,YAAQ,IAAI,6CAA6C,SAAS,CAAC;AACnE,QAAI,cAAc,SAAS;AACvB,cAAQ,IAAI,8CAA8C;AAC1D;AAAA,IACJ;AAIA,kBAAc,UAAU;AACxB,YAAQ,IAAI,6CAA6C,UAAU,gBAAgB,aAAa,mBAAmB,cAAc;AAEjI,QAAI;AACA,UAAI,UAAU;AACV,YAAI,kBAAkB,CAAC,aAAa;AAChC,kBAAQ,IAAI,iDAAiD;AAC7D;AAAA,QACJ;AACA,gBAAQ,IAAI,+BAA+B;AAC3C,aAAI,2CAAa,UAAS,UAAU;AAChC,uBAAa,KAAK;AAAA,QACtB,OAAO;AACH,yBAAe,KAAK;AAAA,QACxB;AACA,wBAAgB,IAAI;AAAA,MACxB,OAAO;AACH,gBAAQ,IAAI,uCAAuC,2CAAa,IAAI;AACpE,oBAAY,IAAI;AAGhB,YAAI,SAAS,GAAG;AACZ,kBAAQ,IAAI,wEAAwE;AACpF,cAAI,SAAS,yBAAyB,aAAa;AAC/C,qBAAS,cAAc,KAAK;AAAA,UAChC;AAAA,QACJ,WAAW,eAAe;AACtB,kBAAQ,IAAI,8CAA8C;AAC1D,wBAAc;AAAA,QAClB;AAEA,wBAAgB,OAAO;AACvB,gBAAQ,IAAI,uCAAuC;AAEnD,aAAI,2CAAa,UAAS,UAAU;AAChC,kBAAQ,IAAI,yCAAyC;AACrD,cAAI;AACA,kBAAM,eAAe,MAAM;AAC3B,oBAAQ,IAAI,kDAAkD;AAAA,UAClE,SAASC,IAAQ;AACb,oBAAQ,MAAM,uCAAuCA,EAAC;AACtD,wBAAY,mBAAmB;AAC/B,4BAAgB,IAAI;AAAA,UACxB;AAAA,QACJ,OAAO;AACH,kBAAQ,IAAI,mDAAmD;AAC/D,cAAI,CAAC,aAAa,aAAa;AAC3B,oBAAQ,MAAM,yCAAyC;AACvD,wBAAY,sBAAsB;AAClC,4BAAgB,IAAI;AACpB;AAAA,UACJ;AACA,kBAAQ,IAAI,6CAA6C;AACzD,uBAAa,MAAM;AACnB,kBAAQ,IAAI,yCAAyC;AAAA,QACzD;AAAA,MACJ;AAAA,IACJ,UAAE;AAEE,iBAAW,MAAM;AACb,sBAAc,UAAU;AAAA,MAC5B,GAAG,GAAG;AAAA,IACV;AAAA,EACJ;AAGA,MAAI,UAAU;AACd,MAAI,QAAQ;AACZ,MAAI,OAAO,6CAAC,kCAAe,WAAU,WAAU;AAE/C,MAAI,aAAa;AACb,cAAU;AACV,YAAQ;AACR,WAAO,6CAAC,kCAAe,WAAU,yBAAwB;AAAA,EAC7D,WAAW,gBAAgB;AACvB,cAAU;AACV,YAAQ;AACR,WACI,8CAAC,SAAI,WAAU,mCAAkC,OAAM,8BAA6B,MAAK,QAAO,SAAQ,aACpG;AAAA,mDAAC,YAAO,WAAU,cAAa,IAAG,MAAK,IAAG,MAAK,GAAE,MAAK,QAAO,gBAAe,aAAY,KAAI;AAAA,MAC5F,6CAAC,UAAK,WAAU,cAAa,MAAK,gBAAe,GAAE,mHAAkH;AAAA,OACzK;AAAA,EAER;AAEA,SACI,8CAAC,SAAI,WAAU,iCAEV;AAAA,iBACG,8CAAC,SAAI,WAAU,mJACX;AAAA,oDAAC,SAAI,WAAU,0DACX;AAAA,qDAAC,UAAK,wBAAU;AAAA,QAChB,8CAAC,SAAI,WAAU,cACX;AAAA,uDAAC,YAAO,SAAS,CAAC,MAAM;AAAE,cAAE,gBAAgB;AAAG,qBAAS;AAAA,UAAG,GAAG,WAAU,kCAAiC,OAAM,aAC3G,uDAAC,oCAAiB,WAAU,WAAU,GAC1C;AAAA,UACA,6CAAC,YAAO,SAAS,CAAC,MAAM;AAAE,cAAE,gBAAgB;AAAG,qBAAS;AAAG,yBAAa,KAAK;AAAA,UAAG,GAAG,WAAU,iCAAgC,OAAM,gBAC/H,uDAAC,6BAAU,WAAU,WAAU,GACnC;AAAA,WACJ;AAAA,SACJ;AAAA,MACC,KAAK,IAAI,CAAC,KAAK,MACZ,6CAAC,SAAY,WAAU,uDAClB,iBADK,CAEV,CACH;AAAA,MACA,KAAK,WAAW,KAAK,6CAAC,SAAI,4BAAc;AAAA,OAC7C;AAAA,IAEJ;AAAA,MAAC;AAAA;AAAA,QACG,SAAS;AAAA,QACT,UAAU,YAAa,kBAAkB,CAAC;AAAA,QAC1C,WAAW;AAAA,kBACT,OAAO;AAAA,kBACP,WAAW,kCAAkC,gBAAgB;AAAA,kBAC7D,SAAS;AAAA,QACX,OAAO;AAAA,QAEP;AAAA,uDAAC,SAAI,WAAU,6CACV,gBACL;AAAA,UACA,6CAAC,UAAK,WAAU,YAAY,iBAAM;AAAA,UACjC,YACG,6CAAC,UAAK,WAAU,uGACX,oBACL;AAAA;AAAA;AAAA,IAER;AAAA,KACJ;AAER;;;AC9SA,IAAAC,iBAAyC;;;ACAzC,IAAAC,gBAAgC;AAmCpB,IAAAC,sBAAA;AAvBZ,IAAM,qBAAwD,CAAC;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AACJ,MAAM;AACF,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,wBAAwB,IAAI;AACxE,QAAM,SAAS;AAGf,QAAM,EAAE,WAAW,SAAS,IAAI;AAEhC,UAAQ,IAAI,oCAAoC,MAAM;AAEtD,QAAM,oBAAoB,CAAC,OAAgB,eAAuB;AAC9D,QAAI,oBAAqB;AAGzB,sBAAkB,UAAU;AAC5B,eAAW,KAAK;AAAA,EACpB;AAEA,SACI,6CAAC,SAAI,WAAU,aACX,wDAAC,SAAI,WAAU,kBACX;AAAA;AAAA,MAAC;AAAA;AAAA,QACG,SAAS,MAAM,kBAAkB,MAAM,SAAS;AAAA,QAChD,UAAU;AAAA,QACV,WAAW,kDAAkD,sBACvD,mBAAmB,YACf,2BACA,iDACJ,6CAA6C;AAAA,QAElD;AAAA;AAAA,IACL;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACG,SAAS,MAAM,kBAAkB,OAAO,QAAQ;AAAA,QAChD,UAAU;AAAA,QACV,WAAW,kDAAkD,sBACvD,mBAAmB,WACf,2BACA,iDACJ,6CAA6C;AAAA,QAElD;AAAA;AAAA,IACL;AAAA,KACJ,GACJ;AAER;AAEA,IAAO,6BAAQ;;;AC/Df,IAAAC,gBAA2C;AAkDvB,IAAAC,sBAAA;AArCpB,IAAM,oBAAsD,CAAC;AAAA,EACzD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,MAAM;AACF,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,wBAAwB,IAAI;AACxE,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAwB,IAAI;AACpE,QAAM,SAAS;AAEf,QAAM,EAAE,UAAU,SAAS,YAAY,IAAI;AAG3C,+BAAU,MAAM;AACZ,QAAI,wBAAuB,mCAAS,gBAAe;AAC/C,YAAM,mBAAmB,OAAO,QAAQ,aAAa;AACrD,wBAAkB,gBAAgB;AAGlC,UAAI,CAAC,QAAQ,SAAS,gBAAgB,GAAG;AACrC,wBAAgB,gBAAgB;AAAA,MACpC;AAAA,IACJ;AAAA,EACJ,GAAG,CAAC,qBAAqB,SAAS,OAAO,CAAC;AAE1C,QAAM,oBAAoB,CAAC,WAAmB;AAC1C,QAAI,oBAAqB;AAEzB,sBAAkB,MAAM;AACxB,oBAAgB,IAAI;AACpB,eAAW,MAAM;AAAA,EACrB;AAEA,SACI,8CAAC,SAAI,WAAU,aACX;AAAA,iDAAC,SAAI,WAAU,wBACV,kBAAQ,IAAI,CAAC,QAAQ,UAClB;AAAA,MAAC;AAAA;AAAA,QAEG,SAAS,MAAM,kBAAkB,MAAM;AAAA,QACvC,UAAU;AAAA,QACV,WAAW,kDAAkD,sBACvD,mBAAmB,SACf,2BACA,iDACJ,6CAA6C;AAAA,QAElD;AAAA;AAAA,MATI;AAAA,IAUT,CACH,GACL;AAAA,IAGC,gBAAgB,uBACb,8CAAC,SAAI,WAAU,uDAAsD;AAAA;AAAA,MACpC,8CAAC,UAAK,WAAU,iBAAgB;AAAA;AAAA,QAAE;AAAA,QAAa;AAAA,SAAC;AAAA,OACjF;AAAA,KAER;AAER;AAEA,IAAO,4BAAQ;;;AC3Ef,IAAAC,gBAAmD;AAEnD,0BAA+C;AAgKvB,IAAAC,sBAAA;AApJxB,IAAM,kBAAkD,CAAC;AAAA,EACrD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,MAAM;AACF,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAS,KAAK;AACpD,QAAM,CAAC,YAAY,aAAa,QAAI,wBAA8B,CAAC,CAAC;AACpE,QAAM,CAAC,YAAY,aAAa,QAAI,wBAAS,KAAK;AAClD,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAsB,CAAC,CAAC;AAChE,QAAM,qBAAiB,sBAAuB,IAAI;AAGlD,QAAM,kBAAkB,MAAM;AAC1B,UAAM,EAAE,QAAQ,aAAa,aAAa,UAAU,aAAa,SAAS,IAAI;AAG9E,QAAI,cAA2B,CAAC;AAEhC,QAAI,WAAW,QAAQ;AAEnB,UAAI,MAAM,QAAQ,WAAW,MAAM,GAAG;AAClC,sBAAc,WAAW,OAAO,IAAI,WAAS;AACzC,cAAI,OAAO,UAAU,UAAU;AAC3B,gBAAI;AACA,oBAAM,YAAY,KAAK,MAAM,KAAK;AAElC,oBAAM,OAAO,UAAU;AAEvB,qBAAO;AAAA,gBACH;AAAA,gBACA,OAAO,UAAU,SAAS;AAAA,gBAC1B,MAAM,UAAU,QAAQ;AAAA,gBACxB,UAAU,UAAU,YAAY;AAAA,gBAChC,SAAS,UAAU,WAAW,CAAC;AAAA,gBAC/B,aAAa,UAAU,eAAe,UAAU,SAAS;AAAA,gBACzD,cAAc,UAAU;AAAA,cAC5B;AAAA,YACJ,SAAS,OAAO;AACZ,sBAAQ,MAAM,wBAAwB,KAAK;AAC3C,qBAAO;AAAA,YACX;AAAA,UACJ;AACA,iBAAO;AAAA,QACX,CAAC,EAAE,OAAO,CAAC,UAA8B,UAAU,IAAI;AAAA,MAC3D,WAES,OAAO,WAAW,WAAW,UAAU;AAC5C,sBAAc,OAAO,QAAQ,WAAW,MAAM,EAAE,IAAI,CAAC,CAAC,MAAM,YAAY,MAAM;AAC1E,cAAI,YAAiC,CAAC;AAGtC,cAAI;AACA,gBAAI,OAAO,iBAAiB,UAAU;AAClC,0BAAY,KAAK,MAAM,YAAY;AAAA,YACvC,OAAO;AACH,0BAAY;AAAA,YAChB;AAAA,UACJ,SAAS,OAAO;AACZ,oBAAQ,MAAM,gCAAgC,IAAI,KAAK,KAAK;AAAA,UAChE;AAEA,iBAAO;AAAA,YACH;AAAA,YACA,OAAO,UAAU,SAAS;AAAA,YAC1B,MAAM,UAAU,QAAQ;AAAA,YACxB,UAAU,UAAU,YAAY;AAAA,YAChC,SAAS,UAAU,WAAW,CAAC;AAAA,YAC/B,aAAa,UAAU,eAAe,UAAU,SAAS;AAAA,YACzD,cAAc,UAAU;AAAA,UAC5B;AAAA,QACJ,CAAC;AAED,gBAAQ,IAAI,kBAAkB,WAAW;AAAA,MAC7C;AAAA,IACJ;AAEA,WAAO;AAAA,MACH,OAAO,UAAU;AAAA,MACjB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IACJ;AAAA,EACJ;AAEA,QAAM,SAAS,gBAAgB;AAG/B,+BAAU,MAAM;AACZ,UAAM,kBAAkB,gBAAgB;AACxC,oBAAgB,gBAAgB,MAAM;AAEtC,UAAM,gBAAqC,CAAC;AAC5C,oBAAgB,OAAO,QAAQ,WAAS;AACpC,UAAI,MAAM,iBAAiB,QAAW;AAClC,sBAAc,MAAM,IAAI,IAAI,MAAM;AAAA,MACtC,WAAW,MAAM,SAAS,YAAY;AAClC,sBAAc,MAAM,IAAI,IAAI;AAAA,MAChC,OAAO;AACH,sBAAc,MAAM,IAAI,IAAI;AAAA,MAChC;AAAA,IACJ,CAAC;AACD,kBAAc,aAAa;AAG3B,QAAI,CAAC,qBAAqB;AACtB,qBAAe,IAAI;AAAA,IACvB;AAAA,EACJ,GAAG,CAAC,YAAY,mBAAmB,CAAC;AAGpC,+BAAU,MAAM;AACZ,QAAI,eAAe,eAAe,SAAS;AACvC,iBAAW,MAAM;AAlI7B;AAmIgB,6BAAe,YAAf,mBAAwB,eAAe,EAAE,UAAU,UAAU,OAAO,SAAS;AAAA,MACjF,GAAG,GAAG;AAAA,IACV;AAAA,EACJ,GAAG,CAAC,WAAW,CAAC;AAEhB,QAAM,oBAAoB,CAAC,OAAkB,UAAe;AACxD,kBAAc,WAAS;AAAA,MACnB,GAAG;AAAA,MACH,CAAC,MAAM,IAAI,GAAG;AAAA,IAClB,EAAE;AAAA,EACN;AAEA,QAAM,eAAe,CAAC,MAAuB;AACzC,MAAE,eAAe;AACjB,eAAW,UAAU;AACrB,mBAAe,KAAK;AAAA,EACxB;AAEA,QAAM,eAAe,MAAM;AACvB,eAAW,CAAC,CAAC;AACb,mBAAe,KAAK;AAAA,EACxB;AAEA,QAAM,cAAc,CAAC,UAAqB;AACtC,UAAM,EAAE,MAAM,OAAO,MAAM,UAAU,SAAS,YAAY,IAAI;AAE9D,YAAQ,MAAM;AAAA,MACV,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACD,eACI,8CAAC,SAAI,WAAU,oCACX;AAAA,wDAAC,WAAM,SAAS,MAAM,WAAU,mDAC3B;AAAA;AAAA,YAAO,YAAY,6CAAC,UAAK,WAAU,gBAAe,eAAC;AAAA,aACxD;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACG,MAAM,SAAS,WAAW,SAAS;AAAA,cACnC,IAAI;AAAA,cACJ;AAAA,cACA,OAAO,WAAW,IAAI,KAAK;AAAA,cAC3B,UAAU,CAAC,MAAM,kBAAkB,OAAO,EAAE,OAAO,KAAK;AAAA,cACxD;AAAA,cACA;AAAA,cACA,UAAU;AAAA,cACV,WAAU;AAAA;AAAA,UACd;AAAA,aAdmD,IAevD;AAAA,MAGR,KAAK;AACD,eACI,8CAAC,SAAI,WAAU,mCACX;AAAA,wDAAC,WAAM,SAAS,MAAM,WAAU,wDAC3B;AAAA;AAAA,YAAO,YAAY,6CAAC,UAAK,WAAU,gBAAe,eAAC;AAAA,aACxD;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACG,IAAI;AAAA,cACJ;AAAA,cACA,OAAO,WAAW,IAAI,KAAK;AAAA,cAC3B,UAAU,CAAC,MAAM,kBAAkB,OAAO,EAAE,OAAO,KAAK;AAAA,cACxD;AAAA,cACA;AAAA,cACA,UAAU;AAAA,cACV,MAAM;AAAA,cACN,WAAU;AAAA;AAAA,UACd;AAAA,aAdkD,IAetD;AAAA,MAGR,KAAK;AACD,eACI,8CAAC,SAAI,WAAU,oCACX;AAAA,wDAAC,WAAM,SAAS,MAAM,WAAU,mDAC3B;AAAA;AAAA,YAAO,YAAY,6CAAC,UAAK,WAAU,gBAAe,eAAC;AAAA,aACxD;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACG,IAAI;AAAA,cACJ;AAAA,cACA,OAAO,WAAW,IAAI,KAAK;AAAA,cAC3B,UAAU,CAAC,MAAM,kBAAkB,OAAO,EAAE,OAAO,KAAK;AAAA,cACxD;AAAA,cACA,UAAU;AAAA,cACV,WAAU;AAAA,cAEV;AAAA,6DAAC,YAAO,OAAM,IAAG,UAAQ,MAAE,yBAAe,oBAAmB;AAAA,gBAC5D,mCAAS,IAAI,CAAC,QAAQ,UACnB,6CAAC,YAAmB,OAAO,QAAS,oBAAvB,KAA8B;AAAA;AAAA;AAAA,UAEnD;AAAA,aAjBmD,IAkBvD;AAAA,MAGR,KAAK;AACD,eACI,8CAAC,SAAI,WAAU,oCACX;AAAA,uDAAC,SAAI,WAAU,iBAAgB;AAAA,UAC/B,8CAAC,SAAI,WAAU,qBACX;AAAA;AAAA,cAAC;AAAA;AAAA,gBACG,MAAK;AAAA,gBACL,IAAI;AAAA,gBACJ;AAAA,gBACA,SAAS,CAAC,CAAC,WAAW,IAAI;AAAA,gBAC1B,UAAU,CAAC,MAAM,kBAAkB,OAAO,EAAE,OAAO,OAAO;AAAA,gBAC1D;AAAA,gBACA,UAAU;AAAA,gBACV,WAAU;AAAA;AAAA,YACd;AAAA,YACA,8CAAC,WAAM,SAAS,MAAM,WAAU,8BAC3B;AAAA;AAAA,cAAO,YAAY,6CAAC,UAAK,WAAU,gBAAe,eAAC;AAAA,eACxD;AAAA,aACJ;AAAA,aAhBmD,IAiBvD;AAAA,MAGR,KAAK;AACD,eACI,8CAAC,SAAI,WAAU,uBACX;AAAA,wDAAC,SAAI,WAAU,wDACV;AAAA;AAAA,YAAO,YAAY,6CAAC,UAAK,WAAU,gBAAe,eAAC;AAAA,aACxD;AAAA,UACA,6CAAC,SAAI,WAAU,oBACV,6CAAS,IAAI,CAAC,QAAQ,UACnB,8CAAC,SAAgB,WAAU,qBACvB;AAAA;AAAA,cAAC;AAAA;AAAA,gBACG,IAAI,GAAG,IAAI,IAAI,KAAK;AAAA,gBACpB;AAAA,gBACA,MAAK;AAAA,gBACL,OAAO;AAAA,gBACP,SAAS,WAAW,IAAI,MAAM;AAAA,gBAC9B,UAAU,MAAM,kBAAkB,OAAO,MAAM;AAAA,gBAC/C;AAAA,gBACA,UAAU;AAAA,gBACV,WAAU;AAAA;AAAA,YACd;AAAA,YACA,6CAAC,WAAM,SAAS,GAAG,IAAI,IAAI,KAAK,IAAI,WAAU,8BACzC,kBACL;AAAA,eAdM,KAeV,IAER;AAAA,aAvBsC,IAwB1C;AAAA,MAGR;AACI,eAAO;AAAA,IACf;AAAA,EACJ;AAEA,MAAI,qBAAqB;AAErB,WACI,8CAAC,SAAI,WAAU,yDACX;AAAA,oDAAC,SAAI,WAAU,oDAAmD,SAAS,MAAM,cAAc,CAAC,UAAU,GACtG;AAAA,sDAAC,UAAK,WAAU,6BAA6B;AAAA,uBAAa,SAAS;AAAA,UAAO;AAAA,WAAe;AAAA,QACxF,aACG,6CAAC,qCAAc,WAAU,yBAAwB,IACjD,6CAAC,uCAAgB,WAAU,yBAAwB;AAAA,SAE3D;AAAA,MAEC,cACG,6CAAC,SAAI,WAAU,kBACV,uBAAa,IAAI,CAAC,UACf,8CAAC,SAAqB,WAAU,QAC5B;AAAA,sDAAC,UAAK,WAAU,0CAA0C;AAAA,gBAAM;AAAA,UAAM;AAAA,WAAC;AAAA,QACvE,6CAAC,UAAK,WAAU,yBACX,kBAAO,mDAAkB,MAAM,WAAU,YACnC,gBAAgB,MAAM,IAAI,IAAI,QAAQ,QACvC,mDAAkB,MAAM,UAAS,gBAC3C;AAAA,WANM,MAAM,IAOhB,CACH,GACL;AAAA,OAER;AAAA,EAER;AAGA,SACI,6CAAC,SAAI,WAAU,QACV,yBACG,6CAAC,SAAI,WAAU,OACX,wDAAC,UAAK,UAAU,cAAc,WAAU,QACnC;AAAA,iBAAa,IAAI,WAAS,YAAY,KAAK,CAAC;AAAA,IAE7C,8CAAC,SAAI,KAAK,gBAAgB,WAAU,mCAChC;AAAA;AAAA,QAAC;AAAA;AAAA,UACG,MAAK;AAAA,UACL,SAAS;AAAA,UACT,UAAU;AAAA,UACV,WAAU;AAAA,UAET,iBAAO;AAAA;AAAA,MACZ;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACG,MAAK;AAAA,UACL,UAAU;AAAA,UACV,WAAU;AAAA,UAET,iBAAO;AAAA;AAAA,MACZ;AAAA,OACJ;AAAA,KACJ,GACJ,GAER;AAER;AAEA,IAAO,0BAAQ;;;ACzUP,IAAAC,uBAAA;AAPR,IAAIC;AACJ,IAAI;AAEA,EAAAA,iBAAgB,QAAQ,gBAAgB;AAC5C,SAAS,OAAO;AAEZ,EAAAA,iBAAgB,CAAC,EAAE,SAAS,MACxB,8CAAC,SAAI,WAAU,uBAAuB,UAAS;AAEvD;AASA,IAAM,qBAAwD,CAAC;AAAA,EAC3D;AACJ,MAAM;AACF,QAAM,SAAS;AACf,QAAM,EAAE,OAAO,SAAS,SAAS,QAAQ,QAAQ,OAAO,IAAI;AAG5D,QAAM,iBAAiB,MAAM;AACzB,YAAQ,OAAO;AAAA,MACX,KAAK;AACD,eAAO;AAAA,UACH,WAAW;AAAA,UACX,OAAO;AAAA,UACP,SAAS;AAAA,QACb;AAAA,MACJ,KAAK;AAAA,MACL,KAAK;AACD,eAAO;AAAA,UACH,WAAW;AAAA,UACX,OAAO;AAAA,UACP,SAAS;AAAA,QACb;AAAA,MACJ,KAAK;AACD,eAAO;AAAA,UACH,WAAW;AAAA,UACX,OAAO;AAAA,UACP,SAAS;AAAA,QACb;AAAA,MACJ,KAAK;AAAA,MACL;AACI,eAAO;AAAA,UACH,WAAW;AAAA,UACX,OAAO;AAAA,UACP,SAAS;AAAA,QACb;AAAA,IACR;AAAA,EACJ;AAEA,QAAM,SAAS,eAAe;AAE9B,SACI,+CAAC,SAAI,WAAW,iBAAiB,OAAO,SAAS,sBAC5C;AAAA,aACG,8CAAC,SAAI,WAAW,eAAe,OAAO,KAAK,SAAU,iBAAM;AAAA,IAE/D,8CAAC,SAAI,WAAW,WAAW,OAAO,OAAO,IACpC,qBAAW,aACR,8CAACA,gBAAA,EAAc,WAAU,6BACpB,mBACL,IACA,WAAW,SACX,8CAAC,SAAI,yBAAyB,EAAE,QAAQ,QAAQ,GAAG,IAEnD,8CAAC,SAAI,WAAU,uBAAuB,mBAAQ,GAEtD;AAAA,KACJ;AAER;AAEA,IAAO,6BAAQ;;;ACjDC,IAAAC,uBAAA;AAfhB,IAAM,4BAAsE,CAAC;AAAA,EACzE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,MAAM;AACF,QAAM,EAAE,UAAU,cAAc,WAAW,IAAI;AAG/C,QAAM,oBAAoB,+CAAe;AAGzC,UAAQ,cAAc;AAAA,IAClB,KAAK;AACD,aACI;AAAA,QAAC;AAAA;AAAA,UACG;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACJ;AAAA,IAGR,KAAK;AACD,aACI;AAAA,QAAC;AAAA;AAAA,UACG;AAAA,UACA;AAAA,UACA;AAAA,UACA,SAAS;AAAA;AAAA,MACb;AAAA,IAGR,KAAK;AACD,aACI;AAAA,QAAC;AAAA;AAAA,UACG;AAAA,UACA;AAAA,UACA;AAAA,UACA,iBAAiB;AAAA;AAAA,MACrB;AAAA,IAGR,KAAK;AACD,aACI;AAAA,QAAC;AAAA;AAAA,UACG;AAAA;AAAA,MACJ;AAAA,IAGR,KAAK;AAED,aAAO;AAAA,IAEX;AACI,cAAQ,KAAK,sCAAsC,YAAY,EAAE;AACjE,aAAO;AAAA,EACf;AACJ;AAEA,IAAO,oCAAQ;;;AL1Ef,IAAAC,kBAAsC;AAqElB,IAAAC,uBAAA;AA/Cb,IAAM,kBAAkD,CAAC;AAAA,EAC5D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,MAAM;AAEF,QAAM,uBAAmB,uBAAuB,IAAI;AAEpD,QAAM,qBAAiB,uBAAuB,IAAI;AAElD,QAAM,6BAAyB,uBAAuB,IAAI;AAG1D,gCAAU,MAAM;AAEZ,QAAI,gBAAgB,uBAAuB,SAAS;AAChD,6BAAuB,QAAQ,eAAe,EAAE,UAAU,SAAS,CAAC;AACpE;AAAA,IACJ;AAGA,QAAI,eAAe,SAAS;AACxB,qBAAe,QAAQ,eAAe,EAAE,UAAU,SAAS,CAAC;AAAA,IAChE,WAAW,iBAAiB,SAAS;AAEjC,uBAAiB,QAAQ,YAAY,iBAAiB,QAAQ;AAAA,IAClE;AAAA,EACJ,GAAG,CAAC,aAAa,YAAY,CAAC;AAG9B,QAAM,4BAA4B,CAAC,WAA4B,aAAkB;AAC7E,QAAI,uBAAuB;AACvB,4BAAsB,WAAW,QAAQ;AAAA,IAC7C;AAAA,EACJ;AAEA,SACI;AAAA,IAAC;AAAA;AAAA,MACG,KAAK;AAAA,MACL,WAAU;AAAA,MAGT;AAAA,oBAAY,WAAW,KAAK,CAAC,gBAC1B,+CAAC,SAAI,WAAU,oBACX;AAAA,wDAAC,QAAG,WAAU,0CAAyC,uCAAyB;AAAA,UAChF,+CAAC,OAAE,WAAU,8BAA6B;AAAA;AAAA,YACR,kBAAkB;AAAA,aACpD;AAAA,WACJ;AAAA,QAIH,YAAY,IAAI,CAAC,SAAS,UAAU;AAEjC,gBAAM,gBAAgB,UAAU,YAAY,SAAS;AACrD,gBAAM,SAAS,QAAQ,SAAS;AAChC,gBAAM,UAAU,QAAQ,SAAS;AAEjC,iBACI;AAAA,YAAC;AAAA;AAAA,cAEG,KAAK,gBAAgB,iBAAiB;AAAA,cACtC,WAAW,wBAAwB,SAAS,cAAc,aAAa;AAAA,cAGvE;AAAA,8DAAC,SAAI,WAAU,mCACV,kBAAQ,YACH,GAAG,SAAS,SAAS,UAAU,OAAO,IAAI,KAAK,QAAQ,SAAS,EAAE,eAAe,CAAC,KAClF,IACV;AAAA,gBAGA,8CAAC,SAAI,WAAU,UACV,kBAAQ,eAAe,QAAQ,kBAC5B,8CAAC,SAAI,WAAW,eAAe,SAAS,YAAY,SAAS,IACzD;AAAA,kBAAC;AAAA;AAAA,oBACG,SAAS,QAAQ;AAAA,oBACjB,YAAY,CAAC,aAAkB;AAC3B,4BAAM,YAAY,QAAQ,MAAM,eAAe,KAAK,IAAI,KAAK,IAAI,CAAC;AAClE,8BAAQ,gBAAgB;AACxB,gDAA0B,WAAW,QAAQ;AAAA,oBACjD;AAAA,oBACA,qBAAqB,CAAC,CAAC,QAAQ;AAAA,oBAC/B,eAAe;AAAA;AAAA,gBACnB,GACJ,IAEA;AAAA,kBAAC;AAAA;AAAA,oBACG;AAAA,oBACA;AAAA;AAAA,gBACJ,GAER;AAAA,gBAEC,UAAU,QAAQ,eACf,+CAAC,SAAI,WAAU,iEACX;AAAA,gEAAC,yCAAsB,WAAU,yBAAwB;AAAA,kBACzD,+CAAC,UACI;AAAA,4BAAQ,YAAY,UAAU;AAAA,oBAC9B,QAAQ,YAAY,YAAY;AAAA,oBAChC,QAAQ,YAAY,aAAa;AAAA,qBACtC;AAAA,mBACJ;AAAA;AAAA;AAAA,YA1CC,QAAQ,MAAM,WAAW,KAAK;AAAA,UA4CvC;AAAA,QAER,CAAC;AAAA,QAGA,gBACG;AAAA,UAAC;AAAA;AAAA,YACG,KAAK;AAAA,YACL,WAAU;AAAA,YAEV,wDAAC,SAAI,WAAU,kFACX,yDAAC,SAAI,WAAU,qBACX;AAAA,4DAAC,UAAK,WAAU,WAAW,0BAAe;AAAA,cAC1C,+CAAC,UAAK,WAAU,uBACZ;AAAA,8DAAC,UAAK,WAAU,mDAAkD,OAAO,EAAE,gBAAgB,MAAM,GAAG;AAAA,gBACpG,8CAAC,UAAK,WAAU,mDAAkD,OAAO,EAAE,gBAAgB,QAAQ,GAAG;AAAA,gBACtG,8CAAC,UAAK,WAAU,mDAAkD,OAAO,EAAE,gBAAgB,QAAQ,GAAG;AAAA,iBAC1G;AAAA,eACJ,GACJ;AAAA;AAAA,QACJ;AAAA,QAIH,eAAe,CAAC,YAAY,YACzB,+CAAC,SAAI,WAAU,yDACX;AAAA,yDAAC,SAAI,WAAU,8BAA6B;AAAA;AAAA,YAChB,YAAY;AAAA,YAAY;AAAA,YAAK,YAAY;AAAA,aACrE;AAAA,UACA,8CAAC,SAAI,WAAU,uCACX;AAAA,YAAC;AAAA;AAAA,cACG,WAAU;AAAA,cACV,OAAO,EAAE,OAAO,GAAI,YAAY,cAAc,YAAY,QAAS,GAAG,IAAI;AAAA;AAAA,UAC7E,GACL;AAAA,WACJ;AAAA;AAAA;AAAA,EAER;AAER;;;AM1KA,IAAAC,uBAAyC;AAa7B,IAAAC,uBAAA;AANL,IAAM,mBAAoD,CAAC;AAAA,EAC9D;AAAA,EACA;AACJ,MAAM;AACF,SACI,+CAAC,SAAI,WAAU,sFACX;AAAA,kDAAC,SAAI,WAAU,6BAA4B,mEAE3C;AAAA,IACC,qBAAqB,eAClB,+CAAC,SAAI,WAAU,oCACX;AAAA,oDAAC,6BAAK,WAAU,gBAAe;AAAA,MAC/B,8CAAC,UAAK,uBAAS;AAAA,OACnB;AAAA,IAEH,qBAAqB,kBAClB,+CAAC,SAAI,WAAU,oCACX;AAAA,oDAAC,kCAAU,WAAU,6BAA4B;AAAA,MACjD,8CAAC,UAAK,6BAAe;AAAA,OACzB;AAAA,IAEH,qBAAqB,kBAClB,+CAAC,SAAI,WAAU,2BACX;AAAA,qDAAC,SAAI,WAAU,kCACX;AAAA,sDAAC,gCAAQ,WAAU,gBAAe;AAAA,QAClC,8CAAC,UAAK,0BAAY;AAAA,SACtB;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACG,SAAS;AAAA,UACT,WAAU;AAAA,UAEV;AAAA,0DAAC,kCAAU,WAAU,gBAAe;AAAA,YACpC,8CAAC,UAAK,uBAAS;AAAA;AAAA;AAAA,MACnB;AAAA,OACJ;AAAA,KAER;AAER;;;AC3BQ,IAAAC,uBAAA;AAbD,IAAM,UAAkC,CAAC;AAAA,EAC5C,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,QAAQ;AACZ,MAAM;AACF,QAAM,cAAc;AAAA,IAChB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACR;AAEA,SACI;AAAA,IAAC;AAAA;AAAA,MACG,WAAW,gBAAgB,YAAY,IAAI,CAAC,IAAI,KAAK,IAAI,SAAS;AAAA,MAClE,OAAM;AAAA,MACN,MAAK;AAAA,MACL,SAAQ;AAAA,MAER;AAAA;AAAA,UAAC;AAAA;AAAA,YACG,WAAU;AAAA,YACV,IAAG;AAAA,YACH,IAAG;AAAA,YACH,GAAE;AAAA,YACF,QAAO;AAAA,YACP,aAAY;AAAA;AAAA,QAChB;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACG,WAAU;AAAA,YACV,MAAK;AAAA,YACL,GAAE;AAAA;AAAA,QACN;AAAA;AAAA;AAAA,EACJ;AAER;;;ACrBA,eAAsB,gBAClB,WACA,QACe;AACf,QAAM,WAAW,IAAI,SAAS;AAC9B,WAAS,OAAO,SAAS,WAAW,gBAAgB;AAEpD,MAAI,OAAO,UAAU;AACjB,aAAS,OAAO,YAAY,OAAO,QAAQ;AAAA,EAC/C;AAEA,MAAI;AACA,UAAM,WAAW,MAAM,MAAM,OAAO,UAAU;AAAA,MAC1C,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS,OAAO,WAAW,CAAC;AAAA,MAC5B,aAAa;AAAA;AAAA,IACjB,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,YAAY,MAAM,SAAS,KAAK;AACtC,YAAM,IAAI,MAAM,yBAAyB,SAAS,MAAM,MAAM,SAAS,EAAE;AAAA,IAC7E;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,WAAO,KAAK;AAAA,EAChB,SAAS,OAAY;AACjB,YAAQ,MAAM,+BAA+B,KAAK;AAClD,UAAM;AAAA,EACV;AACJ;;;ACzCO,SAAS,yBACZ,QACA,WAIW;AACX,SAAO;AAAA,IACH,MAAM;AAAA,IACN,cAAc,uCAAW;AAAA,IACzB,YAAY,uCAAW;AAAA;AAAA;AAAA;AAAA,IAIvB,gBAAgB,OAAO,SAAe;AAClC,aAAO,MAAM,gBAAgB,MAAM,MAAM;AAAA,IAC7C;AAAA,EACJ;AACJ;","names":["import_jsx_runtime","import_jsx_runtime","ReactMarkdown","remarkGfm","import_jsx_runtime","import_react","import_react","error","import_react","import_react","import_jsx_runtime","_a","_b","_c","import_react","import_outline","import_jsx_runtime","React","e","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","ReactMarkdown","import_jsx_runtime","import_outline","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../../../src/ui/react/components/index.ts","../../../../src/ui/react/components/ChatBubble.tsx","../../../../src/ui/react/components/MessageBubble.tsx","../../../../src/ui/react/context/ChatConfigContext.tsx","../../../../src/ui/react/components/ChatHeader.tsx","../../../../src/ui/react/components/ChatInputArea.tsx","../../../../src/ui/react/hooks/useSpeechRecognition.ts","../../../../src/ui/react/hooks/useAudioRecorder.ts","../../../../src/ui/react/hooks/useProactiveResize.ts","../../../../src/ui/react/components/TapToTalk.tsx","../../../../src/ui/react/components/ChatMessageList.tsx","../../../../src/ui/react/components/interactive/ConfirmInteraction.tsx","../../../../src/ui/react/components/interactive/SelectInteraction.tsx","../../../../src/ui/react/components/interactive/FormInteraction.tsx","../../../../src/ui/react/components/interactive/PresentInteraction.tsx","../../../../src/ui/react/components/interactive/InteractiveMessageHandler.tsx","../../../../src/ui/react/components/ConnectionStatus.tsx","../../../../src/ui/react/components/Spinner.tsx","../../../../src/ui/react/services/whisper-client.ts","../../../../src/ui/react/utils/voice-utils.ts"],"sourcesContent":["export * from './ChatBubble';\nexport * from './MessageBubble';\nexport * from './ChatHeader';\nexport * from './ChatInputArea';\nexport * from './TapToTalk';\nexport * from './ChatMessageList';\nexport * from './ConnectionStatus';\nexport * from './Spinner';\nexport * from '../hooks/useProactiveResize';\nexport * from '../hooks/useSpeechRecognition';\nexport * from '../hooks/useAudioRecorder';\nexport * from '../types/chat';\nexport * from '../types/interactive';\nexport * from '../context/ChatConfigContext';\nexport * from '../services/whisper-client';\nexport * from '../utils/voice-utils';\n","'use client';\n\nimport React from 'react';\n\ninterface ChatBubbleProps {\n onClick: () => void;\n}\n\nexport function ChatBubble({ onClick }: ChatBubbleProps) {\n return (\n <button\n onClick={onClick}\n className=\"bg-blue-500 hover:bg-blue-600 text-white rounded-full w-12 h-12 flex items-center justify-center shadow-lg animate-pulse\"\n aria-label=\"Open chat assistant\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z\" />\n </svg>\n </button>\n );\n}\n","'use client';\n\nimport React from 'react';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport { SparklesIcon } from '@heroicons/react/24/solid';\nimport { ChatMessage } from '../types/chat';\nimport { useChatConfig } from '../context/ChatConfigContext';\n\nexport interface MessageBubbleProps {\n message: ChatMessage;\n isUser: boolean;\n userAvatarUrl?: string; // Optional user avatar URL\n onViewChanges?: (diff: { oldContent: string; newContent: string }) => void;\n}\n\nexport const MessageBubble: React.FC<MessageBubbleProps> = ({\n message,\n isUser,\n userAvatarUrl,\n onViewChanges\n}) => {\n const { user } = useChatConfig();\n const finalAvatarUrl = userAvatarUrl || user?.avatarUrl;\n const isSystem = message.role === 'system';\n\n if (isSystem) {\n return (\n <div className=\"text-center my-4\">\n <span className=\"text-xs text-gray-500 italic bg-gray-100 px-3 py-1 rounded-full\">\n {message.content}\n {message.diff && onViewChanges && (\n <button\n onClick={() => onViewChanges(message.diff!)}\n className=\"ml-2 font-semibold text-blue-600 hover:underline focus:outline-none\"\n >\n View Changes\n </button>\n )}\n </span>\n </div>\n );\n }\n\n return (\n <div className={`flex items-start gap-3 my-1 ${isUser ? 'justify-end' : 'justify-start'}`}>\n {/* Assistant Avatar */}\n {!isUser && (\n <div className=\"flex-shrink-0 h-8 w-8 rounded-full bg-blue-500 flex items-center justify-center text-white\">\n <SparklesIcon className=\"h-5 w-5\" />\n </div>\n )}\n\n {/* Content Bubble */}\n <div\n className={`max-w-[85%] px-4 py-3 rounded-2xl shadow-sm overflow-hidden ${isUser\n ? 'bg-blue-500 text-white rounded-br-none'\n : 'bg-gray-100 text-gray-800 rounded-bl-none'\n }`}>\n <div className={`text-sm ${!isUser ? 'prose prose-sm max-w-none' : ''}`}>\n {isUser ? (\n <p className=\"whitespace-pre-wrap\">{message.content}</p>\n ) : (\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n components={{\n p: ({ node, ...props }) => <p className=\"mb-2 last:mb-0\" {...props} />,\n ul: ({ node, ...props }) => <ul className=\"list-disc ml-4 mb-2\" {...props} />,\n ol: ({ node, ...props }) => <ol className=\"list-decimal ml-4 mb-2\" {...props} />,\n li: ({ node, ...props }) => <li className=\"mb-0.5\" {...props} />,\n a: ({ node, ...props }) => <a className=\"text-blue-600 hover:underline\" {...props} />,\n code: ({ node, ...props }) => <code className=\"bg-gray-200 rounded px-1 py-0.5 text-xs font-mono\" {...props} />\n }}\n >\n {message.content}\n </ReactMarkdown>\n )}\n </div>\n {message.role === 'assistant' && message.diff && onViewChanges && (\n <button\n onClick={() => onViewChanges(message.diff!)}\n className=\"mt-2 text-sm text-blue-500 hover:underline block\"\n >\n View Changes\n </button>\n )}\n {message.actionResult && message.actionResult.type === 'link' && (\n <div className=\"mt-2 pt-2 border-t border-gray-300\">\n <a\n href={message.actionResult.url}\n target={message.actionResult.target || '_blank'}\n rel=\"noopener noreferrer\"\n onClick={(e) => {\n if (message.actionResult?.target && message.actionResult.target !== '_blank') {\n e.preventDefault();\n window.open(message.actionResult.url, message.actionResult.target);\n }\n }}\n className={`inline-flex items-center gap-1 text-sm font-medium hover:underline ${isUser\n ? 'text-blue-100 hover:text-white'\n : 'text-blue-600 hover:text-blue-800'\n }`}\n >\n {message.actionResult.label}\n <svg className=\"w-3.5 h-3.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\" />\n </svg>\n </a>\n </div>\n )}\n </div>\n\n {/* User Avatar */}\n {isUser && (\n <div className=\"flex-shrink-0 h-8 w-8 rounded-full bg-gray-200 overflow-hidden flex items-center justify-center text-gray-500\">\n {finalAvatarUrl ? (\n <img\n className=\"h-full w-full object-cover\"\n src={finalAvatarUrl}\n alt=\"User\"\n onError={(e) => {\n // Hide image and show fallback icon if load fails involves state, \n // but for a simple component we can just hide it or let the parent handle it.\n // For now, let's just render the icon if no url, \n // preventing the broken image icon requires state or a different approach (like standard Radix Avatar).\n // A simple hack: set src to a transparent pixel or hide display.\n (e.target as HTMLImageElement).style.display = 'none';\n (e.target as HTMLImageElement).parentElement?.classList.remove('bg-gray-200'); // Clean up?\n // Actually, better to just render the fallback SVG behind it?\n // Let's try separate conditional structure.\n }}\n />\n ) : (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" className=\"w-5 h-5\">\n <path fillRule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clipRule=\"evenodd\" />\n </svg>\n )}\n </div>\n )}\n </div>\n );\n};\n","import React, { createContext, useContext, ReactNode } from 'react';\nimport { VoiceConfig } from '../types/chat';\n\nexport interface ChatConfig {\n user?: {\n avatarUrl?: string;\n name?: string;\n };\n voice?: {\n enabled: boolean;\n config?: VoiceConfig;\n };\n}\n\nconst ChatConfigContext = createContext<ChatConfig>({});\n\nexport const ChatConfigProvider: React.FC<{\n config: ChatConfig;\n children: ReactNode;\n}> = ({ config, children }) => {\n return (\n <ChatConfigContext.Provider value={config}>\n {children}\n </ChatConfigContext.Provider>\n );\n};\n\nexport const useChatConfig = () => useContext(ChatConfigContext);\n","'use client';\n\nimport React from 'react';\nimport { ChatTask } from '../types/chat';\n\ninterface ChatHeaderProps {\n contextTitle: string;\n currentTask: ChatTask | null;\n onClose: () => void;\n}\n\nexport function ChatHeader({\n contextTitle,\n currentTask,\n onClose\n}: ChatHeaderProps) {\n return (\n <div className=\"bg-blue-500 text-white px-4 py-4 flex justify-between items-center\">\n <h3 className=\"font-medium text-lg\">\n {currentTask\n ? `DoveText Virtual Assistant (${currentTask.currentStep}/${currentTask.steps})`\n : `DoveText Virtual Assistant (${contextTitle})`}\n </h3>\n <button\n onClick={onClose}\n className=\"bg-blue-600 hover:bg-blue-700 text-white rounded-full p-1.5 flex items-center justify-center transition-colors cursor-pointer\"\n aria-label=\"Close chat\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path fillRule=\"evenodd\" d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\" clipRule=\"evenodd\" />\n </svg>\n </button>\n </div>\n );\n}\n","'use client';\n\nimport React, { useState, useRef, FormEvent, useImperativeHandle, forwardRef, useEffect, useCallback, useLayoutEffect } from 'react';\nimport { MicrophoneIcon, StopIcon, PaperAirplaneIcon, XMarkIcon, Square2StackIcon } from '@heroicons/react/24/outline';\nimport { ChatMessage, ChatTask, VoiceConfig } from '../types/chat';\nimport { InteractiveFunction } from '../types/interactive';\nimport { useSpeechRecognition } from '../hooks/useSpeechRecognition';\nimport { useAudioRecorder } from '../hooks/useAudioRecorder';\nimport { useProactiveResize } from '../hooks/useProactiveResize';\nimport { useChatConfig } from '../context/ChatConfigContext';\n\n// VoiceConfig imported from types/chat\n\ninterface ChatInputAreaProps {\n onSubmit: (message: string) => void;\n isSending: boolean;\n showInputForm: boolean;\n currentTask: ChatTask | null;\n lastInteractiveMessage?: ChatMessage | null;\n voiceConfig?: VoiceConfig;\n onStop?: () => void;\n hintText?: string;\n placeholder?: string;\n // Controlled props\n value?: string;\n onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;\n defaultInputMode?: 'text' | 'voice'; // Deprecated but kept for compatibility\n}\n\n// Define the handle type for the forwarded ref\nexport interface ChatInputAreaHandle {\n focus: () => void;\n setValue: (value: string) => void;\n}\n\nexport const ChatInputArea = forwardRef<ChatInputAreaHandle, ChatInputAreaProps>(({\n onSubmit,\n isSending,\n showInputForm,\n currentTask,\n lastInteractiveMessage,\n voiceConfig: propVoiceConfig, // Rename to distinguish from context\n onStop,\n hintText,\n placeholder,\n value,\n onChange,\n defaultInputMode = 'text'\n}, ref) => {\n const [internalMessage, setInternalMessage] = useState('');\n const [voiceTrigger, setVoiceTrigger] = useState<'click' | 'space' | null>(null);\n const [isTranscribing, setIsTranscribing] = useState(false);\n const [voiceError, setVoiceError] = useState<string | null>(null);\n const [isFocused, setIsFocused] = useState(false);\n\n // Debug Mode State\n const [showDebug, setShowDebug] = useState(false);\n const [logs, setLogs] = useState<string[]>([]);\n const tapCountRef = useRef<{ count: number, lastTap: number }>({ count: 0, lastTap: 0 });\n\n // Console Interceptor for Debug Mode\n useEffect(() => {\n const originalLog = console.log;\n const originalWarn = console.warn;\n const originalError = console.error;\n\n // Helper to format time as HH:mm:ss.ms\n const formatTime = () => {\n const now = new Date();\n return `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}.${now.getMilliseconds().toString().padStart(3, '0')}`;\n };\n\n const addLog = (type: string, args: any[]) => {\n // Only keep logs if we are potentially debugging, to save memory? \n // Or just keep last 50 always. Let's keep last 50.\n try {\n const msg = args.map(arg => {\n if (arg instanceof Error) return `${arg.name}: ${arg.message}`;\n if (typeof arg === 'object') return JSON.stringify(arg);\n return String(arg);\n }).join(' ');\n // Append new log to the END, keep last 50\n setLogs(prev => [...prev, `[${formatTime()}] [${type}] ${msg}`].slice(-50));\n } catch (e) {\n // Ignore serialization errors\n }\n };\n\n console.log = (...args) => { originalLog(...args); addLog('LOG', args); };\n console.warn = (...args) => { originalWarn(...args); addLog('WRN', args); };\n console.error = (...args) => { originalError(...args); addLog('ERR', args); };\n\n return () => {\n console.log = originalLog;\n console.warn = originalWarn;\n console.error = originalError;\n };\n }, []);\n\n const copyLogs = useCallback(() => {\n navigator.clipboard.writeText(logs.join('\\n'))\n .then(() => alert('Logs copied to clipboard'))\n .catch(err => console.error('Failed to copy logs', err));\n }, [logs]);\n // The left button toggles recording, but input is always text.\n\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const measurementRef = useRef<HTMLSpanElement>(null);\n const pendingSelectionRef = useRef<{ start: number, end: number } | null>(null);\n\n // Determine if controlled or uncontrolled\n const isControlled = value !== undefined;\n const message = isControlled ? value : internalMessage;\n\n // Use refs to access latest state in stable callbacks\n const messageRef = useRef(message);\n messageRef.current = message;\n\n // Use useLayoutEffect to apply selection before browser paint\n useLayoutEffect(() => {\n if (pendingSelectionRef.current && textareaRef.current) {\n const { start, end } = pendingSelectionRef.current;\n textareaRef.current.focus();\n textareaRef.current.setSelectionRange(start, end);\n pendingSelectionRef.current = null;\n }\n }, [message]);\n\n const onChangeRef = useRef(onChange);\n useEffect(() => {\n onChangeRef.current = onChange;\n }, [onChange]);\n\n // Get global config\n const { voice: globalVoice } = useChatConfig();\n\n // Determine effective voice config\n const isVoiceEnabled = globalVoice?.enabled ?? (!!propVoiceConfig);\n const voiceConfig = isVoiceEnabled ? (propVoiceConfig || globalVoice?.config) : undefined;\n\n const voiceConfigRef = useRef(voiceConfig);\n useEffect(() => {\n voiceConfigRef.current = voiceConfig;\n }, [voiceConfig]);\n\n const triggerChange = useCallback((newValue: string) => {\n setVoiceError(null); // Clear any errors when content changes\n if (isControlled && onChangeRef.current) {\n const syntheticEvent = {\n target: { value: newValue },\n currentTarget: { value: newValue }\n } as React.ChangeEvent<HTMLTextAreaElement>;\n onChangeRef.current(syntheticEvent);\n } else {\n setInternalMessage(newValue);\n }\n }, [isControlled]);\n\n // Apply auto-resize\n const isInputDisabled = currentTask?.complete ||\n (lastInteractiveMessage?.interactive &&\n ((lastInteractiveMessage?.interactiveData?.function === 'form' && !lastInteractiveMessage?.isResponseSubmitted) ||\n (lastInteractiveMessage?.interactiveData?.function === 'confirm' && !lastInteractiveMessage?.isResponseSubmitted)));\n\n useProactiveResize(textareaRef, measurementRef, message, isInputDisabled || !!voiceTrigger);\n\n // Helper to insert text at cursor position\n const insertTextAtCursor = useCallback((text: string) => {\n const textarea = textareaRef.current;\n const currentVal = messageRef.current || '';\n\n if (!textarea) {\n triggerChange(currentVal + (currentVal ? ' ' : '') + text);\n return;\n }\n\n const start = textarea.selectionStart;\n const end = textarea.selectionEnd;\n\n const before = currentVal.substring(0, start);\n const after = currentVal.substring(end);\n\n // Add padding space if needed (e.g. not at start and previous char is not space)\n const prefix = (start > 0 && !/\\s$/.test(before)) ? ' ' : '';\n\n const newText = before + prefix + text + after;\n\n // Calculate and store pending selection so it can be applied after render\n const selectionStart = start + prefix.length;\n const selectionEnd = selectionStart + text.length;\n pendingSelectionRef.current = { start: selectionStart, end: selectionEnd };\n\n triggerChange(newText);\n }, [triggerChange]);\n\n // Stable Voice Callbacks\n const handleVoiceResult = useCallback((text: string, isFinal: boolean) => {\n if (isFinal) {\n insertTextAtCursor(text);\n }\n }, [insertTextAtCursor]);\n\n const handleVoiceEnd = useCallback(() => {\n setVoiceTrigger(null);\n // If native and we were listening, it's done. \n // Note: Native recognition result comes via handleVoiceResult\n voiceConfigRef.current?.onVoiceEnd?.();\n }, []);\n\n // Voice Hooks\n const nativeSpeech = useSpeechRecognition(handleVoiceResult, handleVoiceEnd, voiceConfig?.language);\n\n // Sync native errors to UI\n useEffect(() => {\n if (nativeSpeech.error) {\n setVoiceError(nativeSpeech.error);\n // Also ensure it is logged for dev mode\n console.error('[ChatInputArea] Native Speech Error:', nativeSpeech.error);\n }\n }, [nativeSpeech.error]);\n\n const customRecorder = useAudioRecorder(async (blob) => {\n setVoiceTrigger(null);\n setIsTranscribing(true);\n setVoiceError(null);\n voiceConfigRef.current?.onVoiceEnd?.();\n\n if (blob.type === 'audio/simulated') {\n console.log('[ChatInputArea] Handling simulated audio capture');\n // Mock delay for simulation\n await new Promise(resolve => setTimeout(resolve, 1500));\n insertTextAtCursor('This is a simulated transcription for development testing.');\n setIsTranscribing(false);\n return;\n }\n\n if (voiceConfigRef.current?.onAudioCapture) {\n try {\n const text = await voiceConfigRef.current.onAudioCapture(blob);\n if (text) insertTextAtCursor(text);\n } catch (e: any) {\n console.error('[ChatInputArea] Audio capture failed', e);\n setVoiceError(e.message || 'Transcription failed');\n } finally {\n setIsTranscribing(false);\n }\n } else {\n setIsTranscribing(false);\n }\n });\n\n // Expose the focus and setValue method\n useImperativeHandle(ref, () => ({\n focus: () => {\n textareaRef.current?.focus();\n },\n setValue: (newValue: string) => {\n triggerChange(newValue);\n }\n }));\n\n const handleSubmit = (e?: FormEvent) => {\n if (e) e.preventDefault();\n\n if (!message.trim()) {\n setTimeout(() => textareaRef.current?.focus(), 0);\n return;\n }\n\n const currentMessage = message;\n triggerChange(''); // Clear input\n setTimeout(() => textareaRef.current?.focus(), 0);\n onSubmit(currentMessage);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey && !e.metaKey && !e.altKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n // Mobile detection helper\n const isMobile = useCallback(() => {\n if (typeof window === 'undefined') return false;\n return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ||\n ('ontouchstart' in window) ||\n (navigator.maxTouchPoints > 0);\n }, []);\n\n const startRecording = async (trigger: 'click' | 'space') => {\n console.log('[ChatInputArea] startRecording called. trigger:', trigger, 'isMobile:', isMobile());\n console.log('[ChatInputArea] Current state - voiceTrigger:', voiceTrigger, 'isTranscribing:', isTranscribing);\n\n if (voiceTrigger || isTranscribing) {\n console.log('[ChatInputArea] startRecording ignored - already active');\n return;\n }\n\n // FIX: On mobile, do NOT blur or delay - start IMMEDIATELY within user gesture context\n // Mobile browsers require SpeechRecognition.start() to be called synchronously in click handler\n // On desktop, we can refocus textarea after starting\n setVoiceTrigger(trigger);\n setVoiceError(null);\n\n if (voiceConfig?.mode === 'native') {\n console.log('[ChatInputArea] Using native speech recognition');\n if (!nativeSpeech.isSupported) {\n console.error('[ChatInputArea] Native speech not supported');\n alert('Speech recognition is not supported in this browser.');\n setVoiceTrigger(null);\n return;\n }\n console.log('[ChatInputArea] Calling nativeSpeech.start()...');\n nativeSpeech.start();\n console.log('[ChatInputArea] nativeSpeech.start() called');\n\n console.log('[ChatInputArea] Calling voiceConfig.onVoiceStart if exists...');\n try {\n voiceConfig?.onVoiceStart?.();\n console.log('[ChatInputArea] voiceConfig.onVoiceStart completed');\n } catch (e) {\n console.error('[ChatInputArea] voiceConfig.onVoiceStart threw error', e);\n }\n } else {\n console.log('[ChatInputArea] Using custom recorder');\n console.log('[ChatInputArea] Calling voiceConfig.onVoiceStart if exists (custom mode)...');\n try {\n voiceConfig?.onVoiceStart?.();\n console.log('[ChatInputArea] voiceConfig.onVoiceStart completed');\n } catch (e) {\n console.error('[ChatInputArea] voiceConfig.onVoiceStart threw error', e);\n }\n await customRecorder.start();\n console.log('[ChatInputArea] Custom recorder started');\n }\n\n // Desktop only: Refocus textarea for convenience\n if (!isMobile()) {\n console.log('[ChatInputArea] Re-focusing textarea (desktop only)');\n setTimeout(() => textareaRef.current?.focus(), 0);\n }\n };\n\n const stopRecording = () => {\n if (!voiceTrigger) return;\n if (voiceConfig?.mode === 'native') {\n nativeSpeech.stop();\n } else {\n customRecorder.stop();\n }\n };\n\n // Determine placeholder text\n const getPlaceholder = () => {\n if (placeholder) return placeholder;\n if (voiceTrigger) return 'Listening...';\n if (currentTask?.complete) return 'Task completed!';\n\n if (lastInteractiveMessage?.interactive && lastInteractiveMessage?.interactiveData && !lastInteractiveMessage?.isResponseSubmitted) {\n const interactiveType = lastInteractiveMessage.interactiveData.function as InteractiveFunction;\n switch (interactiveType) {\n case 'chat': return 'Type your response...';\n case 'confirm': return 'Select Yes or No, or type your response...';\n case 'select': return 'Choose an option or type your response...';\n case 'form': return 'Fill out the form...';\n default: return 'Type your response...';\n }\n }\n return currentTask ? 'Continue your conversation...' : 'Ask me anything...';\n };\n\n const inputHint = (!isInputDisabled && !lastInteractiveMessage?.interactive) ? null :\n (lastInteractiveMessage?.interactiveData?.function === 'form' ? 'Please provide information by completing above form' : null);\n\n if (!showInputForm) {\n return null;\n }\n\n return (\n <div className=\"flex flex-col w-full relative\">\n {/* Debug Overlay */}\n {showDebug && (\n <div className=\"absolute bottom-full left-0 right-0 mb-2 p-2 bg-black/80 text-green-400 text-xs font-mono h-48 overflow-y-auto rounded z-50 pointer-events-auto\">\n <div className=\"flex justify-between items-center bg-gray-800 p-1 mb-1\">\n <span>Debug Logs</span>\n <div className=\"flex gap-2\">\n <button onClick={copyLogs} className=\"text-white hover:text-blue-400\" title=\"Copy Logs\">\n <Square2StackIcon className=\"w-4 h-4\" />\n </button>\n <button onClick={() => { copyLogs(); setShowDebug(false); }} className=\"text-white hover:text-red-400\" title=\"Copy & Close\">\n <XMarkIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n {logs.map((log, i) => (\n <div key={i} className=\"mb-0.5 border-b border-gray-700/50 pb-0.5 break-all\">\n {log}\n </div>\n ))}\n {logs.length === 0 && <div>No logs yet...</div>}\n </div>\n )}\n\n <div className=\"flex items-center gap-2\">\n {/* Voice Toggle Button (Replacing the Mode Switch) */}\n {voiceConfig && (\n <button\n type=\"button\"\n onClick={() => {\n // Debug Trigger: 5 rapid taps\n const now = Date.now();\n if (now - tapCountRef.current.lastTap < 500) {\n tapCountRef.current.count++;\n } else {\n tapCountRef.current.count = 1;\n }\n tapCountRef.current.lastTap = now;\n\n if (tapCountRef.current.count >= 5) {\n setShowDebug(prev => !prev);\n tapCountRef.current.count = 0;\n // Force stop recording if we accidentally triggered it while tapping\n stopRecording();\n return;\n }\n\n if (voiceTrigger) {\n stopRecording();\n } else if (!isTranscribing) {\n startRecording('click');\n }\n }}\n className={`mb-1 p-2 rounded-full transition-all duration-300 flex-shrink-0 border ${isTranscribing\n ? 'text-white border-indigo-500 bg-indigo-600 scale-110 shadow-lg'\n : voiceTrigger\n ? 'text-white border-orange-400 bg-orange-500 scale-110 shadow-lg'\n : 'text-gray-500 border-gray-300 bg-white hover:text-gray-700 hover:bg-gray-100'\n } ${voiceTrigger ? 'animate-pulse' : ''} ${isTranscribing ? 'cursor-wait' : ''}`}\n disabled={isTranscribing}\n title={isTranscribing ? \"Transcribing...\" : voiceTrigger ? \"Stop Recording\" : \"Start Voice Input\"}\n >\n {isTranscribing ? (\n <div className=\"animate-spin w-5 h-5 flex items-center justify-center\">\n <svg className=\"w-5 h-5 text-white\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" fill=\"none\" />\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\" />\n </svg>\n </div>\n ) : (\n <MicrophoneIcon className=\"w-5 h-5\" />\n )}\n </button>\n )}\n\n {/* Main Input Area */}\n <div\n tabIndex={-1}\n className={`flex-1 flex items-center border border-gray-300 rounded-lg overflow-hidden outline-none bg-white min-h-[42px] mb-1 transition-all ${voiceTrigger ? 'ring-2 ring-orange-100 border-orange-300' : 'focus-within:ring-2 focus-within:ring-blue-500 focus-within:border-blue-500'\n }`}\n >\n {/* Text Input (Always Visible) */}\n <span\n ref={measurementRef}\n className=\"absolute invisible whitespace-pre-wrap p-0 m-0 text-gray-700 leading-6\"\n style={{ fontSize: '1rem' }}\n />\n <textarea\n ref={textareaRef}\n value={message}\n onChange={(e) => {\n if (isControlled && onChange) {\n onChange(e);\n } else {\n setInternalMessage(e.target.value);\n }\n }}\n onKeyDown={handleKeyDown}\n onFocus={() => {\n setIsFocused(true);\n setVoiceError(null); // Clear error on focus\n }}\n onBlur={() => setIsFocused(false)}\n placeholder={getPlaceholder()}\n disabled={isInputDisabled}\n readOnly={!!voiceTrigger || isTranscribing}\n rows={1}\n className={`flex-grow px-4 py-2 outline-none text-gray-700 placeholder-gray-500 resize-none leading-6 w-full ${isInputDisabled ? 'bg-gray-100 cursor-not-allowed' : 'bg-transparent'\n } ${voiceTrigger || isTranscribing ? 'cursor-default' : ''}`}\n />\n\n {/* Send / Stop Button */}\n <div className=\"relative mx-2 flex-shrink-0\">\n {/* Spinner Overlay */}\n {isSending && (\n <div className=\"absolute -inset-1\">\n <svg\n className=\"animate-spin h-full w-full text-blue-500 opacity-75\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n ></circle>\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n ></path>\n </svg>\n </div>\n )}\n\n <button\n type=\"button\"\n onClick={(e) => {\n if (isSending && onStop) {\n e.preventDefault();\n onStop();\n } else {\n handleSubmit();\n }\n }}\n disabled={currentTask?.complete || (isSending && !onStop) || isInputDisabled}\n className={`relative z-10 text-white rounded-full p-2 transition-colors duration-200 disabled:bg-gray-400 disabled:cursor-not-allowed ${isSending && onStop\n ? 'bg-red-500 hover:bg-red-600'\n : 'bg-blue-600 hover:bg-blue-700'\n }`}\n title={isSending && onStop ? \"Stop generating\" : \"Send message\"}\n >\n {isSending ? (\n onStop ? <StopIcon className=\"h-5 w-5\" /> : <div className=\"w-5 h-5\" /> // Spinner handles the visual\n ) : (\n <PaperAirplaneIcon className=\"h-5 w-5\" />\n )}\n </button>\n </div>\n </div>\n </div>\n\n {/* Helper Hints */}\n {inputHint && (\n <div className=\"text-sm text-red-500 bg-red-50 py-1 px-4 rounded-lg mt-1\">\n {inputHint}\n </div>\n )}\n\n {/* Dynamic Interaction Hint */}\n <div className=\"ml-[46px] mb-2 mt-0.5 min-h-[0.75rem]\" style={{ marginLeft: '48px' }}>\n <p className={`text-[10px] leading-tight transition-all duration-200 ${voiceError\n ? 'text-red-500'\n : isTranscribing\n ? 'text-indigo-600 font-bold'\n : voiceTrigger\n ? 'text-orange-600 font-medium'\n : 'text-gray-400'\n }`}>\n {voiceError ? (\n <span className=\"flex items-center gap-1 font-semibold italic\">\n Error: {voiceError}\n </span>\n ) : isTranscribing ? (\n 'Transcribing... please wait'\n ) : voiceTrigger ? (\n 'Transcribing, please wait...'\n ) : voiceTrigger ? (\n 'Listening... tap mic icon again to stop'\n ) : (\n hintText || (voiceConfig ? 'Type in text or tap mic icon to talk' : 'Type your message...')\n )}\n </p>\n </div>\n </div>\n );\n});\n\nChatInputArea.displayName = 'ChatInputArea';\n","import { useState, useEffect, useCallback, useRef } from 'react';\n\nexport interface SpeechRecognitionHook {\n isListening: boolean;\n transcript: string;\n start: () => void;\n stop: () => void;\n resetTranscript: () => void;\n isSupported: boolean;\n error: string | null;\n}\n\ninterface SpeechRecognitionEvent {\n results: {\n [index: number]: {\n [index: number]: {\n transcript: string;\n };\n isFinal: boolean;\n };\n length: number;\n };\n}\n\ninterface SpeechRecognitionErrorEvent {\n error: string;\n}\n\nexport const useSpeechRecognition = (\n onResult?: (text: string, isFinal: boolean) => void,\n onEnd?: () => void,\n language: string = 'en-US'\n): SpeechRecognitionHook => {\n const [isListening, setIsListening] = useState(false);\n const [transcript, setTranscript] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [isSupported, setIsSupported] = useState(false);\n\n const recognitionRef = useRef<any>(null);\n const isSimulatingRef = useRef(false);\n const simulationTimeoutRef = useRef<any>(null);\n const languageRef = useRef(language);\n const instanceIdRef = useRef<string>(Math.random().toString(36).slice(2));\n const lastStartAtRef = useRef<number | null>(null);\n const lastStopAtRef = useRef<number | null>(null);\n\n const onResultRef = useRef(onResult);\n const onEndRef = useRef(onEnd);\n\n useEffect(() => {\n onResultRef.current = onResult;\n onEndRef.current = onEnd;\n }, [onResult, onEnd]);\n\n useEffect(() => {\n languageRef.current = language;\n // Update language on existing instance if present\n if (recognitionRef.current) {\n console.log('[useSpeechRecognition] Updating language to:', language);\n recognitionRef.current.lang = language;\n }\n }, [language]);\n\n const isStartingRef = useRef(false);\n\n // Check if SpeechRecognition is supported (without creating instance)\n useEffect(() => {\n if (typeof window !== 'undefined') {\n const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;\n console.log('[useSpeechRecognition] Env - isSecureContext:', (window as any).isSecureContext, 'protocol:', window.location?.protocol);\n const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ||\n ('ontouchstart' in window) ||\n (navigator.maxTouchPoints > 0);\n console.log('[useSpeechRecognition] Init check - SpeechRecognition available:', !!SpeechRecognition, 'isMobile:', isMobile, 'instanceId:', instanceIdRef.current);\n setIsSupported(!!SpeechRecognition);\n }\n\n return () => {\n console.log('[useSpeechRecognition] Effect cleanup - stopping recognition');\n if (isSimulatingRef.current && simulationTimeoutRef.current) {\n clearTimeout(simulationTimeoutRef.current);\n simulationTimeoutRef.current = null;\n }\n if (recognitionRef.current) {\n try {\n recognitionRef.current.stop();\n } catch (e) {\n // Ignore errors during cleanup\n }\n recognitionRef.current = null;\n }\n\n if (typeof window !== 'undefined') {\n const w = window as any;\n if (w.__llmSpeechRecognitionActiveInstanceId === instanceIdRef.current) {\n console.log('[useSpeechRecognition] Cleanup clearing global active instance lock. instanceId:', instanceIdRef.current);\n w.__llmSpeechRecognitionActiveInstanceId = null;\n }\n }\n }\n }, []);\n\n // Helper to create and configure a fresh recognition instance\n // IMPORTANT: On iOS Safari, this MUST be called within user gesture context (click/tap handler)\n const createRecognitionInstance = useCallback(() => {\n const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;\n if (!SpeechRecognition) {\n console.error('[useSpeechRecognition] SpeechRecognition not available');\n return null;\n }\n\n console.log('[useSpeechRecognition] Creating NEW recognition instance within user gesture context. Timestamp:', Date.now());\n const recognition = new SpeechRecognition();\n const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ||\n ('ontouchstart' in window) ||\n (navigator.maxTouchPoints > 0);\n recognition.continuous = !isMobile;\n recognition.interimResults = true;\n recognition.lang = languageRef.current;\n console.log('[useSpeechRecognition] Instance created. continuous:', recognition.continuous, 'interimResults:', recognition.interimResults, 'lang:', recognition.lang, 'isMobile:', isMobile, 'instanceId:', instanceIdRef.current);\n\n recognition.onaudiostart = () => {\n console.log('[useSpeechRecognition] Native onaudiostart. Timestamp:', Date.now(), 'instanceId:', instanceIdRef.current);\n };\n recognition.onaudioend = () => {\n console.log('[useSpeechRecognition] Native onaudioend. Timestamp:', Date.now(), 'instanceId:', instanceIdRef.current);\n };\n recognition.onsoundstart = () => {\n console.log('[useSpeechRecognition] Native onsoundstart. Timestamp:', Date.now(), 'instanceId:', instanceIdRef.current);\n };\n recognition.onsoundend = () => {\n console.log('[useSpeechRecognition] Native onsoundend. Timestamp:', Date.now(), 'instanceId:', instanceIdRef.current);\n };\n recognition.onspeechstart = () => {\n console.log('[useSpeechRecognition] Native onspeechstart. Timestamp:', Date.now(), 'instanceId:', instanceIdRef.current);\n };\n recognition.onspeechend = () => {\n console.log('[useSpeechRecognition] Native onspeechend. Timestamp:', Date.now(), 'instanceId:', instanceIdRef.current);\n };\n recognition.onnomatch = () => {\n console.log('[useSpeechRecognition] Native onnomatch. Timestamp:', Date.now(), 'instanceId:', instanceIdRef.current);\n };\n\n recognition.onstart = () => {\n console.log('[useSpeechRecognition] Native onstart event fired. Timestamp:', Date.now());\n isStartingRef.current = false;\n setIsListening(true);\n setError(null);\n\n if (typeof window !== 'undefined') {\n const w = window as any;\n w.__llmSpeechRecognitionActiveInstanceId = instanceIdRef.current;\n console.log('[useSpeechRecognition] Set global active instance lock. instanceId:', instanceIdRef.current);\n }\n };\n\n recognition.onend = () => {\n console.log('[useSpeechRecognition] Native onend event fired. Timestamp:', Date.now());\n isStartingRef.current = false;\n if (isSimulatingRef.current) {\n console.log('[useSpeechRecognition] onend ignored - simulating');\n return;\n }\n setIsListening(false);\n if (onEndRef.current) onEndRef.current();\n\n if (typeof window !== 'undefined') {\n const w = window as any;\n if (w.__llmSpeechRecognitionActiveInstanceId === instanceIdRef.current) {\n w.__llmSpeechRecognitionActiveInstanceId = null;\n console.log('[useSpeechRecognition] Cleared global active instance lock. instanceId:', instanceIdRef.current);\n }\n }\n };\n\n recognition.onresult = (event: SpeechRecognitionEvent) => {\n console.log('[useSpeechRecognition] onresult event. results count:', event.results.length);\n let interimTranscript = '';\n let finalTranscript = '';\n\n for (let i = event.results.length - 1; i < event.results.length; ++i) {\n const result = event.results[i];\n if (result.isFinal) {\n finalTranscript += result[0].transcript;\n console.log('[useSpeechRecognition] Final transcript:', finalTranscript);\n if (onResultRef.current) onResultRef.current(finalTranscript, true);\n } else {\n interimTranscript += result[0].transcript;\n console.log('[useSpeechRecognition] Interim transcript:', interimTranscript);\n if (onResultRef.current) onResultRef.current(interimTranscript, false);\n }\n }\n\n setTranscript(prev => prev + finalTranscript);\n };\n\n recognition.onerror = (event: SpeechRecognitionErrorEvent) => {\n console.error('[useSpeechRecognition] Native onerror event:', event.error, 'Timestamp:', Date.now());\n console.error('[useSpeechRecognition] Error context - lastStartAt:', lastStartAtRef.current, 'lastStopAt:', lastStopAtRef.current, 'instanceId:', instanceIdRef.current);\n console.error('[useSpeechRecognition] Error details - This could be caused by:');\n if (event.error === 'aborted') {\n console.error('[useSpeechRecognition] - aborted: Recognition was aborted. Common causes: keyboard appeared, focus changed, another recognition started, or page navigation');\n } else if (event.error === 'not-allowed') {\n console.error('[useSpeechRecognition] - not-allowed: Microphone permission denied');\n } else if (event.error === 'no-speech') {\n console.error('[useSpeechRecognition] - no-speech: No speech detected');\n } else if (event.error === 'network') {\n console.error('[useSpeechRecognition] - network: Network error during recognition');\n }\n isStartingRef.current = false;\n \n // Dev mode fallback: Simulate speech if permission is denied\n if (event.error === 'not-allowed' && process.env.NODE_ENV === 'development') {\n console.warn('Speech recognition blocked. Simulating input for development...');\n isSimulatingRef.current = true;\n setError(null);\n setIsListening(true);\n\n simulationTimeoutRef.current = setTimeout(() => {\n const mockText = \"This is a simulated voice input for testing.\";\n setTranscript(prev => prev + (prev ? ' ' : '') + mockText);\n if (onResultRef.current) onResultRef.current(mockText, true);\n\n isSimulatingRef.current = false;\n setIsListening(false);\n if (onEndRef.current) onEndRef.current();\n simulationTimeoutRef.current = null;\n }, 3000);\n return;\n }\n\n console.error('Speech recognition error', event.error);\n setError(event.error);\n setIsListening(false);\n\n if (typeof window !== 'undefined') {\n const w = window as any;\n if (w.__llmSpeechRecognitionActiveInstanceId === instanceIdRef.current) {\n w.__llmSpeechRecognitionActiveInstanceId = null;\n console.log('[useSpeechRecognition] Cleared global active instance lock after error. instanceId:', instanceIdRef.current);\n }\n }\n };\n\n return recognition;\n }, []);\n\n const start = useCallback(() => {\n const startTimestamp = Date.now();\n console.log('[useSpeechRecognition] start() called. Timestamp:', startTimestamp);\n console.log('[useSpeechRecognition] State check - isListening:', isListening, 'isStarting:', isStartingRef.current, 'hasExistingInstance:', !!recognitionRef.current);\n \n // Check if document has focus (important for mobile)\n if (typeof document !== 'undefined') {\n console.log('[useSpeechRecognition] Document hasFocus:', document.hasFocus(), 'activeElement:', document.activeElement?.tagName);\n }\n\n if (isSimulatingRef.current) {\n console.log('[useSpeechRecognition] isSimulating, ignoring start');\n return;\n }\n\n if (isStartingRef.current) {\n console.warn('[useSpeechRecognition] Already starting - ignoring duplicate call');\n return;\n }\n\n // Use our state as proxy\n if (isListening) {\n console.warn('[useSpeechRecognition] App state says already listening - ignoring');\n return;\n }\n\n if (typeof window !== 'undefined') {\n const w = window as any;\n if (w.__llmSpeechRecognitionActiveInstanceId && w.__llmSpeechRecognitionActiveInstanceId !== instanceIdRef.current) {\n console.error('[useSpeechRecognition] Another recognition instance appears active. activeInstanceId:', w.__llmSpeechRecognitionActiveInstanceId, 'thisInstanceId:', instanceIdRef.current);\n }\n }\n\n try {\n // FIX FOR iOS SAFARI: Create a FRESH recognition instance on each start()\n // iOS requires the instance to be created within user gesture context (click/tap)\n // Reusing an instance created in useEffect doesn't work on iOS Safari\n \n // Stop and clean up any existing instance first\n if (recognitionRef.current) {\n console.log('[useSpeechRecognition] Stopping existing instance before creating new one');\n try {\n recognitionRef.current.stop();\n } catch (e) {\n // Ignore - may not be running\n }\n recognitionRef.current = null;\n }\n\n // Create fresh instance within user gesture context\n const recognition = createRecognitionInstance();\n if (!recognition) {\n console.error('[useSpeechRecognition] Failed to create recognition instance');\n setError('Speech recognition not available');\n return;\n }\n recognitionRef.current = recognition;\n\n setTranscript('');\n isStartingRef.current = true;\n lastStartAtRef.current = Date.now();\n console.log('[useSpeechRecognition] About to call recognition.start(). Timestamp:', Date.now());\n recognitionRef.current.start();\n console.log('[useSpeechRecognition] recognition.start() executed successfully. Timestamp:', Date.now());\n } catch (error: any) {\n isStartingRef.current = false;\n console.error('[useSpeechRecognition] Failed to start recognition:', error?.message || error);\n if (error?.name === 'InvalidStateError') {\n console.error('[useSpeechRecognition] InvalidStateError - recognition may already be running');\n }\n setError(error?.message || 'Failed to start speech recognition');\n }\n }, [isListening, createRecognitionInstance]);\n\n const stop = useCallback(() => {\n console.log('[useSpeechRecognition] stop() called');\n lastStopAtRef.current = Date.now();\n if (isSimulatingRef.current) {\n if (simulationTimeoutRef.current) {\n clearTimeout(simulationTimeoutRef.current);\n simulationTimeoutRef.current = null;\n }\n // If stopped manually during simulation, we can either cancel or complete.\n // Let's complete it so user sees something.\n const mockText = \"This is a simulated voice input for testing.\";\n setTranscript(prev => prev + (prev ? ' ' : '') + mockText);\n if (onResultRef.current) onResultRef.current(mockText, true);\n\n isSimulatingRef.current = false;\n setIsListening(false);\n if (onEndRef.current) onEndRef.current();\n return;\n }\n\n if (recognitionRef.current) {\n recognitionRef.current.stop();\n console.log('[useSpeechRecognition] recognition.stop() executed');\n }\n }, []);\n\n const resetTranscript = useCallback(() => {\n setTranscript('');\n }, []);\n\n return {\n isListening,\n transcript,\n start,\n stop,\n resetTranscript,\n isSupported,\n error\n };\n};\n","import { useState, useRef, useCallback } from 'react';\n\nexport interface AudioRecorderHook {\n isRecording: boolean;\n isSimulated: boolean;\n start: () => Promise<void>;\n stop: () => void;\n blob: Blob | null;\n error: string | null;\n}\n\nexport const useAudioRecorder = (\n onStop?: (blob: Blob) => void\n): AudioRecorderHook => {\n const [isRecording, setIsRecording] = useState(false);\n const [isSimulated, setIsSimulated] = useState(false);\n const [blob, setBlob] = useState<Blob | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const mediaRecorderRef = useRef<MediaRecorder | null>(null);\n const chunksRef = useRef<Blob[]>([]);\n\n const start = useCallback(async () => {\n\n try {\n if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {\n // Dev mode fallback\n if (process.env.NODE_ENV === 'development') {\n console.warn('[useAudioRecorder] MediaDevices not available. Entering simulation mode...');\n setIsRecording(true);\n setIsSimulated(true);\n setError(null);\n return;\n }\n throw new Error('Media devices not available. Ensure you are using HTTPS or localhost.');\n }\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n\n const mediaRecorder = new MediaRecorder(stream);\n\n mediaRecorderRef.current = mediaRecorder;\n chunksRef.current = [];\n\n mediaRecorder.ondataavailable = (e) => {\n if (e.data.size > 0) {\n chunksRef.current.push(e.data);\n }\n };\n\n mediaRecorder.onstop = () => {\n const audioBlob = new Blob(chunksRef.current, { type: 'audio/webm' });\n setBlob(audioBlob);\n setIsRecording(false);\n if (onStop) onStop(audioBlob);\n\n // Stop all tracks\n stream.getTracks().forEach(track => {\n track.stop();\n });\n };\n\n mediaRecorder.start();\n setIsRecording(true);\n setError(null);\n } catch (e: any) {\n console.error('Failed to start audio recording:', e);\n setError(e.message || 'Microphone access denied');\n }\n }, [onStop]);\n\n const stop = useCallback(() => {\n if (isSimulated) {\n setIsRecording(false);\n setIsSimulated(false);\n // Return a special dummy blob that the receiver can recognize as \"simulated\"\n const simulatedBlob = new Blob(['simulated speech'], { type: 'audio/simulated' });\n setBlob(simulatedBlob);\n if (onStop) onStop(simulatedBlob);\n return;\n }\n\n if (mediaRecorderRef.current && mediaRecorderRef.current.state !== 'inactive') {\n mediaRecorderRef.current.stop();\n }\n }, [isSimulated, onStop]);\n\n return {\n isRecording,\n isSimulated,\n start,\n stop,\n blob,\n error\n };\n};\n","import { RefObject, useEffect } from 'react';\n\n/**\n * A hook that proactively resizes a textarea based on the content of a hidden measurement element.\n * This avoids the flickering often seen with standard \"height: auto\" approaches by measuring\n * the content in a hidden span first, then applying the height to the textarea.\n */\nexport function useProactiveResize(\n textareaRef: RefObject<HTMLTextAreaElement>,\n measurementRef: RefObject<HTMLSpanElement>,\n value: string,\n disabled: boolean\n) {\n useEffect(() => {\n if (!textareaRef.current || !measurementRef.current) return;\n\n // Copy styles from textarea to measurement span to ensure accurate sizing\n const styles = window.getComputedStyle(textareaRef.current);\n measurementRef.current.style.width = styles.width;\n measurementRef.current.style.font = styles.font; // Shorthand for font-style, font-variant, font-weight, font-size, line-height, font-family\n measurementRef.current.style.padding = styles.padding;\n measurementRef.current.style.border = styles.border;\n measurementRef.current.style.boxSizing = styles.boxSizing;\n measurementRef.current.style.whiteSpace = 'pre-wrap'; // Important for matching textarea behavior\n measurementRef.current.style.visibility = 'hidden';\n measurementRef.current.style.position = 'absolute';\n measurementRef.current.style.pointerEvents = 'none';\n\n // Set content to measurement span\n // Append a zero-width space to ensure empty lines are counted\n measurementRef.current.textContent = value + '\\u200B';\n\n // Calculate height\n const scrollHeight = measurementRef.current.offsetHeight;\n\n // Apply height to textarea\n // We add a small buffer (e.g., 2px) to prevent scrollbars from appearing due to sub-pixel rendering differences\n // But direct assignment is usually best.\n // Also respect min-height if set in CSS (typically handled by browser, but we set style.height)\n textareaRef.current.style.height = `${scrollHeight}px`;\n\n }, [value, disabled, textareaRef, measurementRef]);\n}\n","import React, { useState, useCallback, useRef } from 'react';\nimport { MicrophoneIcon, StopIcon, XMarkIcon, Square2StackIcon } from '@heroicons/react/24/outline';\nimport { useSpeechRecognition } from '../hooks/useSpeechRecognition';\nimport { useAudioRecorder } from '../hooks/useAudioRecorder';\nimport { VoiceConfig } from '../types/chat';\nimport { useChatConfig } from '../context/ChatConfigContext';\n\ninterface TapToTalkProps {\n onResult: (text: string) => void;\n voiceConfig?: VoiceConfig;\n className?: string;\n disabled?: boolean;\n tooltip?: string;\n onFocusTarget?: () => void;\n accentColor?: string;\n}\n\nexport const TapToTalk: React.FC<TapToTalkProps> = ({\n onResult,\n voiceConfig: propVoiceConfig,\n className = '',\n disabled = false,\n tooltip = 'Tap to speak',\n onFocusTarget,\n accentColor = 'bg-emerald-600'\n}) => {\n const globalConfig = useChatConfig();\n const voiceConfig = propVoiceConfig || globalConfig.voice?.config;\n\n const [isTranscribing, setIsTranscribing] = useState(false);\n const [voiceTrigger, setVoiceTrigger] = useState<'click' | null>(null);\n const [errorMsg, setErrorMsg] = useState<string | null>(null);\n\n // Debug Mode State\n const [showDebug, setShowDebug] = useState(false);\n const [logs, setLogs] = useState<string[]>([]);\n const tapCountRef = useRef<{ count: number, lastTap: number }>({ count: 0, lastTap: 0 });\n\n // Console Interceptor for Debug Mode\n React.useEffect(() => {\n const originalLog = console.log;\n const originalWarn = console.warn;\n const originalError = console.error;\n\n // Helper to format time as HH:mm:ss.ms\n const formatTime = () => {\n const now = new Date();\n return `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}.${now.getMilliseconds().toString().padStart(3, '0')}`;\n };\n\n const addLog = (type: string, args: any[]) => {\n try {\n const msg = args.map(arg => {\n if (arg instanceof Error) return `${arg.name}: ${arg.message}`;\n if (typeof arg === 'object') return JSON.stringify(arg);\n return String(arg);\n }).join(' ');\n // Append new log to the END, keep last 50\n setLogs(prev => [...prev, `[${formatTime()}] [${type}] ${msg}`].slice(-50));\n } catch (e) {\n // Ignore serialization errors\n }\n };\n\n console.log = (...args) => { originalLog(...args); addLog('LOG', args); };\n console.warn = (...args) => { originalWarn(...args); addLog('WRN', args); };\n console.error = (...args) => { originalError(...args); addLog('ERR', args); };\n\n return () => {\n console.log = originalLog;\n console.warn = originalWarn;\n console.error = originalError;\n };\n }, []);\n\n const copyLogs = useCallback(() => {\n navigator.clipboard.writeText(logs.join('\\n'))\n .then(() => alert('Logs copied to clipboard'))\n .catch(err => console.error('Failed to copy logs', err));\n }, [logs]);\n\n // Native Speech Handler\n const handleVoiceResult = useCallback((text: string, isFinal: boolean) => {\n if (isFinal) {\n onResult(text);\n setErrorMsg(null);\n setVoiceTrigger(null);\n }\n }, [onResult]);\n\n const handleVoiceEnd = useCallback(() => {\n setVoiceTrigger(null);\n }, []);\n\n const nativeSpeech = useSpeechRecognition(handleVoiceResult, handleVoiceEnd, voiceConfig?.language);\n\n React.useEffect(() => {\n if (nativeSpeech.error) {\n setErrorMsg(nativeSpeech.error);\n console.error('[TapToTalk] Native Speech Error:', nativeSpeech.error);\n }\n }, [nativeSpeech.error]);\n\n // Custom Audio Recorder Handler\n const customRecorder = useAudioRecorder(async (blob) => {\n setVoiceTrigger(null);\n setIsTranscribing(true);\n setErrorMsg(null);\n\n if (blob.type === 'audio/simulated') {\n console.log('[TapToTalk] Handling simulated audio capture');\n await new Promise(resolve => setTimeout(resolve, 1500));\n onResult('This is a simulated transcription for development testing.');\n setIsTranscribing(false);\n return;\n }\n\n if (voiceConfig?.mode === 'custom' && voiceConfig.onAudioCapture) {\n try {\n const text = await voiceConfig.onAudioCapture(blob);\n if (text) onResult(text);\n } catch (error: any) {\n console.error('[TapToTalk] Custom transcription failed:', error);\n setErrorMsg(error.message || 'Transcription failed');\n } finally {\n setIsTranscribing(false);\n }\n } else {\n setIsTranscribing(false);\n }\n });\n\n const isListening = !!voiceTrigger || nativeSpeech.isListening || customRecorder.isRecording;\n const isActive = isListening || isTranscribing;\n\n const processingRef = useRef(false);\n\n // Mobile detection helper\n const isMobile = useCallback(() => {\n if (typeof window === 'undefined') return false;\n return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ||\n ('ontouchstart' in window) ||\n (navigator.maxTouchPoints > 0);\n }, []);\n\n const toggleVoice = async (e?: React.MouseEvent) => {\n if (e) {\n e.preventDefault();\n e.stopPropagation();\n }\n\n // Debug Trigger: 5 rapid taps logic check first (bypass processing check)\n const now = Date.now();\n if (now - tapCountRef.current.lastTap < 500) {\n tapCountRef.current.count++;\n } else {\n tapCountRef.current.count = 1;\n }\n tapCountRef.current.lastTap = now;\n\n if (tapCountRef.current.count >= 5) {\n setShowDebug(prev => !prev);\n tapCountRef.current.count = 0;\n // Force stop if we accidentally triggered reading\n if (isActive) {\n console.log('[TapToTalk] Debug trigger force-stop');\n if (voiceConfig?.mode === 'native') nativeSpeech.stop();\n else customRecorder.stop();\n setVoiceTrigger(null);\n }\n return;\n }\n\n console.log('[TapToTalk] toggleVoice called. isMobile:', isMobile());\n if (processingRef.current) {\n console.log('[TapToTalk] toggleVoice ignored - processing');\n return;\n }\n\n // Only set processing to true if we are potentially starting an async operation\n // or if we need to debounce rapid taps.\n processingRef.current = true;\n console.log('[TapToTalk] toggleVoice called. isActive:', isActive, 'isListening:', isListening, 'isTranscribing:', isTranscribing);\n\n try {\n if (isActive) {\n if (isTranscribing && !isListening) {\n console.log('[TapToTalk] Ignoring click during transcription');\n return; // Ignore clicks during transcription (unless forced stop)\n }\n console.log('[TapToTalk] Stopping voice...');\n if (voiceConfig?.mode === 'native') {\n nativeSpeech.stop();\n } else {\n customRecorder.stop();\n }\n setVoiceTrigger(null);\n } else {\n console.log('[TapToTalk] Starting voice... mode:', voiceConfig?.mode);\n setErrorMsg(null);\n setVoiceTrigger('click');\n console.log('[TapToTalk] voiceTrigger set to click');\n\n // FIX: On mobile, do NOT blur or delay - start IMMEDIATELY within user gesture context\n // Mobile browsers require SpeechRecognition.start() to be called synchronously in tap handler\n if (!isMobile() && onFocusTarget) {\n console.log('[TapToTalk] Desktop: calling onFocusTarget()');\n onFocusTarget();\n }\n\n if (voiceConfig?.mode === 'custom') {\n console.log('[TapToTalk] Starting custom recorder...');\n try {\n await customRecorder.start();\n console.log('[TapToTalk] Custom recorder started successfully');\n } catch (e: any) {\n console.error('[TapToTalk] Custom recorder failed:', e);\n setErrorMsg('Mic access denied');\n setVoiceTrigger(null);\n }\n } else {\n console.log('[TapToTalk] Starting native speech recognition...');\n if (!nativeSpeech.isSupported) {\n console.error('[TapToTalk] Native speech not supported');\n setErrorMsg('Speech not supported');\n setVoiceTrigger(null);\n return;\n }\n console.log('[TapToTalk] Calling nativeSpeech.start()...');\n nativeSpeech.start();\n console.log('[TapToTalk] nativeSpeech.start() called');\n }\n }\n } finally {\n // Small delay to prevent double-taps being registered immediately\n setTimeout(() => {\n processingRef.current = false;\n }, 300);\n }\n };\n\n // State determination for UI\n let bgColor = accentColor;\n let label = 'Tap to Talk';\n let Icon = <MicrophoneIcon className=\"h-5 w-5\" />;\n\n if (isListening) {\n bgColor = 'bg-orange-500';\n label = 'Listening ... Tap to stop';\n Icon = <MicrophoneIcon className=\"h-5 w-5 animate-pulse\" />;\n } else if (isTranscribing) {\n bgColor = 'bg-indigo-600';\n label = 'Transcribing ...';\n Icon = (\n <svg className=\"animate-spin h-5 w-5 text-white\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\"></circle>\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n );\n }\n\n return (\n <div className=\"flex flex-col w-full relative\">\n {/* Debug Overlay */}\n {showDebug && (\n <div className=\"absolute bottom-full left-0 right-0 mb-2 p-2 bg-black/80 text-green-400 text-xs font-mono h-48 overflow-y-auto rounded z-50 pointer-events-auto\">\n <div className=\"flex justify-between items-center bg-gray-800 p-1 mb-1\">\n <span>Debug Logs</span>\n <div className=\"flex gap-2\">\n <button onClick={(e) => { e.stopPropagation(); copyLogs(); }} className=\"text-white hover:text-blue-400\" title=\"Copy Logs\">\n <Square2StackIcon className=\"w-4 h-4\" />\n </button>\n <button onClick={(e) => { e.stopPropagation(); copyLogs(); setShowDebug(false); }} className=\"text-white hover:text-red-400\" title=\"Copy & Close\">\n <XMarkIcon className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n {logs.map((log, i) => (\n <div key={i} className=\"mb-0.5 border-b border-gray-700/50 pb-0.5 break-all\">\n {log}\n </div>\n ))}\n {logs.length === 0 && <div>No logs yet...</div>}\n </div>\n )}\n <button\n onClick={toggleVoice}\n disabled={disabled || (isTranscribing && !isListening)}\n className={`flex items-center justify-center gap-3 px-6 py-3 rounded-xl transition-all duration-300 w-full font-medium shadow-md active:scale-[0.98]\n ${bgColor} text-white\n ${disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}\n ${className}`}\n title={label}\n >\n <div className=\"flex items-center justify-center shrink-0\">\n {Icon}\n </div>\n <span className=\"truncate\">{label}</span>\n {errorMsg && (\n <span className=\"text-[10px] bg-white/20 px-1.5 py-0.5 rounded text-red-100 animate-in fade-in slide-in-from-right-1\">\n {errorMsg}\n </span>\n )}\n </button>\n </div>\n );\n};\n","'use client';\n\nimport React, { useEffect, useRef } from 'react';\nimport { ChatMessage, ChatTask } from '../types/chat';\nimport InteractiveMessageHandler from './interactive/InteractiveMessageHandler';\nimport { InformationCircleIcon } from '@heroicons/react/24/outline';\nimport { MessageBubble } from './MessageBubble';\n\n// Define the props for the ChatMessageList component\ninterface ChatMessageListProps {\n chatHistory: ChatMessage[];\n isProcessing: boolean;\n processingHint: string;\n currentTask: ChatTask | null;\n getContextExample: () => string;\n onInteractiveResponse?: (messageId: string | number, response: any) => void;\n}\n\n/**\n * ChatMessageList component displays the chat messages and handles scrolling\n * Features:\n * - Displays user and system messages with different styling\n * - Shows a typing indicator when the system is processing\n * - Displays a welcome message when the chat is empty\n * - Auto-scrolls to the bottom when new messages arrive\n * - Handles interactive messages with different UI components\n */\nexport const ChatMessageList: React.FC<ChatMessageListProps> = ({\n chatHistory,\n isProcessing,\n processingHint,\n currentTask,\n getContextExample,\n onInteractiveResponse\n}) => {\n // Reference to the chat container for auto-scrolling\n const chatContainerRef = useRef<HTMLDivElement>(null);\n // Reference to the last message for scrolling into view\n const lastMessageRef = useRef<HTMLDivElement>(null);\n // Reference to the processing indicator\n const processingIndicatorRef = useRef<HTMLDivElement>(null);\n\n // Scroll to the bottom when chat history or processing state changes\n useEffect(() => {\n // If there's a processing indicator, scroll to it\n if (isProcessing && processingIndicatorRef.current) {\n processingIndicatorRef.current.scrollIntoView({ behavior: 'smooth' });\n return;\n }\n\n // If there's a last message, scroll to it\n if (lastMessageRef.current) {\n lastMessageRef.current.scrollIntoView({ behavior: 'smooth' });\n } else if (chatContainerRef.current) {\n // Fallback to scrolling the container\n chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;\n }\n }, [chatHistory, isProcessing]);\n\n // Handle interactive message responses\n const handleInteractiveResponse = (messageId: string | number, response: any) => {\n if (onInteractiveResponse) {\n onInteractiveResponse(messageId, response);\n }\n };\n\n return (\n <div\n ref={chatContainerRef}\n className=\"flex-1 overflow-y-auto p-4 space-y-8 bg-gray-50\"\n >\n {/* Welcome message when chat is empty */}\n {chatHistory.length === 0 && !isProcessing && (\n <div className=\"text-center py-8\">\n <h3 className=\"text-lg font-medium text-gray-700 mb-2\">How can I help you today?</h3>\n <p className=\"text-sm text-gray-500 mb-4\">\n Try asking me something like {getContextExample()}\n </p>\n </div>\n )}\n\n {/* Display chat messages */}\n {chatHistory.map((message, index) => {\n // Determine if this is the last message\n const isLastMessage = index === chatHistory.length - 1;\n const isUser = message.role === 'user';\n const isError = message.role === 'error';\n\n return (\n <div\n key={message.id || `message-${index}`}\n ref={isLastMessage ? lastMessageRef : undefined}\n className={`flex flex-col w-full ${isUser ? 'items-end' : 'items-start'}`}\n >\n {/* Timestamp display */}\n <div className=\"text-xs text-gray-400 mb-1 px-1\">\n {message.timestamp\n ? `${isUser ? 'Sent' : 'Received'} at ${new Date(message.timestamp).toLocaleString()}`\n : ''}\n </div>\n\n {/* Message Content */}\n <div className=\"w-full\">\n {message.interactive && message.interactiveData ? (\n <div className={`max-w-[85%] ${isUser ? 'ml-auto' : 'mr-auto'}`}>\n <InteractiveMessageHandler\n message={message.interactiveData}\n onResponse={(response: any) => {\n const messageId = message.id || `interactive-${index}-${Date.now()}`;\n message.responseValue = response;\n handleInteractiveResponse(messageId, response);\n }}\n isResponseSubmitted={!!message.isResponseSubmitted}\n parentMessage={message}\n />\n </div>\n ) : (\n <MessageBubble\n message={message}\n isUser={isUser}\n />\n )}\n </div>\n\n {isUser && message.interactive && (\n <div className=\"flex items-center mt-1 space-x-1 text-xs text-gray-500 italic\">\n <InformationCircleIcon className=\"h-3 w-3 text-blue-400\" />\n <span>\n {message.request === 'form' && 'Response to form submission'}\n {message.request === 'select' && 'Response to selection prompt'}\n {message.request === 'confirm' && 'Response to confirmation prompt'}\n </span>\n </div>\n )}\n </div>\n );\n })}\n\n {/* Show typing indicator when processing */}\n {isProcessing && (\n <div\n ref={processingIndicatorRef}\n className=\"flex justify-start my-4\"\n >\n <div className=\"bg-white text-gray-800 border border-gray-200 rounded-lg px-4 py-2 max-w-[85%]\">\n <div className=\"flex items-center\">\n <span className=\"text-sm\">{processingHint}</span>\n <span className=\"ml-2 flex space-x-1\">\n <span className=\"h-2 w-2 bg-gray-400 rounded-full animate-bounce\" style={{ animationDelay: '0ms' }}></span>\n <span className=\"h-2 w-2 bg-gray-400 rounded-full animate-bounce\" style={{ animationDelay: '150ms' }}></span>\n <span className=\"h-2 w-2 bg-gray-400 rounded-full animate-bounce\" style={{ animationDelay: '300ms' }}></span>\n </span>\n </div>\n </div>\n </div>\n )}\n\n {/* Show task progress if available */}\n {currentTask && !currentTask.complete && (\n <div className=\"mt-4 bg-blue-50 border border-blue-100 rounded-lg p-3\">\n <div className=\"text-sm text-blue-800 mb-1\">\n Task in progress: Step {currentTask.currentStep} of {currentTask.steps}\n </div>\n <div className=\"w-full bg-blue-200 rounded-full h-2\">\n <div\n className=\"bg-blue-500 h-2 rounded-full\"\n style={{ width: `${(currentTask.currentStep / currentTask.steps) * 100}%` }}\n ></div>\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default ChatMessageList;\n","'use client';\n\nimport React, { useState } from 'react';\nimport { ConfirmInteractionParams } from '../../types/interactive';\n\ninterface ConfirmInteractionProps {\n parameters: Record<string, any>;\n onResponse: (response: boolean) => void;\n isResponseSubmitted: boolean;\n}\n\n/**\n * Component for handling confirm (yes/no) interactions\n */\nconst ConfirmInteraction: React.FC<ConfirmInteractionProps> = ({\n parameters,\n onResponse,\n isResponseSubmitted\n}) => {\n const [selectedOption, setSelectedOption] = useState<string | null>(null);\n const params = parameters as ConfirmInteractionParams;\n\n // Extract parameters\n const { yesPrompt, noPrompt } = params;\n\n console.log('[ConfirmInteraction] Parameters:', params);\n\n const handleOptionClick = (value: boolean, buttonText: string) => {\n if (isResponseSubmitted) return;\n\n // Use the button text (yesPrompt/noPrompt) as the selected option\n setSelectedOption(buttonText);\n onResponse(value);\n };\n\n return (\n <div className=\"mt-2 mb-4\">\n <div className=\"flex space-x-2\">\n <button\n onClick={() => handleOptionClick(true, yesPrompt)}\n disabled={isResponseSubmitted}\n className={`px-4 py-2 rounded-md text-sm transition-colors ${isResponseSubmitted\n ? selectedOption === yesPrompt\n ? 'bg-blue-500 text-white' // Selected and submitted\n : 'bg-gray-200 text-gray-500 cursor-not-allowed' // Not selected and submitted\n : 'bg-blue-100 text-blue-700 hover:bg-blue-200'}`}\n >\n {yesPrompt}\n </button>\n <button\n onClick={() => handleOptionClick(false, noPrompt)}\n disabled={isResponseSubmitted}\n className={`px-4 py-2 rounded-md text-sm transition-colors ${isResponseSubmitted\n ? selectedOption === noPrompt\n ? 'bg-blue-500 text-white' // Selected and submitted\n : 'bg-gray-200 text-gray-500 cursor-not-allowed' // Not selected and submitted\n : 'bg-gray-100 text-gray-700 hover:bg-gray-200'}`}\n >\n {noPrompt}\n </button>\n </div>\n </div>\n );\n};\n\nexport default ConfirmInteraction;\n","'use client';\n\nimport React, { useState, useEffect } from 'react';\nimport { SelectInteractionParams } from '../../types/interactive';\n\ninterface SelectInteractionProps {\n parameters: Record<string, any>;\n onResponse: (response: string) => void;\n isResponseSubmitted: boolean;\n message?: any;\n}\n\n/**\n * Component for handling select interactions (choosing from multiple options)\n */\nconst SelectInteraction: React.FC<SelectInteractionProps> = ({\n parameters,\n onResponse,\n isResponseSubmitted,\n message\n}) => {\n const [selectedOption, setSelectedOption] = useState<string | null>(null);\n const [customOption, setCustomOption] = useState<string | null>(null);\n const params = parameters as SelectInteractionParams;\n\n const { question, options, placeholder } = params;\n\n // Effect to check if there's a responseValue to use\n useEffect(() => {\n if (isResponseSubmitted && message?.responseValue) {\n const responseValueStr = String(message.responseValue);\n setSelectedOption(responseValueStr);\n\n // Check if it's a custom option\n if (!options.includes(responseValueStr)) {\n setCustomOption(responseValueStr);\n }\n }\n }, [isResponseSubmitted, message, options]);\n\n const handleOptionClick = (option: string) => {\n if (isResponseSubmitted) return;\n\n setSelectedOption(option);\n setCustomOption(null); // Clear any custom option when selecting a predefined one\n onResponse(option);\n };\n\n return (\n <div className=\"mt-2 mb-4\">\n <div className=\"flex flex-wrap gap-2\">\n {options.map((option, index) => (\n <button\n key={index}\n onClick={() => handleOptionClick(option)}\n disabled={isResponseSubmitted}\n className={`px-4 py-2 rounded-md text-sm transition-colors ${isResponseSubmitted\n ? selectedOption === option\n ? 'bg-blue-500 text-white' // Selected and submitted\n : 'bg-gray-200 text-gray-500 cursor-not-allowed' // Not selected and submitted\n : 'bg-blue-100 text-blue-700 hover:bg-blue-200'}`}\n >\n {option}\n </button>\n ))}\n </div>\n\n {/* Show custom option message if applicable */}\n {customOption && isResponseSubmitted && (\n <div className=\"mt-2 text-sm text-amber-600 bg-amber-50 p-2 rounded\">\n User provided custom option: <span className=\"font-semibold\">\"{customOption}\"</span>\n </div>\n )}\n </div>\n );\n};\n\nexport default SelectInteraction;\n","'use client';\n\nimport React, { useState, useEffect, useRef } from 'react';\nimport { FormInteractionParams, FormField } from '../../types/interactive';\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-react';\n\ninterface FormInteractionProps {\n parameters: Record<string, any>;\n onResponse: (response: Record<string, any>) => void;\n isResponseSubmitted: boolean;\n submittedValues?: Record<string, any>;\n}\n\n/**\n * Component for handling form interactions (collecting structured data)\n */\nconst FormInteraction: React.FC<FormInteractionProps> = ({\n parameters,\n onResponse,\n isResponseSubmitted,\n submittedValues\n}) => {\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [formValues, setFormValues] = useState<Record<string, any>>({});\n const [isExpanded, setIsExpanded] = useState(false);\n const [parsedFields, setParsedFields] = useState<FormField[]>([]);\n const formButtonsRef = useRef<HTMLDivElement>(null);\n\n // Parse parameters to handle both array and object-based fields\n const parseParameters = () => {\n const { prompt, description, submitText = 'Submit', cancelText = 'Cancel' } = parameters;\n\n // Handle fields that might come as an array of stringified JSON\n let fieldsArray: FormField[] = [];\n\n if (parameters.fields) {\n // If fields is an array, parse each item if it's a string\n if (Array.isArray(parameters.fields)) {\n fieldsArray = parameters.fields.map(field => {\n if (typeof field === 'string') {\n try {\n const fieldData = JSON.parse(field);\n\n const name = fieldData.name;\n\n return {\n name,\n label: fieldData.label || name,\n type: fieldData.type || 'string',\n required: fieldData.required || false,\n options: fieldData.options || [],\n placeholder: fieldData.description || fieldData.label || name,\n defaultValue: fieldData.defaultValue\n } as FormField;\n } catch (error) {\n console.error(`Error parsing field:`, error);\n return null;\n }\n }\n return field;\n }).filter((field): field is FormField => field !== null);\n }\n // If fields is an object with stringified JSON values\n else if (typeof parameters.fields === 'object') {\n fieldsArray = Object.entries(parameters.fields).map(([name, fieldDataStr]) => {\n let fieldData: Record<string, any> = {};\n\n // Try to parse the stringified JSON\n try {\n if (typeof fieldDataStr === 'string') {\n fieldData = JSON.parse(fieldDataStr);\n } else {\n fieldData = fieldDataStr as Record<string, any>;\n }\n } catch (error) {\n console.error(`Error parsing field data for ${name}:`, error);\n }\n\n return {\n name,\n label: fieldData.label || name,\n type: fieldData.type || 'string',\n required: fieldData.required || false,\n options: fieldData.options || [],\n placeholder: fieldData.description || fieldData.label || name,\n defaultValue: fieldData.defaultValue\n } as FormField;\n });\n\n console.log('Field arrays: ', fieldsArray)\n }\n }\n\n return {\n title: prompt || 'Please fill out this form',\n description,\n fields: fieldsArray,\n submitText,\n cancelText\n };\n };\n\n const params = parseParameters();\n\n // Initialize form values with default values\n useEffect(() => {\n const processedParams = parseParameters();\n setParsedFields(processedParams.fields);\n\n const initialValues: Record<string, any> = {};\n processedParams.fields.forEach(field => {\n if (field.defaultValue !== undefined) {\n initialValues[field.name] = field.defaultValue;\n } else if (field.type === 'checkbox') {\n initialValues[field.name] = false;\n } else {\n initialValues[field.name] = '';\n }\n });\n setFormValues(initialValues);\n\n // Automatically open the modal when the component mounts\n if (!isResponseSubmitted) {\n setIsModalOpen(true);\n }\n }, [parameters, isResponseSubmitted]);\n\n // Effect to scroll form buttons into view when modal is opened\n useEffect(() => {\n if (isModalOpen && formButtonsRef.current) {\n setTimeout(() => {\n formButtonsRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }, 100); // Small delay to ensure form is rendered\n }\n }, [isModalOpen]);\n\n const handleInputChange = (field: FormField, value: any) => {\n setFormValues(prev => ({\n ...prev,\n [field.name]: value\n }));\n };\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n onResponse(formValues);\n setIsModalOpen(false);\n };\n\n const handleCancel = () => {\n onResponse({});\n setIsModalOpen(false);\n };\n\n const renderField = (field: FormField) => {\n const { name, label, type, required, options, placeholder } = field;\n\n switch (type) {\n case 'string':\n case 'email':\n case 'number':\n case 'password':\n return (\n <div className=\"mb-4 flex items-center space-x-4\" key={name}>\n <label htmlFor={name} className=\"text-sm font-medium text-gray-700 min-w-[120px]\">\n {label}{required && <span className=\"text-red-500\">*</span>}\n </label>\n <input\n type={type === 'string' ? 'text' : type}\n id={name}\n name={name}\n value={formValues[name] || ''}\n onChange={(e) => handleInputChange(field, e.target.value)}\n placeholder={placeholder}\n required={required}\n disabled={isResponseSubmitted}\n className=\"flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n </div>\n );\n\n case 'textarea':\n return (\n <div className=\"mb-4 flex items-start space-x-4\" key={name}>\n <label htmlFor={name} className=\"text-sm font-medium text-gray-700 min-w-[120px] pt-2\">\n {label}{required && <span className=\"text-red-500\">*</span>}\n </label>\n <textarea\n id={name}\n name={name}\n value={formValues[name] || ''}\n onChange={(e) => handleInputChange(field, e.target.value)}\n placeholder={placeholder}\n required={required}\n disabled={isResponseSubmitted}\n rows={4}\n className=\"flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n </div>\n );\n\n case 'select':\n return (\n <div className=\"mb-4 flex items-center space-x-4\" key={name}>\n <label htmlFor={name} className=\"text-sm font-medium text-gray-700 min-w-[120px]\">\n {label}{required && <span className=\"text-red-500\">*</span>}\n </label>\n <select\n id={name}\n name={name}\n value={formValues[name] || ''}\n onChange={(e) => handleInputChange(field, e.target.value)}\n required={required}\n disabled={isResponseSubmitted}\n className=\"flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n <option value=\"\" disabled>{placeholder || 'Select an option'}</option>\n {options?.map((option, index) => (\n <option key={index} value={option}>{option}</option>\n ))}\n </select>\n </div>\n );\n\n case 'checkbox':\n return (\n <div className=\"mb-4 flex items-center space-x-4\" key={name}>\n <div className=\"min-w-[120px]\" />\n <div className=\"flex items-center\">\n <input\n type=\"checkbox\"\n id={name}\n name={name}\n checked={!!formValues[name]}\n onChange={(e) => handleInputChange(field, e.target.checked)}\n required={required}\n disabled={isResponseSubmitted}\n className=\"h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500\"\n />\n <label htmlFor={name} className=\"ml-2 text-sm text-gray-700\">\n {label}{required && <span className=\"text-red-500\">*</span>}\n </label>\n </div>\n </div>\n );\n\n case 'radio':\n return (\n <div className=\"mb-4 flex space-x-4\" key={name}>\n <div className=\"text-sm font-medium text-gray-700 min-w-[120px] pt-2\">\n {label}{required && <span className=\"text-red-500\">*</span>}\n </div>\n <div className=\"flex-1 space-y-2\">\n {options?.map((option, index) => (\n <div key={index} className=\"flex items-center\">\n <input\n id={`${name}-${index}`}\n name={name}\n type=\"radio\"\n value={option}\n checked={formValues[name] === option}\n onChange={() => handleInputChange(field, option)}\n required={required}\n disabled={isResponseSubmitted}\n className=\"h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500\"\n />\n <label htmlFor={`${name}-${index}`} className=\"ml-2 text-sm text-gray-700\">\n {option}\n </label>\n </div>\n ))}\n </div>\n </div>\n );\n\n default:\n return null;\n }\n };\n\n if (isResponseSubmitted) {\n // For submitted forms, show a summary of the responses\n return (\n <div className=\"mt-2 bg-gray-50 p-3 rounded-md border border-gray-200\">\n <div className=\"flex justify-between items-center cursor-pointer\" onClick={() => setIsExpanded(!isExpanded)}>\n <span className=\"font-medium text-gray-700\">{isExpanded ? 'Hide' : 'Show'} Form Responses</span>\n {isExpanded ?\n <ChevronUpIcon className=\"h-5 w-5 text-gray-500\" /> :\n <ChevronDownIcon className=\"h-5 w-5 text-gray-500\" />\n }\n </div>\n\n {isExpanded && (\n <div className=\"mt-2 space-y-2\">\n {parsedFields.map((field) => (\n <div key={field.name} className=\"flex\">\n <span className=\"text-sm font-medium text-gray-600 mr-2\">{field.label}:</span>\n <span className=\"text-sm text-gray-800\">\n {typeof submittedValues?.[field.name] === 'boolean'\n ? (submittedValues[field.name] ? 'Yes' : 'No')\n : submittedValues?.[field.name] || 'Not provided'}\n </span>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n }\n\n // For new forms, show the modal\n return (\n <div className=\"mt-2\">\n {isModalOpen && (\n <div className=\"p-4\">\n <form onSubmit={handleSubmit} className=\"mt-4\">\n {parsedFields.map(field => renderField(field))}\n\n <div ref={formButtonsRef} className=\"flex justify-end mt-4 space-x-2\">\n <button\n type=\"button\"\n onClick={handleCancel}\n disabled={isResponseSubmitted}\n className=\"px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 border border-gray-300 rounded-md hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n {params.cancelText}\n </button>\n <button\n type=\"submit\"\n disabled={isResponseSubmitted}\n className=\"px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n {params.submitText}\n </button>\n </div>\n </form>\n </div>\n )}\n </div>\n );\n};\n\nexport default FormInteraction;\n","'use client';\n\nimport React from 'react';\nimport { PresentInteractionParams } from '../../types/interactive';\n\n// Try to import ReactMarkdown, but provide a fallback if it's not available\nlet ReactMarkdown: any;\ntry {\n // Dynamic import for ReactMarkdown\n ReactMarkdown = require('react-markdown');\n} catch (error) {\n // Fallback if ReactMarkdown is not available\n ReactMarkdown = ({ children }: { children: string }) => (\n <div className=\"whitespace-pre-wrap\">{children}</div>\n );\n}\n\ninterface PresentInteractionProps {\n parameters: Record<string, any>;\n}\n\n/**\n * Component for handling present interactions (displaying information)\n */\nconst PresentInteraction: React.FC<PresentInteractionProps> = ({\n parameters\n}) => {\n const params = parameters as PresentInteractionParams;\n const { title, content, format = 'text', level = 'info' } = params;\n\n // Define styles based on level\n const getLevelStyles = () => {\n switch (level) {\n case 'error':\n return {\n container: 'bg-red-50 border-red-100',\n title: 'text-red-800',\n content: 'text-red-700'\n };\n case 'warn':\n case 'warning':\n return {\n container: 'bg-amber-50 border-amber-100',\n title: 'text-amber-800',\n content: 'text-amber-700'\n };\n case 'success':\n return {\n container: 'bg-green-50 border-green-100',\n title: 'text-green-800',\n content: 'text-green-700'\n };\n case 'info':\n default:\n return {\n container: 'bg-blue-50 border-blue-100',\n title: 'text-blue-800',\n content: 'text-blue-700'\n };\n }\n };\n\n const styles = getLevelStyles();\n\n return (\n <div className={`mt-2 mb-4 p-4 ${styles.container} border rounded-md`}>\n {title && (\n <div className={`font-medium ${styles.title} mb-2`}>{title}</div>\n )}\n <div className={`text-sm ${styles.content}`}>\n {format === 'markdown' ? (\n <ReactMarkdown className=\"prose prose-sm max-w-none\">\n {content}\n </ReactMarkdown>\n ) : format === 'html' ? (\n <div dangerouslySetInnerHTML={{ __html: content }} />\n ) : (\n <div className=\"whitespace-pre-wrap\">{content}</div>\n )}\n </div>\n </div>\n );\n};\n\nexport default PresentInteraction;\n","'use client';\n\nimport React from 'react';\nimport { InteractiveMessage } from '../../types/interactive';\nimport ConfirmInteraction from './ConfirmInteraction';\nimport SelectInteraction from './SelectInteraction';\nimport FormInteraction from './FormInteraction';\nimport PresentInteraction from './PresentInteraction';\n\ninterface InteractiveMessageHandlerProps {\n message: InteractiveMessage;\n onResponse: (response: any) => void;\n isResponseSubmitted: boolean;\n parentMessage?: any; // Add reference to the parent ChatMessage\n}\n\n/**\n * Component that handles rendering different types of interactive messages\n * based on the function type (chat, confirm, select, form, present)\n */\nconst InteractiveMessageHandler: React.FC<InteractiveMessageHandlerProps> = ({\n message,\n onResponse,\n isResponseSubmitted,\n parentMessage\n}) => {\n const { function: functionType, parameters } = message;\n\n // Extract submitted response from parent message if available\n const submittedResponse = parentMessage?.responseValue;\n\n // Render the appropriate interaction component based on the function type\n switch (functionType) {\n case 'confirm':\n return (\n <ConfirmInteraction\n parameters={parameters}\n onResponse={onResponse}\n isResponseSubmitted={isResponseSubmitted}\n />\n );\n\n case 'select':\n return (\n <SelectInteraction\n parameters={parameters}\n onResponse={onResponse}\n isResponseSubmitted={isResponseSubmitted}\n message={parentMessage}\n />\n );\n\n case 'form':\n return (\n <FormInteraction\n parameters={parameters}\n onResponse={onResponse}\n isResponseSubmitted={isResponseSubmitted}\n submittedValues={submittedResponse}\n />\n );\n\n case 'present':\n return (\n <PresentInteraction\n parameters={parameters}\n />\n );\n\n case 'chat':\n // Chat is handled by the main input form, so we don't need a special component\n return null;\n\n default:\n console.warn(`Unknown interactive function type: ${functionType}`);\n return null;\n }\n};\n\nexport default InteractiveMessageHandler;\n","'use client';\n\nimport React from 'react';\nimport { Wifi, WifiOff, RefreshCw } from 'lucide-react';\n\ninterface ConnectionStatusProps {\n connectionStatus: 'connected' | 'disconnected' | 'reconnecting';\n onReconnect: () => void;\n}\n\nexport const ConnectionStatus: React.FC<ConnectionStatusProps> = ({\n connectionStatus,\n onReconnect\n}) => {\n return (\n <div className=\"bg-amber-100 connection-status flex items-center justify-between px-4 py-1 text-xs\">\n <div className=\"text-gray-700 font-medium\">\n You are talking with your personal Content Strategist\n </div>\n {connectionStatus === 'connected' && (\n <div className=\"flex items-center text-green-600\">\n <Wifi className=\"w-3 h-3 mr-1\" />\n <span>Connected</span>\n </div>\n )}\n {connectionStatus === 'reconnecting' && (\n <div className=\"flex items-center text-amber-600\">\n <RefreshCw className=\"w-3 h-3 mr-1 animate-spin\" />\n <span>Reconnecting...</span>\n </div>\n )}\n {connectionStatus === 'disconnected' && (\n <div className=\"flex items-center gap-2\">\n <div className=\"text-red-600 flex items-center\">\n <WifiOff className=\"w-3 h-3 mr-1\" />\n <span>Disconnected</span>\n </div>\n <button\n onClick={onReconnect}\n className=\"text-blue-600 hover:text-blue-800 flex items-center\"\n >\n <RefreshCw className=\"w-3 h-3 mr-1\" />\n <span>Reconnect</span>\n </button>\n </div>\n )}\n </div>\n );\n}\n","import React from 'react';\n\ninterface SpinnerProps {\n size?: 'sm' | 'md' | 'lg' | 'xl';\n className?: string;\n color?: string;\n}\n\nexport const Spinner: React.FC<SpinnerProps> = ({\n size = 'md',\n className = '',\n color = 'text-blue-600'\n}) => {\n const sizeClasses = {\n sm: 'h-4 w-4',\n md: 'h-6 w-6',\n lg: 'h-8 w-8',\n xl: 'h-12 w-12'\n };\n\n return (\n <svg\n className={`animate-spin ${sizeClasses[size]} ${color} ${className}`}\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n );\n};\n","/**\n * Lightweight client for sending audio to a backend transcription endpoint.\n * This keeps the API key secret on the server.\n */\n\nexport interface TranscriptionConfig {\n endpoint: string;\n language?: string;\n // No headers needed if using standard fetch or cookies\n // Add custom headers support if needed for token auth\n headers?: Record<string, string>;\n}\n\nexport interface TranscriptionResult {\n text: string;\n error?: string;\n}\n\n/**\n * Transcribe audio blob by sending it to the configured backend endpoint.\n */\nexport async function transcribeAudio(\n audioBlob: Blob,\n config: TranscriptionConfig\n): Promise<string> {\n const formData = new FormData();\n formData.append('audio', audioBlob, 'recording.webm');\n\n if (config.language) {\n formData.append('language', config.language);\n }\n\n try {\n const response = await fetch(config.endpoint, {\n method: 'POST',\n body: formData,\n headers: config.headers || {},\n credentials: 'same-origin', // Ensure cookies are sent for same-domain requests\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Transcription failed (${response.status}): ${errorText}`);\n }\n\n const data = await response.json();\n return data.text;\n } catch (error: any) {\n console.error('Transcription client error:', error);\n throw error;\n }\n}\n","import { VoiceConfig } from '../types/chat';\nimport { TranscriptionConfig, transcribeAudio } from '../services/whisper-client';\n\n/**\n * Helper to create a VoiceConfig that uses the backend Whisper transcription service.\n * \n * @param config - Configuration for the transcription endpoint\n * @param callbacks - Optional callbacks for voice events\n * @returns VoiceConfig ready to be used in ChatInputArea\n */\nexport function createWhisperVoiceConfig(\n config: TranscriptionConfig,\n callbacks?: {\n onVoiceStart?: () => void;\n onVoiceEnd?: () => void;\n }\n): VoiceConfig {\n return {\n mode: 'custom',\n onVoiceStart: callbacks?.onVoiceStart,\n onVoiceEnd: callbacks?.onVoiceEnd,\n /**\n * The core handler: takes the recorded blob and sends it to the server.\n */\n onAudioCapture: async (blob: Blob) => {\n return await transcribeAudio(blob, config);\n }\n };\n}\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","ReactMarkdown","remarkGfm","import_jsx_runtime","import_react","import_react","error","import_react","import_react","import_jsx_runtime","_a","_b","_c","import_react","import_outline","import_jsx_runtime","React","e","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","ReactMarkdown","import_jsx_runtime","import_outline","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_jsx_runtime"]}